Bug 1277 - Move ByteBuffUtils to separate bundle
[openflowjava.git] / openflow-protocol-impl / src / main / java / org / opendaylight / openflowjava / protocol / impl / deserialization / factories / MultipartReplyMessageFactory.java
1 /*
2  * Copyright (c) 2013 Pantheon Technologies s.r.o. 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
9 package org.opendaylight.openflowjava.protocol.impl.deserialization.factories;
10
11 import io.netty.buffer.ByteBuf;
12
13 import java.math.BigInteger;
14 import java.util.ArrayList;
15 import java.util.List;
16
17 import org.opendaylight.openflowjava.protocol.api.extensibility.DeserializerRegistry;
18 import org.opendaylight.openflowjava.protocol.api.extensibility.DeserializerRegistryInjector;
19 import org.opendaylight.openflowjava.protocol.api.extensibility.MessageCodeKey;
20 import org.opendaylight.openflowjava.protocol.api.extensibility.OFDeserializer;
21 import org.opendaylight.openflowjava.protocol.impl.util.ByteBufUtils;
22 import org.opendaylight.openflowjava.protocol.impl.util.CodeKeyMaker;
23 import org.opendaylight.openflowjava.protocol.impl.util.CodeKeyMakerFactory;
24 import org.opendaylight.openflowjava.protocol.api.util.EncodeConstants;
25 import org.opendaylight.openflowjava.protocol.impl.util.ListDeserializer;
26 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev100924.MacAddress;
27 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.augments.rev131002.ActionRelatedTableFeatureProperty;
28 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.augments.rev131002.ActionRelatedTableFeaturePropertyBuilder;
29 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.augments.rev131002.ExperimenterRelatedTableFeatureProperty;
30 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.augments.rev131002.ExperimenterRelatedTableFeaturePropertyBuilder;
31 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.augments.rev131002.InstructionRelatedTableFeatureProperty;
32 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.augments.rev131002.InstructionRelatedTableFeaturePropertyBuilder;
33 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.augments.rev131002.NextTableRelatedTableFeatureProperty;
34 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.augments.rev131002.NextTableRelatedTableFeaturePropertyBuilder;
35 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.augments.rev131002.OxmRelatedTableFeatureProperty;
36 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.augments.rev131002.OxmRelatedTableFeaturePropertyBuilder;
37 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.augments.rev131002.table.features.properties.container.table.feature.properties.NextTableIds;
38 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.augments.rev131002.table.features.properties.container.table.feature.properties.NextTableIdsBuilder;
39 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.action.rev130731.actions.grouping.Action;
40 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.instruction.rev130731.instructions.grouping.Instruction;
41 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.ActionType;
42 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.FlowModFlags;
43 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.GroupCapabilities;
44 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.GroupId;
45 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.GroupType;
46 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.GroupTypes;
47 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.MeterBandType;
48 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.MeterBandTypeBitmap;
49 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.MeterFlags;
50 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.MeterId;
51 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.MultipartRequestFlags;
52 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.MultipartType;
53 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.PortConfig;
54 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.PortFeatures;
55 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.PortNumber;
56 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.PortState;
57 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.TableConfig;
58 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.TableFeaturesPropType;
59 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev130731.match.grouping.Match;
60 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev130731.oxm.fields.grouping.MatchEntries;
61 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.MultipartReplyMessage;
62 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.MultipartReplyMessageBuilder;
63 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.buckets.grouping.BucketsList;
64 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.buckets.grouping.BucketsListBuilder;
65 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.meter.band.header.meter.band.MeterBandDropCaseBuilder;
66 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.meter.band.header.meter.band.MeterBandDscpRemarkCaseBuilder;
67 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.meter.band.header.meter.band.MeterBandExperimenterCaseBuilder;
68 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.meter.band.header.meter.band.meter.band.drop._case.MeterBandDropBuilder;
69 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.meter.band.header.meter.band.meter.band.dscp.remark._case.MeterBandDscpRemarkBuilder;
70 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.meter.band.header.meter.band.meter.band.experimenter._case.MeterBandExperimenterBuilder;
71 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.MultipartReplyAggregateCase;
72 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.MultipartReplyAggregateCaseBuilder;
73 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.MultipartReplyDescCase;
74 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.MultipartReplyDescCaseBuilder;
75 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.MultipartReplyExperimenterCase;
76 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.MultipartReplyExperimenterCaseBuilder;
77 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.MultipartReplyFlowCase;
78 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.MultipartReplyFlowCaseBuilder;
79 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.MultipartReplyGroupCase;
80 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.MultipartReplyGroupCaseBuilder;
81 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.MultipartReplyGroupDescCase;
82 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.MultipartReplyGroupDescCaseBuilder;
83 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.MultipartReplyGroupFeaturesCase;
84 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.MultipartReplyGroupFeaturesCaseBuilder;
85 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.MultipartReplyMeterCase;
86 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.MultipartReplyMeterCaseBuilder;
87 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.MultipartReplyMeterConfigCase;
88 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.MultipartReplyMeterConfigCaseBuilder;
89 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.MultipartReplyMeterFeaturesCase;
90 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.MultipartReplyMeterFeaturesCaseBuilder;
91 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.MultipartReplyPortDescCase;
92 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.MultipartReplyPortDescCaseBuilder;
93 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.MultipartReplyPortStatsCase;
94 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.MultipartReplyPortStatsCaseBuilder;
95 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.MultipartReplyQueueCase;
96 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.MultipartReplyQueueCaseBuilder;
97 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.MultipartReplyTableCase;
98 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.MultipartReplyTableCaseBuilder;
99 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.MultipartReplyTableFeaturesCase;
100 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.MultipartReplyTableFeaturesCaseBuilder;
101 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.multipart.reply.aggregate._case.MultipartReplyAggregateBuilder;
102 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.multipart.reply.desc._case.MultipartReplyDescBuilder;
103 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.multipart.reply.experimenter._case.MultipartReplyExperimenterBuilder;
104 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.multipart.reply.flow._case.MultipartReplyFlowBuilder;
105 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.multipart.reply.flow._case.multipart.reply.flow.FlowStats;
106 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.multipart.reply.flow._case.multipart.reply.flow.FlowStatsBuilder;
107 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.multipart.reply.group._case.MultipartReplyGroupBuilder;
108 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.multipart.reply.group._case.multipart.reply.group.GroupStats;
109 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.multipart.reply.group._case.multipart.reply.group.GroupStatsBuilder;
110 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.multipart.reply.group._case.multipart.reply.group.group.stats.BucketStats;
111 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.multipart.reply.group._case.multipart.reply.group.group.stats.BucketStatsBuilder;
112 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.multipart.reply.group.desc._case.MultipartReplyGroupDescBuilder;
113 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.multipart.reply.group.desc._case.multipart.reply.group.desc.GroupDesc;
114 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.multipart.reply.group.desc._case.multipart.reply.group.desc.GroupDescBuilder;
115 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.multipart.reply.group.features._case.MultipartReplyGroupFeaturesBuilder;
116 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.multipart.reply.meter._case.MultipartReplyMeterBuilder;
117 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.multipart.reply.meter._case.multipart.reply.meter.MeterStats;
118 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.multipart.reply.meter._case.multipart.reply.meter.MeterStatsBuilder;
119 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.multipart.reply.meter._case.multipart.reply.meter.meter.stats.MeterBandStats;
120 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.multipart.reply.meter._case.multipart.reply.meter.meter.stats.MeterBandStatsBuilder;
121 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.multipart.reply.meter.config._case.MultipartReplyMeterConfigBuilder;
122 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.multipart.reply.meter.config._case.multipart.reply.meter.config.MeterConfig;
123 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.multipart.reply.meter.config._case.multipart.reply.meter.config.MeterConfigBuilder;
124 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.multipart.reply.meter.config._case.multipart.reply.meter.config.meter.config.Bands;
125 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.multipart.reply.meter.config._case.multipart.reply.meter.config.meter.config.BandsBuilder;
126 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.multipart.reply.meter.features._case.MultipartReplyMeterFeaturesBuilder;
127 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.multipart.reply.port.desc._case.MultipartReplyPortDescBuilder;
128 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.multipart.reply.port.desc._case.multipart.reply.port.desc.Ports;
129 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.multipart.reply.port.desc._case.multipart.reply.port.desc.PortsBuilder;
130 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.multipart.reply.port.stats._case.MultipartReplyPortStatsBuilder;
131 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.multipart.reply.port.stats._case.multipart.reply.port.stats.PortStats;
132 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.multipart.reply.port.stats._case.multipart.reply.port.stats.PortStatsBuilder;
133 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.multipart.reply.queue._case.MultipartReplyQueueBuilder;
134 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.multipart.reply.queue._case.multipart.reply.queue.QueueStats;
135 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.multipart.reply.queue._case.multipart.reply.queue.QueueStatsBuilder;
136 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.multipart.reply.table._case.MultipartReplyTableBuilder;
137 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.multipart.reply.table._case.multipart.reply.table.TableStats;
138 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.multipart.reply.table._case.multipart.reply.table.TableStatsBuilder;
139 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.multipart.reply.table.features._case.MultipartReplyTableFeaturesBuilder;
140 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.multipart.reply.table.features._case.multipart.reply.table.features.TableFeatures;
141 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.multipart.reply.table.features._case.multipart.reply.table.features.TableFeaturesBuilder;
142 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.table.features.properties.grouping.TableFeatureProperties;
143 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.table.features.properties.grouping.TableFeaturePropertiesBuilder;
144
145 /**
146  * Translates MultipartReply messages
147  * @author timotej.kubas
148  * @author michal.polkorab
149  */
150 public class MultipartReplyMessageFactory implements OFDeserializer<MultipartReplyMessage>,
151         DeserializerRegistryInjector {
152
153     private static final byte PADDING_IN_MULTIPART_REPLY_HEADER = 4;
154     private static final int DESC_STR_LEN = 256;
155     private static final int SERIAL_NUM_LEN = 32;
156     private static final byte PADDING_IN_FLOW_STATS_HEADER_01 = 1;
157     private static final byte PADDING_IN_FLOW_STATS_HEADER_02 = 4;
158     private static final byte PADDING_IN_AGGREGATE_HEADER = 4;
159     private static final byte PADDING_IN_TABLE_HEADER = 3;
160     private static final byte PADDING_IN_MULTIPART_REPLY_TABLE_FEATURES = 5;
161     private static final byte MAX_TABLE_NAME_LENGTH = 32;
162     private static final byte MULTIPART_REPLY_TABLE_FEATURES_STRUCTURE_LENGTH = 64;
163     private static final byte COMMON_PROPERTY_LENGTH = 4;
164     private static final byte PADDING_IN_PORT_STATS_HEADER = 4;
165     private static final byte PADDING_IN_GROUP_HEADER_01 = 2;
166     private static final byte PADDING_IN_GROUP_HEADER_02 = 4;
167     private static final byte BUCKET_COUNTER_LENGTH = 16;
168     private static final byte GROUP_BODY_LENGTH = 40;
169     private static final byte PADDING_IN_METER_FEATURES_HEADER = 2;
170     private static final byte PADDING_IN_METER_STATS_HEADER = 6;
171     private static final byte METER_BAND_STATS_LENGTH = 16;
172     private static final byte METER_BODY_LENGTH = 40;
173     private static final byte METER_CONFIG_LENGTH = 8;
174     private static final byte PADDING_IN_METER_BAND_DROP_HEADER = 4;
175     private static final byte PADDING_IN_METER_BAND_DSCP_HEADER = 3;
176     private static final byte PADDING_IN_PORT_DESC_HEADER_01 = 4;
177     private static final byte PADDING_IN_PORT_DESC_HEADER_02 = 2;
178     private static final int GROUP_TYPES = 4;
179     private static final byte PADDING_IN_GROUP_DESC_HEADER = 1;
180     private static final byte PADDING_IN_BUCKETS_HEADER = 4;
181     private static final byte GROUP_DESC_HEADER_LENGTH = 8;
182     private static final byte BUCKETS_HEADER_LENGTH = 16;
183     private DeserializerRegistry registry;
184
185     @Override
186     public MultipartReplyMessage deserialize(ByteBuf rawMessage) {
187         MultipartReplyMessageBuilder builder = new MultipartReplyMessageBuilder();
188         builder.setVersion((short) EncodeConstants.OF13_VERSION_ID);
189         builder.setXid(rawMessage.readUnsignedInt());
190         int type = rawMessage.readUnsignedShort();
191         builder.setType(MultipartType.forValue(type));
192         builder.setFlags(new MultipartRequestFlags((rawMessage.readUnsignedShort() & 0x01) != 0));
193         rawMessage.skipBytes(PADDING_IN_MULTIPART_REPLY_HEADER);
194
195         switch (type) {
196         case 0:  builder.setMultipartReplyBody(setDesc(rawMessage));
197                  break;
198         case 1:  builder.setMultipartReplyBody(setFlow(rawMessage));
199                  break;
200         case 2:  builder.setMultipartReplyBody(setAggregate(rawMessage));
201                  break;
202         case 3:  builder.setMultipartReplyBody(setTable(rawMessage));
203                  break;         
204         case 4:  builder.setMultipartReplyBody(setPortStats(rawMessage));
205                  break;
206         case 5:  builder.setMultipartReplyBody(setQueue(rawMessage));
207                  break;         
208         case 6:  builder.setMultipartReplyBody(setGroup(rawMessage));
209                  break;
210         case 7:  builder.setMultipartReplyBody(setGroupDesc(rawMessage));
211                  break;
212         case 8:  builder.setMultipartReplyBody(setGroupFeatures(rawMessage));
213                  break;
214         case 9:  builder.setMultipartReplyBody(setMeter(rawMessage));
215                  break;
216         case 10: builder.setMultipartReplyBody(setMeterConfig(rawMessage));
217                  break;
218         case 11: builder.setMultipartReplyBody(setMeterFeatures(rawMessage));
219                  break;
220         case 12: builder.setMultipartReplyBody(setTableFeatures(rawMessage));
221                  break;
222         case 13: builder.setMultipartReplyBody(setPortDesc(rawMessage));
223                  break;
224         case 0xFFFF: builder.setMultipartReplyBody(setExperimenter(rawMessage));
225                  break;
226         default: 
227                  break;
228         }
229         
230         return builder.build();
231     }
232     
233     private static MultipartReplyDescCase setDesc(ByteBuf input) {
234         MultipartReplyDescCaseBuilder caseBuilder = new MultipartReplyDescCaseBuilder();
235         MultipartReplyDescBuilder descBuilder = new MultipartReplyDescBuilder();
236         byte[] mfrDescBytes = new byte[DESC_STR_LEN];
237         input.readBytes(mfrDescBytes);
238         String mfrDesc = new String(mfrDescBytes);
239         descBuilder.setMfrDesc(mfrDesc.trim());
240         byte[] hwDescBytes = new byte[DESC_STR_LEN];
241         input.readBytes(hwDescBytes);
242         String hwDesc = new String(hwDescBytes);
243         descBuilder.setHwDesc(hwDesc.trim());
244         byte[] swDescBytes = new byte[DESC_STR_LEN];
245         input.readBytes(swDescBytes);
246         String swDesc = new String(swDescBytes);
247         descBuilder.setSwDesc(swDesc.trim());
248         byte[] serialNumBytes = new byte[SERIAL_NUM_LEN];
249         input.readBytes(serialNumBytes);
250         String serialNum = new String(serialNumBytes);
251         descBuilder.setSerialNum(serialNum.trim());
252         byte[] dpDescBytes = new byte[DESC_STR_LEN];
253         input.readBytes(dpDescBytes);
254         String dpDesc = new String(dpDescBytes);
255         descBuilder.setDpDesc(dpDesc.trim());
256         caseBuilder.setMultipartReplyDesc(descBuilder.build());
257         return caseBuilder.build();
258     }
259     
260     private MultipartReplyFlowCase setFlow(ByteBuf input) {
261         MultipartReplyFlowCaseBuilder caseBuilder = new MultipartReplyFlowCaseBuilder();
262         MultipartReplyFlowBuilder flowBuilder = new MultipartReplyFlowBuilder();
263         List<FlowStats> flowStatsList = new ArrayList<>();
264         while (input.readableBytes() > 0) {
265             FlowStatsBuilder flowStatsBuilder = new FlowStatsBuilder();
266             int flowRecordLength = input.readUnsignedShort();
267             ByteBuf subInput = input.readSlice(flowRecordLength - EncodeConstants.SIZE_OF_SHORT_IN_BYTES);
268             flowStatsBuilder.setTableId(subInput.readUnsignedByte());
269             subInput.skipBytes(PADDING_IN_FLOW_STATS_HEADER_01);
270             flowStatsBuilder.setDurationSec(subInput.readUnsignedInt());
271             flowStatsBuilder.setDurationNsec(subInput.readUnsignedInt());
272             flowStatsBuilder.setPriority(subInput.readUnsignedShort());
273             flowStatsBuilder.setIdleTimeout(subInput.readUnsignedShort());
274             flowStatsBuilder.setHardTimeout(subInput.readUnsignedShort());
275             flowStatsBuilder.setFlags(createFlowModFlagsFromBitmap(subInput.readUnsignedShort()));
276             subInput.skipBytes(PADDING_IN_FLOW_STATS_HEADER_02);
277             byte[] cookie = new byte[EncodeConstants.SIZE_OF_LONG_IN_BYTES];
278             subInput.readBytes(cookie);
279             flowStatsBuilder.setCookie(new BigInteger(1, cookie));
280             byte[] packetCount = new byte[EncodeConstants.SIZE_OF_LONG_IN_BYTES];
281             subInput.readBytes(packetCount);
282             flowStatsBuilder.setPacketCount(new BigInteger(1, packetCount));
283             byte[] byteCount = new byte[EncodeConstants.SIZE_OF_LONG_IN_BYTES];
284             subInput.readBytes(byteCount);
285             flowStatsBuilder.setByteCount(new BigInteger(1, byteCount));
286             OFDeserializer<Match> matchDeserializer = registry.getDeserializer(new MessageCodeKey(
287                     EncodeConstants.OF13_VERSION_ID, EncodeConstants.EMPTY_VALUE, Match.class));
288             flowStatsBuilder.setMatch(matchDeserializer.deserialize(subInput));
289             CodeKeyMaker keyMaker = CodeKeyMakerFactory
290                     .createInstructionsKeyMaker(EncodeConstants.OF13_VERSION_ID);
291             List<Instruction> instructions = ListDeserializer.deserializeList(
292                     EncodeConstants.OF13_VERSION_ID, subInput.readableBytes(), subInput, keyMaker, registry);
293             flowStatsBuilder.setInstruction(instructions);
294             flowStatsList.add(flowStatsBuilder.build());
295         }
296         flowBuilder.setFlowStats(flowStatsList);
297         caseBuilder.setMultipartReplyFlow(flowBuilder.build());
298         return caseBuilder.build();
299     }
300     
301     private static FlowModFlags createFlowModFlagsFromBitmap(int input){
302         final Boolean _oFPFFSENDFLOWREM = (input & (1 << 0)) != 0;
303         final Boolean _oFPFFCHECKOVERLAP = (input & (1 << 1)) != 0;
304         final Boolean _oFPFFRESETCOUNTS = (input & (1 << 2)) != 0; 
305         final Boolean _oFPFFNOPKTCOUNTS = (input & (1 << 3)) != 0;
306         final Boolean _oFPFFNOBYTCOUNTS = (input & (1 << 4)) != 0;
307         return new FlowModFlags(_oFPFFCHECKOVERLAP, _oFPFFNOBYTCOUNTS, _oFPFFNOPKTCOUNTS, _oFPFFRESETCOUNTS, _oFPFFSENDFLOWREM);
308     }
309     
310     private static MultipartReplyAggregateCase setAggregate(ByteBuf input) {
311         MultipartReplyAggregateCaseBuilder caseBuilder = new MultipartReplyAggregateCaseBuilder();
312         MultipartReplyAggregateBuilder builder = new MultipartReplyAggregateBuilder();
313         byte[] packetCount = new byte[EncodeConstants.SIZE_OF_LONG_IN_BYTES];
314         input.readBytes(packetCount);
315         builder.setPacketCount(new BigInteger(1, packetCount));
316         byte[] byteCount = new byte[EncodeConstants.SIZE_OF_LONG_IN_BYTES];
317         input.readBytes(byteCount);
318         builder.setByteCount(new BigInteger(1, byteCount));
319         builder.setFlowCount(input.readUnsignedInt());
320         input.skipBytes(PADDING_IN_AGGREGATE_HEADER);
321         caseBuilder.setMultipartReplyAggregate(builder.build());
322         return caseBuilder.build();
323     }
324     
325     private static MultipartReplyTableCase setTable(ByteBuf input) {
326         MultipartReplyTableCaseBuilder caseBuilder = new MultipartReplyTableCaseBuilder();
327         MultipartReplyTableBuilder builder = new MultipartReplyTableBuilder();
328         List<TableStats> tableStatsList = new ArrayList<>();
329         while (input.readableBytes() > 0) {
330             TableStatsBuilder tableStatsBuilder = new TableStatsBuilder();
331             tableStatsBuilder.setTableId(input.readUnsignedByte());
332             input.skipBytes(PADDING_IN_TABLE_HEADER);
333             tableStatsBuilder.setActiveCount(input.readUnsignedInt());
334             byte[] lookupCount = new byte[EncodeConstants.SIZE_OF_LONG_IN_BYTES];
335             input.readBytes(lookupCount);
336             tableStatsBuilder.setLookupCount(new BigInteger(1, lookupCount));
337             byte[] matchedCount = new byte[EncodeConstants.SIZE_OF_LONG_IN_BYTES];
338             input.readBytes(matchedCount);
339             tableStatsBuilder.setMatchedCount(new BigInteger(1, matchedCount));
340             tableStatsList.add(tableStatsBuilder.build());
341         }
342         builder.setTableStats(tableStatsList);
343         caseBuilder.setMultipartReplyTable(builder.build());
344         return caseBuilder.build();
345     }
346     
347     private MultipartReplyTableFeaturesCase setTableFeatures(ByteBuf input) {
348         MultipartReplyTableFeaturesCaseBuilder caseBuilder = new MultipartReplyTableFeaturesCaseBuilder();
349         MultipartReplyTableFeaturesBuilder builder = new MultipartReplyTableFeaturesBuilder();
350         List<TableFeatures> features = new ArrayList<>();
351         while (input.readableBytes() > 0) {
352             TableFeaturesBuilder featuresBuilder = new TableFeaturesBuilder();
353             int length = input.readUnsignedShort();
354             featuresBuilder.setTableId(input.readUnsignedByte());
355             input.skipBytes(PADDING_IN_MULTIPART_REPLY_TABLE_FEATURES);
356             featuresBuilder.setName(input.readBytes(MAX_TABLE_NAME_LENGTH).toString());
357             byte[] metadataMatch = new byte[EncodeConstants.SIZE_OF_LONG_IN_BYTES];
358             input.readBytes(metadataMatch);
359             featuresBuilder.setMetadataMatch(metadataMatch);
360             byte[] metadataWrite = new byte[EncodeConstants.SIZE_OF_LONG_IN_BYTES];
361             input.readBytes(metadataWrite);
362             featuresBuilder.setMetadataWrite(metadataWrite);
363             featuresBuilder.setConfig(createTableConfig(input.readUnsignedInt()));
364             featuresBuilder.setMaxEntries(input.readUnsignedInt());
365             featuresBuilder.setTableFeatureProperties(createTableFeaturesProperties(input, 
366                     length - MULTIPART_REPLY_TABLE_FEATURES_STRUCTURE_LENGTH));
367             features.add(featuresBuilder.build());
368         }
369         builder.setTableFeatures(features);
370         caseBuilder.setMultipartReplyTableFeatures(builder.build());
371         return caseBuilder.build();
372     }
373     
374     private static TableConfig createTableConfig(long input) {
375         boolean deprecated = (input & 3) != 0;
376         return new TableConfig(deprecated);
377     }
378     
379     private List<TableFeatureProperties> createTableFeaturesProperties(ByteBuf input, int length) {
380         List<TableFeatureProperties> properties = new ArrayList<>();
381         int tableFeaturesLength = length;
382         while (tableFeaturesLength > 0) {
383             TableFeaturePropertiesBuilder builder = new TableFeaturePropertiesBuilder();
384             TableFeaturesPropType type = TableFeaturesPropType.forValue(input.readUnsignedShort());
385             builder.setType(type);
386             int propertyLength = input.readUnsignedShort();
387             int paddingRemainder = propertyLength % EncodeConstants.PADDING;
388             tableFeaturesLength -= propertyLength;
389             if (type.equals(TableFeaturesPropType.OFPTFPTINSTRUCTIONS)
390                     || type.equals(TableFeaturesPropType.OFPTFPTINSTRUCTIONSMISS)) {
391                 InstructionRelatedTableFeaturePropertyBuilder insBuilder = new InstructionRelatedTableFeaturePropertyBuilder();
392                 CodeKeyMaker keyMaker = CodeKeyMakerFactory.createInstructionsKeyMaker(EncodeConstants.OF13_VERSION_ID);
393                 List<Instruction> instructions = ListDeserializer.deserializeHeaders(EncodeConstants.OF13_VERSION_ID,
394                         propertyLength - COMMON_PROPERTY_LENGTH, input, keyMaker, registry);
395                 insBuilder.setInstruction(instructions);
396                 builder.addAugmentation(InstructionRelatedTableFeatureProperty.class, insBuilder.build());
397             } else if (type.equals(TableFeaturesPropType.OFPTFPTNEXTTABLES)
398                     || type.equals(TableFeaturesPropType.OFPTFPTNEXTTABLESMISS)) {
399                 propertyLength -= COMMON_PROPERTY_LENGTH;
400                 NextTableRelatedTableFeaturePropertyBuilder tableBuilder = new NextTableRelatedTableFeaturePropertyBuilder();
401                 List<NextTableIds> ids = new ArrayList<>();
402                 while (propertyLength > 0) {
403                     NextTableIdsBuilder nextTableIdsBuilder = new NextTableIdsBuilder();
404                     nextTableIdsBuilder.setTableId(input.readUnsignedByte());
405                     ids.add(nextTableIdsBuilder.build());
406                     propertyLength--;
407                 }
408                 tableBuilder.setNextTableIds(ids);
409                 builder.addAugmentation(NextTableRelatedTableFeatureProperty.class, tableBuilder.build());
410             } else if (type.equals(TableFeaturesPropType.OFPTFPTWRITEACTIONS)
411                     || type.equals(TableFeaturesPropType.OFPTFPTWRITEACTIONSMISS)
412                     || type.equals(TableFeaturesPropType.OFPTFPTAPPLYACTIONS)
413                     || type.equals(TableFeaturesPropType.OFPTFPTAPPLYACTIONSMISS)) {
414                 ActionRelatedTableFeaturePropertyBuilder actionBuilder = new ActionRelatedTableFeaturePropertyBuilder();
415                 CodeKeyMaker keyMaker = CodeKeyMakerFactory.createActionsKeyMaker(EncodeConstants.OF13_VERSION_ID);
416                 List<Action> actions = ListDeserializer.deserializeHeaders(EncodeConstants.OF13_VERSION_ID,
417                         propertyLength - COMMON_PROPERTY_LENGTH, input, keyMaker, registry);
418                 actionBuilder.setAction(actions);
419                 builder.addAugmentation(ActionRelatedTableFeatureProperty.class, actionBuilder.build());
420             } else if (type.equals(TableFeaturesPropType.OFPTFPTMATCH)
421                     || type.equals(TableFeaturesPropType.OFPTFPTWILDCARDS)
422                     || type.equals(TableFeaturesPropType.OFPTFPTWRITESETFIELD)
423                     || type.equals(TableFeaturesPropType.OFPTFPTWRITESETFIELDMISS)
424                     || type.equals(TableFeaturesPropType.OFPTFPTAPPLYSETFIELD)
425                     || type.equals(TableFeaturesPropType.OFPTFPTAPPLYSETFIELDMISS)) {
426                 OxmRelatedTableFeaturePropertyBuilder oxmBuilder = new OxmRelatedTableFeaturePropertyBuilder();
427                 CodeKeyMaker keyMaker = CodeKeyMakerFactory
428                         .createMatchEntriesKeyMaker(EncodeConstants.OF13_VERSION_ID);
429                 List<MatchEntries> entries = ListDeserializer.deserializeHeaders(EncodeConstants.OF13_VERSION_ID,
430                         propertyLength - COMMON_PROPERTY_LENGTH, input, keyMaker, registry);
431                 oxmBuilder.setMatchEntries(entries);
432                 builder.addAugmentation(OxmRelatedTableFeatureProperty.class, oxmBuilder.build());
433             } else if (type.equals(TableFeaturesPropType.OFPTFPTEXPERIMENTER)
434                     || type.equals(TableFeaturesPropType.OFPTFPTEXPERIMENTERMISS)) {
435                 ExperimenterRelatedTableFeaturePropertyBuilder expBuilder = new ExperimenterRelatedTableFeaturePropertyBuilder();
436                 expBuilder.setExperimenter(input.readUnsignedInt());
437                 expBuilder.setExpType(input.readUnsignedInt());
438                 OFDeserializer<ExperimenterRelatedTableFeatureProperty> propDeserializer = registry.getDeserializer(
439                         new MessageCodeKey(EncodeConstants.OF13_VERSION_ID,
440                                 type.getIntValue(), ExperimenterRelatedTableFeatureProperty.class));
441                 ExperimenterRelatedTableFeatureProperty expProp = propDeserializer.deserialize(input);
442                 builder.addAugmentation(ExperimenterRelatedTableFeatureProperty.class, expProp);
443             }
444             if (paddingRemainder != 0) {
445                 input.skipBytes(EncodeConstants.PADDING - paddingRemainder);
446                 tableFeaturesLength -= EncodeConstants.PADDING - paddingRemainder;
447             }
448             properties.add(builder.build());
449         }
450         return properties;
451     }
452     
453     private static MultipartReplyPortStatsCase setPortStats(ByteBuf input) {
454         MultipartReplyPortStatsCaseBuilder caseBuilder = new MultipartReplyPortStatsCaseBuilder();
455         MultipartReplyPortStatsBuilder builder = new MultipartReplyPortStatsBuilder();
456         List<PortStats> portStatsList = new ArrayList<>();
457         while (input.readableBytes() > 0) {
458             PortStatsBuilder portStatsBuilder = new PortStatsBuilder();
459             portStatsBuilder.setPortNo(input.readUnsignedInt());
460             input.skipBytes(PADDING_IN_PORT_STATS_HEADER);
461             byte[] rxPackets = new byte[EncodeConstants.SIZE_OF_LONG_IN_BYTES];
462             input.readBytes(rxPackets);
463             portStatsBuilder.setRxPackets(new BigInteger(1, rxPackets));
464             byte[] txPackets = new byte[EncodeConstants.SIZE_OF_LONG_IN_BYTES];
465             input.readBytes(txPackets);
466             portStatsBuilder.setTxPackets(new BigInteger(1, txPackets));
467             byte[] rxBytes = new byte[EncodeConstants.SIZE_OF_LONG_IN_BYTES];
468             input.readBytes(rxBytes);
469             portStatsBuilder.setRxBytes(new BigInteger(1, rxBytes));
470             byte[] txBytes = new byte[EncodeConstants.SIZE_OF_LONG_IN_BYTES];
471             input.readBytes(txBytes);
472             portStatsBuilder.setTxBytes(new BigInteger(1, txBytes));
473             byte[] rxDropped = new byte[EncodeConstants.SIZE_OF_LONG_IN_BYTES];
474             input.readBytes(rxDropped);
475             portStatsBuilder.setRxDropped(new BigInteger(1, rxDropped));
476             byte[] txDropped = new byte[EncodeConstants.SIZE_OF_LONG_IN_BYTES];
477             input.readBytes(txDropped);
478             portStatsBuilder.setTxDropped(new BigInteger(1, txDropped));
479             byte[] rxErrors = new byte[EncodeConstants.SIZE_OF_LONG_IN_BYTES];
480             input.readBytes(rxErrors);
481             portStatsBuilder.setRxErrors(new BigInteger(1, rxErrors));
482             byte[] txErrors = new byte[EncodeConstants.SIZE_OF_LONG_IN_BYTES];
483             input.readBytes(txErrors);
484             portStatsBuilder.setTxErrors(new BigInteger(1, txErrors));
485             byte[] rxFrameErr = new byte[EncodeConstants.SIZE_OF_LONG_IN_BYTES];
486             input.readBytes(rxFrameErr);
487             portStatsBuilder.setRxFrameErr(new BigInteger(1, rxFrameErr));
488             byte[] rxOverErr = new byte[EncodeConstants.SIZE_OF_LONG_IN_BYTES];
489             input.readBytes(rxOverErr);
490             portStatsBuilder.setRxOverErr(new BigInteger(1, rxOverErr));
491             byte[] rxCrcErr = new byte[EncodeConstants.SIZE_OF_LONG_IN_BYTES];
492             input.readBytes(rxCrcErr);
493             portStatsBuilder.setRxCrcErr(new BigInteger(1, rxCrcErr));
494             byte[] collisions = new byte[EncodeConstants.SIZE_OF_LONG_IN_BYTES];
495             input.readBytes(collisions);
496             portStatsBuilder.setCollisions(new BigInteger(1, collisions));
497             portStatsBuilder.setDurationSec(input.readUnsignedInt());
498             portStatsBuilder.setDurationNsec(input.readUnsignedInt());
499             portStatsList.add(portStatsBuilder.build());
500         }
501         builder.setPortStats(portStatsList);
502         caseBuilder.setMultipartReplyPortStats(builder.build());
503         return caseBuilder.build();
504     }
505     
506     private static MultipartReplyQueueCase setQueue(ByteBuf input) {
507         MultipartReplyQueueCaseBuilder caseBuilder = new MultipartReplyQueueCaseBuilder();
508         MultipartReplyQueueBuilder builder = new MultipartReplyQueueBuilder();
509         List<QueueStats> queueStatsList = new ArrayList<>();
510         while (input.readableBytes() > 0) {
511             QueueStatsBuilder queueStatsBuilder = new QueueStatsBuilder();
512             queueStatsBuilder.setPortNo(input.readUnsignedInt());
513             queueStatsBuilder.setQueueId(input.readUnsignedInt());
514             byte[] txBytes = new byte[EncodeConstants.SIZE_OF_LONG_IN_BYTES];
515             input.readBytes(txBytes);
516             queueStatsBuilder.setTxBytes(new BigInteger(1, txBytes));
517             byte[] txPackets = new byte[EncodeConstants.SIZE_OF_LONG_IN_BYTES];
518             input.readBytes(txPackets);
519             queueStatsBuilder.setTxPackets(new BigInteger(1, txPackets));
520             byte[] txErrors = new byte[EncodeConstants.SIZE_OF_LONG_IN_BYTES];
521             input.readBytes(txErrors);
522             queueStatsBuilder.setTxErrors(new BigInteger(1, txErrors));
523             queueStatsBuilder.setDurationSec(input.readUnsignedInt());
524             queueStatsBuilder.setDurationNsec(input.readUnsignedInt());
525             queueStatsList.add(queueStatsBuilder.build());
526         }
527         builder.setQueueStats(queueStatsList);
528         caseBuilder.setMultipartReplyQueue(builder.build());
529         return caseBuilder.build();
530     }
531     
532     private static MultipartReplyGroupCase setGroup(ByteBuf input) {
533         MultipartReplyGroupCaseBuilder caseBuilder = new MultipartReplyGroupCaseBuilder();
534         MultipartReplyGroupBuilder builder = new MultipartReplyGroupBuilder();
535         List<GroupStats> groupStatsList = new ArrayList<>();
536         while (input.readableBytes() > 0) {
537             GroupStatsBuilder groupStatsBuilder = new GroupStatsBuilder();
538             int bodyLength = input.readUnsignedShort();
539             input.skipBytes(PADDING_IN_GROUP_HEADER_01);
540             groupStatsBuilder.setGroupId(new GroupId(input.readUnsignedInt()));
541             groupStatsBuilder.setRefCount(input.readUnsignedInt());
542             input.skipBytes(PADDING_IN_GROUP_HEADER_02);
543             byte[] packetCount = new byte[EncodeConstants.SIZE_OF_LONG_IN_BYTES];
544             input.readBytes(packetCount);
545             groupStatsBuilder.setPacketCount(new BigInteger(1, packetCount));
546             byte[] byteCount = new byte[EncodeConstants.SIZE_OF_LONG_IN_BYTES];
547             input.readBytes(byteCount);
548             groupStatsBuilder.setByteCount(new BigInteger(1, byteCount));
549             groupStatsBuilder.setDurationSec(input.readUnsignedInt());
550             groupStatsBuilder.setDurationNsec(input.readUnsignedInt());
551             int actualLength = GROUP_BODY_LENGTH;
552             List<BucketStats> bucketStatsList = new ArrayList<>();
553             while (actualLength < bodyLength) {
554                 BucketStatsBuilder bucketStatsBuilder = new BucketStatsBuilder();
555                 byte[] packetCountBucket = new byte[EncodeConstants.SIZE_OF_LONG_IN_BYTES];
556                 input.readBytes(packetCountBucket);
557                 bucketStatsBuilder.setPacketCount(new BigInteger(1, packetCountBucket));
558                 byte[] byteCountBucket = new byte[EncodeConstants.SIZE_OF_LONG_IN_BYTES];
559                 input.readBytes(byteCountBucket);
560                 bucketStatsBuilder.setByteCount(new BigInteger(1, byteCountBucket));
561                 bucketStatsList.add(bucketStatsBuilder.build());
562                 actualLength += BUCKET_COUNTER_LENGTH;
563             } 
564             groupStatsBuilder.setBucketStats(bucketStatsList);
565             groupStatsList.add(groupStatsBuilder.build());
566         }
567         builder.setGroupStats(groupStatsList);
568         caseBuilder.setMultipartReplyGroup(builder.build());
569         return caseBuilder.build();
570     }
571     
572     private static MultipartReplyMeterFeaturesCase setMeterFeatures(ByteBuf input) {
573         MultipartReplyMeterFeaturesCaseBuilder caseBuilder = new MultipartReplyMeterFeaturesCaseBuilder();
574         MultipartReplyMeterFeaturesBuilder builder = new MultipartReplyMeterFeaturesBuilder();
575         builder.setMaxMeter(input.readUnsignedInt());
576         builder.setBandTypes(createMeterBandsBitmap(input.readUnsignedInt()));
577         builder.setCapabilities(createMeterFlags(input.readUnsignedInt()));
578         builder.setMaxBands(input.readUnsignedByte());
579         builder.setMaxColor(input.readUnsignedByte());
580         input.skipBytes(PADDING_IN_METER_FEATURES_HEADER);
581         caseBuilder.setMultipartReplyMeterFeatures(builder.build());
582         return caseBuilder.build();
583     }
584     
585     private static MeterFlags createMeterFlags(long input){
586         final Boolean _oFPMFKBPS = (input & (1 << 0)) != 0;
587         final Boolean _oFPMFPKTPS = (input & (1 << 1)) != 0;
588         final Boolean _oFPMFBURST = (input & (1 << 2)) != 0;
589         final Boolean _oFPMFSTATS = (input & (1 << 3)) != 0;
590         return new MeterFlags(_oFPMFBURST, _oFPMFKBPS, _oFPMFPKTPS, _oFPMFSTATS);
591     }
592     
593     private static MeterBandTypeBitmap createMeterBandsBitmap(long input) {
594         final Boolean _oFPMBTDROP = (input & (1 << 0)) != 0;
595         final Boolean _oFPMBTDSCPREMARK = (input & (1 << 1)) != 0;
596         return new MeterBandTypeBitmap(_oFPMBTDROP, _oFPMBTDSCPREMARK);
597     }
598     
599     private static MultipartReplyMeterCase setMeter(ByteBuf input) {
600         MultipartReplyMeterCaseBuilder caseBuilder = new MultipartReplyMeterCaseBuilder();
601         MultipartReplyMeterBuilder builder = new MultipartReplyMeterBuilder();
602         List<MeterStats> meterStatsList = new ArrayList<>();
603         while (input.readableBytes() > 0) {
604             MeterStatsBuilder meterStatsBuilder = new MeterStatsBuilder();
605             meterStatsBuilder.setMeterId(new MeterId(input.readUnsignedInt()));
606             int meterStatsBodyLength = input.readUnsignedShort();
607             input.skipBytes(PADDING_IN_METER_STATS_HEADER);
608             meterStatsBuilder.setFlowCount(input.readUnsignedInt());
609             byte[] packetInCount = new byte[EncodeConstants.SIZE_OF_LONG_IN_BYTES];
610             input.readBytes(packetInCount);
611             meterStatsBuilder.setPacketInCount(new BigInteger(1, packetInCount));
612             byte[] byteInCount = new byte[EncodeConstants.SIZE_OF_LONG_IN_BYTES];
613             input.readBytes(byteInCount);
614             meterStatsBuilder.setByteInCount(new BigInteger(1, byteInCount));
615             meterStatsBuilder.setDurationSec(input.readUnsignedInt());
616             meterStatsBuilder.setDurationNsec(input.readUnsignedInt());
617             int actualLength = METER_BODY_LENGTH;
618             List<MeterBandStats> meterBandStatsList = new ArrayList<>();
619             while (actualLength < meterStatsBodyLength) {
620                 MeterBandStatsBuilder meterBandStatsBuilder = new MeterBandStatsBuilder();
621                 byte[] packetBandCount = new byte[EncodeConstants.SIZE_OF_LONG_IN_BYTES];
622                 input.readBytes(packetBandCount);
623                 meterBandStatsBuilder.setPacketBandCount(new BigInteger(1, packetBandCount));
624                 byte[] byteBandCount = new byte[EncodeConstants.SIZE_OF_LONG_IN_BYTES];
625                 input.readBytes(byteBandCount);
626                 meterBandStatsBuilder.setByteBandCount(new BigInteger(1, byteBandCount));
627                 meterBandStatsList.add(meterBandStatsBuilder.build());
628                 actualLength += METER_BAND_STATS_LENGTH;
629             }
630             meterStatsBuilder.setMeterBandStats(meterBandStatsList);
631             meterStatsList.add(meterStatsBuilder.build());
632         }
633         builder.setMeterStats(meterStatsList);
634         caseBuilder.setMultipartReplyMeter(builder.build());
635         return caseBuilder.build();
636     }
637     
638     private static MultipartReplyMeterConfigCase setMeterConfig(ByteBuf input) {
639         MultipartReplyMeterConfigCaseBuilder caseBuilder = new MultipartReplyMeterConfigCaseBuilder();
640         MultipartReplyMeterConfigBuilder builder = new MultipartReplyMeterConfigBuilder();
641         List<MeterConfig> meterConfigList = new ArrayList<>();
642         while (input.readableBytes() > 0) {
643             MeterConfigBuilder meterConfigBuilder = new MeterConfigBuilder();
644             int meterConfigBodyLength = input.readUnsignedShort();
645             meterConfigBuilder.setFlags(createMeterFlags(input.readUnsignedShort()));
646             meterConfigBuilder.setMeterId(new MeterId(input.readUnsignedInt()));
647             int actualLength = METER_CONFIG_LENGTH;
648             List<Bands> bandsList = new ArrayList<>();
649             while (actualLength < meterConfigBodyLength) {
650                 BandsBuilder bandsBuilder = new BandsBuilder();
651                 int bandType = input.readUnsignedShort();
652                 switch (bandType) {
653                     case 1:
654                         MeterBandDropCaseBuilder bandDropCaseBuilder = new MeterBandDropCaseBuilder();
655                         MeterBandDropBuilder bandDropBuilder = new MeterBandDropBuilder();
656                         bandDropBuilder.setType(MeterBandType.forValue(bandType));
657                         actualLength += input.readUnsignedShort();
658                         bandDropBuilder.setRate(input.readUnsignedInt());
659                         bandDropBuilder.setBurstSize(input.readUnsignedInt());
660                         input.skipBytes(PADDING_IN_METER_BAND_DROP_HEADER);
661                         bandDropCaseBuilder.setMeterBandDrop(bandDropBuilder.build());
662                         bandsBuilder.setMeterBand(bandDropCaseBuilder.build());
663                         break;
664                     case 2:
665                         MeterBandDscpRemarkCaseBuilder bandDscpRemarkCaseBuilder = new MeterBandDscpRemarkCaseBuilder();
666                         MeterBandDscpRemarkBuilder bandDscpRemarkBuilder = new MeterBandDscpRemarkBuilder();
667                         bandDscpRemarkBuilder.setType(MeterBandType.forValue(bandType));
668                         actualLength += input.readUnsignedShort();
669                         bandDscpRemarkBuilder.setRate(input.readUnsignedInt());
670                         bandDscpRemarkBuilder.setBurstSize(input.readUnsignedInt());
671                         bandDscpRemarkBuilder.setPrecLevel(input.readUnsignedByte());
672                         input.skipBytes(PADDING_IN_METER_BAND_DSCP_HEADER);
673                         bandDscpRemarkCaseBuilder.setMeterBandDscpRemark(bandDscpRemarkBuilder.build());
674                         bandsBuilder.setMeterBand(bandDscpRemarkCaseBuilder.build());
675                         break;
676                     case 0xFFFF:
677                         MeterBandExperimenterCaseBuilder bandExperimenterCaseBuilder = new MeterBandExperimenterCaseBuilder();
678                         MeterBandExperimenterBuilder bandExperimenterBuilder = new MeterBandExperimenterBuilder();
679                         bandExperimenterBuilder.setType(MeterBandType.forValue(bandType));
680                         actualLength += input.readUnsignedShort();
681                         bandExperimenterBuilder.setRate(input.readUnsignedInt());
682                         bandExperimenterBuilder.setBurstSize(input.readUnsignedInt());
683                         bandExperimenterBuilder.setExperimenter(input.readUnsignedInt());
684                         bandExperimenterCaseBuilder.setMeterBandExperimenter(bandExperimenterBuilder.build());
685                         bandsBuilder.setMeterBand(bandExperimenterCaseBuilder.build());
686                         break;
687                     default:
688                         break;
689                 }
690                 bandsList.add(bandsBuilder.build());
691             }
692             meterConfigBuilder.setBands(bandsList);
693             meterConfigList.add(meterConfigBuilder.build());
694         }
695         builder.setMeterConfig(meterConfigList);
696         caseBuilder.setMultipartReplyMeterConfig(builder.build());
697         return caseBuilder.build();
698     }
699     
700     private static MultipartReplyExperimenterCase setExperimenter(ByteBuf input) {
701         MultipartReplyExperimenterCaseBuilder caseBuilder = new MultipartReplyExperimenterCaseBuilder();
702         MultipartReplyExperimenterBuilder builder = new MultipartReplyExperimenterBuilder();
703         builder.setExperimenter(input.readUnsignedInt());
704         builder.setExpType(input.readUnsignedInt());
705         byte[] data = new byte[input.readableBytes()];
706         input.readBytes(data);
707         builder.setData(data);
708         caseBuilder.setMultipartReplyExperimenter(builder.build());
709         return caseBuilder.build();
710     }
711     
712     private static MultipartReplyPortDescCase setPortDesc(ByteBuf input) {
713         MultipartReplyPortDescCaseBuilder caseBuilder = new MultipartReplyPortDescCaseBuilder();
714         MultipartReplyPortDescBuilder builder = new MultipartReplyPortDescBuilder();
715         List<Ports> portsList = new ArrayList<>();
716         while (input.readableBytes() > 0) {
717             PortsBuilder portsBuilder = new PortsBuilder();
718             portsBuilder.setPortNo(input.readUnsignedInt());
719             input.skipBytes(PADDING_IN_PORT_DESC_HEADER_01);
720             byte[] hwAddress = new byte[EncodeConstants.MAC_ADDRESS_LENGTH];
721             input.readBytes(hwAddress);
722             portsBuilder.setHwAddr(new MacAddress(ByteBufUtils.macAddressToString(hwAddress)));
723             input.skipBytes(PADDING_IN_PORT_DESC_HEADER_02);
724             portsBuilder.setName(ByteBufUtils.decodeNullTerminatedString(input, EncodeConstants.MAX_PORT_NAME_LENGTH));
725             portsBuilder.setConfig(createPortConfig(input.readUnsignedInt()));
726             portsBuilder.setState(createPortState(input.readUnsignedInt()));
727             portsBuilder.setCurrentFeatures(createPortFeatures(input.readUnsignedInt()));
728             portsBuilder.setAdvertisedFeatures(createPortFeatures(input.readUnsignedInt()));
729             portsBuilder.setSupportedFeatures(createPortFeatures(input.readUnsignedInt()));
730             portsBuilder.setPeerFeatures(createPortFeatures(input.readUnsignedInt()));
731             portsBuilder.setCurrSpeed(input.readUnsignedInt());
732             portsBuilder.setMaxSpeed(input.readUnsignedInt());
733             portsList.add(portsBuilder.build());
734         }
735         builder.setPorts(portsList);
736         caseBuilder.setMultipartReplyPortDesc(builder.build());
737         return caseBuilder.build();
738     }
739     
740     private static PortConfig createPortConfig(long input){
741         final Boolean _portDown   = ((input) & (1<<0)) != 0;
742         final Boolean _noRecv    = ((input) & (1<<2)) != 0;
743         final Boolean _noFwd       = ((input) & (1<<5)) != 0;
744         final Boolean _noPacketIn = ((input) & (1<<6)) != 0;
745         return new PortConfig(_noFwd, _noPacketIn, _noRecv, _portDown);
746     }
747     
748     private static PortState createPortState(long input){
749         final Boolean _linkDown = ((input) & (1<<0)) != 0;
750         final Boolean _blocked  = ((input) & (1<<1)) != 0;
751         final Boolean _live     = ((input) & (1<<2)) != 0;
752         return new PortState(_blocked, _linkDown, _live);
753     }
754     
755     private static PortFeatures createPortFeatures(long input){
756         final Boolean _10mbHd = ((input) & (1<<0)) != 0;
757         final Boolean _10mbFd = ((input) & (1<<1)) != 0;
758         final Boolean _100mbHd = ((input) & (1<<2)) != 0;
759         final Boolean _100mbFd = ((input) & (1<<3)) != 0;
760         final Boolean _1gbHd = ((input) & (1<<4)) != 0;
761         final Boolean _1gbFd = ((input) & (1<<5)) != 0;
762         final Boolean _10gbFd = ((input) & (1<<6)) != 0;
763         final Boolean _40gbFd = ((input) & (1<<7)) != 0;
764         final Boolean _100gbFd = ((input) & (1<<8)) != 0;
765         final Boolean _1tbFd = ((input) & (1<<9)) != 0;
766         final Boolean _other = ((input) & (1<<10)) != 0;
767         final Boolean _copper = ((input) & (1<<11)) != 0;
768         final Boolean _fiber = ((input) & (1<<12)) != 0;
769         final Boolean _autoneg = ((input) & (1<<13)) != 0;
770         final Boolean _pause = ((input) & (1<<14)) != 0;
771         final Boolean _pauseAsym = ((input) & (1<<15)) != 0;
772         return new PortFeatures(_100gbFd, _100mbFd, _100mbHd, _10gbFd, _10mbFd, _10mbHd, _1gbFd,
773                 _1gbHd, _1tbFd, _40gbFd, _autoneg, _copper, _fiber, _other, _pause, _pauseAsym);
774     }
775     
776     private static MultipartReplyGroupFeaturesCase setGroupFeatures(ByteBuf rawMessage) {
777         MultipartReplyGroupFeaturesCaseBuilder caseBuilder = new MultipartReplyGroupFeaturesCaseBuilder();
778         MultipartReplyGroupFeaturesBuilder featuresBuilder = new MultipartReplyGroupFeaturesBuilder();
779         featuresBuilder.setTypes(createGroupType(rawMessage.readUnsignedInt()));
780         featuresBuilder.setCapabilities(createCapabilities(rawMessage.readUnsignedInt()));
781         List<Long> maxGroupsList = new ArrayList<>();
782         for (int i = 0; i < GROUP_TYPES ; i++) {
783             maxGroupsList.add(rawMessage.readUnsignedInt());
784         }
785         featuresBuilder.setMaxGroups(maxGroupsList);
786         List<ActionType> actionBitmaps = new ArrayList<>();
787         for (int i = 0; i < GROUP_TYPES ; i++) {
788             actionBitmaps.add(createActionBitmap(rawMessage.readUnsignedInt()));
789         }
790         featuresBuilder.setActionsBitmap(actionBitmaps);
791         caseBuilder.setMultipartReplyGroupFeatures(featuresBuilder.build());
792         return caseBuilder.build();
793     }
794     
795     private static ActionType createActionBitmap(long input) {
796         final Boolean OFPAT_OUTPUT = ((input) & (1<<0)) != 0;
797         final Boolean OFPAT_COPY_TTL_OUT = ((input) & (1<<1)) != 0;
798         final Boolean OFPAT_COPY_TTL_IN = ((input) & (1<<2)) != 0;
799         final Boolean OFPAT_SET_MPLS_TTL = ((input) & (1<<3)) != 0;
800         final Boolean OFPAT_DEC_MPLS_TTL = ((input) & (1<<4)) != 0;
801         final Boolean OFPAT_PUSH_VLAN = ((input) & (1<<5)) != 0;
802         final Boolean OFPAT_POP_VLAN = ((input) & (1<<6)) != 0;
803         final Boolean OFPAT_PUSH_MPLS = ((input) & (1<<7)) != 0;
804         final Boolean OFPAT_POP_MPLS = ((input) & (1<<8)) != 0;
805         final Boolean OFPAT_SET_QUEUE = ((input) & (1<<9)) != 0;
806         final Boolean OFPAT_GROUP = ((input) & (1<<10)) != 0;
807         final Boolean OFPAT_SET_NW_TTL = ((input) & (1<<11)) != 0;
808         final Boolean OFPAT_DEC_NW_TTL = ((input) & (1<<12)) != 0;
809         final Boolean OFPAT_SET_FIELD = ((input) & (1<<13)) != 0;
810         final Boolean OFPAT_PUSH_PBB = ((input) & (1<<14)) != 0;
811         final Boolean OFPAT_POP_PBB = ((input) & (1<<15)) != 0;
812         final Boolean OFPAT_EXPERIMENTER = ((input) & (1<<16)) != 0;
813         return new ActionType(OFPAT_COPY_TTL_IN, OFPAT_COPY_TTL_OUT, OFPAT_DEC_MPLS_TTL,
814                 OFPAT_DEC_NW_TTL, OFPAT_EXPERIMENTER, OFPAT_GROUP, OFPAT_OUTPUT, OFPAT_POP_MPLS,
815                 OFPAT_POP_PBB, OFPAT_POP_VLAN, OFPAT_PUSH_MPLS, OFPAT_PUSH_PBB, OFPAT_PUSH_VLAN,
816                 OFPAT_SET_FIELD, OFPAT_SET_MPLS_TTL, OFPAT_SET_NW_TTL, OFPAT_SET_QUEUE);
817     }
818
819     private static GroupCapabilities createCapabilities(long input) {
820         final Boolean OFOFPGFC_SELECT_WEIGHT = ((input) & (1<<0)) != 0;
821         final Boolean OFPGFC_SELECT_LIVENESS = ((input) & (1<<1)) != 0;
822         final Boolean OFPGFC_CHAINING = ((input) & (1<<2)) != 0;
823         final Boolean OFPGFC_CHAINING_CHECKS = ((input) & (1<<3)) != 0;
824         return new GroupCapabilities(OFPGFC_CHAINING, OFPGFC_CHAINING_CHECKS, OFPGFC_SELECT_LIVENESS, OFOFPGFC_SELECT_WEIGHT);
825     }
826
827     private static GroupTypes createGroupType(long input) {
828         final Boolean OFPGT_ALL = ((input) & (1<<0)) != 0;
829         final Boolean OFPGT_SELECT = ((input) & (1<<1)) != 0;
830         final Boolean OFPGT_INDIRECT = ((input) & (1<<2)) != 0;
831         final Boolean OFPGT_FF = ((input) & (1<<3)) != 0;
832         return new GroupTypes(OFPGT_ALL, OFPGT_FF, OFPGT_INDIRECT, OFPGT_SELECT);
833     }
834     
835     private MultipartReplyGroupDescCase setGroupDesc(ByteBuf input) {
836         MultipartReplyGroupDescCaseBuilder caseBuilder = new MultipartReplyGroupDescCaseBuilder();
837         MultipartReplyGroupDescBuilder builder = new MultipartReplyGroupDescBuilder();
838         List<GroupDesc> groupDescsList = new ArrayList<>();
839         while (input.readableBytes() > 0) {
840             GroupDescBuilder groupDescBuilder = new GroupDescBuilder();
841             int bodyLength = input.readUnsignedShort();
842             groupDescBuilder.setType(GroupType.forValue(input.readUnsignedByte()));
843             input.skipBytes(PADDING_IN_GROUP_DESC_HEADER);
844             groupDescBuilder.setGroupId(new GroupId(input.readUnsignedInt()));
845             int actualLength = GROUP_DESC_HEADER_LENGTH;
846             List<BucketsList> bucketsList = new ArrayList<>();
847             while (actualLength < bodyLength) {
848                 BucketsListBuilder bucketsBuilder = new BucketsListBuilder();
849                 int bucketsLength = input.readUnsignedShort();
850                 bucketsBuilder.setWeight(input.readUnsignedShort());
851                 bucketsBuilder.setWatchPort(new PortNumber(input.readUnsignedInt()));
852                 bucketsBuilder.setWatchGroup(input.readUnsignedInt());
853                 input.skipBytes(PADDING_IN_BUCKETS_HEADER);
854                 CodeKeyMaker keyMaker = CodeKeyMakerFactory.createActionsKeyMaker(EncodeConstants.OF13_VERSION_ID);
855                 List<Action> actions = ListDeserializer.deserializeList(EncodeConstants.OF13_VERSION_ID,
856                         bucketsLength - BUCKETS_HEADER_LENGTH, input, keyMaker, registry);
857                 bucketsBuilder.setAction(actions);
858                 bucketsList.add(bucketsBuilder.build());
859                 actualLength += bucketsLength;
860             }
861             groupDescBuilder.setBucketsList(bucketsList);
862             groupDescsList.add(groupDescBuilder.build());
863         }
864         builder.setGroupDesc(groupDescsList);
865         caseBuilder.setMultipartReplyGroupDesc(builder.build());
866         return caseBuilder.build();
867     }
868
869     @Override
870     public void injectDeserializerRegistry(
871             DeserializerRegistry deserializerRegistry) {
872         registry = deserializerRegistry;
873     }
874 }