Copyright update
[openflowjava.git] / openflow-protocol-impl / src / main / java / org / opendaylight / openflowjava / protocol / impl / serialization / factories / MeterModInputMessageFactory.java
1 /*
2  * Copyright (c) 2013 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.openflowjava.protocol.impl.serialization.factories;
10
11 import io.netty.buffer.ByteBuf;
12
13 import java.util.HashMap;
14 import java.util.List;
15 import java.util.Map;
16
17 import org.opendaylight.openflowjava.protocol.impl.serialization.OFSerializer;
18 import org.opendaylight.openflowjava.protocol.impl.util.ByteBufUtils;
19 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.MeterFlags;
20 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.MeterBandCommons;
21 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.MeterModInput;
22 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.meter.band.header.MeterBand;
23 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.meter.band.header.meter.band.MeterBandDrop;
24 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.meter.band.header.meter.band.MeterBandDscpRemark;
25 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.meter.band.header.meter.band.MeterBandExperimenter;
26 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.meter.mod.Bands;
27
28 /**
29  * Translates MeterMod messages
30  * @author timotej.kubas
31  * @author michal.polkorab
32  */
33 public class MeterModInputMessageFactory implements OFSerializer<MeterModInput> {
34     private static final byte MESSAGE_TYPE = 29;
35     private static final int MESSAGE_LENGTH = 16;
36     private static final short LENGTH_OF_METER_BANDS = 16;
37     private static final short PADDING_IN_METER_BAND_DROP = 4;
38     private static final short PADDING_IN_METER_BAND_DSCP_REMARK = 3;
39     private static MeterModInputMessageFactory instance;
40     
41     private MeterModInputMessageFactory() {
42         // singleton
43     }
44     
45     /**
46      * @return singleton factory
47      */
48     public static synchronized MeterModInputMessageFactory getInstance() {
49         if (instance == null) {
50             instance = new MeterModInputMessageFactory();
51         }
52         return instance;
53     }
54     
55     @Override
56     public void messageToBuffer(short version, ByteBuf out,
57             MeterModInput message) {
58         ByteBufUtils.writeOFHeader(instance, message, out);
59         out.writeShort(message.getCommand().getIntValue());
60         out.writeShort(createMeterFlagsBitmask(message.getFlags()));
61         out.writeInt(message.getMeterId().getValue().intValue());
62         encodeBands(message.getBands(), out);
63     }
64
65     @Override
66     public int computeLength(MeterModInput message) {
67         int length = MESSAGE_LENGTH;
68         if (message.getBands() != null) {
69             length += message.getBands().size() * LENGTH_OF_METER_BANDS;
70         }
71         return length;
72     }
73
74     @Override
75     public byte getMessageType() {
76         return MESSAGE_TYPE;
77     }
78
79     private static int createMeterFlagsBitmask(MeterFlags flags) {
80         int meterFlagBitmask = 0;
81         Map<Integer, Boolean> meterModFlagsMap = new HashMap<>();
82         meterModFlagsMap.put(0, flags.isOFPMFKBPS());
83         meterModFlagsMap.put(1, flags.isOFPMFPKTPS());
84         meterModFlagsMap.put(2, flags.isOFPMFBURST());
85         meterModFlagsMap.put(3, flags.isOFPMFSTATS());
86         
87         meterFlagBitmask = ByteBufUtils.fillBitMaskFromMap(meterModFlagsMap);
88         return meterFlagBitmask;
89     }
90     
91     private static void encodeBands(List<Bands> bands, ByteBuf outBuffer) {
92         if (bands != null) {
93             for (Bands currentBand : bands) {
94                 MeterBand meterBand = currentBand.getMeterBand();
95                 writeBandCommonFields((MeterBandCommons) meterBand, outBuffer);
96                 if (meterBand instanceof MeterBandDrop) {
97                     ByteBufUtils.padBuffer(PADDING_IN_METER_BAND_DROP, outBuffer);
98                 } else if (meterBand instanceof MeterBandDscpRemark) {
99                     MeterBandDscpRemark dscpRemarkBand = (MeterBandDscpRemark) meterBand;
100                     outBuffer.writeByte(dscpRemarkBand.getPrecLevel());
101                     ByteBufUtils.padBuffer(PADDING_IN_METER_BAND_DSCP_REMARK, outBuffer);
102                 } else if (meterBand instanceof MeterBandExperimenter) {
103                     MeterBandExperimenter experimenterBand = (MeterBandExperimenter) meterBand;
104                     outBuffer.writeInt(experimenterBand.getExperimenter().intValue());
105                 }
106             }
107         }
108     }
109     
110     private static void writeBandCommonFields(MeterBandCommons meterBand, ByteBuf outBuffer) {
111         outBuffer.writeShort(meterBand.getType().getIntValue());
112         outBuffer.writeShort(LENGTH_OF_METER_BANDS);
113         outBuffer.writeInt(meterBand.getRate().intValue());
114         outBuffer.writeInt(meterBand.getBurstSize().intValue());
115     }
116     
117 }