1 /* Copyright (C)2013 Pantheon Technologies, s.r.o. All rights reserved. */
\r
2 package org.opendaylight.openflowjava.protocol.impl.serialization.factories;
\r
4 import io.netty.buffer.ByteBuf;
\r
6 import java.util.List;
\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
17 * @author michal.polkorab
\r
20 public class HelloInputMessageFactory implements OFSerializer<HelloInput>{
\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
29 private static final Logger LOGGER = LoggerFactory
\r
30 .getLogger(HelloInputMessageFactory.class);
\r
33 private HelloInputMessageFactory() {
\r
34 // do nothing, just singleton
\r
38 * @return singleton factory
\r
40 public static synchronized HelloInputMessageFactory getInstance() {
\r
41 if (instance == null) {
\r
42 instance = new HelloInputMessageFactory();
\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.debug("writtenbytes: " + writtenBytesDiff);
\r
55 ByteBufUtils.padBuffer(writtenBytesDiff, out);
\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 int bitmapLength = computeVersionBitmapLength(element);
\r
66 int paddingRemainder = bitmapLength % EncodeConstants.PADDING;
\r
67 if (paddingRemainder != 0) {
\r
68 bitmapLength += EncodeConstants.PADDING - paddingRemainder;
\r
70 length += bitmapLength;
\r
78 public byte getMessageType() {
\r
79 return MESSAGE_TYPE;
\r
82 private static void encodeElementsList(HelloInput message, ByteBuf output) {
\r
83 int[] versionBitmap;
\r
84 if (message.getElements() != null) {
\r
85 for (Elements currElement : message.getElements()) {
\r
86 output.writeShort(currElement.getType().getIntValue());
\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 LOGGER.debug("vbs: " + versionBitmap.length);
\r
92 LOGGER.debug("Version bitmap (below):");
\r
93 for (int i = 0; i < versionBitmap.length; i++) {
\r
94 LOGGER.debug(Integer.toBinaryString(versionBitmap[i]));
\r
95 output.writeInt(versionBitmap[i]);
\r
97 int padding = bitmapLength - versionBitmap.length * 4 - HELLO_ELEMENT_HEADER_SIZE;
\r
98 ByteBufUtils.padBuffer(padding , output);
\r
104 private static short computeVersionBitmapLength(Elements element) {
\r
105 short elementlength = HELLO_ELEMENT_HEADER_SIZE;
\r
106 if (!element.getVersionBitmap().isEmpty()) {
\r
107 elementlength += ((element.getVersionBitmap().size() - 1) / Integer.SIZE + 1) * (Integer.SIZE / Byte.SIZE);
\r
109 return elementlength;
\r