Performacne improvements via adding a netty-based openflowj and openflow plugin;...
[controller.git] / third-party / openflowj_netty / src / main / java / org / openflow / protocol / vendor / OFBasicVendorId.java
diff --git a/third-party/openflowj_netty/src/main/java/org/openflow/protocol/vendor/OFBasicVendorId.java b/third-party/openflowj_netty/src/main/java/org/openflow/protocol/vendor/OFBasicVendorId.java
new file mode 100644 (file)
index 0000000..5f789dc
--- /dev/null
@@ -0,0 +1,162 @@
+/**
+*    Copyright 2011, Big Switch Networks, Inc. 
+*    Originally created by David Erickson & Rob Sherwood, Stanford University
+* 
+*    Licensed under the Apache License, Version 2.0 (the "License"); you may
+*    not use this file except in compliance with the License. You may obtain
+*    a copy of the License at
+*
+*         http://www.apache.org/licenses/LICENSE-2.0
+*
+*    Unless required by applicable law or agreed to in writing, software
+*    distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+*    WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+*    License for the specific language governing permissions and limitations
+*    under the License.
+**/
+
+package org.openflow.protocol.vendor;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import org.jboss.netty.buffer.ChannelBuffer;
+import org.openflow.protocol.Instantiable;
+
+/**
+ * Basic subclass of OFVendorId that works with any vendor data format where
+ * the data begins with an integral data type value.
+ * 
+ * @author Rob Vaterlaus (rob.vaterlaus@bigswitch.com)
+ */
+public class OFBasicVendorId extends OFVendorId {
+    
+    /**
+     * The size of the data type value at the beginning of all vendor
+     * data associated with this vendor id. The data type size must be
+     * either 1, 2, 4 or 8.
+     */
+    protected int dataTypeSize;
+    
+    /**
+     * Map of the vendor data types that have been registered for this
+     * vendor id.
+     */
+    protected Map<Long, OFBasicVendorDataType> dataTypeMap =
+            new HashMap<Long, OFBasicVendorDataType>();
+    
+    /**
+     * Construct an OFVendorId that where the vendor data begins
+     * with a data type value whose size is dataTypeSize.
+     * @param id the id of the vendor, typically the OUI of a vendor
+     *     prefixed with 0.
+     * @param dataTypeSize the size of the integral data type value
+     *     at the beginning of the vendor data. The value must be the
+     *     size of an integeral data type (i.e. either 1,2,4 or 8).
+     */
+    public OFBasicVendorId(int id, int dataTypeSize) {
+        super(id);
+        assert (dataTypeSize == 1) || (dataTypeSize == 2) ||
+               (dataTypeSize == 4) || (dataTypeSize == 8);
+        this.dataTypeSize = dataTypeSize;
+    }
+
+    /**
+     * Get the size of the data type value at the beginning of the vendor
+     * data. OFBasicVendorId assumes that this value is common across all of
+     * the vendor data formats associated with a given vendor id.
+     * @return
+     */
+    public int getDataTypeSize() {
+        return dataTypeSize;
+    }
+    
+    /**
+     * Register a vendor data type with this vendor id.
+     * @param vendorDataType
+     */
+    public void registerVendorDataType(OFBasicVendorDataType vendorDataType) {
+        dataTypeMap.put(vendorDataType.getTypeValue(), vendorDataType);
+    }
+    
+    /**
+     * Lookup the OFVendorDataType instance that has been registered with
+     * this vendor id.
+     * 
+     * @param vendorDataType the integer code that was parsed from the 
+     * @return
+     */
+    public OFVendorDataType lookupVendorDataType(int vendorDataType) {
+        return dataTypeMap.get(Long.valueOf(vendorDataType));
+    }
+
+    /**
+     * This function parses enough of the data from the buffer to be able
+     * to determine the appropriate OFVendorDataType for the data. It is meant
+     * to be a reasonably generic implementation that will work for most
+     * formats of vendor extensions. If the vendor data doesn't fit the
+     * assumptions listed below, then this method will need to be overridden
+     * to implement custom parsing.
+     * 
+     * This implementation assumes that the vendor data begins with a data
+     * type code that is used to distinguish different formats of vendor
+     * data associated with a particular vendor ID.
+     * The exact format of the data is vendor-defined, so we don't know how
+     * how big the code is (or really even if there is a code). This code
+     * assumes that the common case will be that the data does include
+     * an initial type code (i.e. so that the vendor can have multiple
+     * message/data types) and that the size is either 1, 2 or 4 bytes.
+     * The size of the initial type code is configured by the subclass of
+     * OFVendorId.
+     * 
+     * @param data the channel buffer containing the vendor data.
+     * @param length the length to the end of the enclosing message
+     * @return the OFVendorDataType that can be used to instantiate the
+     *         appropriate subclass of OFVendorData.
+     */
+    public OFVendorDataType parseVendorDataType(ChannelBuffer data, int length) {
+        OFVendorDataType vendorDataType = null;
+        
+        // Parse out the type code from the vendor data.
+        long dataTypeValue = 0;
+        if ((length == 0) || (length >= dataTypeSize)) {
+            switch (dataTypeSize) {
+                case 1:
+                    dataTypeValue = data.readByte();
+                    break;
+                case 2:
+                    dataTypeValue = data.readShort();
+                    break;
+                case 4:
+                    dataTypeValue = data.readInt();
+                    break;
+                case 8:
+                    dataTypeValue = data.readLong();
+                    break;
+                default:
+                    // This would be indicative of a coding error where the
+                    // dataTypeSize was specified incorrectly. This should have been
+                    // caught in the constructor for OFVendorId.
+                    assert false;
+            }
+            
+            vendorDataType = dataTypeMap.get(dataTypeValue);
+        }
+        
+        // If we weren't able to parse/map the data to a known OFVendorDataType,
+        // then map it to a generic vendor data type.
+        if (vendorDataType == null) {
+            vendorDataType = new OFBasicVendorDataType(dataTypeValue,
+                new Instantiable<OFVendorData>() {
+                    @Override
+                    public OFVendorData instantiate() {
+                        return new OFByteArrayVendorData();
+                    }
+                }
+            );
+        }
+        
+        return vendorDataType;
+    }
+
+}