hello-VersionBitmap fixed
[openflowjava.git] / openflow-protocol-impl / src / main / java / org / opendaylight / openflowjava / protocol / impl / serialization / factories / HelloInputMessageFactory.java
1 /* Copyright (C)2013 Pantheon Technologies, s.r.o. All rights reserved. */\r
2 package org.opendaylight.openflowjava.protocol.impl.serialization.factories;\r
3 \r
4 import io.netty.buffer.ByteBuf;\r
5 \r
6 import java.util.List;\r
7 \r
8 import org.opendaylight.openflowjava.protocol.impl.serialization.OFSerializer;\r
9 import org.opendaylight.openflowjava.protocol.impl.util.ByteBufUtils;\r
10 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.HelloElementType;\r
11 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.HelloInput;\r
12 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.hello.Elements;\r
13 import org.slf4j.Logger;\r
14 import org.slf4j.LoggerFactory;\r
15 \r
16 /**\r
17  * @author michal.polkorab\r
18  *\r
19  */\r
20 public class HelloInputMessageFactory implements OFSerializer<HelloInput>{\r
21 \r
22     /** Code type of Hello message */\r
23     private static final byte MESSAGE_TYPE = 0;\r
24     private static int MESSAGE_LENGTH = 8;\r
25     public static final byte HELLO_ELEMENT_HEADER_SIZE = 4;\r
26     private static HelloInputMessageFactory instance;\r
27     \r
28     private static final Logger LOGGER = LoggerFactory\r
29             .getLogger(HelloInputMessageFactory.class);\r
30     \r
31     \r
32     private HelloInputMessageFactory() {\r
33         // do nothing, just singleton\r
34     }\r
35     \r
36     /**\r
37      * @return singleton factory\r
38      */\r
39     public static synchronized HelloInputMessageFactory getInstance() {\r
40         if (instance == null) {\r
41             instance = new HelloInputMessageFactory();\r
42         }\r
43         return instance;\r
44     }\r
45 \r
46     @Override\r
47     public void messageToBuffer(short version, ByteBuf out, HelloInput message) {\r
48         int startWriterIndex = out.writerIndex();\r
49         ByteBufUtils.writeOFHeader(instance, message, out);\r
50         encodeElementsList(message, out);\r
51         int endWriterIndex = out.writerIndex();\r
52         int writtenBytesDiff = computeLength(message) - (endWriterIndex - startWriterIndex);\r
53         LOGGER.info("writtenbytes: " + writtenBytesDiff);\r
54         ByteBufUtils.padBuffer(writtenBytesDiff, out);\r
55     }\r
56 \r
57     @Override\r
58     public int computeLength(HelloInput message) {\r
59         int length = MESSAGE_LENGTH;\r
60         List<Elements> elements = message.getElements();\r
61         if (elements != null) {\r
62             for (Elements element : elements) {\r
63                 if (HelloElementType.VERSIONBITMAP.equals(element.getType())) {\r
64                     length += computeVersionBitmapLength(element);\r
65                 }\r
66             }\r
67             int paddingRemainder = length % EncodeConstants.PADDING;\r
68             if (paddingRemainder != 0) {\r
69                 length += EncodeConstants.PADDING - paddingRemainder;\r
70             }\r
71         }\r
72         return length;\r
73     }\r
74 \r
75     @Override\r
76     public byte getMessageType() {\r
77         return MESSAGE_TYPE;\r
78     }\r
79     \r
80     private static void encodeElementsList(HelloInput message, ByteBuf output) {\r
81         int[] versionBitmap;\r
82         int arraySize = 0;\r
83         if (message.getElements() != null) {\r
84             for (Elements currElement : message.getElements()) {\r
85                 output.writeShort(currElement.getType().getIntValue());\r
86                 \r
87                 if (currElement.getType().equals(HelloElementType.VERSIONBITMAP)) {\r
88                     short bitmapLength = computeVersionBitmapLength(currElement);\r
89                     output.writeShort(bitmapLength);\r
90                     versionBitmap = ByteBufUtils.fillBitMaskFromList(currElement.getVersionBitmap());\r
91                     arraySize = (versionBitmap.length/Integer.SIZE);\r
92                     for (int i = 0; i < arraySize; i++) {\r
93                         output.writeInt(versionBitmap[i]);\r
94                     }\r
95                     int padding = bitmapLength - arraySize * 4 - HELLO_ELEMENT_HEADER_SIZE;\r
96                     ByteBufUtils.padBuffer(padding , output);\r
97                 }\r
98             } \r
99         }\r
100     }\r
101     \r
102     private static short computeVersionBitmapLength(Elements element) {\r
103         short elementlength = HELLO_ELEMENT_HEADER_SIZE;\r
104         if (!element.getVersionBitmap().isEmpty()) {\r
105             elementlength += ((element.getVersionBitmap().size() - 1) / Integer.SIZE + 1) * 4;\r
106         }\r
107         return elementlength;\r
108     }\r
109 }\r