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.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
18 * Translates Hello messages
\r
19 * @author michal.polkorab
\r
20 * @author timotej.kubas
\r
22 public class HelloInputMessageFactory implements OFSerializer<HelloInput>{
\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
31 private static final Logger LOGGER = LoggerFactory
\r
32 .getLogger(HelloInputMessageFactory.class);
\r
35 private HelloInputMessageFactory() {
\r
36 // do nothing, just singleton
\r
40 * @return singleton factory
\r
42 public static synchronized HelloInputMessageFactory getInstance() {
\r
43 if (instance == null) {
\r
44 instance = new HelloInputMessageFactory();
\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
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
72 length += bitmapLength;
\r
80 public byte getMessageType() {
\r
81 return MESSAGE_TYPE;
\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
99 int padding = bitmapLength - versionBitmap.length * 4 - HELLO_ELEMENT_HEADER_SIZE;
\r
100 ByteBufUtils.padBuffer(padding , output);
\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
111 return elementlength;
\r