64bf2ac39cedd932e0afb823129e525d7070f3b6
[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.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.FlowModFlags;\r
12 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.MultipartRequestFlags;\r
13 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.MultipartType;\r
14 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.MultipartReplyMessage;\r
15 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.MultipartReplyMessageBuilder;\r
16 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.MultipartReplyAggregate;\r
17 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.MultipartReplyAggregateBuilder;\r
18 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.MultipartReplyDesc;\r
19 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.MultipartReplyDescBuilder;\r
20 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.MultipartReplyFlow;\r
21 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.MultipartReplyFlowBuilder;\r
22 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.MultipartReplyGroup;\r
23 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.MultipartReplyGroupBuilder;\r
24 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.MultipartReplyPortStats;\r
25 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.MultipartReplyPortStatsBuilder;\r
26 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.MultipartReplyQueue;\r
27 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.MultipartReplyQueueBuilder;\r
28 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.MultipartReplyTable;\r
29 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.MultipartReplyTableBuilder;\r
30 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.multipart.reply.flow.FlowStats;\r
31 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.multipart.reply.flow.FlowStatsBuilder;\r
32 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.multipart.reply.group.GroupStats;\r
33 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.multipart.reply.group.GroupStatsBuilder;\r
34 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.multipart.reply.group.group.stats.BucketStats;\r
35 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.multipart.reply.group.group.stats.BucketStatsBuilder;\r
36 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.multipart.reply.port.stats.PortStats;\r
37 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.multipart.reply.port.stats.PortStatsBuilder;\r
38 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.multipart.reply.queue.QueueStats;\r
39 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.multipart.reply.queue.QueueStatsBuilder;\r
40 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.multipart.reply.table.TableStats;\r
41 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.multipart.reply.table.TableStatsBuilder;\r
42 \r
43 /**\r
44  * @author timotej.kubas\r
45  * @author michal.polkorab\r
46  */\r
47 public class MultipartReplyMessageFactory implements OFDeserializer<MultipartReplyMessage> {\r
48 \r
49     private static MultipartReplyMessageFactory instance;\r
50     private static final byte PADDING_IN_MULTIPART_REPLY_HEADER = 4;\r
51     \r
52     private MultipartReplyMessageFactory() {\r
53         // singleton\r
54     }\r
55     \r
56     /**\r
57      * @return singleton factory\r
58      */\r
59     public static synchronized MultipartReplyMessageFactory getInstance() {\r
60         if (instance == null){\r
61             instance = new MultipartReplyMessageFactory();\r
62         }\r
63         return instance;\r
64     }\r
65 \r
66     @Override\r
67     public MultipartReplyMessage bufferToMessage(ByteBuf rawMessage, short version) {\r
68         MultipartReplyMessageBuilder builder = new MultipartReplyMessageBuilder();\r
69         builder.setVersion(version);\r
70         builder.setXid(rawMessage.readUnsignedInt());\r
71         builder.setType(MultipartType.forValue(rawMessage.readUnsignedShort()));\r
72         builder.setFlags(new MultipartRequestFlags((rawMessage.readUnsignedShort() & 0x01) != 0));\r
73         rawMessage.skipBytes(PADDING_IN_MULTIPART_REPLY_HEADER);\r
74         // TODO - implement body\r
75         //mrmb.setBody(rawMessage.readBytes(rawMessage.readableBytes()).array());\r
76         \r
77         switch (builder.getType().getIntValue()) {\r
78         case 0:  builder.setMultipartReplyBody(setDesc(rawMessage));\r
79                  break;\r
80         case 1:  builder.setMultipartReplyBody(setFlow(rawMessage));\r
81                  break;\r
82         case 2:  builder.setMultipartReplyBody(setAggregate(rawMessage));\r
83                  break;\r
84         case 3:  builder.setMultipartReplyBody(setTable(rawMessage));\r
85                  break;         \r
86         case 4:  builder.setMultipartReplyBody(setPortStats(rawMessage));\r
87                  break;\r
88         case 5:  builder.setMultipartReplyBody(setQueue(rawMessage));\r
89                  break;         \r
90         case 6:  builder.setMultipartReplyBody(setGroup(rawMessage));\r
91                  break;\r
92         default: \r
93                  break;\r
94         }\r
95         \r
96         return builder.build();\r
97     }\r
98     \r
99     private static MultipartReplyDesc setDesc(ByteBuf input) {\r
100         final int DESC_STR_LEN = 256;\r
101         final int SERIAL_NUM_LEN = 32;\r
102         MultipartReplyDescBuilder descBuilder = new MultipartReplyDescBuilder();\r
103         byte[] mfrDescBytes = new byte[DESC_STR_LEN];\r
104         input.readBytes(mfrDescBytes);\r
105         String mfrDesc = new String(mfrDescBytes);\r
106         descBuilder.setMfrDesc(mfrDesc.trim());\r
107         byte[] hwDescBytes = new byte[DESC_STR_LEN];\r
108         input.readBytes(hwDescBytes);\r
109         String hwDesc = new String(hwDescBytes);\r
110         descBuilder.setHwDesc(hwDesc.trim());\r
111         byte[] swDescBytes = new byte[DESC_STR_LEN];\r
112         input.readBytes(swDescBytes);\r
113         String swDesc = new String(swDescBytes);\r
114         descBuilder.setSwDesc(swDesc.trim());\r
115         byte[] serialNumBytes = new byte[SERIAL_NUM_LEN];\r
116         input.readBytes(serialNumBytes);\r
117         String serialNum = new String(serialNumBytes);\r
118         descBuilder.setSerialNum(serialNum.trim());\r
119         byte[] dpDescBytes = new byte[DESC_STR_LEN];\r
120         input.readBytes(dpDescBytes);\r
121         String dpDesc = new String(dpDescBytes);\r
122         descBuilder.setDpDesc(dpDesc.trim());\r
123         return descBuilder.build();\r
124     }\r
125     \r
126     private static MultipartReplyFlow setFlow(ByteBuf input) {\r
127         final byte PADDING_IN_FLOW_STATS_HEADER_01 = 1;\r
128         final byte PADDING_IN_FLOW_STATS_HEADER_02 = 4;\r
129         MultipartReplyFlowBuilder flowBuilder = new MultipartReplyFlowBuilder();\r
130         List<FlowStats> flowStatsList = new ArrayList<>();\r
131         FlowStatsBuilder flowStatsBuilder = new FlowStatsBuilder();\r
132         while (input.readableBytes() > 0) {\r
133             flowStatsBuilder.setTableId(input.readUnsignedByte());\r
134             input.skipBytes(PADDING_IN_FLOW_STATS_HEADER_01);\r
135             flowStatsBuilder.setDurationSec(input.readUnsignedInt());\r
136             flowStatsBuilder.setDurationNsec(input.readUnsignedInt());\r
137             flowStatsBuilder.setPriority(input.readUnsignedShort());\r
138             flowStatsBuilder.setIdleTimeout(input.readUnsignedShort());\r
139             flowStatsBuilder.setHardTimeout(input.readUnsignedShort());\r
140             flowStatsBuilder.setFlags(createFlowModFalgsFromBitmap(input.readShort()));\r
141             input.skipBytes(PADDING_IN_FLOW_STATS_HEADER_02);\r
142             byte[] cookie = new byte[Long.SIZE/Byte.SIZE];\r
143             input.readBytes(cookie);\r
144             flowStatsBuilder.setCookie(new BigInteger(cookie));\r
145             byte[] packetCount = new byte[Long.SIZE/Byte.SIZE];\r
146             input.readBytes(packetCount);\r
147             flowStatsBuilder.setPacketCount(new BigInteger(packetCount));\r
148             byte[] byteCount = new byte[Long.SIZE/Byte.SIZE];\r
149             input.readBytes(byteCount);\r
150             flowStatsBuilder.setByteCount(new BigInteger(byteCount));\r
151             // TODO match\r
152             // TODO instructions\r
153             flowStatsList.add(flowStatsBuilder.build());\r
154         }\r
155         flowBuilder.setFlowStats(flowStatsList);\r
156         return flowBuilder.build();\r
157     }\r
158     \r
159     private static FlowModFlags createFlowModFalgsFromBitmap(short input){\r
160         final Boolean _oFPFFSENDFLOWREM = (input & (1 << 0)) > 0;\r
161         final Boolean _oFPFFCHECKOVERLAP = (input & (1 << 1)) > 0;\r
162         final Boolean _oFPFFRESETCOUNTS = (input & (1 << 2)) > 0; \r
163         final Boolean _oFPFFNOPKTCOUNTS = (input & (1 << 3)) > 0;\r
164         final Boolean _oFPFFNOBYTCOUNTS = (input & (1 << 4)) > 0;\r
165         return new FlowModFlags(_oFPFFCHECKOVERLAP, _oFPFFNOBYTCOUNTS, _oFPFFNOPKTCOUNTS, _oFPFFRESETCOUNTS, _oFPFFSENDFLOWREM);\r
166     }\r
167     \r
168     private static MultipartReplyAggregate setAggregate(ByteBuf input) {\r
169         final byte PADDING_IN_AGGREGATE_HEADER = 4;\r
170         MultipartReplyAggregateBuilder builder = new MultipartReplyAggregateBuilder();\r
171         byte[] packetCount = new byte[Long.SIZE/Byte.SIZE];\r
172         input.readBytes(packetCount);\r
173         builder.setPacketCount(new BigInteger(packetCount));\r
174         byte[] byteCount = new byte[Long.SIZE/Byte.SIZE];\r
175         input.readBytes(byteCount);\r
176         builder.setByteCount(new BigInteger(byteCount));\r
177         builder.setFlowCount(input.readUnsignedInt());\r
178         input.skipBytes(PADDING_IN_AGGREGATE_HEADER);\r
179         return builder.build();\r
180     }\r
181     \r
182     private static MultipartReplyTable setTable(ByteBuf input) {\r
183         final byte PADDING_IN_TABLE_HEADER = 3;\r
184         MultipartReplyTableBuilder builder = new MultipartReplyTableBuilder();\r
185         TableStatsBuilder tableStatsBuilder = new TableStatsBuilder();\r
186         List<TableStats> tableStatsList = new ArrayList<>();\r
187         while (input.readableBytes() > 0) {\r
188             tableStatsBuilder.setTableId(input.readUnsignedByte());\r
189             input.skipBytes(PADDING_IN_TABLE_HEADER);\r
190             tableStatsBuilder.setActiveCount(input.readUnsignedInt());\r
191             byte[] lookupCount = new byte[Long.SIZE/Byte.SIZE];\r
192             input.readBytes(lookupCount);\r
193             tableStatsBuilder.setLookupCount(new BigInteger(lookupCount));\r
194             byte[] matchedCount = new byte[Long.SIZE/Byte.SIZE];\r
195             input.readBytes(matchedCount);\r
196             tableStatsBuilder.setMatchedCount(new BigInteger(matchedCount));\r
197             tableStatsList.add(tableStatsBuilder.build());\r
198         }\r
199         builder.setTableStats(tableStatsList);\r
200         return builder.build();\r
201     }\r
202     \r
203     private static MultipartReplyPortStats setPortStats(ByteBuf input) {\r
204         final byte PADDING_IN_PORT_STATS_HEADER = 4;\r
205         MultipartReplyPortStatsBuilder builder = new MultipartReplyPortStatsBuilder();\r
206         PortStatsBuilder portStatsBuilder = new PortStatsBuilder();\r
207         List<PortStats> portStatsList = new ArrayList<>();\r
208         while (input.readableBytes() > 0) {\r
209             portStatsBuilder.setPortNo(input.readUnsignedInt());\r
210             input.skipBytes(PADDING_IN_PORT_STATS_HEADER);\r
211             \r
212             byte[] rxPackets = new byte[Long.SIZE/Byte.SIZE];\r
213             input.readBytes(rxPackets);\r
214             portStatsBuilder.setRxPackets(new BigInteger(rxPackets));\r
215             \r
216             byte[] txPackets = new byte[Long.SIZE/Byte.SIZE];\r
217             input.readBytes(txPackets);\r
218             portStatsBuilder.setTxPackets(new BigInteger(txPackets));\r
219             \r
220             byte[] rxBytes = new byte[Long.SIZE/Byte.SIZE];\r
221             input.readBytes(rxBytes);\r
222             portStatsBuilder.setRxBytes(new BigInteger(rxBytes));\r
223             \r
224             byte[] txBytes = new byte[Long.SIZE/Byte.SIZE];\r
225             input.readBytes(txBytes);\r
226             portStatsBuilder.setTxBytes(new BigInteger(txBytes));\r
227             \r
228             byte[] rxDropped = new byte[Long.SIZE/Byte.SIZE];\r
229             input.readBytes(rxDropped);\r
230             portStatsBuilder.setRxDropped(new BigInteger(rxDropped));\r
231             \r
232             byte[] txDropped = new byte[Long.SIZE/Byte.SIZE];\r
233             input.readBytes(txDropped);\r
234             portStatsBuilder.setTxDropped(new BigInteger(txDropped));\r
235             \r
236             byte[] rxErrors = new byte[Long.SIZE/Byte.SIZE];\r
237             input.readBytes(rxErrors);\r
238             portStatsBuilder.setRxErrors(new BigInteger(rxErrors));\r
239             \r
240             byte[] txErrors = new byte[Long.SIZE/Byte.SIZE];\r
241             input.readBytes(txErrors);\r
242             portStatsBuilder.setTxErrors(new BigInteger(txErrors));\r
243             \r
244             byte[] rxFrameErr = new byte[Long.SIZE/Byte.SIZE];\r
245             input.readBytes(rxFrameErr);\r
246             portStatsBuilder.setRxFrameErr(new BigInteger(rxFrameErr));\r
247             \r
248             byte[] rxOverErr = new byte[Long.SIZE/Byte.SIZE];\r
249             input.readBytes(rxOverErr);\r
250             portStatsBuilder.setRxOverErr(new BigInteger(rxOverErr));\r
251             \r
252             byte[] rxCrcErr = new byte[Long.SIZE/Byte.SIZE];\r
253             input.readBytes(rxCrcErr);\r
254             portStatsBuilder.setRxCrcErr(new BigInteger(rxCrcErr));\r
255             \r
256             byte[] collisions = new byte[Long.SIZE/Byte.SIZE];\r
257             input.readBytes(collisions);\r
258             portStatsBuilder.setCollisions(new BigInteger(collisions));\r
259             \r
260             portStatsBuilder.setDurationSec(input.readUnsignedInt());\r
261             portStatsBuilder.setDurationNsec(input.readUnsignedInt());\r
262             portStatsList.add(portStatsBuilder.build());\r
263         }\r
264         builder.setPortStats(portStatsList);\r
265         return builder.build();\r
266     }\r
267     \r
268     private static MultipartReplyQueue setQueue(ByteBuf input) {\r
269         MultipartReplyQueueBuilder builder = new MultipartReplyQueueBuilder();\r
270         QueueStatsBuilder queueStatsBuilder = new QueueStatsBuilder();\r
271         List<QueueStats> queueStatsList = new ArrayList<>();\r
272         \r
273         while (input.readableBytes() > 0) {\r
274             queueStatsBuilder.setPortNo(input.readUnsignedInt());\r
275             queueStatsBuilder.setQueueId(input.readUnsignedInt());\r
276 \r
277             byte[] txBytes = new byte[Long.SIZE/Byte.SIZE];\r
278             input.readBytes(txBytes);\r
279             queueStatsBuilder.setTxBytes(new BigInteger(txBytes));\r
280 \r
281             byte[] txPackets = new byte[Long.SIZE/Byte.SIZE];\r
282             input.readBytes(txPackets);\r
283             queueStatsBuilder.setTxPackets(new BigInteger(txPackets));\r
284 \r
285             byte[] txErrors = new byte[Long.SIZE/Byte.SIZE];\r
286             input.readBytes(txErrors);\r
287             queueStatsBuilder.setTxErrors(new BigInteger(txErrors));\r
288 \r
289             queueStatsBuilder.setDurationSec(input.readUnsignedInt());\r
290             queueStatsBuilder.setDurationNsec(input.readUnsignedInt());\r
291             queueStatsList.add(queueStatsBuilder.build());\r
292         }\r
293         builder.setQueueStats(queueStatsList);\r
294         return builder.build();\r
295     }\r
296     \r
297     private static MultipartReplyGroup setGroup(ByteBuf input) {\r
298         final byte PADDING_IN_GROUP_HEADER_01 = 2;\r
299         final byte PADDING_IN_GROUP_HEADER_02 = 4;\r
300         final byte BUCKET_COUNTER_LENGTH = 16;\r
301         final byte GROUP_BODY_LENGTH = 40;\r
302         int actualLength;\r
303         MultipartReplyGroupBuilder builder = new MultipartReplyGroupBuilder();\r
304         GroupStatsBuilder groupStatsBuilder = new GroupStatsBuilder();\r
305         List<GroupStats> groupStatsList = new ArrayList<>();\r
306         \r
307         BucketStatsBuilder bucketStatsBuilder = new BucketStatsBuilder();\r
308         List<BucketStats> bucketStatsList = new ArrayList<>();\r
309         \r
310         while (input.readableBytes() > 0) {\r
311             int bodyLength = input.readUnsignedShort();\r
312             actualLength = 0;\r
313             \r
314             input.skipBytes(PADDING_IN_GROUP_HEADER_01);\r
315             groupStatsBuilder.setGroupId(input.readUnsignedInt());\r
316             groupStatsBuilder.setRefCount(input.readUnsignedInt());\r
317             input.skipBytes(PADDING_IN_GROUP_HEADER_02);\r
318             byte[] packetCount = new byte[Long.SIZE/Byte.SIZE];\r
319             input.readBytes(packetCount);\r
320             groupStatsBuilder.setPacketCount(new BigInteger(packetCount));\r
321             byte[] byteCount = new byte[Long.SIZE/Byte.SIZE];\r
322             input.readBytes(byteCount);\r
323             groupStatsBuilder.setByteCount(new BigInteger(byteCount));\r
324             groupStatsBuilder.setDurationSec(input.readUnsignedInt());\r
325             groupStatsBuilder.setDurationNsec(input.readUnsignedInt());\r
326             actualLength = GROUP_BODY_LENGTH;\r
327             \r
328             while (actualLength < bodyLength) {\r
329                 byte[] packetCountBucket = new byte[Long.SIZE/Byte.SIZE];\r
330                 input.readBytes(packetCountBucket);\r
331                 bucketStatsBuilder.setPacketCount(new BigInteger(packetCountBucket));\r
332                 byte[] byteCountBucket = new byte[Long.SIZE/Byte.SIZE];\r
333                 input.readBytes(byteCountBucket);\r
334                 bucketStatsBuilder.setByteCount(new BigInteger(byteCountBucket));\r
335                 bucketStatsList.add(bucketStatsBuilder.build());\r
336 \r
337                 groupStatsBuilder.setBucketStats(bucketStatsList);\r
338                 groupStatsList.add(groupStatsBuilder.build());\r
339                 actualLength = actualLength + BUCKET_COUNTER_LENGTH;\r
340             } \r
341         }\r
342         builder.setGroupStats(groupStatsList);\r
343         return builder.build();\r
344     }\r
345 }\r