2 * Copyright (c) 2013 Pantheon Technologies s.r.o. and others. All rights reserved.
4 * This program and the accompanying materials are made available under the
5 * terms of the Eclipse Public License v1.0 which accompanies this distribution,
6 * and is available at http://www.eclipse.org/legal/epl-v10.html
9 package org.opendaylight.openflowjava.protocol.impl.serialization.factories;
11 import io.netty.buffer.ByteBuf;
13 import java.util.List;
15 import org.opendaylight.openflowjava.protocol.impl.serialization.OFSerializer;
16 import org.opendaylight.openflowjava.protocol.impl.util.ByteBufUtils;
17 import org.opendaylight.openflowjava.protocol.impl.util.EncodeConstants;
18 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.HelloElementType;
19 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.HelloInput;
20 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.hello.Elements;
21 import org.slf4j.Logger;
22 import org.slf4j.LoggerFactory;
25 * Translates Hello messages
26 * @author michal.polkorab
27 * @author timotej.kubas
29 public class HelloInputMessageFactory implements OFSerializer<HelloInput>{
31 /** Code type of Hello message */
32 private static final byte MESSAGE_TYPE = 0;
33 private static int MESSAGE_LENGTH = 8;
34 /** Size of hello element header (in bytes) */
35 public static final byte HELLO_ELEMENT_HEADER_SIZE = 4;
36 private static HelloInputMessageFactory instance;
38 private static final Logger LOGGER = LoggerFactory
39 .getLogger(HelloInputMessageFactory.class);
42 private HelloInputMessageFactory() {
43 // do nothing, just singleton
47 * @return singleton factory
49 public static synchronized HelloInputMessageFactory getInstance() {
50 if (instance == null) {
51 instance = new HelloInputMessageFactory();
57 public void messageToBuffer(short version, ByteBuf out, HelloInput message) {
58 int startWriterIndex = out.writerIndex();
59 ByteBufUtils.writeOFHeader(instance, message, out);
60 encodeElementsList(message, out);
61 int endWriterIndex = out.writerIndex();
62 int writtenBytesDiff = computeLength(message) - (endWriterIndex - startWriterIndex);
63 LOGGER.debug("writtenbytes: " + writtenBytesDiff);
64 ByteBufUtils.padBuffer(writtenBytesDiff, out);
68 public int computeLength(HelloInput message) {
69 int length = MESSAGE_LENGTH;
70 List<Elements> elements = message.getElements();
71 if (elements != null) {
72 for (Elements element : elements) {
73 if (HelloElementType.VERSIONBITMAP.equals(element.getType())) {
74 int bitmapLength = computeVersionBitmapLength(element);
75 int paddingRemainder = bitmapLength % EncodeConstants.PADDING;
76 if (paddingRemainder != 0) {
77 bitmapLength += EncodeConstants.PADDING - paddingRemainder;
79 length += bitmapLength;
87 public byte getMessageType() {
91 private static void encodeElementsList(HelloInput message, ByteBuf output) {
93 if (message.getElements() != null) {
94 for (Elements currElement : message.getElements()) {
95 output.writeShort(currElement.getType().getIntValue());
96 if (currElement.getType().equals(HelloElementType.VERSIONBITMAP)) {
97 short bitmapLength = computeVersionBitmapLength(currElement);
98 output.writeShort(bitmapLength);
99 versionBitmap = ByteBufUtils.fillBitMaskFromList(currElement.getVersionBitmap());
100 LOGGER.debug("vbs: " + versionBitmap.length);
101 LOGGER.debug("Version bitmap (below):");
102 for (int i = 0; i < versionBitmap.length; i++) {
103 LOGGER.debug(Integer.toBinaryString(versionBitmap[i]));
104 output.writeInt(versionBitmap[i]);
106 int padding = bitmapLength - versionBitmap.length * 4 - HELLO_ELEMENT_HEADER_SIZE;
107 ByteBufUtils.padBuffer(padding , output);
113 private static short computeVersionBitmapLength(Elements element) {
114 short elementlength = HELLO_ELEMENT_HEADER_SIZE;
115 if (!element.getVersionBitmap().isEmpty()) {
116 elementlength += ((element.getVersionBitmap().size() - 1) / Integer.SIZE + 1) * (EncodeConstants.SIZE_OF_INT_IN_BYTES);
118 return elementlength;