Javadoc update
[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  * Translates Hello messages\r
18  * @author michal.polkorab\r
19  * @author timotej.kubas\r
20  */\r
21 public class HelloInputMessageFactory implements OFSerializer<HelloInput>{\r
22 \r
23     /** Code type of Hello message */\r
24     private static final byte MESSAGE_TYPE = 0;\r
25     private static int MESSAGE_LENGTH = 8;\r
26     /** Size of hello element header (in bytes) */\r
27     public static final byte HELLO_ELEMENT_HEADER_SIZE = 4;\r
28     private static HelloInputMessageFactory instance;\r
29     \r
30     private static final Logger LOGGER = LoggerFactory\r
31             .getLogger(HelloInputMessageFactory.class);\r
32     \r
33     \r
34     private HelloInputMessageFactory() {\r
35         // do nothing, just singleton\r
36     }\r
37     \r
38     /**\r
39      * @return singleton factory\r
40      */\r
41     public static synchronized HelloInputMessageFactory getInstance() {\r
42         if (instance == null) {\r
43             instance = new HelloInputMessageFactory();\r
44         }\r
45         return instance;\r
46     }\r
47 \r
48     @Override\r
49     public void messageToBuffer(short version, ByteBuf out, HelloInput message) {\r
50         int startWriterIndex = out.writerIndex();\r
51         ByteBufUtils.writeOFHeader(instance, message, out);\r
52         encodeElementsList(message, out);\r
53         int endWriterIndex = out.writerIndex();\r
54         int writtenBytesDiff = computeLength(message) - (endWriterIndex - startWriterIndex);\r
55         LOGGER.debug("writtenbytes: " + writtenBytesDiff);\r
56         ByteBufUtils.padBuffer(writtenBytesDiff, out);\r
57     }\r
58 \r
59     @Override\r
60     public int computeLength(HelloInput message) {\r
61         int length = MESSAGE_LENGTH;\r
62         List<Elements> elements = message.getElements();\r
63         if (elements != null) {\r
64             for (Elements element : elements) {\r
65                 if (HelloElementType.VERSIONBITMAP.equals(element.getType())) {\r
66                     int bitmapLength = computeVersionBitmapLength(element);\r
67                     int paddingRemainder = bitmapLength % EncodeConstants.PADDING;\r
68                     if (paddingRemainder != 0) {\r
69                         bitmapLength += EncodeConstants.PADDING - paddingRemainder;\r
70                     }\r
71                     length += bitmapLength;\r
72                 }\r
73             }\r
74         }\r
75         return length;\r
76     }\r
77 \r
78     @Override\r
79     public byte getMessageType() {\r
80         return MESSAGE_TYPE;\r
81     }\r
82     \r
83     private static void encodeElementsList(HelloInput message, ByteBuf output) {\r
84         int[] versionBitmap;\r
85         if (message.getElements() != null) {\r
86             for (Elements currElement : message.getElements()) {\r
87                 output.writeShort(currElement.getType().getIntValue());\r
88                 if (currElement.getType().equals(HelloElementType.VERSIONBITMAP)) {\r
89                     short bitmapLength = computeVersionBitmapLength(currElement);\r
90                     output.writeShort(bitmapLength);\r
91                     versionBitmap = ByteBufUtils.fillBitMaskFromList(currElement.getVersionBitmap());\r
92                     LOGGER.debug("vbs: " + versionBitmap.length);\r
93                     LOGGER.debug("Version bitmap (below):");\r
94                     for (int i = 0; i < versionBitmap.length; i++) {\r
95                         LOGGER.debug(Integer.toBinaryString(versionBitmap[i]));\r
96                         output.writeInt(versionBitmap[i]);\r
97                     }\r
98                     int padding = bitmapLength - versionBitmap.length * 4 - HELLO_ELEMENT_HEADER_SIZE;\r
99                     ByteBufUtils.padBuffer(padding , output);\r
100                 }\r
101             } \r
102         }\r
103     }\r
104     \r
105     private static short computeVersionBitmapLength(Elements element) {\r
106         short elementlength = HELLO_ELEMENT_HEADER_SIZE;\r
107         if (!element.getVersionBitmap().isEmpty()) {\r
108             elementlength += ((element.getVersionBitmap().size() - 1) / Integer.SIZE + 1) * (Integer.SIZE / Byte.SIZE);\r
109         }\r
110         return elementlength;\r
111     }\r
112 }\r