Merge "add basic lib - plugin communication"
[openflowjava.git] / openflow-protocol-impl / src / main / java / org / opendaylight / openflowjava / protocol / impl / core / OFFrameDecoder.java
1 /* Copyright (C)2013 Pantheon Technologies, s.r.o. All rights reserved. */
2
3 package org.opendaylight.openflowjava.protocol.impl.core;
4
5 import io.netty.buffer.ByteBuf;
6 import io.netty.channel.ChannelHandlerContext;
7 import io.netty.handler.codec.ByteToMessageDecoder;
8
9 import java.util.List;
10
11 import org.slf4j.Logger;
12 import org.slf4j.LoggerFactory;
13 import org.opendaylight.openflowjava.protocol.impl.core.TcpHandler.COMPONENT_NAMES;
14
15 /**
16  * Class for decoding incoming messages into message frames.
17  *
18  * @author michal.polkorab
19  */
20 public class OFFrameDecoder extends ByteToMessageDecoder {
21
22     /** Length of OpenFlow 1.3 header */
23     public static final byte LENGTH_OF_HEADER = 8;
24     private static final byte LENGTH_INDEX_IN_HEADER = 2;
25     private static final Logger LOGGER = LoggerFactory.getLogger(OFFrameDecoder.class);
26
27     /**
28      * Constructor of class.
29      */
30     public OFFrameDecoder() {
31         LOGGER.info("Creating OFFrameDecoder");
32     }
33
34     @Override
35     public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
36         LOGGER.warn("Unexpected exception from downstream.", cause);
37         ctx.close();
38     }
39
40     @Override
41     protected void decode(ChannelHandlerContext chc, ByteBuf bb, List<Object> list) throws Exception {
42         if (bb.readableBytes() < LENGTH_OF_HEADER) {
43             LOGGER.debug("skipping bb - too few data for header");
44             return;
45         }
46
47         int length = bb.getUnsignedShort(LENGTH_INDEX_IN_HEADER);
48         if (bb.readableBytes() < length) {
49             LOGGER.debug("skipping bb - too few data for msg");
50             return;
51         }
52
53         LOGGER.info("OF Protocol message received");
54
55         enableOFVersionDetector(chc);
56
57         List<String> componentList = chc.pipeline().names();
58         LOGGER.debug(componentList.toString());
59
60         ByteBuf messageBuffer = bb.slice(bb.readerIndex(), length);
61         list.add(messageBuffer);
62         messageBuffer.retain();
63         bb.skipBytes(length);
64     }
65
66     private static void enableOFVersionDetector(ChannelHandlerContext ctx) {
67         if (ctx.pipeline().get(COMPONENT_NAMES.OF_VERSION_DETECTOR.name()) == null) {
68             LOGGER.info("Adding OFVD");
69             ctx.pipeline().addLast(COMPONENT_NAMES.OF_VERSION_DETECTOR.name(), new OFVersionDetector());
70         } else {
71             LOGGER.debug("OFVD already in pipeline");
72         }
73     }
74 }