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