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