2 * Copyright (c) 2013 Pantheon Technologies s.r.o. and others. All rights reserved.
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
9 package org.opendaylight.openflowjava.protocol.impl.deserialization.factories;
11 import io.netty.buffer.ByteBuf;
13 import java.math.BigInteger;
14 import java.util.ArrayList;
15 import java.util.List;
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.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;
56 * Translates StatsReply messages (OpenFlow v1.0)
57 * @author michal.polkorab
59 public class OF10StatsReplyMessageFactory implements OFDeserializer<MultipartReplyMessage> {
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;
71 private static OF10StatsReplyMessageFactory instance;
73 private OF10StatsReplyMessageFactory() {
78 * @return singleton factory
80 public static synchronized OF10StatsReplyMessageFactory getInstance() {
81 if (instance == null){
82 instance = new OF10StatsReplyMessageFactory();
88 public MultipartReplyMessage bufferToMessage(ByteBuf rawMessage, short version) {
89 MultipartReplyMessageBuilder builder = new MultipartReplyMessageBuilder();
90 builder.setVersion(version);
91 builder.setXid(rawMessage.readUnsignedInt());
92 int type = rawMessage.readUnsignedShort();
93 builder.setType(MultipartType.forValue(type));
94 builder.setFlags(new MultipartRequestFlags((rawMessage.readUnsignedShort() & 0x01) != 0));
96 case 0: builder.setMultipartReplyBody(setDesc(rawMessage));
98 case 1: builder.setMultipartReplyBody(setFlow(rawMessage));
100 case 2: builder.setMultipartReplyBody(setAggregate(rawMessage));
102 case 3: builder.setMultipartReplyBody(setTable(rawMessage));
104 case 4: builder.setMultipartReplyBody(setPortStats(rawMessage));
106 case 5: builder.setMultipartReplyBody(setQueue(rawMessage));
108 case 0xFFFF: builder.setMultipartReplyBody(setExperimenter(rawMessage));
113 return builder.build();
116 private static MultipartReplyDescCase setDesc(ByteBuf input) {
117 MultipartReplyDescCaseBuilder caseBuilder = new MultipartReplyDescCaseBuilder();
118 MultipartReplyDescBuilder descBuilder = new MultipartReplyDescBuilder();
119 byte[] mfrDescBytes = new byte[DESC_STR_LEN];
120 input.readBytes(mfrDescBytes);
121 String mfrDesc = new String(mfrDescBytes);
122 descBuilder.setMfrDesc(mfrDesc.trim());
123 byte[] hwDescBytes = new byte[DESC_STR_LEN];
124 input.readBytes(hwDescBytes);
125 String hwDesc = new String(hwDescBytes);
126 descBuilder.setHwDesc(hwDesc.trim());
127 byte[] swDescBytes = new byte[DESC_STR_LEN];
128 input.readBytes(swDescBytes);
129 String swDesc = new String(swDescBytes);
130 descBuilder.setSwDesc(swDesc.trim());
131 byte[] serialNumBytes = new byte[SERIAL_NUM_LEN];
132 input.readBytes(serialNumBytes);
133 String serialNum = new String(serialNumBytes);
134 descBuilder.setSerialNum(serialNum.trim());
135 byte[] dpDescBytes = new byte[DESC_STR_LEN];
136 input.readBytes(dpDescBytes);
137 String dpDesc = new String(dpDescBytes);
138 descBuilder.setDpDesc(dpDesc.trim());
139 caseBuilder.setMultipartReplyDesc(descBuilder.build());
140 return caseBuilder.build();
143 private static MultipartReplyFlowCase setFlow(ByteBuf input) {
144 MultipartReplyFlowCaseBuilder caseBuilder = new MultipartReplyFlowCaseBuilder();
145 MultipartReplyFlowBuilder flowBuilder = new MultipartReplyFlowBuilder();
146 List<FlowStats> flowStatsList = new ArrayList<>();
147 while (input.readableBytes() > 0) {
148 FlowStatsBuilder flowStatsBuilder = new FlowStatsBuilder();
149 input.skipBytes(EncodeConstants.SIZE_OF_SHORT_IN_BYTES);
150 flowStatsBuilder.setTableId(input.readUnsignedByte());
151 input.skipBytes(PADDING_IN_FLOW_STATS_HEADER);
152 flowStatsBuilder.setMatchV10(OF10MatchDeserializer.createMatchV10(input));
153 flowStatsBuilder.setDurationSec(input.readUnsignedInt());
154 flowStatsBuilder.setDurationNsec(input.readUnsignedInt());
155 flowStatsBuilder.setPriority(input.readUnsignedShort());
156 flowStatsBuilder.setIdleTimeout(input.readUnsignedShort());
157 flowStatsBuilder.setHardTimeout(input.readUnsignedShort());
158 input.skipBytes(PADDING_IN_FLOW_STATS_HEADER_02);
159 byte[] cookie = new byte[Long.SIZE/Byte.SIZE];
160 input.readBytes(cookie);
161 flowStatsBuilder.setCookie(new BigInteger(cookie));
162 byte[] packetCount = new byte[Long.SIZE/Byte.SIZE];
163 input.readBytes(packetCount);
164 flowStatsBuilder.setPacketCount(new BigInteger(packetCount));
165 byte[] byteCount = new byte[Long.SIZE/Byte.SIZE];
166 input.readBytes(byteCount);
167 flowStatsBuilder.setByteCount(new BigInteger(byteCount));
168 flowStatsBuilder.setActionsList(OF10ActionsDeserializer.createActionsList(input));
169 flowStatsList.add(flowStatsBuilder.build());
171 flowBuilder.setFlowStats(flowStatsList);
172 caseBuilder.setMultipartReplyFlow(flowBuilder.build());
173 return caseBuilder.build();
176 private static MultipartReplyAggregateCase setAggregate(ByteBuf input) {
177 MultipartReplyAggregateCaseBuilder caseBuilder = new MultipartReplyAggregateCaseBuilder();
178 MultipartReplyAggregateBuilder builder = new MultipartReplyAggregateBuilder();
179 byte[] packetCount = new byte[Long.SIZE/Byte.SIZE];
180 input.readBytes(packetCount);
181 builder.setPacketCount(new BigInteger(packetCount));
182 byte[] byteCount = new byte[Long.SIZE/Byte.SIZE];
183 input.readBytes(byteCount);
184 builder.setByteCount(new BigInteger(byteCount));
185 builder.setFlowCount(input.readUnsignedInt());
186 input.skipBytes(PADDING_IN_AGGREGATE_HEADER);
187 caseBuilder.setMultipartReplyAggregate(builder.build());
188 return caseBuilder.build();
191 private static MultipartReplyTableCase setTable(ByteBuf input) {
192 MultipartReplyTableCaseBuilder caseBuilder = new MultipartReplyTableCaseBuilder();
193 MultipartReplyTableBuilder builder = new MultipartReplyTableBuilder();
194 List<TableStats> tableStatsList = new ArrayList<>();
195 while (input.readableBytes() > 0) {
196 TableStatsBuilder tableStatsBuilder = new TableStatsBuilder();
197 tableStatsBuilder.setTableId(input.readUnsignedByte());
198 input.skipBytes(PADDING_IN_TABLE_HEADER);
199 tableStatsBuilder.setName(input.readBytes(MAX_TABLE_NAME_LENGTH).toString());
200 tableStatsBuilder.setActiveCount(input.readUnsignedInt());
201 byte[] lookupCount = new byte[Long.SIZE/Byte.SIZE];
202 input.readBytes(lookupCount);
203 tableStatsBuilder.setLookupCount(new BigInteger(lookupCount));
204 byte[] matchedCount = new byte[Long.SIZE/Byte.SIZE];
205 input.readBytes(matchedCount);
206 tableStatsBuilder.setMatchedCount(new BigInteger(matchedCount));
207 tableStatsList.add(tableStatsBuilder.build());
209 builder.setTableStats(tableStatsList);
210 caseBuilder.setMultipartReplyTable(builder.build());
211 return caseBuilder.build();
214 private static MultipartReplyPortStatsCase setPortStats(ByteBuf input) {
215 MultipartReplyPortStatsCaseBuilder caseBuilder = new MultipartReplyPortStatsCaseBuilder();
216 MultipartReplyPortStatsBuilder builder = new MultipartReplyPortStatsBuilder();
217 List<PortStats> portStatsList = new ArrayList<>();
218 while (input.readableBytes() > 0) {
219 PortStatsBuilder portStatsBuilder = new PortStatsBuilder();
220 portStatsBuilder.setPortNo((long) input.readUnsignedShort());
221 input.skipBytes(PADDING_IN_PORT_STATS_HEADER);
222 byte[] rxPackets = new byte[Long.SIZE/Byte.SIZE];
223 input.readBytes(rxPackets);
224 portStatsBuilder.setRxPackets(new BigInteger(rxPackets));
225 byte[] txPackets = new byte[Long.SIZE/Byte.SIZE];
226 input.readBytes(txPackets);
227 portStatsBuilder.setTxPackets(new BigInteger(txPackets));
228 byte[] rxBytes = new byte[Long.SIZE/Byte.SIZE];
229 input.readBytes(rxBytes);
230 portStatsBuilder.setRxBytes(new BigInteger(rxBytes));
231 byte[] txBytes = new byte[Long.SIZE/Byte.SIZE];
232 input.readBytes(txBytes);
233 portStatsBuilder.setTxBytes(new BigInteger(txBytes));
234 byte[] rxDropped = new byte[Long.SIZE/Byte.SIZE];
235 input.readBytes(rxDropped);
236 portStatsBuilder.setRxDropped(new BigInteger(rxDropped));
237 byte[] txDropped = new byte[Long.SIZE/Byte.SIZE];
238 input.readBytes(txDropped);
239 portStatsBuilder.setTxDropped(new BigInteger(txDropped));
240 byte[] rxErrors = new byte[Long.SIZE/Byte.SIZE];
241 input.readBytes(rxErrors);
242 portStatsBuilder.setRxErrors(new BigInteger(rxErrors));
243 byte[] txErrors = new byte[Long.SIZE/Byte.SIZE];
244 input.readBytes(txErrors);
245 portStatsBuilder.setTxErrors(new BigInteger(txErrors));
246 byte[] rxFrameErr = new byte[Long.SIZE/Byte.SIZE];
247 input.readBytes(rxFrameErr);
248 portStatsBuilder.setRxFrameErr(new BigInteger(rxFrameErr));
249 byte[] rxOverErr = new byte[Long.SIZE/Byte.SIZE];
250 input.readBytes(rxOverErr);
251 portStatsBuilder.setRxOverErr(new BigInteger(rxOverErr));
252 byte[] rxCrcErr = new byte[Long.SIZE/Byte.SIZE];
253 input.readBytes(rxCrcErr);
254 portStatsBuilder.setRxCrcErr(new BigInteger(rxCrcErr));
255 byte[] collisions = new byte[Long.SIZE/Byte.SIZE];
256 input.readBytes(collisions);
257 portStatsBuilder.setCollisions(new BigInteger(collisions));
259 builder.setPortStats(portStatsList);
260 caseBuilder.setMultipartReplyPortStats(builder.build());
261 return caseBuilder.build();
264 private static MultipartReplyQueueCase setQueue(ByteBuf input) {
265 MultipartReplyQueueCaseBuilder caseBuilder = new MultipartReplyQueueCaseBuilder();
266 MultipartReplyQueueBuilder builder = new MultipartReplyQueueBuilder();
267 List<QueueStats> queueStatsList = new ArrayList<>();
268 while (input.readableBytes() > 0) {
269 QueueStatsBuilder queueStatsBuilder = new QueueStatsBuilder();
270 queueStatsBuilder.setPortNo((long) input.readUnsignedShort());
271 input.skipBytes(PADDING_IN_QUEUE_HEADER);
272 queueStatsBuilder.setQueueId(input.readUnsignedInt());
273 byte[] txBytes = new byte[Long.SIZE/Byte.SIZE];
274 input.readBytes(txBytes);
275 queueStatsBuilder.setTxBytes(new BigInteger(txBytes));
276 byte[] txPackets = new byte[Long.SIZE/Byte.SIZE];
277 input.readBytes(txPackets);
278 queueStatsBuilder.setTxPackets(new BigInteger(txPackets));
279 byte[] txErrors = new byte[Long.SIZE/Byte.SIZE];
280 input.readBytes(txErrors);
281 queueStatsBuilder.setTxErrors(new BigInteger(txErrors));
282 queueStatsList.add(queueStatsBuilder.build());
284 builder.setQueueStats(queueStatsList);
285 caseBuilder.setMultipartReplyQueue(builder.build());
286 return caseBuilder.build();
289 private static MultipartReplyExperimenterCase setExperimenter(ByteBuf input) {
290 MultipartReplyExperimenterCaseBuilder caseBuilder = new MultipartReplyExperimenterCaseBuilder();
291 MultipartReplyExperimenterBuilder builder = new MultipartReplyExperimenterBuilder();
292 builder.setExperimenter(input.readUnsignedInt());
293 byte[] data = new byte[Long.SIZE/Byte.SIZE];
294 input.readBytes(data);
295 builder.setData(data);
296 caseBuilder.setMultipartReplyExperimenter(builder.build());
297 return caseBuilder.build();