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.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;
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;
70 private static final byte LENGTH_OF_FLOW_STATS = 88;
72 private static OF10StatsReplyMessageFactory instance;
74 private OF10StatsReplyMessageFactory() {
79 * @return singleton factory
81 public static synchronized OF10StatsReplyMessageFactory getInstance() {
82 if (instance == null){
83 instance = new OF10StatsReplyMessageFactory();
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));
97 case 0: builder.setMultipartReplyBody(setDesc(rawMessage));
99 case 1: builder.setMultipartReplyBody(setFlow(rawMessage));
101 case 2: builder.setMultipartReplyBody(setAggregate(rawMessage));
103 case 3: builder.setMultipartReplyBody(setTable(rawMessage));
105 case 4: builder.setMultipartReplyBody(setPortStats(rawMessage));
107 case 5: builder.setMultipartReplyBody(setQueue(rawMessage));
109 case 0xFFFF: builder.setMultipartReplyBody(setExperimenter(rawMessage));
114 return builder.build();
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();
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());
173 flowBuilder.setFlowStats(flowStatsList);
174 caseBuilder.setMultipartReplyFlow(flowBuilder.build());
175 return caseBuilder.build();
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();
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());
216 builder.setTableStats(tableStatsList);
217 caseBuilder.setMultipartReplyTable(builder.build());
218 return caseBuilder.build();
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());
267 builder.setPortStats(portStatsList);
268 caseBuilder.setMultipartReplyPortStats(builder.build());
269 return caseBuilder.build();
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());
292 builder.setQueueStats(queueStatsList);
293 caseBuilder.setMultipartReplyQueue(builder.build());
294 return caseBuilder.build();
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();