Update MRI projects for Aluminium
[openflowplugin.git] / openflowplugin-impl / src / main / java / org / opendaylight / openflowplugin / impl / protocol / deserialization / messages / MeterMessageDeserializer.java
1 /*
2  * Copyright (c) 2016 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.messages;
10
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.types.rev130918.BandId;
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.MeterMessage;
24 import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.types.rev130918.MeterMessageBuilder;
25 import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.types.rev130918.band.type.band.type.DropBuilder;
26 import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.types.rev130918.band.type.band.type.DscpRemarkBuilder;
27 import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.types.rev130918.band.type.band.type.Experimenter;
28 import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.types.rev130918.meter.MeterBandHeadersBuilder;
29 import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.types.rev130918.meter.meter.band.headers.MeterBandHeader;
30 import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.types.rev130918.meter.meter.band.headers.MeterBandHeaderBuilder;
31 import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.types.rev130918.meter.meter.band.headers.MeterBandHeaderKey;
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.openflow.common.types.rev130731.MeterModCommand;
34 import org.slf4j.Logger;
35 import org.slf4j.LoggerFactory;
36
37 public class MeterMessageDeserializer implements OFDeserializer<MeterMessage>, DeserializerRegistryInjector {
38     private static final Logger LOG = LoggerFactory.getLogger(MeterMessageDeserializer.class);
39     private static final int OFPMBTDROP = 1;
40     private static final int OFPMBTDSCP = 2;
41     private static final int OFPMBTEXPERIMENTER = 0xFFFF;
42     private static final byte PADDING_IN_METER_BAND_DROP_HEADER = 4;
43     private static final byte PADDING_IN_METER_BAND_DSCP_HEADER = 3;
44     private DeserializerRegistry registry;
45
46     @Override
47     public MeterMessage deserialize(ByteBuf message) {
48         final MeterMessageBuilder builder = new MeterMessageBuilder()
49                 .setVersion((short) EncodeConstants.OF13_VERSION_ID)
50                 .setXid(message.readUnsignedInt())
51                 .setCommand(MeterModCommand.forValue(message.readUnsignedShort()))
52                 .setFlags(readMeterFlags(message))
53                 .setMeterId(new MeterId(message.readUnsignedInt()));
54
55         final List<MeterBandHeader> bands = new ArrayList<>();
56         long key = 0;
57
58         while (message.readableBytes() > 0) {
59             final MeterBandHeaderBuilder bandBuilder = new MeterBandHeaderBuilder();
60             final int bandStartIndex = message.readerIndex();
61             final int bandType = message.readUnsignedShort();
62
63             switch (bandType) {
64                 case OFPMBTDROP: {
65                     bandBuilder
66                             .setMeterBandTypes(new MeterBandTypesBuilder()
67                                     .setFlags(new MeterBandType(true, false, false))
68                                     .build())
69                             .setBandType(new DropBuilder()
70                                     .setDropRate(message.readUnsignedInt())
71                                     .setDropBurstSize(message.readUnsignedInt())
72                                     .build());
73                     message.skipBytes(PADDING_IN_METER_BAND_DROP_HEADER);
74                     break;
75                 }
76                 case OFPMBTDSCP: {
77                     bandBuilder
78                             .setMeterBandTypes(new MeterBandTypesBuilder()
79                                     .setFlags(new MeterBandType(false, true, false))
80                                     .build())
81                             .setBandType(new DscpRemarkBuilder()
82                                     .setDscpRemarkRate(message.readUnsignedInt())
83                                     .setDscpRemarkBurstSize(message.readUnsignedInt())
84                                     .setPrecLevel(message.readUnsignedByte())
85                                     .build());
86                     message.skipBytes(PADDING_IN_METER_BAND_DSCP_HEADER);
87                     break;
88                 }
89                 case OFPMBTEXPERIMENTER: {
90                     // TODO: Finish meter band experimenter deserialization
91                     long expId =
92                             message.getUnsignedInt(message.readerIndex() + 2 * EncodeConstants.SIZE_OF_INT_IN_BYTES);
93                     message.readerIndex(bandStartIndex);
94
95                     OFDeserializer<Experimenter> deserializer = registry.getDeserializer(
96                             new ExperimenterIdDeserializerKey(EncodeConstants.OF13_VERSION_ID, expId,
97                                     Experimenter.class));
98
99                     bandBuilder
100                             .setMeterBandTypes(new MeterBandTypesBuilder()
101                                     .setFlags(new MeterBandType(false, false, true))
102                                     .build())
103                             .setBandType(deserializer.deserialize(message));
104                     break;
105                 }
106                 default:
107                     // no operation
108             }
109
110             bands.add(bandBuilder.withKey(new MeterBandHeaderKey(new BandId(key++))).build());
111         }
112
113         return builder
114                 .setMeterBandHeaders(new MeterBandHeadersBuilder()
115                         .setMeterBandHeader(bands)
116                         .build())
117                 .build();
118     }
119
120
121     @Override
122     public void injectDeserializerRegistry(DeserializerRegistry deserializerRegistry) {
123         registry = deserializerRegistry;
124     }
125
126     private static MeterFlags readMeterFlags(ByteBuf message) {
127         int input = message.readUnsignedShort();
128         final Boolean mfKbps = (input & (1)) != 0;
129         final Boolean mfPktps = (input & (1 << 1)) != 0;
130         final Boolean mfBurst = (input & (1 << 2)) != 0;
131         final Boolean mfStats = (input & (1 << 3)) != 0;
132         return new MeterFlags(mfBurst, mfKbps, mfPktps, mfStats);
133     }
134
135 }