multipart reply message updated
[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.ActionCreator;\r
12 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev100924.MacAddress;\r
13 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.FlowModFlags;\r
14 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.GroupType;\r
15 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.MeterBandType;\r
16 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.MeterFlags;\r
17 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.MeterModCommand;\r
18 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.MultipartRequestFlags;\r
19 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.MultipartType;\r
20 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.PortConfig;\r
21 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.PortFeatures;\r
22 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.PortNumber;\r
23 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.PortState;\r
24 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.MultipartReplyMessage;\r
25 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.MultipartReplyMessageBuilder;\r
26 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.bucket.ActionsList;\r
27 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.meter.band.header.meter.band.MeterBandDropBuilder;\r
28 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.meter.band.header.meter.band.MeterBandDscpRemarkBuilder;\r
29 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.meter.band.header.meter.band.MeterBandExperimenterBuilder;\r
30 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.MultipartReplyAggregate;\r
31 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.MultipartReplyAggregateBuilder;\r
32 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.MultipartReplyDesc;\r
33 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.MultipartReplyDescBuilder;\r
34 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.MultipartReplyExperimenter;\r
35 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.MultipartReplyExperimenterBuilder;\r
36 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.MultipartReplyFlow;\r
37 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.MultipartReplyFlowBuilder;\r
38 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.MultipartReplyGroup;\r
39 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.MultipartReplyGroupBuilder;\r
40 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.MultipartReplyGroupDesc;\r
41 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.MultipartReplyGroupDescBuilder;\r
42 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.MultipartReplyMeter;\r
43 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.MultipartReplyMeterBuilder;\r
44 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.MultipartReplyMeterConfig;\r
45 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.MultipartReplyMeterConfigBuilder;\r
46 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.MultipartReplyMeterFeatures;\r
47 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.MultipartReplyMeterFeaturesBuilder;\r
48 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.MultipartReplyPortDesc;\r
49 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.MultipartReplyPortDescBuilder;\r
50 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.MultipartReplyPortStats;\r
51 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.MultipartReplyPortStatsBuilder;\r
52 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.MultipartReplyQueue;\r
53 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.MultipartReplyQueueBuilder;\r
54 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.MultipartReplyTable;\r
55 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.MultipartReplyTableBuilder;\r
56 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.multipart.reply.flow.FlowStats;\r
57 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.multipart.reply.flow.FlowStatsBuilder;\r
58 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.multipart.reply.group.GroupStats;\r
59 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.multipart.reply.group.GroupStatsBuilder;\r
60 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.multipart.reply.group.desc.GroupDesc;\r
61 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.multipart.reply.group.desc.GroupDescBuilder;\r
62 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.multipart.reply.group.desc.group.desc.BucketsList;\r
63 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.multipart.reply.group.desc.group.desc.BucketsListBuilder;\r
64 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.multipart.reply.group.group.stats.BucketStats;\r
65 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.multipart.reply.group.group.stats.BucketStatsBuilder;\r
66 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.multipart.reply.meter.MeterStats;\r
67 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.multipart.reply.meter.MeterStatsBuilder;\r
68 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.multipart.reply.meter.config.MeterConfig;\r
69 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.multipart.reply.meter.config.MeterConfigBuilder;\r
70 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.multipart.reply.meter.config.meter.config.Bands;\r
71 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.multipart.reply.meter.config.meter.config.BandsBuilder;\r
72 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.multipart.reply.meter.meter.stats.MeterBandStats;\r
73 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.multipart.reply.meter.meter.stats.MeterBandStatsBuilder;\r
74 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.multipart.reply.port.desc.Ports;\r
75 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.multipart.reply.port.desc.PortsBuilder;\r
76 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.multipart.reply.port.stats.PortStats;\r
77 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.multipart.reply.port.stats.PortStatsBuilder;\r
78 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.multipart.reply.queue.QueueStats;\r
79 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.multipart.reply.queue.QueueStatsBuilder;\r
80 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.multipart.reply.table.TableStats;\r
81 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.multipart.reply.table.TableStatsBuilder;\r
82 \r
83 /**\r
84  * @author timotej.kubas\r
85  * @author michal.polkorab\r
86  */\r
87 public class MultipartReplyMessageFactory implements OFDeserializer<MultipartReplyMessage> {\r
88 \r
89     private static MultipartReplyMessageFactory instance;\r
90     private static final byte PADDING_IN_MULTIPART_REPLY_HEADER = 4;\r
91     \r
92     private MultipartReplyMessageFactory() {\r
93         // singleton\r
94     }\r
95     \r
96     /**\r
97      * @return singleton factory\r
98      */\r
99     public static synchronized MultipartReplyMessageFactory getInstance() {\r
100         if (instance == null){\r
101             instance = new MultipartReplyMessageFactory();\r
102         }\r
103         return instance;\r
104     }\r
105 \r
106     @Override\r
107     public MultipartReplyMessage bufferToMessage(ByteBuf rawMessage, short version) {\r
108         MultipartReplyMessageBuilder builder = new MultipartReplyMessageBuilder();\r
109         builder.setVersion(version);\r
110         builder.setXid(rawMessage.readUnsignedInt());\r
111         builder.setType(MultipartType.forValue(rawMessage.readUnsignedShort()));\r
112         builder.setFlags(new MultipartRequestFlags((rawMessage.readUnsignedShort() & 0x01) != 0));\r
113         rawMessage.skipBytes(PADDING_IN_MULTIPART_REPLY_HEADER);\r
114         // TODO - implement body\r
115         //mrmb.setBody(rawMessage.readBytes(rawMessage.readableBytes()).array());\r
116 \r
117         switch (builder.getType().getIntValue()) {\r
118         case 0:  builder.setMultipartReplyBody(setDesc(rawMessage));\r
119                  break;\r
120         case 1:  builder.setMultipartReplyBody(setFlow(rawMessage));\r
121                  break;\r
122         case 2:  builder.setMultipartReplyBody(setAggregate(rawMessage));\r
123                  break;\r
124         case 3:  builder.setMultipartReplyBody(setTable(rawMessage));\r
125                  break;         \r
126         case 4:  builder.setMultipartReplyBody(setPortStats(rawMessage));\r
127                  break;\r
128         case 5:  builder.setMultipartReplyBody(setQueue(rawMessage));\r
129                  break;         \r
130         case 6:  builder.setMultipartReplyBody(setGroup(rawMessage));\r
131                  break;\r
132         case 7:  builder.setMultipartReplyBody(setGroupDesc(rawMessage));\r
133                  break;\r
134         case 9:  builder.setMultipartReplyBody(setMeter(rawMessage));\r
135                  break;\r
136         case 10:  builder.setMultipartReplyBody(setMeterConfig(rawMessage));\r
137                  break;\r
138         case 11: builder.setMultipartReplyBody(setMeterFeatures(rawMessage));\r
139                  break;\r
140         case 13: builder.setMultipartReplyBody(setPortDesc(rawMessage));\r
141                  break;\r
142         case 0xFFFF: builder.setMultipartReplyBody(setExperimenter(rawMessage));\r
143                  break;\r
144         default: \r
145                  break;\r
146         }\r
147         \r
148         return builder.build();\r
149     }\r
150     \r
151     private static MultipartReplyDesc setDesc(ByteBuf input) {\r
152         final int DESC_STR_LEN = 256;\r
153         final int SERIAL_NUM_LEN = 32;\r
154         MultipartReplyDescBuilder descBuilder = new MultipartReplyDescBuilder();\r
155         byte[] mfrDescBytes = new byte[DESC_STR_LEN];\r
156         input.readBytes(mfrDescBytes);\r
157         String mfrDesc = new String(mfrDescBytes);\r
158         descBuilder.setMfrDesc(mfrDesc.trim());\r
159         byte[] hwDescBytes = new byte[DESC_STR_LEN];\r
160         input.readBytes(hwDescBytes);\r
161         String hwDesc = new String(hwDescBytes);\r
162         descBuilder.setHwDesc(hwDesc.trim());\r
163         byte[] swDescBytes = new byte[DESC_STR_LEN];\r
164         input.readBytes(swDescBytes);\r
165         String swDesc = new String(swDescBytes);\r
166         descBuilder.setSwDesc(swDesc.trim());\r
167         byte[] serialNumBytes = new byte[SERIAL_NUM_LEN];\r
168         input.readBytes(serialNumBytes);\r
169         String serialNum = new String(serialNumBytes);\r
170         descBuilder.setSerialNum(serialNum.trim());\r
171         byte[] dpDescBytes = new byte[DESC_STR_LEN];\r
172         input.readBytes(dpDescBytes);\r
173         String dpDesc = new String(dpDescBytes);\r
174         descBuilder.setDpDesc(dpDesc.trim());\r
175         return descBuilder.build();\r
176     }\r
177     \r
178     private static MultipartReplyFlow setFlow(ByteBuf input) {\r
179         final byte PADDING_IN_FLOW_STATS_HEADER_01 = 1;\r
180         final byte PADDING_IN_FLOW_STATS_HEADER_02 = 4;\r
181         final byte flowLength = 2;\r
182         MultipartReplyFlowBuilder flowBuilder = new MultipartReplyFlowBuilder();\r
183         List<FlowStats> flowStatsList = new ArrayList<>();\r
184         FlowStatsBuilder flowStatsBuilder = new FlowStatsBuilder();\r
185         while (input.readableBytes() > 0) {\r
186             input.skipBytes(flowLength);\r
187             flowStatsBuilder.setTableId(input.readUnsignedByte());\r
188             input.skipBytes(PADDING_IN_FLOW_STATS_HEADER_01);\r
189             flowStatsBuilder.setDurationSec(input.readUnsignedInt());\r
190             flowStatsBuilder.setDurationNsec(input.readUnsignedInt());\r
191             flowStatsBuilder.setPriority(input.readUnsignedShort());\r
192             flowStatsBuilder.setIdleTimeout(input.readUnsignedShort());\r
193             flowStatsBuilder.setHardTimeout(input.readUnsignedShort());\r
194             flowStatsBuilder.setFlags(createFlowModFalgsFromBitmap(input.readShort()));\r
195             input.skipBytes(PADDING_IN_FLOW_STATS_HEADER_02);\r
196             byte[] cookie = new byte[Long.SIZE/Byte.SIZE];\r
197             input.readBytes(cookie);\r
198             flowStatsBuilder.setCookie(new BigInteger(cookie));\r
199             byte[] packetCount = new byte[Long.SIZE/Byte.SIZE];\r
200             input.readBytes(packetCount);\r
201             flowStatsBuilder.setPacketCount(new BigInteger(packetCount));\r
202             byte[] byteCount = new byte[Long.SIZE/Byte.SIZE];\r
203             input.readBytes(byteCount);\r
204             flowStatsBuilder.setByteCount(new BigInteger(byteCount));\r
205             // TODO match\r
206             // TODO instructions\r
207             flowStatsList.add(flowStatsBuilder.build());\r
208         }\r
209         flowBuilder.setFlowStats(new ArrayList<>(flowStatsList));\r
210         flowStatsList.clear();\r
211         return flowBuilder.build();\r
212     }\r
213     \r
214     private static FlowModFlags createFlowModFalgsFromBitmap(short input){\r
215         final Boolean _oFPFFSENDFLOWREM = (input & (1 << 0)) > 0;\r
216         final Boolean _oFPFFCHECKOVERLAP = (input & (1 << 1)) > 0;\r
217         final Boolean _oFPFFRESETCOUNTS = (input & (1 << 2)) > 0; \r
218         final Boolean _oFPFFNOPKTCOUNTS = (input & (1 << 3)) > 0;\r
219         final Boolean _oFPFFNOBYTCOUNTS = (input & (1 << 4)) > 0;\r
220         return new FlowModFlags(_oFPFFCHECKOVERLAP, _oFPFFNOBYTCOUNTS, _oFPFFNOPKTCOUNTS, _oFPFFRESETCOUNTS, _oFPFFSENDFLOWREM);\r
221     }\r
222     \r
223     private static MultipartReplyAggregate setAggregate(ByteBuf input) {\r
224         final byte PADDING_IN_AGGREGATE_HEADER = 4;\r
225         MultipartReplyAggregateBuilder builder = new MultipartReplyAggregateBuilder();\r
226         byte[] packetCount = new byte[Long.SIZE/Byte.SIZE];\r
227         input.readBytes(packetCount);\r
228         builder.setPacketCount(new BigInteger(packetCount));\r
229         byte[] byteCount = new byte[Long.SIZE/Byte.SIZE];\r
230         input.readBytes(byteCount);\r
231         builder.setByteCount(new BigInteger(byteCount));\r
232         builder.setFlowCount(input.readUnsignedInt());\r
233         input.skipBytes(PADDING_IN_AGGREGATE_HEADER);\r
234         return builder.build();\r
235     }\r
236     \r
237     private static MultipartReplyTable setTable(ByteBuf input) {\r
238         final byte PADDING_IN_TABLE_HEADER = 3;\r
239         MultipartReplyTableBuilder builder = new MultipartReplyTableBuilder();\r
240         TableStatsBuilder tableStatsBuilder = new TableStatsBuilder();\r
241         List<TableStats> tableStatsList = new ArrayList<>();\r
242         while (input.readableBytes() > 0) {\r
243             tableStatsBuilder.setTableId(input.readUnsignedByte());\r
244             input.skipBytes(PADDING_IN_TABLE_HEADER);\r
245             tableStatsBuilder.setActiveCount(input.readUnsignedInt());\r
246             byte[] lookupCount = new byte[Long.SIZE/Byte.SIZE];\r
247             input.readBytes(lookupCount);\r
248             tableStatsBuilder.setLookupCount(new BigInteger(lookupCount));\r
249             byte[] matchedCount = new byte[Long.SIZE/Byte.SIZE];\r
250             input.readBytes(matchedCount);\r
251             tableStatsBuilder.setMatchedCount(new BigInteger(matchedCount));\r
252             tableStatsList.add(tableStatsBuilder.build());\r
253         }\r
254         builder.setTableStats(new ArrayList<>(tableStatsList));\r
255         tableStatsList.clear();\r
256         return builder.build();\r
257     }\r
258     \r
259     private static MultipartReplyPortStats setPortStats(ByteBuf input) {\r
260         final byte PADDING_IN_PORT_STATS_HEADER = 4;\r
261         MultipartReplyPortStatsBuilder builder = new MultipartReplyPortStatsBuilder();\r
262         PortStatsBuilder portStatsBuilder = new PortStatsBuilder();\r
263         List<PortStats> portStatsList = new ArrayList<>();\r
264         while (input.readableBytes() > 0) {\r
265             portStatsBuilder.setPortNo(input.readUnsignedInt());\r
266             input.skipBytes(PADDING_IN_PORT_STATS_HEADER);\r
267             \r
268             byte[] rxPackets = new byte[Long.SIZE/Byte.SIZE];\r
269             input.readBytes(rxPackets);\r
270             portStatsBuilder.setRxPackets(new BigInteger(rxPackets));\r
271             \r
272             byte[] txPackets = new byte[Long.SIZE/Byte.SIZE];\r
273             input.readBytes(txPackets);\r
274             portStatsBuilder.setTxPackets(new BigInteger(txPackets));\r
275             \r
276             byte[] rxBytes = new byte[Long.SIZE/Byte.SIZE];\r
277             input.readBytes(rxBytes);\r
278             portStatsBuilder.setRxBytes(new BigInteger(rxBytes));\r
279             \r
280             byte[] txBytes = new byte[Long.SIZE/Byte.SIZE];\r
281             input.readBytes(txBytes);\r
282             portStatsBuilder.setTxBytes(new BigInteger(txBytes));\r
283             \r
284             byte[] rxDropped = new byte[Long.SIZE/Byte.SIZE];\r
285             input.readBytes(rxDropped);\r
286             portStatsBuilder.setRxDropped(new BigInteger(rxDropped));\r
287             \r
288             byte[] txDropped = new byte[Long.SIZE/Byte.SIZE];\r
289             input.readBytes(txDropped);\r
290             portStatsBuilder.setTxDropped(new BigInteger(txDropped));\r
291             \r
292             byte[] rxErrors = new byte[Long.SIZE/Byte.SIZE];\r
293             input.readBytes(rxErrors);\r
294             portStatsBuilder.setRxErrors(new BigInteger(rxErrors));\r
295             \r
296             byte[] txErrors = new byte[Long.SIZE/Byte.SIZE];\r
297             input.readBytes(txErrors);\r
298             portStatsBuilder.setTxErrors(new BigInteger(txErrors));\r
299             \r
300             byte[] rxFrameErr = new byte[Long.SIZE/Byte.SIZE];\r
301             input.readBytes(rxFrameErr);\r
302             portStatsBuilder.setRxFrameErr(new BigInteger(rxFrameErr));\r
303             \r
304             byte[] rxOverErr = new byte[Long.SIZE/Byte.SIZE];\r
305             input.readBytes(rxOverErr);\r
306             portStatsBuilder.setRxOverErr(new BigInteger(rxOverErr));\r
307             \r
308             byte[] rxCrcErr = new byte[Long.SIZE/Byte.SIZE];\r
309             input.readBytes(rxCrcErr);\r
310             portStatsBuilder.setRxCrcErr(new BigInteger(rxCrcErr));\r
311             \r
312             byte[] collisions = new byte[Long.SIZE/Byte.SIZE];\r
313             input.readBytes(collisions);\r
314             portStatsBuilder.setCollisions(new BigInteger(collisions));\r
315             \r
316             portStatsBuilder.setDurationSec(input.readUnsignedInt());\r
317             portStatsBuilder.setDurationNsec(input.readUnsignedInt());\r
318             portStatsList.add(portStatsBuilder.build());\r
319         }\r
320         builder.setPortStats(new ArrayList<>(portStatsList));\r
321         portStatsList.clear();\r
322         return builder.build();\r
323     }\r
324     \r
325     private static MultipartReplyQueue setQueue(ByteBuf input) {\r
326         MultipartReplyQueueBuilder builder = new MultipartReplyQueueBuilder();\r
327         QueueStatsBuilder queueStatsBuilder = new QueueStatsBuilder();\r
328         List<QueueStats> queueStatsList = new ArrayList<>();\r
329         \r
330         while (input.readableBytes() > 0) {\r
331             queueStatsBuilder.setPortNo(input.readUnsignedInt());\r
332             queueStatsBuilder.setQueueId(input.readUnsignedInt());\r
333 \r
334             byte[] txBytes = new byte[Long.SIZE/Byte.SIZE];\r
335             input.readBytes(txBytes);\r
336             queueStatsBuilder.setTxBytes(new BigInteger(txBytes));\r
337 \r
338             byte[] txPackets = new byte[Long.SIZE/Byte.SIZE];\r
339             input.readBytes(txPackets);\r
340             queueStatsBuilder.setTxPackets(new BigInteger(txPackets));\r
341 \r
342             byte[] txErrors = new byte[Long.SIZE/Byte.SIZE];\r
343             input.readBytes(txErrors);\r
344             queueStatsBuilder.setTxErrors(new BigInteger(txErrors));\r
345 \r
346             queueStatsBuilder.setDurationSec(input.readUnsignedInt());\r
347             queueStatsBuilder.setDurationNsec(input.readUnsignedInt());\r
348             queueStatsList.add(queueStatsBuilder.build());\r
349         }\r
350         builder.setQueueStats(new ArrayList<>(queueStatsList));\r
351         queueStatsList.clear();\r
352         return builder.build();\r
353     }\r
354     \r
355     private static MultipartReplyGroup setGroup(ByteBuf input) {\r
356         final byte PADDING_IN_GROUP_HEADER_01 = 2;\r
357         final byte PADDING_IN_GROUP_HEADER_02 = 4;\r
358         final byte BUCKET_COUNTER_LENGTH = 16;\r
359         final byte GROUP_BODY_LENGTH = 40;\r
360         int actualLength;\r
361         MultipartReplyGroupBuilder builder = new MultipartReplyGroupBuilder();\r
362         GroupStatsBuilder groupStatsBuilder = new GroupStatsBuilder();\r
363         List<GroupStats> groupStatsList = new ArrayList<>();\r
364         \r
365         BucketStatsBuilder bucketStatsBuilder = new BucketStatsBuilder();\r
366         List<BucketStats> bucketStatsList = new ArrayList<>();\r
367         \r
368         while (input.readableBytes() > 0) {\r
369             int bodyLength = input.readUnsignedShort();\r
370             actualLength = 0;\r
371             \r
372             input.skipBytes(PADDING_IN_GROUP_HEADER_01);\r
373             groupStatsBuilder.setGroupId(input.readUnsignedInt());\r
374             groupStatsBuilder.setRefCount(input.readUnsignedInt());\r
375             input.skipBytes(PADDING_IN_GROUP_HEADER_02);\r
376             byte[] packetCount = new byte[Long.SIZE/Byte.SIZE];\r
377             input.readBytes(packetCount);\r
378             groupStatsBuilder.setPacketCount(new BigInteger(packetCount));\r
379             byte[] byteCount = new byte[Long.SIZE/Byte.SIZE];\r
380             input.readBytes(byteCount);\r
381             groupStatsBuilder.setByteCount(new BigInteger(byteCount));\r
382             groupStatsBuilder.setDurationSec(input.readUnsignedInt());\r
383             groupStatsBuilder.setDurationNsec(input.readUnsignedInt());\r
384             actualLength = GROUP_BODY_LENGTH;\r
385             \r
386             while (actualLength < bodyLength) {\r
387                 byte[] packetCountBucket = new byte[Long.SIZE/Byte.SIZE];\r
388                 input.readBytes(packetCountBucket);\r
389                 bucketStatsBuilder.setPacketCount(new BigInteger(packetCountBucket));\r
390                 byte[] byteCountBucket = new byte[Long.SIZE/Byte.SIZE];\r
391                 input.readBytes(byteCountBucket);\r
392                 bucketStatsBuilder.setByteCount(new BigInteger(byteCountBucket));\r
393                 bucketStatsList.add(bucketStatsBuilder.build());\r
394 \r
395                 actualLength = actualLength + BUCKET_COUNTER_LENGTH;\r
396             } \r
397             groupStatsBuilder.setBucketStats(new ArrayList<>(bucketStatsList));\r
398             bucketStatsList.clear();\r
399             groupStatsList.add(groupStatsBuilder.build());\r
400         }\r
401         builder.setGroupStats(new ArrayList<>(groupStatsList));\r
402         groupStatsList.clear();\r
403         return builder.build();\r
404     }\r
405     \r
406     private static MultipartReplyMeterFeatures setMeterFeatures(ByteBuf input) {\r
407         final byte PADDING_IN_METER_FEATURES_HEADER = 2;\r
408         MultipartReplyMeterFeaturesBuilder builder = new MultipartReplyMeterFeaturesBuilder();\r
409         builder.setMaxMeter(input.readUnsignedInt());\r
410         builder.setBandTypes(MeterBandType.forValue(input.readInt()));\r
411         builder.setCapabilities(decodeMeterModFlags((int) input.readUnsignedInt()));\r
412         builder.setMaxBands(input.readUnsignedByte());\r
413         builder.setMaxColor(input.readUnsignedByte());\r
414         input.skipBytes(PADDING_IN_METER_FEATURES_HEADER);\r
415         return builder.build();\r
416     }\r
417     \r
418     private static MeterFlags decodeMeterModFlags(int input){\r
419         final Boolean _oFPMFKBPS = (input & (1 << 0)) > 0;\r
420         final Boolean _oFPMFPKTPS = (input & (1 << 1)) > 0;\r
421         final Boolean _oFPMFBURST = (input & (1 << 2)) > 0; \r
422         final Boolean _oFPMFSTATS = (input & (1 << 3)) > 0;\r
423         return new MeterFlags(_oFPMFBURST, _oFPMFKBPS, _oFPMFPKTPS, _oFPMFSTATS);\r
424     }\r
425     \r
426     private static MultipartReplyMeter setMeter(ByteBuf input) {\r
427         final byte PADDING_IN_METER_STATS_HEADER = 6;\r
428         final byte METER_BAND_STATS_LENGTH = 16;\r
429         final byte METER_BODY_LENGTH = 40;\r
430         int actualLength;\r
431         MultipartReplyMeterBuilder builder = new MultipartReplyMeterBuilder();\r
432         List<MeterStats> meterStatsList = new ArrayList<>();\r
433         MeterStatsBuilder meterStatsBuilder = new MeterStatsBuilder();\r
434         List<MeterBandStats> meterBandStatsList = new ArrayList<>();\r
435         MeterBandStatsBuilder meterBandStatsBuilder = new MeterBandStatsBuilder();\r
436         while (input.readableBytes() > 0) {\r
437             meterStatsBuilder.setMeterId(input.readUnsignedInt());\r
438             actualLength = 0;\r
439             int meterStatsBodyLength = input.readUnsignedShort();\r
440             input.skipBytes(PADDING_IN_METER_STATS_HEADER);\r
441             meterStatsBuilder.setFlowCount(input.readUnsignedInt());\r
442             byte[] packetInCount = new byte[Long.SIZE/Byte.SIZE];\r
443             input.readBytes(packetInCount);\r
444             meterStatsBuilder.setPacketInCount(new BigInteger(packetInCount));\r
445             byte[] byteInCount = new byte[Long.SIZE/Byte.SIZE];\r
446             input.readBytes(byteInCount);\r
447             meterStatsBuilder.setByteInCount(new BigInteger(byteInCount));\r
448             meterStatsBuilder.setDurationSec(input.readUnsignedInt());\r
449             meterStatsBuilder.setDurationNsec(input.readUnsignedInt());\r
450             actualLength = METER_BODY_LENGTH;\r
451             \r
452             while (actualLength < meterStatsBodyLength) {\r
453                 byte[] packetBandCount = new byte[Long.SIZE/Byte.SIZE];\r
454                 input.readBytes(packetBandCount);\r
455                 meterBandStatsBuilder.setPacketBandCount(new BigInteger(packetBandCount));\r
456                 byte[] byteBandCount = new byte[Long.SIZE/Byte.SIZE];\r
457                 input.readBytes(byteBandCount);\r
458                 meterBandStatsBuilder.setByteBandCount(new BigInteger(byteBandCount));\r
459                 \r
460                 meterBandStatsList.add(meterBandStatsBuilder.build());\r
461                 actualLength = actualLength + METER_BAND_STATS_LENGTH;\r
462             }\r
463         \r
464             meterStatsBuilder.setMeterBandStats(new ArrayList<>(meterBandStatsList));\r
465             meterBandStatsList.clear();\r
466             meterStatsList.add(meterStatsBuilder.build());\r
467         }\r
468         builder.setMeterStats(new ArrayList<>(meterStatsList));\r
469         meterStatsList.clear();\r
470         return builder.build();\r
471     }\r
472     \r
473     private static MultipartReplyMeterConfig setMeterConfig(ByteBuf input) {\r
474         final byte METER_BAND_LENGTH = 16;\r
475         final byte METER_CONFIG_LENGTH = 8;\r
476         final byte bandLength = 2;\r
477         int actualLength;\r
478         MultipartReplyMeterConfigBuilder builder = new MultipartReplyMeterConfigBuilder();\r
479         List<MeterConfig> meterConfigList = new ArrayList<>();\r
480         MeterConfigBuilder meterConfigBuilder = new MeterConfigBuilder();\r
481         List<Bands> bandsList = new ArrayList<Bands>();\r
482         BandsBuilder bandsBuilder = new BandsBuilder();\r
483         \r
484         while (input.readableBytes() > 0) {\r
485             int meterConfigBodyLength = input.readUnsignedShort();\r
486             actualLength = 0;\r
487             meterConfigBuilder.setFlags(MeterModCommand.forValue(input.readUnsignedShort()));\r
488             meterConfigBuilder.setMeterId(input.readUnsignedInt());\r
489             actualLength = METER_CONFIG_LENGTH;\r
490             \r
491             while (actualLength < meterConfigBodyLength) {\r
492                 MeterBandDropBuilder bandDropBuilder = new MeterBandDropBuilder();\r
493                 final byte PADDING_IN_METER_BAND_DROP_HEADER = 4;\r
494                 MeterBandDscpRemarkBuilder bandDscpRemarkBuilder = new MeterBandDscpRemarkBuilder();\r
495                 final byte PADDING_IN_METER_BAND_DSCP_HEADER = 3;\r
496                 MeterBandExperimenterBuilder bandExperimenterBuilder = new MeterBandExperimenterBuilder(); \r
497                 int bandType = input.readUnsignedShort();\r
498                 switch (bandType) {\r
499                     case 1: bandDropBuilder.setType(MeterBandType.forValue(bandType));\r
500                             input.skipBytes(bandLength);\r
501                             bandDropBuilder.setRate(input.readUnsignedInt());\r
502                             bandDropBuilder.setBurstSize(input.readUnsignedInt());\r
503                             input.skipBytes(PADDING_IN_METER_BAND_DROP_HEADER);\r
504                             bandsBuilder.setMeterBand(bandDropBuilder.build());\r
505                             break;\r
506                     case 2: bandDscpRemarkBuilder.setType(MeterBandType.forValue(bandType));\r
507                             input.skipBytes(bandLength);\r
508                             bandDscpRemarkBuilder.setRate(input.readUnsignedInt());\r
509                             bandDscpRemarkBuilder.setBurstSize(input.readUnsignedInt());\r
510                             bandDscpRemarkBuilder.setPrecLevel(input.readUnsignedByte());\r
511                             input.skipBytes(PADDING_IN_METER_BAND_DSCP_HEADER);\r
512                             bandsBuilder.setMeterBand(bandDscpRemarkBuilder.build());\r
513                             break;\r
514                     case 0xFFFF: bandExperimenterBuilder.setType(MeterBandType.forValue(bandType));\r
515                                  input.skipBytes(bandLength);\r
516                                  bandExperimenterBuilder.setRate(input.readUnsignedInt());\r
517                                  bandExperimenterBuilder.setBurstSize(input.readUnsignedInt());\r
518                                  bandExperimenterBuilder.setExperimenter(input.readUnsignedInt());\r
519                                  bandsBuilder.setMeterBand(bandExperimenterBuilder.build());\r
520                                  break;\r
521                     default: break;\r
522                 }\r
523                 bandsList.add(bandsBuilder.build());\r
524                 actualLength = actualLength + METER_BAND_LENGTH;\r
525             }\r
526             meterConfigBuilder.setBands(new ArrayList<>(bandsList));\r
527             bandsList.clear();\r
528             meterConfigList.add(meterConfigBuilder.build());\r
529         }\r
530         builder.setMeterConfig(new ArrayList<>(meterConfigList));\r
531         meterConfigList.clear();\r
532         return builder.build();\r
533     }\r
534     \r
535     private static MultipartReplyExperimenter setExperimenter(ByteBuf input) {\r
536         MultipartReplyExperimenterBuilder builder = new MultipartReplyExperimenterBuilder();\r
537         builder.setExperimenter(input.readUnsignedInt());\r
538         builder.setExpType(input.readUnsignedInt());\r
539         byte[] data = new byte[Long.SIZE/Byte.SIZE];\r
540         input.readBytes(data);\r
541         builder.setData(data);\r
542         return builder.build();\r
543     }\r
544     \r
545     private static MultipartReplyPortDesc setPortDesc(ByteBuf input) {\r
546         final byte PADDING_IN_PORT_DESC_HEADER_01 = 4;\r
547         final byte PADDING_IN_PORT_DESC_HEADER_02 = 2;\r
548         final int macAddressLength = 6;\r
549         final byte MAX_PORT_NAME_LEN = 16;\r
550         MultipartReplyPortDescBuilder builder = new MultipartReplyPortDescBuilder();\r
551         List<Ports> portsList = new ArrayList<>();\r
552         PortsBuilder portsBuilder = new PortsBuilder();\r
553         \r
554         while (input.readableBytes() > 0) {\r
555             portsBuilder.setPortNo(input.readUnsignedInt());\r
556             input.skipBytes(PADDING_IN_PORT_DESC_HEADER_01);\r
557             StringBuffer macToString = new StringBuffer();\r
558             for(int i=0; i<macAddressLength; i++){\r
559                 short mac = 0;\r
560                 mac = input.readUnsignedByte();\r
561                 macToString.append(String.format("%02X", mac));\r
562             }\r
563             portsBuilder.setHwAddr(new MacAddress(macToString.toString()));\r
564             input.skipBytes(PADDING_IN_PORT_DESC_HEADER_02);\r
565             \r
566             byte[] portNameBytes = new byte[MAX_PORT_NAME_LEN];\r
567             input.readBytes(portNameBytes);\r
568             String portName = new String(portNameBytes);\r
569             portsBuilder.setName(portName.trim());\r
570             \r
571             portsBuilder.setConfig(createPortConfig(input.readUnsignedInt()));\r
572             portsBuilder.setState(createPortState(input.readUnsignedInt()));\r
573             portsBuilder.setCurrentFeatures(createPortFeatures(input.readUnsignedInt()));\r
574             portsBuilder.setAdvertisedFeatures(createPortFeatures(input.readUnsignedInt()));\r
575             portsBuilder.setSupportedFeatures(createPortFeatures(input.readUnsignedInt()));\r
576             portsBuilder.setPeerFeatures(createPortFeatures(input.readUnsignedInt()));\r
577             portsBuilder.setCurrSpeed(input.readUnsignedInt());\r
578             portsBuilder.setMaxSpeed(input.readUnsignedInt());\r
579             portsList.add(portsBuilder.build());\r
580         }\r
581         \r
582         builder.setPorts(new ArrayList<>(portsList));\r
583         portsList.clear();\r
584         return builder.build();\r
585     }\r
586     \r
587     private static PortConfig createPortConfig(long input){\r
588         final Boolean _portDown   = ((input) & (1<<0)) != 0;\r
589         final Boolean _noRecv    = ((input) & (1<<2)) != 0;\r
590         final Boolean _noFwd       = ((input) & (1<<5)) != 0;\r
591         final Boolean _noPacketIn = ((input) & (1<<6)) != 0;\r
592         return new PortConfig(_noFwd, _noPacketIn, _noRecv, _portDown);\r
593     }\r
594     \r
595     private static PortState createPortState(long input){\r
596         final Boolean _linkDown = ((input) & (1<<0)) != 0;\r
597         final Boolean _blocked  = ((input) & (1<<1)) != 0;\r
598         final Boolean _live     = ((input) & (1<<2)) != 0;\r
599         return new PortState(_linkDown, _blocked,_live);\r
600     }\r
601     \r
602     private static PortFeatures createPortFeatures(long input){\r
603         final Boolean _10mbHd = ((input) & (1<<0)) != 0;\r
604         final Boolean _10mbFd = ((input) & (1<<1)) != 0;\r
605         final Boolean _100mbHd = ((input) & (1<<2)) != 0;\r
606         final Boolean _100mbFd = ((input) & (1<<3)) != 0;\r
607         final Boolean _1gbHd = ((input) & (1<<4)) != 0;\r
608         final Boolean _1gbFd = ((input) & (1<<5)) != 0;\r
609         final Boolean _10gbFd = ((input) & (1<<6)) != 0;\r
610         final Boolean _40gbFd = ((input) & (1<<7)) != 0;\r
611         final Boolean _100gbFd = ((input) & (1<<8)) != 0;\r
612         final Boolean _1tbFd = ((input) & (1<<9)) != 0;\r
613         final Boolean _other = ((input) & (1<<10)) != 0;\r
614         final Boolean _copper = ((input) & (1<<11)) != 0;\r
615         final Boolean _fiber = ((input) & (1<<12)) != 0;\r
616         final Boolean _autoneg = ((input) & (1<<13)) != 0;\r
617         final Boolean _pause = ((input) & (1<<14)) != 0;\r
618         final Boolean _pauseAsym = ((input) & (1<<15)) != 0;\r
619         return new PortFeatures(_10mbHd, _10mbFd, _100mbHd, _100mbFd, _1gbHd, _1gbFd, _10gbFd,\r
620                 _40gbFd, _100gbFd, _1tbFd, _other, _copper, _fiber, _autoneg, _pause, _pauseAsym);\r
621     }\r
622     \r
623     private static MultipartReplyGroupDesc setGroupDesc(ByteBuf input) {\r
624         final byte PADDING_IN_GROUP_DESC_HEADER = 1;\r
625         final byte PADDING_IN_BUCKETS_HEADER = 4;\r
626         final byte GROUP_DESC_HEADER_LENGTH = 8;\r
627         int actualLength;\r
628         int bucketsLength = 0;\r
629         int bucketsCurrentLength = 0;\r
630         int bodyLength = 0;\r
631         MultipartReplyGroupDescBuilder builder = new MultipartReplyGroupDescBuilder();\r
632         GroupDescBuilder groupDescBuilder = new GroupDescBuilder();\r
633         List<GroupDesc> groupDescsList = new ArrayList<>();\r
634         BucketsListBuilder bucketsBuilder = new BucketsListBuilder();\r
635         List<BucketsList> bucketsList = new ArrayList<>();\r
636         List<ActionsList> actionsList = new ArrayList<>();\r
637         \r
638         while (input.readableBytes() > 0) {\r
639             bodyLength = input.readUnsignedShort();\r
640             actualLength = 0;\r
641             \r
642             groupDescBuilder.setType(GroupType.forValue(input.readUnsignedByte())); // TODO enum or class?\r
643             input.skipBytes(PADDING_IN_GROUP_DESC_HEADER);\r
644             groupDescBuilder.setGroupId(input.readUnsignedInt());\r
645             actualLength = GROUP_DESC_HEADER_LENGTH;\r
646             \r
647             while (actualLength < bodyLength) {\r
648                 \r
649                 bucketsLength = input.readUnsignedShort();\r
650                 bucketsBuilder.setWeight(input.readUnsignedShort());\r
651                 bucketsBuilder.setWatchPort(new PortNumber(input.readUnsignedInt()));\r
652                 bucketsBuilder.setWatchGroup(input.readUnsignedInt());\r
653                 input.skipBytes(PADDING_IN_BUCKETS_HEADER);\r
654                 bucketsCurrentLength = bucketsLength;\r
655                 actionsList = ActionCreator.createActionsList(input, bucketsLength);\r
656                 bucketsBuilder.setActionsList(new ArrayList<>(actionsList));\r
657                 actionsList.clear();\r
658                 bucketsList.add(bucketsBuilder.build());\r
659                 actualLength = actualLength + bucketsCurrentLength;\r
660             }\r
661             groupDescBuilder.setBucketsList(new ArrayList<>(bucketsList));\r
662             bucketsList.clear();\r
663             groupDescsList.add(groupDescBuilder.build());\r
664         }\r
665         builder.setGroupDesc(new ArrayList<>(groupDescsList));\r
666         groupDescsList.clear();\r
667         return builder.build();\r
668     }\r
669     \r
670 }\r