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