Add multipart request message serializers
[openflowplugin.git] / openflowplugin-impl / src / main / java / org / opendaylight / openflowplugin / impl / protocol / deserialization / multipart / MultipartReplyFlowStatsDeserializer.java
1 /*
2  * Copyright (c) 2017 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.openflowplugin.impl.protocol.deserialization.multipart;
10
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.openflowplugin.api.OFConstants;
21 import org.opendaylight.openflowplugin.extension.api.path.MatchPath;
22 import org.opendaylight.openflowplugin.impl.protocol.deserialization.key.MessageCodeMatchKey;
23 import org.opendaylight.openflowplugin.impl.protocol.deserialization.util.InstructionUtil;
24 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev130715.Counter32;
25 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev130715.Counter64;
26 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.statistics.rev130819.flow.and.statistics.map.list.FlowAndStatisticsMapList;
27 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.statistics.rev130819.flow.and.statistics.map.list.FlowAndStatisticsMapListBuilder;
28 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.statistics.rev130819.multipart.reply.multipart.reply.body.MultipartReplyFlowStatsBuilder;
29 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.FlowCookie;
30 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.FlowModFlags;
31 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.flow.InstructionsBuilder;
32 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.flow.MatchBuilder;
33 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.list.InstructionBuilder;
34 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.list.InstructionKey;
35 import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.Match;
36 import org.opendaylight.yang.gen.v1.urn.opendaylight.model.statistics.types.rev130925.duration.DurationBuilder;
37 import org.opendaylight.yang.gen.v1.urn.opendaylight.multipart.types.rev170112.multipart.reply.MultipartReplyBody;
38
39 public class MultipartReplyFlowStatsDeserializer implements OFDeserializer<MultipartReplyBody>, DeserializerRegistryInjector {
40
41     private static final MessageCodeKey MATCH_KEY = new MessageCodeMatchKey(EncodeConstants.OF13_VERSION_ID,
42             EncodeConstants.EMPTY_VALUE, Match.class,
43             MatchPath.FLOWSSTATISTICSUPDATE_FLOWANDSTATISTICSMAPLIST_MATCH);
44
45     private static final byte PADDING_IN_FLOW_STATS_HEADER_01 = 1;
46     private static final byte PADDING_IN_FLOW_STATS_HEADER_02 = 4;
47     private DeserializerRegistry registry;
48
49     @Override
50     public MultipartReplyBody deserialize(ByteBuf message) {
51         final MultipartReplyFlowStatsBuilder builder = new MultipartReplyFlowStatsBuilder();
52         final List<FlowAndStatisticsMapList> items = new ArrayList<>();
53
54         while (message.readableBytes() > 0) {
55             final FlowAndStatisticsMapListBuilder itemBuilder = new FlowAndStatisticsMapListBuilder();
56             final int itemLength = message.readUnsignedShort();
57             final ByteBuf itemMessage = message.readSlice(itemLength - EncodeConstants.SIZE_OF_SHORT_IN_BYTES);
58
59             itemBuilder.setTableId(itemMessage.readUnsignedByte());
60             itemMessage.skipBytes(PADDING_IN_FLOW_STATS_HEADER_01);
61
62             itemBuilder
63                 .setDuration(new DurationBuilder()
64                         .setSecond(new Counter32(itemMessage.readUnsignedInt()))
65                         .setNanosecond(new Counter32(itemMessage.readUnsignedInt()))
66                         .build())
67                 .setPriority(itemMessage.readUnsignedShort())
68                 .setIdleTimeout(itemMessage.readUnsignedShort())
69                 .setHardTimeout(itemMessage.readUnsignedShort())
70                 .setFlags(createFlowModFlagsFromBitmap(itemMessage.readUnsignedShort()));
71
72             itemMessage.skipBytes(PADDING_IN_FLOW_STATS_HEADER_02);
73
74             final byte[] cookie = new byte[EncodeConstants.SIZE_OF_LONG_IN_BYTES];
75             itemMessage.readBytes(cookie);
76             final byte[] packetCount = new byte[EncodeConstants.SIZE_OF_LONG_IN_BYTES];
77             itemMessage.readBytes(packetCount);
78             final byte[] byteCount = new byte[EncodeConstants.SIZE_OF_LONG_IN_BYTES];
79             itemMessage.readBytes(byteCount);
80
81             itemBuilder
82                 .setCookie(new FlowCookie(new BigInteger(1, cookie)))
83                 .setCookieMask(new FlowCookie(OFConstants.DEFAULT_COOKIE_MASK))
84                 .setPacketCount(new Counter64(new BigInteger(1, packetCount)))
85                 .setByteCount(new Counter64(new BigInteger(1, byteCount)));
86
87             final OFDeserializer<Match> matchDeserializer = registry.getDeserializer(MATCH_KEY);
88             itemBuilder.setMatch(new MatchBuilder(matchDeserializer.deserialize(itemMessage)).build());
89
90             final int length = itemMessage.readableBytes();
91
92             if (length > 0) {
93                 final List<org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.list
94                     .Instruction> instructions = new ArrayList<>();
95                 final int startIndex = itemMessage.readerIndex();
96                 int offset = 0;
97
98                 while ((itemMessage.readerIndex() - startIndex) < length) {
99                     instructions.add(new InstructionBuilder()
100                             .setKey(new InstructionKey(offset))
101                             .setOrder(offset)
102                             .setInstruction(InstructionUtil
103                                 .readInstruction(EncodeConstants.OF13_VERSION_ID, itemMessage, registry))
104                             .build());
105
106                     offset++;
107                 }
108
109                 itemBuilder.setInstructions(new InstructionsBuilder()
110                         .setInstruction(instructions)
111                         .build());
112             }
113
114             items.add(itemBuilder.build());
115         }
116
117         return builder
118             .setFlowAndStatisticsMapList(items)
119             .build();
120     }
121
122     private static FlowModFlags createFlowModFlagsFromBitmap(int input) {
123         final Boolean _oFPFFSENDFLOWREM = (input & (1)) > 0;
124         final Boolean _oFPFFCHECKOVERLAP = (input & (1 << 1)) > 0;
125         final Boolean _oFPFFRESETCOUNTS = (input & (1 << 2)) > 0;
126         final Boolean _oFPFFNOPKTCOUNTS = (input & (1 << 3)) > 0;
127         final Boolean _oFPFFNOBYTCOUNTS = (input & (1 << 4)) > 0;
128         return new FlowModFlags(_oFPFFCHECKOVERLAP, _oFPFFNOBYTCOUNTS, _oFPFFNOPKTCOUNTS, _oFPFFRESETCOUNTS,
129                 _oFPFFSENDFLOWREM);
130     }
131
132     @Override
133     public void injectDeserializerRegistry(DeserializerRegistry deserializerRegistry) {
134         registry = deserializerRegistry;
135     }
136
137 }