2 * Copyright (c) 2015 NetIDE Consortium 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
8 package org.opendaylight.openflowjava.protocol.impl.serialization.factories;
10 import io.netty.buffer.ByteBuf;
11 import io.netty.buffer.UnpooledByteBufAllocator;
12 import java.util.HashMap;
14 import org.opendaylight.openflowjava.protocol.api.extensibility.OFSerializer;
15 import org.opendaylight.openflowjava.protocol.api.extensibility.SerializerRegistry;
16 import org.opendaylight.openflowjava.protocol.api.extensibility.SerializerRegistryInjector;
17 import org.opendaylight.openflowjava.protocol.api.keys.MessageTypeKey;
18 import org.opendaylight.openflowjava.protocol.api.util.EncodeConstants;
19 import org.opendaylight.openflowjava.protocol.impl.util.ListSerializer;
20 import org.opendaylight.openflowjava.protocol.impl.util.TypeKeyMaker;
21 import org.opendaylight.openflowjava.protocol.impl.util.TypeKeyMakerFactory;
22 import org.opendaylight.openflowjava.util.ByteBufUtils;
23 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.action.rev150203.actions.grouping.Action;
24 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.FlowWildcardsV10;
25 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.MultipartRequestFlags;
26 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.match.v10.grouping.MatchV10;
27 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.MultipartReplyMessage;
28 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.MultipartReplyBody;
29 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.MultipartReplyAggregateCase;
30 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.MultipartReplyDescCase;
31 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.MultipartReplyExperimenterCase;
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.MultipartReplyPortStatsCase;
34 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.MultipartReplyQueueCase;
35 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.MultipartReplyTableCase;
36 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.multipart.reply.aggregate._case.MultipartReplyAggregate;
37 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.multipart.reply.desc._case.MultipartReplyDesc;
38 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.multipart.reply.experimenter._case.MultipartReplyExperimenter;
39 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.multipart.reply.flow._case.MultipartReplyFlow;
40 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.multipart.reply.flow._case.multipart.reply.flow.FlowStats;
41 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.multipart.reply.port.stats._case.MultipartReplyPortStats;
42 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;
43 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.multipart.reply.queue._case.MultipartReplyQueue;
44 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.multipart.reply.queue._case.multipart.reply.queue.QueueStats;
45 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.multipart.reply.table._case.MultipartReplyTable;
46 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.multipart.reply.table._case.multipart.reply.table.TableStats;
49 * @author giuseppex.petralia@intel.com
52 public class OF10StatsReplyMessageFactory implements OFSerializer<MultipartReplyMessage>, SerializerRegistryInjector {
54 private SerializerRegistry registry;
55 private static final byte MESSAGE_TYPE = 17;
56 private static final byte FLOW_STATS_PADDING_1 = 1;
57 private static final byte FLOW_STATS_PADDING_2 = 6;
58 private static final TypeKeyMaker<Action> ACTION_KEY_MAKER = TypeKeyMakerFactory
59 .createActionKeyMaker(EncodeConstants.OF10_VERSION_ID);
60 private static final int FLOW_STATS_LENGTH_INDEX = 0;
61 private static final int QUEUE_STATS_LENGTH_INDEX = 0;
62 private static final byte AGGREGATE_PADDING = 4;
63 private static final byte TABLE_PADDING = 3;
64 private static final byte QUEUE_PADDING = 2;
65 private static final byte PORT_STATS_PADDING = 6;
68 public void injectSerializerRegistry(SerializerRegistry serializerRegistry) {
69 registry = serializerRegistry;
73 public void serialize(MultipartReplyMessage message, ByteBuf outBuffer) {
74 ByteBufUtils.writeOFHeader(MESSAGE_TYPE, message, outBuffer, EncodeConstants.EMPTY_LENGTH);
75 outBuffer.writeShort(message.getType().getIntValue());
76 writeFlags(message.getFlags(), outBuffer);
77 switch (message.getType()) {
79 serializeDescBody(message.getMultipartReplyBody(), outBuffer);
82 serializeFlowBody(message.getMultipartReplyBody(), outBuffer, message);
85 serializeAggregateBody(message.getMultipartReplyBody(), outBuffer);
88 serializeTableBody(message.getMultipartReplyBody(), outBuffer);
91 serializePortStatsBody(message.getMultipartReplyBody(), outBuffer);
94 serializeQueueBody(message.getMultipartReplyBody(), outBuffer);
96 case OFPMPEXPERIMENTER:
97 serializeExperimenterBody(message.getMultipartReplyBody(), outBuffer);
102 ByteBufUtils.updateOFHeaderLength(outBuffer);
105 private void serializeExperimenterBody(MultipartReplyBody body, ByteBuf outBuffer) {
106 MultipartReplyExperimenterCase experimenterCase = (MultipartReplyExperimenterCase) body;
107 MultipartReplyExperimenter experimenterBody = experimenterCase.getMultipartReplyExperimenter();
108 // TODO: experimenterBody does not have get methods
111 private void serializeQueueBody(MultipartReplyBody body, ByteBuf outBuffer) {
112 MultipartReplyQueueCase queueCase = (MultipartReplyQueueCase) body;
113 MultipartReplyQueue queue = queueCase.getMultipartReplyQueue();
114 for (QueueStats queueStats : queue.getQueueStats()) {
115 ByteBuf queueStatsBuff = UnpooledByteBufAllocator.DEFAULT.buffer();
116 queueStatsBuff.writeShort(EncodeConstants.EMPTY_LENGTH);
117 queueStatsBuff.writeZero(QUEUE_PADDING);
118 queueStatsBuff.writeInt(queueStats.getQueueId().intValue());
119 queueStatsBuff.writeLong(queueStats.getTxBytes().longValue());
120 queueStatsBuff.writeLong(queueStats.getTxPackets().longValue());
121 queueStatsBuff.writeLong(queueStats.getTxErrors().longValue());
122 queueStatsBuff.setShort(QUEUE_STATS_LENGTH_INDEX, queueStatsBuff.readableBytes());
123 outBuffer.writeBytes(queueStatsBuff);
127 private void serializePortStatsBody(MultipartReplyBody body, ByteBuf outBuffer) {
128 MultipartReplyPortStatsCase portStatsCase = (MultipartReplyPortStatsCase) body;
129 MultipartReplyPortStats portStats = portStatsCase.getMultipartReplyPortStats();
130 for (PortStats portStat : portStats.getPortStats()) {
131 outBuffer.writeInt(portStat.getPortNo().intValue());
132 outBuffer.writeZero(PORT_STATS_PADDING);
133 outBuffer.writeLong(portStat.getRxPackets().longValue());
134 outBuffer.writeLong(portStat.getTxPackets().longValue());
135 outBuffer.writeLong(portStat.getRxBytes().longValue());
136 outBuffer.writeLong(portStat.getTxBytes().longValue());
137 outBuffer.writeLong(portStat.getRxDropped().longValue());
138 outBuffer.writeLong(portStat.getTxDropped().longValue());
139 outBuffer.writeLong(portStat.getRxErrors().longValue());
140 outBuffer.writeLong(portStat.getTxErrors().longValue());
141 outBuffer.writeLong(portStat.getRxFrameErr().longValue());
142 outBuffer.writeLong(portStat.getRxOverErr().longValue());
143 outBuffer.writeLong(portStat.getRxCrcErr().longValue());
144 outBuffer.writeLong(portStat.getCollisions().longValue());
148 private void serializeTableBody(MultipartReplyBody body, ByteBuf outBuffer) {
149 MultipartReplyTableCase tableCase = (MultipartReplyTableCase) body;
150 MultipartReplyTable table = tableCase.getMultipartReplyTable();
151 for (TableStats tableStats : table.getTableStats()) {
152 outBuffer.writeByte(tableStats.getTableId());
153 outBuffer.writeZero(TABLE_PADDING);
154 write16String(tableStats.getName(), outBuffer);
155 writeFlowWildcardsV10(tableStats.getWildcards(), outBuffer);
156 outBuffer.writeInt(tableStats.getMaxEntries().intValue());
157 outBuffer.writeInt(tableStats.getActiveCount().intValue());
158 outBuffer.writeLong(tableStats.getLookupCount().longValue());
159 outBuffer.writeLong(tableStats.getMatchedCount().longValue());
163 private void writeFlowWildcardsV10(FlowWildcardsV10 feature, ByteBuf outBuffer) {
164 Map<Integer, Boolean> map = new HashMap<>();
165 map.put(0, feature.isINPORT());
166 map.put(1, feature.isDLVLAN());
167 map.put(2, feature.isDLSRC());
168 map.put(3, feature.isDLDST());
169 map.put(4, feature.isDLTYPE());
170 map.put(5, feature.isNWPROTO());
171 map.put(6, feature.isTPSRC());
172 map.put(7, feature.isTPDST());
173 map.put(20, feature.isDLVLANPCP());
174 map.put(21, feature.isNWTOS());
175 int bitmap = ByteBufUtils.fillBitMaskFromMap(map);
176 outBuffer.writeInt(bitmap);
179 private void serializeAggregateBody(MultipartReplyBody body, ByteBuf outBuffer) {
180 MultipartReplyAggregateCase aggregateCase = (MultipartReplyAggregateCase) body;
181 MultipartReplyAggregate aggregate = aggregateCase.getMultipartReplyAggregate();
182 outBuffer.writeLong(aggregate.getPacketCount().longValue());
183 outBuffer.writeLong(aggregate.getByteCount().longValue());
184 outBuffer.writeInt(aggregate.getFlowCount().intValue());
185 outBuffer.writeZero(AGGREGATE_PADDING);
188 private void serializeFlowBody(MultipartReplyBody body, ByteBuf outBuffer, MultipartReplyMessage message) {
189 MultipartReplyFlowCase flowCase = (MultipartReplyFlowCase) body;
190 MultipartReplyFlow flow = flowCase.getMultipartReplyFlow();
191 for (FlowStats flowStats : flow.getFlowStats()) {
192 ByteBuf flowStatsBuff = UnpooledByteBufAllocator.DEFAULT.buffer();
193 flowStatsBuff.writeShort(EncodeConstants.EMPTY_LENGTH);
194 flowStatsBuff.writeByte(new Long(flowStats.getTableId()).byteValue());
195 flowStatsBuff.writeZero(FLOW_STATS_PADDING_1);
196 OFSerializer<MatchV10> matchSerializer = registry
197 .getSerializer(new MessageTypeKey<>(message.getVersion(), MatchV10.class));
198 matchSerializer.serialize(flowStats.getMatchV10(), flowStatsBuff);
199 flowStatsBuff.writeInt(flowStats.getDurationSec().intValue());
200 flowStatsBuff.writeInt(flowStats.getDurationNsec().intValue());
201 flowStatsBuff.writeShort(flowStats.getPriority());
202 flowStatsBuff.writeShort(flowStats.getIdleTimeout());
203 flowStatsBuff.writeShort(flowStats.getHardTimeout());
204 flowStatsBuff.writeZero(FLOW_STATS_PADDING_2);
205 flowStatsBuff.writeLong(flowStats.getCookie().longValue());
206 flowStatsBuff.writeLong(flowStats.getPacketCount().longValue());
207 flowStatsBuff.writeLong(flowStats.getByteCount().longValue());
208 ListSerializer.serializeList(flowStats.getAction(), ACTION_KEY_MAKER, registry, flowStatsBuff);
209 flowStatsBuff.setShort(FLOW_STATS_LENGTH_INDEX, flowStatsBuff.readableBytes());
210 outBuffer.writeBytes(flowStatsBuff);
214 private void writeFlags(MultipartRequestFlags flags, ByteBuf outBuffer) {
215 Map<Integer, Boolean> map = new HashMap<>();
216 map.put(0, flags.isOFPMPFREQMORE());
217 int bitmap = ByteBufUtils.fillBitMaskFromMap(map);
218 outBuffer.writeShort(bitmap);
221 private void serializeDescBody(MultipartReplyBody body, ByteBuf outBuffer) {
222 MultipartReplyDescCase descCase = (MultipartReplyDescCase) body;
223 MultipartReplyDesc desc = descCase.getMultipartReplyDesc();
224 write256String(desc.getMfrDesc(), outBuffer);
225 write256String(desc.getHwDesc(), outBuffer);
226 write256String(desc.getSwDesc(), outBuffer);
227 write32String(desc.getSerialNum(), outBuffer);
228 write256String(desc.getDpDesc(), outBuffer);
231 private void write256String(String toWrite, ByteBuf outBuffer) {
232 byte[] nameBytes = toWrite.getBytes();
233 if (nameBytes.length < 256) {
234 byte[] nameBytesPadding = new byte[256];
236 for (byte b : nameBytes) {
237 nameBytesPadding[i] = b;
240 for (; i < 256; i++) {
241 nameBytesPadding[i] = 0x0;
243 outBuffer.writeBytes(nameBytesPadding);
245 outBuffer.writeBytes(nameBytes);
249 private void write16String(String toWrite, ByteBuf outBuffer) {
250 byte[] nameBytes = toWrite.getBytes();
251 if (nameBytes.length < 16) {
252 byte[] nameBytesPadding = new byte[16];
254 for (byte b : nameBytes) {
255 nameBytesPadding[i] = b;
258 for (; i < 16; i++) {
259 nameBytesPadding[i] = 0x0;
261 outBuffer.writeBytes(nameBytesPadding);
263 outBuffer.writeBytes(nameBytes);
267 private void write32String(String toWrite, ByteBuf outBuffer) {
268 byte[] nameBytes = toWrite.getBytes();
269 if (nameBytes.length < 32) {
270 byte[] nameBytesPadding = new byte[32];
272 for (byte b : nameBytes) {
273 nameBytesPadding[i] = b;
276 for (; i < 32; i++) {
277 nameBytesPadding[i] = 0x0;
279 outBuffer.writeBytes(nameBytesPadding);
281 outBuffer.writeBytes(nameBytes);