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