2 * Copyright (c) 2017 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.openflowplugin.impl.protocol.deserialization.multipart;
11 import io.netty.buffer.ByteBuf;
12 import java.math.BigInteger;
13 import java.util.ArrayList;
14 import java.util.List;
15 import org.opendaylight.openflowjava.protocol.api.extensibility.DeserializerRegistry;
16 import org.opendaylight.openflowjava.protocol.api.extensibility.DeserializerRegistryInjector;
17 import org.opendaylight.openflowjava.protocol.api.extensibility.OFDeserializer;
18 import org.opendaylight.openflowjava.protocol.api.keys.MessageCodeKey;
19 import org.opendaylight.openflowjava.protocol.api.util.EncodeConstants;
20 import org.opendaylight.openflowjava.protocol.impl.util.InstructionConstants;
21 import org.opendaylight.openflowplugin.api.openflow.protocol.deserialization.MessageCodeExperimenterKey;
22 import org.opendaylight.openflowplugin.extension.api.path.ActionPath;
23 import org.opendaylight.openflowplugin.extension.api.path.MatchPath;
24 import org.opendaylight.openflowplugin.impl.protocol.deserialization.key.MessageCodeActionExperimenterKey;
25 import org.opendaylight.openflowplugin.impl.protocol.deserialization.key.MessageCodeMatchKey;
26 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev130715.Counter32;
27 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev130715.Counter64;
28 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.statistics.rev130819.flow.and.statistics.map.list.FlowAndStatisticsMapList;
29 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.statistics.rev130819.flow.and.statistics.map.list.FlowAndStatisticsMapListBuilder;
30 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.statistics.rev130819.multipart.reply.multipart.reply.body.MultipartReplyFlowStatsBuilder;
31 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.FlowCookie;
32 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.FlowModFlags;
33 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.flow.InstructionsBuilder;
34 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.flow.MatchBuilder;
35 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.Instruction;
36 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.list.InstructionBuilder;
37 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.list.InstructionKey;
38 import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.Match;
39 import org.opendaylight.yang.gen.v1.urn.opendaylight.model.statistics.types.rev130925.duration.DurationBuilder;
40 import org.opendaylight.yang.gen.v1.urn.opendaylight.multipart.types.rev170112.multipart.reply.MultipartReplyBody;
42 public class MultipartReplyFlowStatsDeserializer implements OFDeserializer<MultipartReplyBody>, DeserializerRegistryInjector {
44 private static final MessageCodeKey MATCH_KEY = new MessageCodeMatchKey(EncodeConstants.OF13_VERSION_ID,
45 EncodeConstants.EMPTY_VALUE, Match.class,
46 MatchPath.FLOWSSTATISTICSUPDATE_FLOWANDSTATISTICSMAPLIST_MATCH);
48 private static final byte PADDING_IN_FLOW_STATS_HEADER_01 = 1;
49 private static final byte PADDING_IN_FLOW_STATS_HEADER_02 = 4;
50 private DeserializerRegistry registry;
53 public MultipartReplyBody deserialize(ByteBuf message) {
54 final MultipartReplyFlowStatsBuilder builder = new MultipartReplyFlowStatsBuilder();
55 final List<FlowAndStatisticsMapList> items = new ArrayList<>();
57 while (message.readableBytes() > 0) {
58 final FlowAndStatisticsMapListBuilder itemBuilder = new FlowAndStatisticsMapListBuilder();
59 final int itemLength = message.readUnsignedShort();
60 final ByteBuf itemMessage = message.readSlice(itemLength - EncodeConstants.SIZE_OF_SHORT_IN_BYTES);
62 itemBuilder.setTableId(itemMessage.readUnsignedByte());
63 itemMessage.skipBytes(PADDING_IN_FLOW_STATS_HEADER_01);
67 .setDuration(new DurationBuilder()
68 .setSecond(new Counter32(itemMessage.readUnsignedInt()))
69 .setNanosecond(new Counter32(itemMessage.readUnsignedInt()))
71 .setPriority(itemMessage.readUnsignedShort())
72 .setIdleTimeout(itemMessage.readUnsignedShort())
73 .setHardTimeout(itemMessage.readUnsignedShort())
74 .setFlags(createFlowModFlagsFromBitmap(itemMessage.readUnsignedShort()));
76 itemMessage.skipBytes(PADDING_IN_FLOW_STATS_HEADER_02);
79 .setCookie(new FlowCookie(BigInteger.valueOf(message.readLong())))
80 .setCookieMask(new FlowCookie(BigInteger.valueOf(message.readLong())))
81 .setPacketCount(new Counter64(BigInteger.valueOf(message.readLong())))
82 .setByteCount(new Counter64(BigInteger.valueOf(message.readLong())));
85 final OFDeserializer<Match> matchDeserializer = registry.getDeserializer(MATCH_KEY);
86 itemBuilder.setMatch(new MatchBuilder(matchDeserializer.deserialize(message)).build());
88 final int length = itemMessage.readableBytes();
91 final List<org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.list
92 .Instruction> instructions = new ArrayList<>();
93 final int startIndex = itemMessage.readerIndex();
96 while ((itemMessage.readerIndex() - startIndex) < length) {
97 final int type = itemMessage.getUnsignedShort(itemMessage.readerIndex());
98 OFDeserializer<Instruction> deserializer = null;
100 if (InstructionConstants.APPLY_ACTIONS_TYPE == type) {
101 deserializer = registry.getDeserializer(
102 new MessageCodeActionExperimenterKey(
103 EncodeConstants.OF13_VERSION_ID, type, Instruction.class,
104 ActionPath.NODES_NODE_TABLE_FLOW_INSTRUCTIONS_INSTRUCTION_APPLYACTIONSCASE_APPLYACTIONS_ACTION_ACTION_EXTENSIONLIST_EXTENSION,
106 } else if (InstructionConstants.WRITE_ACTIONS_TYPE == type) {
107 deserializer = registry.getDeserializer(
108 new MessageCodeActionExperimenterKey(
109 EncodeConstants.OF13_VERSION_ID, type, Instruction.class,
110 ActionPath.NODES_NODE_TABLE_FLOW_INSTRUCTIONS_INSTRUCTION_WRITEACTIONSCASE_WRITEACTIONS_ACTION_ACTION_EXTENSIONLIST_EXTENSION,
115 if (EncodeConstants.EXPERIMENTER_VALUE == type) {
116 expId = itemMessage.getUnsignedInt(itemMessage.readerIndex() +
117 2 * EncodeConstants.SIZE_OF_SHORT_IN_BYTES);
120 deserializer = registry.getDeserializer(
121 new MessageCodeExperimenterKey(
122 EncodeConstants.OF13_VERSION_ID, type, Instruction.class, expId));
125 instructions.add(new InstructionBuilder()
126 .setKey(new InstructionKey(offset))
128 .setInstruction(deserializer.deserialize(itemMessage))
134 itemBuilder.setInstructions(new InstructionsBuilder()
135 .setInstruction(instructions)
139 items.add(itemBuilder.build());
143 .setFlowAndStatisticsMapList(items)
147 private static FlowModFlags createFlowModFlagsFromBitmap(int input) {
148 final Boolean _oFPFFSENDFLOWREM = (input & (1 << 0)) > 0;
149 final Boolean _oFPFFCHECKOVERLAP = (input & (1 << 1)) > 0;
150 final Boolean _oFPFFRESETCOUNTS = (input & (1 << 2)) > 0;
151 final Boolean _oFPFFNOPKTCOUNTS = (input & (1 << 3)) > 0;
152 final Boolean _oFPFFNOBYTCOUNTS = (input & (1 << 4)) > 0;
153 return new FlowModFlags(_oFPFFCHECKOVERLAP, _oFPFFNOBYTCOUNTS, _oFPFFNOPKTCOUNTS, _oFPFFRESETCOUNTS,
158 public void injectDeserializerRegistry(DeserializerRegistry deserializerRegistry) {
159 registry = deserializerRegistry;