2a6ab7e314b485d4ec96e41b9180c33080263c15
[openflowplugin.git] / openflowjava / openflow-protocol-impl / src / main / java / org / opendaylight / openflowjava / protocol / impl / deserialization / factories / MeterModInputMessageFactory.java
1 /*
2  * Copyright (c) 2015 NetIDE Consortium 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 package org.opendaylight.openflowjava.protocol.impl.deserialization.factories;
9
10 import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
11 import io.netty.buffer.ByteBuf;
12 import java.util.ArrayList;
13 import java.util.List;
14 import java.util.Objects;
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.util.EncodeConstants;
19 import org.opendaylight.openflowjava.util.ExperimenterDeserializerKeyFactory;
20 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.MeterBandType;
21 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.MeterFlags;
22 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.MeterId;
23 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.MeterModCommand;
24 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.MeterModInput;
25 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.MeterModInputBuilder;
26 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.meter.band.header.meter.band.MeterBandDropCaseBuilder;
27 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.meter.band.header.meter.band.MeterBandDscpRemarkCaseBuilder;
28 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.meter.band.header.meter.band.MeterBandExperimenterCase;
29 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.meter.band.header.meter.band.meter.band.drop._case.MeterBandDropBuilder;
30 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.meter.band.header.meter.band.meter.band.dscp.remark._case.MeterBandDscpRemarkBuilder;
31 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.meter.mod.Bands;
32 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.meter.mod.BandsBuilder;
33
34 /**
35  * Translates MeterModInput messages.
36  *
37  * @author giuseppex.petralia@intel.com
38  */
39 public class MeterModInputMessageFactory implements OFDeserializer<MeterModInput>, DeserializerRegistryInjector {
40
41     private DeserializerRegistry registry;
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
45     @Override
46     public void injectDeserializerRegistry(DeserializerRegistry deserializerRegistry) {
47         registry = deserializerRegistry;
48     }
49
50     @Override
51     @SuppressFBWarnings("UWF_FIELD_NOT_INITIALIZED_IN_CONSTRUCTOR") // FB doesn't recognize Objects.requireNonNull
52     public MeterModInput deserialize(ByteBuf rawMessage) {
53         Objects.requireNonNull(registry);
54
55         MeterModInputBuilder builder = new MeterModInputBuilder();
56         builder.setVersion((short) EncodeConstants.OF13_VERSION_ID);
57         builder.setXid(rawMessage.readUnsignedInt());
58         builder.setCommand(MeterModCommand.forValue(rawMessage.readUnsignedShort()));
59         builder.setFlags(createMeterFlags(rawMessage.readUnsignedShort()));
60         builder.setMeterId(new MeterId(rawMessage.readUnsignedInt()));
61         List<Bands> bandsList = new ArrayList<>();
62         while (rawMessage.readableBytes() > 0) {
63             BandsBuilder bandsBuilder = new BandsBuilder();
64             int bandStartIndex = rawMessage.readerIndex();
65             int bandType = rawMessage.readUnsignedShort();
66             switch (bandType) {
67                 case 1:
68                     final MeterBandDropCaseBuilder bandDropCaseBuilder = new MeterBandDropCaseBuilder();
69                     MeterBandDropBuilder bandDropBuilder = new MeterBandDropBuilder();
70                     bandDropBuilder.setType(MeterBandType.forValue(bandType));
71                     rawMessage.readUnsignedShort();
72                     bandDropBuilder.setRate(rawMessage.readUnsignedInt());
73                     bandDropBuilder.setBurstSize(rawMessage.readUnsignedInt());
74                     rawMessage.skipBytes(PADDING_IN_METER_BAND_DROP_HEADER);
75                     bandDropCaseBuilder.setMeterBandDrop(bandDropBuilder.build());
76                     bandsBuilder.setMeterBand(bandDropCaseBuilder.build());
77                     break;
78                 case 2:
79                     final MeterBandDscpRemarkCaseBuilder bandDscpRemarkCaseBuilder =
80                         new MeterBandDscpRemarkCaseBuilder();
81                     MeterBandDscpRemarkBuilder bandDscpRemarkBuilder = new MeterBandDscpRemarkBuilder();
82                     bandDscpRemarkBuilder.setType(MeterBandType.forValue(bandType));
83                     rawMessage.readUnsignedShort();
84                     bandDscpRemarkBuilder.setRate(rawMessage.readUnsignedInt());
85                     bandDscpRemarkBuilder.setBurstSize(rawMessage.readUnsignedInt());
86                     bandDscpRemarkBuilder.setPrecLevel(rawMessage.readUnsignedByte());
87                     rawMessage.skipBytes(PADDING_IN_METER_BAND_DSCP_HEADER);
88                     bandDscpRemarkCaseBuilder.setMeterBandDscpRemark(bandDscpRemarkBuilder.build());
89                     bandsBuilder.setMeterBand(bandDscpRemarkCaseBuilder.build());
90                     break;
91                 case 0xFFFF:
92                     long expId = rawMessage.getUnsignedInt(rawMessage.readerIndex()
93                             + 2 * EncodeConstants.SIZE_OF_INT_IN_BYTES);
94                     rawMessage.readerIndex(bandStartIndex);
95                     OFDeserializer<MeterBandExperimenterCase> deserializer = registry
96                             .getDeserializer(ExperimenterDeserializerKeyFactory
97                                     .createMeterBandDeserializerKey(EncodeConstants.OF13_VERSION_ID, expId));
98                     bandsBuilder.setMeterBand(deserializer.deserialize(rawMessage));
99                     break;
100                 default:
101                     break;
102             }
103             bandsList.add(bandsBuilder.build());
104         }
105         builder.setBands(bandsList);
106         return builder.build();
107     }
108
109     @SuppressWarnings("checkstyle:AbbreviationAsWordInName")
110     private static MeterFlags createMeterFlags(int input) {
111         final Boolean mfKBPS = (input & 1 << 0) != 0;
112         final Boolean mfPKTPS = (input & 1 << 1) != 0;
113         final Boolean mfBURST = (input & 1 << 2) != 0;
114         final Boolean mfSTATS = (input & 1 << 3) != 0;
115         return new MeterFlags(mfBURST, mfKBPS, mfPKTPS, mfSTATS);
116     }
117
118 }