Extend openflow-protocol-impl serialization
[openflowjava.git] / openflow-protocol-impl / src / main / java / org / opendaylight / openflowjava / protocol / impl / deserialization / factories / MultipartRequestInputMessageFactory.java
1 /*
2  * Copyright (c) 2015 NetIDE Consortium and others.  All rights reserved.
3  *
4  * This program and the accompanying materials are made available under the
5  * terms of the Eclipse Public License v1.0 which accompanies this distribution,
6  * and is available at http://www.eclipse.org/legal/epl-v10.html
7  */
8 package org.opendaylight.openflowjava.protocol.impl.deserialization.factories;
9
10 import io.netty.buffer.ByteBuf;
11 import java.math.BigInteger;
12 import java.util.ArrayList;
13 import java.util.List;
14 import org.opendaylight.openflowjava.protocol.api.extensibility.DeserializerRegistry;
15 import org.opendaylight.openflowjava.protocol.api.extensibility.DeserializerRegistryInjector;
16 import org.opendaylight.openflowjava.protocol.api.extensibility.OFDeserializer;
17 import org.opendaylight.openflowjava.protocol.api.keys.MessageCodeKey;
18 import org.opendaylight.openflowjava.protocol.api.util.EncodeConstants;
19 import org.opendaylight.openflowjava.protocol.impl.util.CodeKeyMaker;
20 import org.opendaylight.openflowjava.protocol.impl.util.CodeKeyMakerFactory;
21 import org.opendaylight.openflowjava.protocol.impl.util.ListDeserializer;
22 import org.opendaylight.openflowjava.util.ByteBufUtils;
23 import org.opendaylight.openflowjava.util.ExperimenterDeserializerKeyFactory;
24 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.augments.rev150225.ActionRelatedTableFeatureProperty;
25 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.augments.rev150225.ActionRelatedTableFeaturePropertyBuilder;
26 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.augments.rev150225.InstructionRelatedTableFeatureProperty;
27 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.augments.rev150225.InstructionRelatedTableFeaturePropertyBuilder;
28 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.augments.rev150225.NextTableRelatedTableFeatureProperty;
29 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.augments.rev150225.NextTableRelatedTableFeaturePropertyBuilder;
30 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.augments.rev150225.OxmRelatedTableFeatureProperty;
31 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.augments.rev150225.OxmRelatedTableFeaturePropertyBuilder;
32 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.augments.rev150225.table.features.properties.container.table.feature.properties.NextTableIds;
33 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.augments.rev150225.table.features.properties.container.table.feature.properties.NextTableIdsBuilder;
34 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.action.rev150203.actions.grouping.Action;
35 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.instruction.rev130731.instructions.grouping.Instruction;
36 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.GroupId;
37 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.MeterId;
38 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.MultipartRequestFlags;
39 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.MultipartType;
40 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.TableConfig;
41 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.TableFeaturesPropType;
42 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.match.entries.grouping.MatchEntry;
43 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.match.grouping.Match;
44 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.MultipartRequestInput;
45 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.MultipartRequestInputBuilder;
46 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.request.multipart.request.body.MultipartRequestAggregateCase;
47 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.request.multipart.request.body.MultipartRequestAggregateCaseBuilder;
48 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.request.multipart.request.body.MultipartRequestDescCase;
49 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.request.multipart.request.body.MultipartRequestDescCaseBuilder;
50 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.request.multipart.request.body.MultipartRequestExperimenterCase;
51 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.request.multipart.request.body.MultipartRequestExperimenterCaseBuilder;
52 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.request.multipart.request.body.MultipartRequestFlowCase;
53 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.request.multipart.request.body.MultipartRequestFlowCaseBuilder;
54 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.request.multipart.request.body.MultipartRequestGroupCase;
55 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.request.multipart.request.body.MultipartRequestGroupCaseBuilder;
56 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.request.multipart.request.body.MultipartRequestGroupDescCase;
57 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.request.multipart.request.body.MultipartRequestGroupDescCaseBuilder;
58 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.request.multipart.request.body.MultipartRequestGroupFeaturesCase;
59 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.request.multipart.request.body.MultipartRequestGroupFeaturesCaseBuilder;
60 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.request.multipart.request.body.MultipartRequestMeterCase;
61 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.request.multipart.request.body.MultipartRequestMeterCaseBuilder;
62 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.request.multipart.request.body.MultipartRequestMeterConfigCase;
63 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.request.multipart.request.body.MultipartRequestMeterConfigCaseBuilder;
64 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.request.multipart.request.body.MultipartRequestMeterFeaturesCase;
65 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.request.multipart.request.body.MultipartRequestMeterFeaturesCaseBuilder;
66 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.request.multipart.request.body.MultipartRequestPortDescCase;
67 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.request.multipart.request.body.MultipartRequestPortDescCaseBuilder;
68 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.request.multipart.request.body.MultipartRequestPortStatsCase;
69 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.request.multipart.request.body.MultipartRequestPortStatsCaseBuilder;
70 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.request.multipart.request.body.MultipartRequestQueueCase;
71 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.request.multipart.request.body.MultipartRequestQueueCaseBuilder;
72 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.request.multipart.request.body.MultipartRequestTableCase;
73 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.request.multipart.request.body.MultipartRequestTableCaseBuilder;
74 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.request.multipart.request.body.MultipartRequestTableFeaturesCase;
75 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.request.multipart.request.body.MultipartRequestTableFeaturesCaseBuilder;
76 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.request.multipart.request.body.multipart.request.aggregate._case.MultipartRequestAggregateBuilder;
77 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.request.multipart.request.body.multipart.request.desc._case.MultipartRequestDescBuilder;
78 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.request.multipart.request.body.multipart.request.experimenter._case.MultipartRequestExperimenterBuilder;
79 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.request.multipart.request.body.multipart.request.flow._case.MultipartRequestFlowBuilder;
80 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.request.multipart.request.body.multipart.request.group._case.MultipartRequestGroupBuilder;
81 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.request.multipart.request.body.multipart.request.group.desc._case.MultipartRequestGroupDescBuilder;
82 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.request.multipart.request.body.multipart.request.group.features._case.MultipartRequestGroupFeaturesBuilder;
83 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.request.multipart.request.body.multipart.request.meter._case.MultipartRequestMeterBuilder;
84 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.request.multipart.request.body.multipart.request.meter.config._case.MultipartRequestMeterConfigBuilder;
85 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.request.multipart.request.body.multipart.request.meter.features._case.MultipartRequestMeterFeaturesBuilder;
86 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.request.multipart.request.body.multipart.request.port.desc._case.MultipartRequestPortDescBuilder;
87 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.request.multipart.request.body.multipart.request.port.stats._case.MultipartRequestPortStatsBuilder;
88 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.request.multipart.request.body.multipart.request.queue._case.MultipartRequestQueueBuilder;
89 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.request.multipart.request.body.multipart.request.table._case.MultipartRequestTableBuilder;
90 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.request.multipart.request.body.multipart.request.table.features._case.MultipartRequestTableFeaturesBuilder;
91 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.request.multipart.request.body.multipart.request.table.features._case.multipart.request.table.features.TableFeatures;
92 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.request.multipart.request.body.multipart.request.table.features._case.multipart.request.table.features.TableFeaturesBuilder;
93 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.table.features.properties.grouping.TableFeatureProperties;
94 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.table.features.properties.grouping.TableFeaturePropertiesBuilder;
95
96 /**
97  * @author giuseppex.petralia@intel.com
98  *
99  */
100 public class MultipartRequestInputMessageFactory
101         implements OFDeserializer<MultipartRequestInput>, DeserializerRegistryInjector {
102     private DeserializerRegistry registry;
103     private static final byte PADDING = 4;
104     private static final byte FLOW_PADDING_1 = 3;
105     private static final byte FLOW_PADDING_2 = 4;
106     private static final byte AGGREGATE_PADDING_1 = 3;
107     private static final byte AGGREGATE_PADDING_2 = 4;
108     private static final byte PADDING_IN_MULTIPART_REQUEST_TABLE_FEATURES = 5;
109     private static final byte MAX_TABLE_NAME_LENGTH = 32;
110     private static final byte MULTIPART_REQUEST_TABLE_FEATURES_STRUCTURE_LENGTH = 64;
111     private static final byte COMMON_PROPERTY_LENGTH = 4;
112
113     @Override
114     public void injectDeserializerRegistry(DeserializerRegistry deserializerRegistry) {
115         registry = deserializerRegistry;
116     }
117
118     @Override
119     public MultipartRequestInput deserialize(ByteBuf rawMessage) {
120         MultipartRequestInputBuilder builder = new MultipartRequestInputBuilder();
121         builder.setVersion((short) EncodeConstants.OF13_VERSION_ID);
122         builder.setXid(rawMessage.readUnsignedInt());
123         int type = rawMessage.readUnsignedShort();
124         builder.setType(getMultipartType(type));
125         builder.setFlags(getMultipartRequestFlags(rawMessage.readUnsignedShort()));
126         rawMessage.skipBytes(PADDING);
127         switch (MultipartType.forValue(type)) {
128         case OFPMPDESC:
129             builder.setMultipartRequestBody(setDesc(rawMessage));
130             break;
131         case OFPMPFLOW:
132             builder.setMultipartRequestBody(setFlow(rawMessage));
133             break;
134         case OFPMPAGGREGATE:
135             builder.setMultipartRequestBody(setAggregate(rawMessage));
136             break;
137         case OFPMPTABLE:
138             builder.setMultipartRequestBody(setTable(rawMessage));
139             break;
140         case OFPMPTABLEFEATURES:
141             builder.setMultipartRequestBody(setTableFeatures(rawMessage));
142             break;
143         case OFPMPPORTSTATS:
144             builder.setMultipartRequestBody(setPortStats(rawMessage));
145             break;
146         case OFPMPPORTDESC:
147             builder.setMultipartRequestBody(setPortDesc(rawMessage));
148             break;
149         case OFPMPQUEUE:
150             builder.setMultipartRequestBody(setQueue(rawMessage));
151             break;
152         case OFPMPGROUP:
153             builder.setMultipartRequestBody(setGroup(rawMessage));
154             break;
155         case OFPMPGROUPDESC:
156             builder.setMultipartRequestBody(setGroupDesc(rawMessage));
157             break;
158         case OFPMPGROUPFEATURES:
159             builder.setMultipartRequestBody(setGroupFeatures(rawMessage));
160             break;
161         case OFPMPMETER:
162             builder.setMultipartRequestBody(setMeter(rawMessage));
163             break;
164         case OFPMPMETERCONFIG:
165             builder.setMultipartRequestBody(setMeterConfig(rawMessage));
166             break;
167         case OFPMPMETERFEATURES:
168             builder.setMultipartRequestBody(setMeterFeatures(rawMessage));
169             break;
170         case OFPMPEXPERIMENTER:
171             builder.setMultipartRequestBody(setExperimenter(rawMessage));
172             break;
173         default:
174             break;
175         }
176
177         return builder.build();
178     }
179
180     private static MultipartType getMultipartType(int input) {
181         return MultipartType.forValue(input);
182     }
183
184     private static MultipartRequestFlags getMultipartRequestFlags(int input) {
185         final Boolean _oFPMPFREQMORE = (input & (1 << 0)) > 0;
186         MultipartRequestFlags flag = new MultipartRequestFlags(_oFPMPFREQMORE);
187         return flag;
188     }
189
190     private MultipartRequestTableFeaturesCase setTableFeatures(ByteBuf input) {
191         MultipartRequestTableFeaturesCaseBuilder caseBuilder = new MultipartRequestTableFeaturesCaseBuilder();
192         MultipartRequestTableFeaturesBuilder tableFeaturesBuilder = new MultipartRequestTableFeaturesBuilder();
193         List<TableFeatures> features = new ArrayList<>();
194         while (input.readableBytes() > 0) {
195             TableFeaturesBuilder featuresBuilder = new TableFeaturesBuilder();
196             int length = input.readUnsignedShort();
197             featuresBuilder.setTableId(input.readUnsignedByte());
198             input.skipBytes(PADDING_IN_MULTIPART_REQUEST_TABLE_FEATURES);
199             featuresBuilder.setName(ByteBufUtils.decodeNullTerminatedString(input, MAX_TABLE_NAME_LENGTH));
200             byte[] metadataMatch = new byte[EncodeConstants.SIZE_OF_LONG_IN_BYTES];
201             input.readBytes(metadataMatch);
202             featuresBuilder.setMetadataMatch(new BigInteger(1, metadataMatch));
203             byte[] metadataWrite = new byte[EncodeConstants.SIZE_OF_LONG_IN_BYTES];
204             input.readBytes(metadataWrite);
205             featuresBuilder.setMetadataWrite(new BigInteger(1, metadataWrite));
206             featuresBuilder.setConfig(createTableConfig(input.readUnsignedInt()));
207             featuresBuilder.setMaxEntries(input.readUnsignedInt());
208             featuresBuilder.setTableFeatureProperties(
209                     createTableFeaturesProperties(input, length - MULTIPART_REQUEST_TABLE_FEATURES_STRUCTURE_LENGTH));
210             features.add(featuresBuilder.build());
211         }
212         tableFeaturesBuilder.setTableFeatures(features);
213         caseBuilder.setMultipartRequestTableFeatures(tableFeaturesBuilder.build());
214         return caseBuilder.build();
215     }
216
217     private List<TableFeatureProperties> createTableFeaturesProperties(ByteBuf input, int length) {
218         List<TableFeatureProperties> properties = new ArrayList<>();
219         int tableFeaturesLength = length;
220         while (tableFeaturesLength > 0) {
221             int propStartIndex = input.readerIndex();
222             TableFeaturePropertiesBuilder builder = new TableFeaturePropertiesBuilder();
223             TableFeaturesPropType type = TableFeaturesPropType.forValue(input.readUnsignedShort());
224             builder.setType(type);
225             int propertyLength = input.readUnsignedShort();
226             int paddingRemainder = propertyLength % EncodeConstants.PADDING;
227             tableFeaturesLength -= propertyLength;
228             if (type.equals(TableFeaturesPropType.OFPTFPTINSTRUCTIONS)
229                     || type.equals(TableFeaturesPropType.OFPTFPTINSTRUCTIONSMISS)) {
230                 InstructionRelatedTableFeaturePropertyBuilder insBuilder = new InstructionRelatedTableFeaturePropertyBuilder();
231                 CodeKeyMaker keyMaker = CodeKeyMakerFactory.createInstructionsKeyMaker(EncodeConstants.OF13_VERSION_ID);
232                 List<Instruction> instructions = ListDeserializer.deserializeHeaders(EncodeConstants.OF13_VERSION_ID,
233                         propertyLength - COMMON_PROPERTY_LENGTH, input, keyMaker, registry);
234                 insBuilder.setInstruction(instructions);
235                 builder.addAugmentation(InstructionRelatedTableFeatureProperty.class, insBuilder.build());
236             } else if (type.equals(TableFeaturesPropType.OFPTFPTNEXTTABLES)
237                     || type.equals(TableFeaturesPropType.OFPTFPTNEXTTABLESMISS)) {
238                 propertyLength -= COMMON_PROPERTY_LENGTH;
239                 NextTableRelatedTableFeaturePropertyBuilder tableBuilder = new NextTableRelatedTableFeaturePropertyBuilder();
240                 List<NextTableIds> ids = new ArrayList<>();
241                 while (propertyLength > 0) {
242                     NextTableIdsBuilder nextTableIdsBuilder = new NextTableIdsBuilder();
243                     nextTableIdsBuilder.setTableId(input.readUnsignedByte());
244                     ids.add(nextTableIdsBuilder.build());
245                     propertyLength--;
246                 }
247                 tableBuilder.setNextTableIds(ids);
248                 builder.addAugmentation(NextTableRelatedTableFeatureProperty.class, tableBuilder.build());
249             } else if (type.equals(TableFeaturesPropType.OFPTFPTWRITEACTIONS)
250                     || type.equals(TableFeaturesPropType.OFPTFPTWRITEACTIONSMISS)
251                     || type.equals(TableFeaturesPropType.OFPTFPTAPPLYACTIONS)
252                     || type.equals(TableFeaturesPropType.OFPTFPTAPPLYACTIONSMISS)) {
253                 ActionRelatedTableFeaturePropertyBuilder actionBuilder = new ActionRelatedTableFeaturePropertyBuilder();
254                 CodeKeyMaker keyMaker = CodeKeyMakerFactory.createActionsKeyMaker(EncodeConstants.OF13_VERSION_ID);
255                 List<Action> actions = ListDeserializer.deserializeHeaders(EncodeConstants.OF13_VERSION_ID,
256                         propertyLength - COMMON_PROPERTY_LENGTH, input, keyMaker, registry);
257                 actionBuilder.setAction(actions);
258                 builder.addAugmentation(ActionRelatedTableFeatureProperty.class, actionBuilder.build());
259             } else if (type.equals(TableFeaturesPropType.OFPTFPTMATCH)
260                     || type.equals(TableFeaturesPropType.OFPTFPTWILDCARDS)
261                     || type.equals(TableFeaturesPropType.OFPTFPTWRITESETFIELD)
262                     || type.equals(TableFeaturesPropType.OFPTFPTWRITESETFIELDMISS)
263                     || type.equals(TableFeaturesPropType.OFPTFPTAPPLYSETFIELD)
264                     || type.equals(TableFeaturesPropType.OFPTFPTAPPLYSETFIELDMISS)) {
265                 OxmRelatedTableFeaturePropertyBuilder oxmBuilder = new OxmRelatedTableFeaturePropertyBuilder();
266                 CodeKeyMaker keyMaker = CodeKeyMakerFactory.createMatchEntriesKeyMaker(EncodeConstants.OF13_VERSION_ID);
267                 List<MatchEntry> entries = ListDeserializer.deserializeHeaders(EncodeConstants.OF13_VERSION_ID,
268                         propertyLength - COMMON_PROPERTY_LENGTH, input, keyMaker, registry);
269                 oxmBuilder.setMatchEntry(entries);
270                 builder.addAugmentation(OxmRelatedTableFeatureProperty.class, oxmBuilder.build());
271             } else if (type.equals(TableFeaturesPropType.OFPTFPTEXPERIMENTER)
272                     || type.equals(TableFeaturesPropType.OFPTFPTEXPERIMENTERMISS)) {
273                 long expId = input.readUnsignedInt();
274                 input.readerIndex(propStartIndex);
275                 OFDeserializer<TableFeatureProperties> propDeserializer = registry
276                         .getDeserializer(ExperimenterDeserializerKeyFactory
277                                 .createMultipartReplyTFDeserializerKey(EncodeConstants.OF13_VERSION_ID, expId));
278                 TableFeatureProperties expProp = propDeserializer.deserialize(input);
279                 properties.add(expProp);
280                 continue;
281             }
282             if (paddingRemainder != 0) {
283                 input.skipBytes(EncodeConstants.PADDING - paddingRemainder);
284                 tableFeaturesLength -= EncodeConstants.PADDING - paddingRemainder;
285             }
286             properties.add(builder.build());
287         }
288         return properties;
289     }
290
291     private static TableConfig createTableConfig(long input) {
292         boolean deprecated = (input & 3) != 0;
293         return new TableConfig(deprecated);
294     }
295
296     private MultipartRequestDescCase setDesc(ByteBuf input) {
297         MultipartRequestDescCaseBuilder caseBuilder = new MultipartRequestDescCaseBuilder();
298         MultipartRequestDescBuilder descBuilder = new MultipartRequestDescBuilder();
299         descBuilder.setEmpty(true);
300         caseBuilder.setMultipartRequestDesc(descBuilder.build());
301         return caseBuilder.build();
302     }
303
304     private MultipartRequestFlowCase setFlow(ByteBuf input) {
305         MultipartRequestFlowCaseBuilder caseBuilder = new MultipartRequestFlowCaseBuilder();
306         MultipartRequestFlowBuilder flowBuilder = new MultipartRequestFlowBuilder();
307         flowBuilder.setTableId(input.readUnsignedByte());
308         input.skipBytes(FLOW_PADDING_1);
309         flowBuilder.setOutPort(input.readUnsignedInt());
310         flowBuilder.setOutGroup(input.readUnsignedInt());
311         input.skipBytes(FLOW_PADDING_2);
312         byte[] cookie = new byte[EncodeConstants.SIZE_OF_LONG_IN_BYTES];
313         input.readBytes(cookie);
314         flowBuilder.setCookie(new BigInteger(1, cookie));
315         byte[] cookie_mask = new byte[EncodeConstants.SIZE_OF_LONG_IN_BYTES];
316         input.readBytes(cookie_mask);
317         flowBuilder.setCookieMask(new BigInteger(1, cookie_mask));
318         OFDeserializer<Match> matchDeserializer = registry.getDeserializer(
319                 new MessageCodeKey(EncodeConstants.OF13_VERSION_ID, EncodeConstants.EMPTY_VALUE, Match.class));
320         flowBuilder.setMatch(matchDeserializer.deserialize(input));
321         caseBuilder.setMultipartRequestFlow(flowBuilder.build());
322         return caseBuilder.build();
323     }
324
325     private MultipartRequestAggregateCase setAggregate(ByteBuf input) {
326         MultipartRequestAggregateCaseBuilder caseBuilder = new MultipartRequestAggregateCaseBuilder();
327         MultipartRequestAggregateBuilder aggregateBuilder = new MultipartRequestAggregateBuilder();
328         aggregateBuilder.setTableId(input.readUnsignedByte());
329         input.skipBytes(AGGREGATE_PADDING_1);
330         aggregateBuilder.setOutPort(input.readUnsignedInt());
331         aggregateBuilder.setOutGroup(input.readUnsignedInt());
332         input.skipBytes(AGGREGATE_PADDING_2);
333         byte[] cookie = new byte[EncodeConstants.SIZE_OF_LONG_IN_BYTES];
334         input.readBytes(cookie);
335         aggregateBuilder.setCookie(new BigInteger(1, cookie));
336         byte[] cookie_mask = new byte[EncodeConstants.SIZE_OF_LONG_IN_BYTES];
337         input.readBytes(cookie_mask);
338         aggregateBuilder.setCookieMask(new BigInteger(1, cookie_mask));
339         OFDeserializer<Match> matchDeserializer = registry.getDeserializer(
340                 new MessageCodeKey(EncodeConstants.OF13_VERSION_ID, EncodeConstants.EMPTY_VALUE, Match.class));
341         aggregateBuilder.setMatch(matchDeserializer.deserialize(input));
342         caseBuilder.setMultipartRequestAggregate(aggregateBuilder.build());
343         return caseBuilder.build();
344     }
345
346     private MultipartRequestPortDescCase setPortDesc(ByteBuf input) {
347         MultipartRequestPortDescCaseBuilder caseBuilder = new MultipartRequestPortDescCaseBuilder();
348         MultipartRequestPortDescBuilder portBuilder = new MultipartRequestPortDescBuilder();
349         portBuilder.setEmpty(true);
350         caseBuilder.setMultipartRequestPortDesc(portBuilder.build());
351         return caseBuilder.build();
352     }
353
354     private MultipartRequestPortStatsCase setPortStats(ByteBuf input) {
355         MultipartRequestPortStatsCaseBuilder caseBuilder = new MultipartRequestPortStatsCaseBuilder();
356         MultipartRequestPortStatsBuilder portBuilder = new MultipartRequestPortStatsBuilder();
357         portBuilder.setPortNo(input.readUnsignedInt());
358         caseBuilder.setMultipartRequestPortStats(portBuilder.build());
359         return caseBuilder.build();
360     }
361
362     private MultipartRequestQueueCase setQueue(ByteBuf input) {
363         MultipartRequestQueueCaseBuilder caseBuilder = new MultipartRequestQueueCaseBuilder();
364         MultipartRequestQueueBuilder queueBuilder = new MultipartRequestQueueBuilder();
365         queueBuilder.setPortNo(input.readUnsignedInt());
366         queueBuilder.setQueueId(input.readUnsignedInt());
367         caseBuilder.setMultipartRequestQueue(queueBuilder.build());
368         return caseBuilder.build();
369     }
370
371     private MultipartRequestGroupCase setGroup(ByteBuf input) {
372         MultipartRequestGroupCaseBuilder caseBuilder = new MultipartRequestGroupCaseBuilder();
373         MultipartRequestGroupBuilder groupBuilder = new MultipartRequestGroupBuilder();
374         groupBuilder.setGroupId(new GroupId(input.readUnsignedInt()));
375         caseBuilder.setMultipartRequestGroup(groupBuilder.build());
376         return caseBuilder.build();
377     }
378
379     private MultipartRequestGroupDescCase setGroupDesc(ByteBuf input) {
380         MultipartRequestGroupDescCaseBuilder caseBuilder = new MultipartRequestGroupDescCaseBuilder();
381         MultipartRequestGroupDescBuilder groupBuilder = new MultipartRequestGroupDescBuilder();
382         groupBuilder.setEmpty(true);
383         caseBuilder.setMultipartRequestGroupDesc(groupBuilder.build());
384         return caseBuilder.build();
385     }
386
387     private MultipartRequestGroupFeaturesCase setGroupFeatures(ByteBuf input) {
388         MultipartRequestGroupFeaturesCaseBuilder caseBuilder = new MultipartRequestGroupFeaturesCaseBuilder();
389         MultipartRequestGroupFeaturesBuilder groupBuilder = new MultipartRequestGroupFeaturesBuilder();
390         groupBuilder.setEmpty(true);
391         caseBuilder.setMultipartRequestGroupFeatures(groupBuilder.build());
392         return caseBuilder.build();
393     }
394
395     private MultipartRequestMeterCase setMeter(ByteBuf input) {
396         MultipartRequestMeterCaseBuilder caseBuilder = new MultipartRequestMeterCaseBuilder();
397         MultipartRequestMeterBuilder meterBuilder = new MultipartRequestMeterBuilder();
398         meterBuilder.setMeterId(new MeterId(input.readUnsignedInt()));
399         caseBuilder.setMultipartRequestMeter(meterBuilder.build());
400         return caseBuilder.build();
401     }
402
403     private MultipartRequestMeterConfigCase setMeterConfig(ByteBuf input) {
404         MultipartRequestMeterConfigCaseBuilder caseBuilder = new MultipartRequestMeterConfigCaseBuilder();
405         MultipartRequestMeterConfigBuilder meterBuilder = new MultipartRequestMeterConfigBuilder();
406         meterBuilder.setMeterId(new MeterId(input.readUnsignedInt()));
407         caseBuilder.setMultipartRequestMeterConfig(meterBuilder.build());
408         return caseBuilder.build();
409     }
410
411     private MultipartRequestMeterFeaturesCase setMeterFeatures(ByteBuf input) {
412         MultipartRequestMeterFeaturesCaseBuilder caseBuilder = new MultipartRequestMeterFeaturesCaseBuilder();
413         MultipartRequestMeterFeaturesBuilder meterBuilder = new MultipartRequestMeterFeaturesBuilder();
414         meterBuilder.setEmpty(true);
415         caseBuilder.setMultipartRequestMeterFeatures(meterBuilder.build());
416         return caseBuilder.build();
417     }
418
419     private MultipartRequestTableCase setTable(ByteBuf input) {
420         MultipartRequestTableCaseBuilder caseBuilder = new MultipartRequestTableCaseBuilder();
421         MultipartRequestTableBuilder tableBuilder = new MultipartRequestTableBuilder();
422         tableBuilder.setEmpty(true);
423         caseBuilder.setMultipartRequestTable(tableBuilder.build());
424         return caseBuilder.build();
425     }
426
427     private MultipartRequestExperimenterCase setExperimenter(ByteBuf input) {
428         MultipartRequestExperimenterCaseBuilder caseBuilder = new MultipartRequestExperimenterCaseBuilder();
429         MultipartRequestExperimenterBuilder experimenterBuilder = new MultipartRequestExperimenterBuilder();
430         caseBuilder.setMultipartRequestExperimenter(experimenterBuilder.build());
431         return caseBuilder.build();
432     }
433 }