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