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.util.ArrayList;
13 import java.util.List;
14 import org.opendaylight.openflowjava.protocol.api.extensibility.DeserializerRegistry;
15 import org.opendaylight.openflowjava.protocol.api.extensibility.DeserializerRegistryInjector;
16 import org.opendaylight.openflowjava.protocol.api.extensibility.OFDeserializer;
17 import org.opendaylight.openflowjava.protocol.api.keys.ExperimenterIdDeserializerKey;
18 import org.opendaylight.openflowjava.protocol.api.util.EncodeConstants;
19 import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.statistics.rev131111.multipart.reply.multipart.reply.body.MultipartReplyMeterConfigBuilder;
20 import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.types.rev130918.MeterBandType;
21 import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.types.rev130918.MeterFlags;
22 import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.types.rev130918.MeterId;
23 import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.types.rev130918.band.type.band.type.DropBuilder;
24 import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.types.rev130918.band.type.band.type.DscpRemarkBuilder;
25 import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.types.rev130918.band.type.band.type.Experimenter;
26 import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.types.rev130918.meter.MeterBandHeadersBuilder;
27 import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.types.rev130918.meter.config.stats.reply.MeterConfigStats;
28 import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.types.rev130918.meter.config.stats.reply.MeterConfigStatsBuilder;
29 import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.types.rev130918.meter.config.stats.reply.MeterConfigStatsKey;
30 import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.types.rev130918.meter.meter.band.headers.MeterBandHeader;
31 import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.types.rev130918.meter.meter.band.headers.MeterBandHeaderBuilder;
32 import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.types.rev130918.meter.meter.band.headers.meter.band.header.MeterBandTypesBuilder;
33 import org.opendaylight.yang.gen.v1.urn.opendaylight.multipart.types.rev170112.multipart.reply.MultipartReplyBody;
34 import org.slf4j.Logger;
35 import org.slf4j.LoggerFactory;
37 public class MultipartReplyMeterConfigDeserializer implements OFDeserializer<MultipartReplyBody>,
38 DeserializerRegistryInjector {
40 private static final Logger LOG = LoggerFactory.getLogger(MultipartReplyMeterConfigDeserializer.class);
42 private static final byte METER_CONFIG_LENGTH = 8;
43 private static final int OFPMBTDROP = 1;
44 private static final int OFPMBTDSCP = 2;
45 private static final int OFPMBTEXPERIMENTER = 0xFFFF;
46 private static final byte PADDING_IN_METER_BAND_DROP_HEADER = 4;
47 private static final byte PADDING_IN_METER_BAND_DSCP_HEADER = 3;
49 private DeserializerRegistry registry;
52 public MultipartReplyBody deserialize(ByteBuf message) {
53 final MultipartReplyMeterConfigBuilder builder = new MultipartReplyMeterConfigBuilder();
54 final List<MeterConfigStats> items = new ArrayList<>();
56 while (message.readableBytes() > 0) {
57 final int itemLength = message.readUnsignedShort();
59 final MeterConfigStatsBuilder itemBuilder = new MeterConfigStatsBuilder()
60 .setFlags(readMeterFlags(message))
61 .setMeterId(new MeterId(message.readUnsignedInt()));
63 final List<MeterBandHeader> subItems = new ArrayList<>();
64 int actualLength = METER_CONFIG_LENGTH;
66 while (actualLength < itemLength) {
67 final int itemStartIndex = message.readerIndex();
68 final int itemBandType = message.readUnsignedShort();
69 final MeterBandHeaderBuilder subItemBuilder = new MeterBandHeaderBuilder();
70 actualLength += message.readUnsignedShort();
72 switch (itemBandType) {
75 .setMeterBandTypes(new MeterBandTypesBuilder()
76 .setFlags(new MeterBandType(true, false, false))
78 .setBandType(new DropBuilder()
79 .setDropRate(message.readUnsignedInt())
80 .setDropBurstSize(message.readUnsignedInt())
82 message.skipBytes(PADDING_IN_METER_BAND_DROP_HEADER);
87 .setMeterBandTypes(new MeterBandTypesBuilder()
88 .setFlags(new MeterBandType(false, true, false))
90 .setBandType(new DscpRemarkBuilder()
91 .setDscpRemarkRate(message.readUnsignedInt())
92 .setDscpRemarkBurstSize(message.readUnsignedInt())
93 .setPrecLevel(message.readUnsignedByte())
95 message.skipBytes(PADDING_IN_METER_BAND_DSCP_HEADER);
98 case OFPMBTEXPERIMENTER:
99 // TODO: Finish meter band experimenter deserialization
100 final long expId = message.getUnsignedInt(message.readerIndex() + 2 * EncodeConstants
101 .SIZE_OF_INT_IN_BYTES);
102 message.readerIndex(itemStartIndex);
104 final OFDeserializer<Experimenter> deserializer = registry.getDeserializer(
105 new ExperimenterIdDeserializerKey(EncodeConstants.OF13_VERSION_ID, expId,
106 Experimenter.class));
109 .setMeterBandTypes(new MeterBandTypesBuilder()
110 .setFlags(new MeterBandType(false, false, true))
112 .setBandType(deserializer.deserialize(message));
118 subItems.add(subItemBuilder.build());
121 items.add(itemBuilder
122 .setKey(new MeterConfigStatsKey(itemBuilder.getMeterId()))
123 .setMeterBandHeaders(new MeterBandHeadersBuilder()
124 .setMeterBandHeader(subItems)
130 .setMeterConfigStats(items)
134 private static MeterFlags readMeterFlags(ByteBuf message) {
135 int input = message.readUnsignedShort();
136 final Boolean mfKbps = (input & (1)) != 0;
137 final Boolean mfPktps = (input & (1 << 1)) != 0;
138 final Boolean mfBurst = (input & (1 << 2)) != 0;
139 final Boolean mfStats = (input & (1 << 3)) != 0;
140 return new MeterFlags(mfBurst, mfKbps, mfPktps, mfStats);
144 public void injectDeserializerRegistry(DeserializerRegistry deserializerRegistry) {
145 registry = deserializerRegistry;