blob: 33bb0bda355dac1a514109b294b1f87018daab4a [file] [log] [blame]
Umesh Krishnaswamy345ee992012-12-13 20:29:48 -08001/**
2* Copyright 2011, Big Switch Networks, Inc.
3* Originally created by David Erickson & Rob Sherwood, Stanford University
4*
5* Licensed under the Apache License, Version 2.0 (the "License"); you may
6* not use this file except in compliance with the License. You may obtain
7* a copy of the License at
8*
9* http://www.apache.org/licenses/LICENSE-2.0
10*
11* Unless required by applicable law or agreed to in writing, software
12* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
13* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
14* License for the specific language governing permissions and limitations
15* under the License.
16**/
17
18package org.openflow.protocol.vendor;
19
20import java.util.HashMap;
21import java.util.Map;
22
23import org.jboss.netty.buffer.ChannelBuffer;
24import org.openflow.protocol.Instantiable;
25
26/**
27 * Basic subclass of OFVendorId that works with any vendor data format where
28 * the data begins with an integral data type value.
29 *
30 * @author Rob Vaterlaus (rob.vaterlaus@bigswitch.com)
31 */
32public class OFBasicVendorId extends OFVendorId {
33
34 /**
35 * The size of the data type value at the beginning of all vendor
36 * data associated with this vendor id. The data type size must be
37 * either 1, 2, 4 or 8.
38 */
39 protected int dataTypeSize;
40
41 /**
42 * Map of the vendor data types that have been registered for this
43 * vendor id.
44 */
45 protected Map<Long, OFBasicVendorDataType> dataTypeMap =
46 new HashMap<Long, OFBasicVendorDataType>();
47
48 /**
49 * Construct an OFVendorId that where the vendor data begins
50 * with a data type value whose size is dataTypeSize.
51 * @param id the id of the vendor, typically the OUI of a vendor
52 * prefixed with 0.
53 * @param dataTypeSize the size of the integral data type value
54 * at the beginning of the vendor data. The value must be the
55 * size of an integeral data type (i.e. either 1,2,4 or 8).
56 */
57 public OFBasicVendorId(int id, int dataTypeSize) {
58 super(id);
59 assert (dataTypeSize == 1) || (dataTypeSize == 2) ||
60 (dataTypeSize == 4) || (dataTypeSize == 8);
61 this.dataTypeSize = dataTypeSize;
62 }
63
64 /**
65 * Get the size of the data type value at the beginning of the vendor
66 * data. OFBasicVendorId assumes that this value is common across all of
67 * the vendor data formats associated with a given vendor id.
68 * @return
69 */
70 public int getDataTypeSize() {
71 return dataTypeSize;
72 }
73
74 /**
75 * Register a vendor data type with this vendor id.
76 * @param vendorDataType
77 */
78 public void registerVendorDataType(OFBasicVendorDataType vendorDataType) {
79 dataTypeMap.put(vendorDataType.getTypeValue(), vendorDataType);
80 }
81
82 /**
83 * Lookup the OFVendorDataType instance that has been registered with
84 * this vendor id.
85 *
86 * @param vendorDataType the integer code that was parsed from the
87 * @return
88 */
89 public OFVendorDataType lookupVendorDataType(int vendorDataType) {
Naoki Shiota1a5ca912014-01-03 17:02:31 -080090 return dataTypeMap.get((long)vendorDataType);
Umesh Krishnaswamy345ee992012-12-13 20:29:48 -080091 }
92
93 /**
94 * This function parses enough of the data from the buffer to be able
95 * to determine the appropriate OFVendorDataType for the data. It is meant
96 * to be a reasonably generic implementation that will work for most
97 * formats of vendor extensions. If the vendor data doesn't fit the
98 * assumptions listed below, then this method will need to be overridden
99 * to implement custom parsing.
100 *
101 * This implementation assumes that the vendor data begins with a data
102 * type code that is used to distinguish different formats of vendor
103 * data associated with a particular vendor ID.
104 * The exact format of the data is vendor-defined, so we don't know how
105 * how big the code is (or really even if there is a code). This code
106 * assumes that the common case will be that the data does include
107 * an initial type code (i.e. so that the vendor can have multiple
108 * message/data types) and that the size is either 1, 2 or 4 bytes.
109 * The size of the initial type code is configured by the subclass of
110 * OFVendorId.
111 *
112 * @param data the channel buffer containing the vendor data.
113 * @param length the length to the end of the enclosing message
114 * @return the OFVendorDataType that can be used to instantiate the
115 * appropriate subclass of OFVendorData.
116 */
117 public OFVendorDataType parseVendorDataType(ChannelBuffer data, int length) {
118 OFVendorDataType vendorDataType = null;
119
120 // Parse out the type code from the vendor data.
121 long dataTypeValue = 0;
122 if ((length == 0) || (length >= dataTypeSize)) {
123 switch (dataTypeSize) {
124 case 1:
125 dataTypeValue = data.readByte();
126 break;
127 case 2:
128 dataTypeValue = data.readShort();
129 break;
130 case 4:
131 dataTypeValue = data.readInt();
132 break;
133 case 8:
134 dataTypeValue = data.readLong();
135 break;
136 default:
137 // This would be indicative of a coding error where the
138 // dataTypeSize was specified incorrectly. This should have been
139 // caught in the constructor for OFVendorId.
140 assert false;
141 }
142
143 vendorDataType = dataTypeMap.get(dataTypeValue);
144 }
145
146 // If we weren't able to parse/map the data to a known OFVendorDataType,
147 // then map it to a generic vendor data type.
148 if (vendorDataType == null) {
149 vendorDataType = new OFBasicVendorDataType(dataTypeValue,
150 new Instantiable<OFVendorData>() {
151 @Override
152 public OFVendorData instantiate() {
153 return new OFByteArrayVendorData();
154 }
155 }
156 );
157 }
158
159 return vendorDataType;
160 }
161
162}