Fixed issues
[openflowjava.git] / openflow-protocol-impl / src / main / java / org / opendaylight / openflowjava / protocol / impl / deserialization / factories / OF10StatsReplyMessageFactory.java
1 /*
2  * Copyright (c) 2013 Pantheon Technologies s.r.o. and others. All rights reserved.
3  *
4  * This program and the accompanying materials are made available under the
5  * terms of the Eclipse Public License v1.0 which accompanies this distribution,
6  * and is available at http://www.eclipse.org/legal/epl-v10.html
7  */
8
9 package org.opendaylight.openflowjava.protocol.impl.deserialization.factories;
10
11 import io.netty.buffer.ByteBuf;
12
13 import java.math.BigInteger;
14 import java.util.ArrayList;
15 import java.util.List;
16
17 import org.opendaylight.openflowjava.protocol.impl.deserialization.OFDeserializer;
18 import org.opendaylight.openflowjava.protocol.impl.util.ByteBufUtils;
19 import org.opendaylight.openflowjava.protocol.impl.util.OF10ActionsDeserializer;
20 import org.opendaylight.openflowjava.protocol.impl.util.OF10MatchDeserializer;
21 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.MultipartRequestFlags;
22 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.MultipartType;
23 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.MultipartReplyMessage;
24 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.MultipartReplyMessageBuilder;
25 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.MultipartReplyAggregateCase;
26 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.MultipartReplyAggregateCaseBuilder;
27 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.MultipartReplyDescCase;
28 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.MultipartReplyDescCaseBuilder;
29 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.MultipartReplyExperimenterCase;
30 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.MultipartReplyExperimenterCaseBuilder;
31 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.MultipartReplyFlowCase;
32 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.MultipartReplyFlowCaseBuilder;
33 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.MultipartReplyPortStatsCase;
34 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.MultipartReplyPortStatsCaseBuilder;
35 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.MultipartReplyQueueCase;
36 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.MultipartReplyQueueCaseBuilder;
37 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.MultipartReplyTableCase;
38 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.MultipartReplyTableCaseBuilder;
39 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.multipart.reply.aggregate._case.MultipartReplyAggregateBuilder;
40 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.multipart.reply.desc._case.MultipartReplyDescBuilder;
41 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.multipart.reply.experimenter._case.MultipartReplyExperimenterBuilder;
42 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.multipart.reply.flow._case.MultipartReplyFlowBuilder;
43 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.multipart.reply.flow._case.multipart.reply.flow.FlowStats;
44 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.multipart.reply.flow._case.multipart.reply.flow.FlowStatsBuilder;
45 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.multipart.reply.port.stats._case.MultipartReplyPortStatsBuilder;
46 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.multipart.reply.port.stats._case.multipart.reply.port.stats.PortStats;
47 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.multipart.reply.port.stats._case.multipart.reply.port.stats.PortStatsBuilder;
48 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.multipart.reply.queue._case.MultipartReplyQueueBuilder;
49 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.multipart.reply.queue._case.multipart.reply.queue.QueueStats;
50 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.multipart.reply.queue._case.multipart.reply.queue.QueueStatsBuilder;
51 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.multipart.reply.table._case.MultipartReplyTableBuilder;
52 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.multipart.reply.table._case.multipart.reply.table.TableStats;
53 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.multipart.reply.table._case.multipart.reply.table.TableStatsBuilder;
54
55 /**
56  * Translates StatsReply messages (OpenFlow v1.0)
57  * @author michal.polkorab
58  */
59 public class OF10StatsReplyMessageFactory implements OFDeserializer<MultipartReplyMessage> {
60
61     private static final int DESC_STR_LEN = 256;
62     private static final int SERIAL_NUM_LEN = 32;
63     private static final byte PADDING_IN_FLOW_STATS_HEADER = 1;
64     private static final byte PADDING_IN_FLOW_STATS_HEADER_02 = 6;
65     private static final byte PADDING_IN_AGGREGATE_HEADER = 4;
66     private static final byte PADDING_IN_TABLE_HEADER = 3;
67     private static final byte MAX_TABLE_NAME_LENGTH = 32;
68     private static final byte PADDING_IN_PORT_STATS_HEADER = 6;
69     private static final byte PADDING_IN_QUEUE_HEADER = 2;
70     private static final byte LENGTH_OF_FLOW_STATS = 88;
71     
72     private static OF10StatsReplyMessageFactory instance;
73     
74     private OF10StatsReplyMessageFactory() {
75         // singleton
76     }
77     
78     /**
79      * @return singleton factory
80      */
81     public static synchronized OF10StatsReplyMessageFactory getInstance() {
82         if (instance == null){
83             instance = new OF10StatsReplyMessageFactory();
84         }
85         return instance;
86     }
87
88     @Override
89     public MultipartReplyMessage bufferToMessage(ByteBuf rawMessage, short version) {
90         MultipartReplyMessageBuilder builder = new MultipartReplyMessageBuilder();
91         builder.setVersion(version);
92         builder.setXid(rawMessage.readUnsignedInt());
93         int type = rawMessage.readUnsignedShort();
94         builder.setType(MultipartType.forValue(type));
95         builder.setFlags(new MultipartRequestFlags((rawMessage.readUnsignedShort() & 0x01) != 0));
96         switch (type) {
97         case 0:  builder.setMultipartReplyBody(setDesc(rawMessage));
98             break;
99         case 1:  builder.setMultipartReplyBody(setFlow(rawMessage));
100             break;
101         case 2:  builder.setMultipartReplyBody(setAggregate(rawMessage));
102             break;
103         case 3:  builder.setMultipartReplyBody(setTable(rawMessage));
104             break;         
105         case 4:  builder.setMultipartReplyBody(setPortStats(rawMessage));
106             break;
107         case 5:  builder.setMultipartReplyBody(setQueue(rawMessage));
108             break;         
109         case 0xFFFF: builder.setMultipartReplyBody(setExperimenter(rawMessage));
110             break;
111         default: 
112             break;
113         }
114         return builder.build();
115     }
116     
117     private static MultipartReplyDescCase setDesc(ByteBuf input) {
118         MultipartReplyDescCaseBuilder caseBuilder = new MultipartReplyDescCaseBuilder();
119         MultipartReplyDescBuilder descBuilder = new MultipartReplyDescBuilder();
120         byte[] mfrDescBytes = new byte[DESC_STR_LEN];
121         input.readBytes(mfrDescBytes);
122         String mfrDesc = new String(mfrDescBytes);
123         descBuilder.setMfrDesc(mfrDesc.trim());
124         byte[] hwDescBytes = new byte[DESC_STR_LEN];
125         input.readBytes(hwDescBytes);
126         String hwDesc = new String(hwDescBytes);
127         descBuilder.setHwDesc(hwDesc.trim());
128         byte[] swDescBytes = new byte[DESC_STR_LEN];
129         input.readBytes(swDescBytes);
130         String swDesc = new String(swDescBytes);
131         descBuilder.setSwDesc(swDesc.trim());
132         byte[] serialNumBytes = new byte[SERIAL_NUM_LEN];
133         input.readBytes(serialNumBytes);
134         String serialNum = new String(serialNumBytes);
135         descBuilder.setSerialNum(serialNum.trim());
136         byte[] dpDescBytes = new byte[DESC_STR_LEN];
137         input.readBytes(dpDescBytes);
138         String dpDesc = new String(dpDescBytes);
139         descBuilder.setDpDesc(dpDesc.trim());
140         caseBuilder.setMultipartReplyDesc(descBuilder.build());
141         return caseBuilder.build();
142     }
143     
144     private static MultipartReplyFlowCase setFlow(ByteBuf input) {
145         MultipartReplyFlowCaseBuilder caseBuilder = new MultipartReplyFlowCaseBuilder();
146         MultipartReplyFlowBuilder flowBuilder = new MultipartReplyFlowBuilder();
147         List<FlowStats> flowStatsList = new ArrayList<>();
148         while (input.readableBytes() > 0) {
149             FlowStatsBuilder flowStatsBuilder = new FlowStatsBuilder();
150             int length = input.readUnsignedShort();
151             flowStatsBuilder.setTableId(input.readUnsignedByte());
152             input.skipBytes(PADDING_IN_FLOW_STATS_HEADER);
153             flowStatsBuilder.setMatchV10(OF10MatchDeserializer.createMatchV10(input));
154             flowStatsBuilder.setDurationSec(input.readUnsignedInt());
155             flowStatsBuilder.setDurationNsec(input.readUnsignedInt());
156             flowStatsBuilder.setPriority(input.readUnsignedShort());
157             flowStatsBuilder.setIdleTimeout(input.readUnsignedShort());
158             flowStatsBuilder.setHardTimeout(input.readUnsignedShort());
159             input.skipBytes(PADDING_IN_FLOW_STATS_HEADER_02);
160             byte[] cookie = new byte[Long.SIZE/Byte.SIZE];
161             input.readBytes(cookie);
162             flowStatsBuilder.setCookie(new BigInteger(cookie));
163             byte[] packetCount = new byte[Long.SIZE/Byte.SIZE];
164             input.readBytes(packetCount);
165             flowStatsBuilder.setPacketCount(new BigInteger(packetCount));
166             byte[] byteCount = new byte[Long.SIZE/Byte.SIZE];
167             input.readBytes(byteCount);
168             flowStatsBuilder.setByteCount(new BigInteger(byteCount));
169             flowStatsBuilder.setActionsList(OF10ActionsDeserializer
170                     .createActionsList(input, length - LENGTH_OF_FLOW_STATS));
171             flowStatsList.add(flowStatsBuilder.build());
172         }
173         flowBuilder.setFlowStats(flowStatsList);
174         caseBuilder.setMultipartReplyFlow(flowBuilder.build());
175         return caseBuilder.build();
176     }
177     
178     private static MultipartReplyAggregateCase setAggregate(ByteBuf input) {
179         MultipartReplyAggregateCaseBuilder caseBuilder = new MultipartReplyAggregateCaseBuilder();
180         MultipartReplyAggregateBuilder builder = new MultipartReplyAggregateBuilder();
181         byte[] packetCount = new byte[Long.SIZE/Byte.SIZE];
182         input.readBytes(packetCount);
183         builder.setPacketCount(new BigInteger(packetCount));
184         byte[] byteCount = new byte[Long.SIZE/Byte.SIZE];
185         input.readBytes(byteCount);
186         builder.setByteCount(new BigInteger(byteCount));
187         builder.setFlowCount(input.readUnsignedInt());
188         input.skipBytes(PADDING_IN_AGGREGATE_HEADER);
189         caseBuilder.setMultipartReplyAggregate(builder.build());
190         return caseBuilder.build();
191     }
192     
193     private static MultipartReplyTableCase setTable(ByteBuf input) {
194         MultipartReplyTableCaseBuilder caseBuilder = new MultipartReplyTableCaseBuilder();
195         MultipartReplyTableBuilder builder = new MultipartReplyTableBuilder();
196         List<TableStats> tableStatsList = new ArrayList<>();
197         while (input.readableBytes() > 0) {
198             TableStatsBuilder tableStatsBuilder = new TableStatsBuilder();
199             tableStatsBuilder.setTableId(input.readUnsignedByte());
200             input.skipBytes(PADDING_IN_TABLE_HEADER);
201             tableStatsBuilder.setName(ByteBufUtils.decodeNullTerminatedString(input, MAX_TABLE_NAME_LENGTH));
202             long wildcards = input.readUnsignedInt();
203             tableStatsBuilder.setWildcards(OF10MatchDeserializer.createWildcards(wildcards));
204             tableStatsBuilder.setNwSrcMask(OF10MatchDeserializer.decodeNwSrcMask(wildcards));
205             tableStatsBuilder.setNwDstMask(OF10MatchDeserializer.decodeNwDstMask(wildcards));
206             tableStatsBuilder.setMaxEntries(input.readUnsignedInt());
207             tableStatsBuilder.setActiveCount(input.readUnsignedInt());
208             byte[] lookupCount = new byte[Long.SIZE/Byte.SIZE];
209             input.readBytes(lookupCount);
210             tableStatsBuilder.setLookupCount(new BigInteger(lookupCount));
211             byte[] matchedCount = new byte[Long.SIZE/Byte.SIZE];
212             input.readBytes(matchedCount);
213             tableStatsBuilder.setMatchedCount(new BigInteger(matchedCount));
214             tableStatsList.add(tableStatsBuilder.build());
215         }
216         builder.setTableStats(tableStatsList);
217         caseBuilder.setMultipartReplyTable(builder.build());
218         return caseBuilder.build();
219     }
220     
221     private static MultipartReplyPortStatsCase setPortStats(ByteBuf input) {
222         MultipartReplyPortStatsCaseBuilder caseBuilder = new MultipartReplyPortStatsCaseBuilder();
223         MultipartReplyPortStatsBuilder builder = new MultipartReplyPortStatsBuilder();
224         List<PortStats> portStatsList = new ArrayList<>();
225         while (input.readableBytes() > 0) {
226             PortStatsBuilder portStatsBuilder = new PortStatsBuilder();
227             portStatsBuilder.setPortNo((long) input.readUnsignedShort());
228             input.skipBytes(PADDING_IN_PORT_STATS_HEADER);
229             byte[] rxPackets = new byte[Long.SIZE/Byte.SIZE];
230             input.readBytes(rxPackets);
231             portStatsBuilder.setRxPackets(new BigInteger(rxPackets));
232             byte[] txPackets = new byte[Long.SIZE/Byte.SIZE];
233             input.readBytes(txPackets);
234             portStatsBuilder.setTxPackets(new BigInteger(txPackets));
235             byte[] rxBytes = new byte[Long.SIZE/Byte.SIZE];
236             input.readBytes(rxBytes);
237             portStatsBuilder.setRxBytes(new BigInteger(rxBytes));
238             byte[] txBytes = new byte[Long.SIZE/Byte.SIZE];
239             input.readBytes(txBytes);
240             portStatsBuilder.setTxBytes(new BigInteger(txBytes));
241             byte[] rxDropped = new byte[Long.SIZE/Byte.SIZE];
242             input.readBytes(rxDropped);
243             portStatsBuilder.setRxDropped(new BigInteger(rxDropped));
244             byte[] txDropped = new byte[Long.SIZE/Byte.SIZE];
245             input.readBytes(txDropped);
246             portStatsBuilder.setTxDropped(new BigInteger(txDropped));
247             byte[] rxErrors = new byte[Long.SIZE/Byte.SIZE];
248             input.readBytes(rxErrors);
249             portStatsBuilder.setRxErrors(new BigInteger(rxErrors));
250             byte[] txErrors = new byte[Long.SIZE/Byte.SIZE];
251             input.readBytes(txErrors);
252             portStatsBuilder.setTxErrors(new BigInteger(txErrors));
253             byte[] rxFrameErr = new byte[Long.SIZE/Byte.SIZE];
254             input.readBytes(rxFrameErr);
255             portStatsBuilder.setRxFrameErr(new BigInteger(rxFrameErr));
256             byte[] rxOverErr = new byte[Long.SIZE/Byte.SIZE];
257             input.readBytes(rxOverErr);
258             portStatsBuilder.setRxOverErr(new BigInteger(rxOverErr));
259             byte[] rxCrcErr = new byte[Long.SIZE/Byte.SIZE];
260             input.readBytes(rxCrcErr);
261             portStatsBuilder.setRxCrcErr(new BigInteger(rxCrcErr));
262             byte[] collisions = new byte[Long.SIZE/Byte.SIZE];
263             input.readBytes(collisions);
264             portStatsBuilder.setCollisions(new BigInteger(collisions));
265             portStatsList.add(portStatsBuilder.build());
266         }
267         builder.setPortStats(portStatsList);
268         caseBuilder.setMultipartReplyPortStats(builder.build());
269         return caseBuilder.build();
270     }
271     
272     private static MultipartReplyQueueCase setQueue(ByteBuf input) {
273         MultipartReplyQueueCaseBuilder caseBuilder = new MultipartReplyQueueCaseBuilder();
274         MultipartReplyQueueBuilder builder = new MultipartReplyQueueBuilder();
275         List<QueueStats> queueStatsList = new ArrayList<>();
276         while (input.readableBytes() > 0) {
277             QueueStatsBuilder queueStatsBuilder = new QueueStatsBuilder();
278             queueStatsBuilder.setPortNo((long) input.readUnsignedShort());
279             input.skipBytes(PADDING_IN_QUEUE_HEADER);
280             queueStatsBuilder.setQueueId(input.readUnsignedInt());
281             byte[] txBytes = new byte[Long.SIZE/Byte.SIZE];
282             input.readBytes(txBytes);
283             queueStatsBuilder.setTxBytes(new BigInteger(txBytes));
284             byte[] txPackets = new byte[Long.SIZE/Byte.SIZE];
285             input.readBytes(txPackets);
286             queueStatsBuilder.setTxPackets(new BigInteger(txPackets));
287             byte[] txErrors = new byte[Long.SIZE/Byte.SIZE];
288             input.readBytes(txErrors);
289             queueStatsBuilder.setTxErrors(new BigInteger(txErrors));
290             queueStatsList.add(queueStatsBuilder.build());
291         }
292         builder.setQueueStats(queueStatsList);
293         caseBuilder.setMultipartReplyQueue(builder.build());
294         return caseBuilder.build();
295     }
296     
297     private static MultipartReplyExperimenterCase setExperimenter(ByteBuf input) {
298         MultipartReplyExperimenterCaseBuilder caseBuilder = new MultipartReplyExperimenterCaseBuilder();
299         MultipartReplyExperimenterBuilder builder = new MultipartReplyExperimenterBuilder();
300         builder.setExperimenter(input.readUnsignedInt());
301         byte[] data = new byte[Long.SIZE/Byte.SIZE];
302         input.readBytes(data);
303         builder.setData(data);
304         caseBuilder.setMultipartReplyExperimenter(builder.build());
305         return caseBuilder.build();
306     }
307 }