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