1 /* Copyright (C)2013 Pantheon Technologies, s.r.o. All rights reserved. */
\r
2 package org.openflow.lib;
\r
4 import io.netty.buffer.ByteBuf;
\r
5 import io.netty.channel.ChannelHandlerContext;
\r
6 import io.netty.channel.ChannelInboundHandlerAdapter;
\r
8 import org.openflow.lib.deserialization.DeserializationFactory;
\r
9 import org.openflow.util.ByteBufUtils;
\r
10 import org.slf4j.Logger;
\r
11 import org.slf4j.LoggerFactory;
\r
14 * Transforms OpenFlow Protocol messages to Java messages / objects and takes appropriate
\r
17 * @author michal.polkorab
\r
19 public class Of13Codec extends ChannelInboundHandlerAdapter {
\r
21 // TODO - fix with enum in API
\r
22 private static final int MESSAGE_TYPES = 29;
\r
23 private static final Logger LOGGER = LoggerFactory.getLogger(Of13Codec.class);
\r
26 * Constructor of class
\r
28 public Of13Codec() {
\r
29 LOGGER.info("Creating OF 1.3 Codec");
\r
34 public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
\r
35 LOGGER.info("Reading frame");
\r
36 LOGGER.debug("Received msg is of type: " + msg.getClass().getName());
\r
37 ByteBuf bb = (ByteBuf) msg;
\r
38 if (LOGGER.isDebugEnabled()) {
\r
39 LOGGER.debug(ByteBufUtils.byteBufToHexString(bb));
\r
42 bb.markReaderIndex();
\r
43 short type = bb.readUnsignedByte();
\r
44 int length = bb.readUnsignedShort();
\r
45 long xid = bb.readUnsignedInt();
\r
46 bb.resetReaderIndex();
\r
48 if (!checkOFHeader(type, length)) {
\r
49 bb.discardReadBytes();
\r
50 LOGGER.info("Non-OF Protocol message received (discarding)");
\r
54 // TODO - change hardcoded version to constant, enum, ...
\r
55 DeserializationFactory.bufferToMessage(bb, (short) 0x04);
\r
57 // TODO - delete this switch case after completing deserialization factory
\r
58 ByteBuf out = ctx.alloc().buffer();
\r
61 LOGGER.info("OFPT_HELLO received");
\r
62 byte[] hello = new byte[]{0x04, 0x0, 0x0, 0x08, 0x0, 0x0, 0x0, 0x01};
\r
63 out.writeBytes(hello);
\r
67 LOGGER.info("OFPT_ERROR received");
\r
70 LOGGER.info("OFPT_ECHO_REQUEST received");
\r
71 byte[] echoReply = new byte[]{0x04, 0x03, 0x00, 0x08};
\r
72 out.writeBytes(echoReply);
\r
73 out.writeInt((int) xid);
\r
74 // TODO - append original data field
\r
78 LOGGER.info("OFPT_ECHO_REPLY received");
\r
81 LOGGER.info("OFPT_FEATURES_REQUEST received");
\r
84 LOGGER.info("OFPT_FEATURES_REPLY received");
\r
87 LOGGER.info("Received message type: " + type);
\r
90 if (LOGGER.isDebugEnabled()) {
\r
91 LOGGER.debug(ByteBufUtils.byteBufToHexString(out));
\r
94 ctx.writeAndFlush(out);
\r
95 LOGGER.info("Flushed");
\r
97 int bytesRemaining = bb.readableBytes();
\r
98 LOGGER.debug("Skipping unread bytes");
\r
99 bb.skipBytes(bytesRemaining);
\r
100 LOGGER.debug("Discarding read bytes");
\r
101 LOGGER.debug("RI: " + bb.readerIndex());
\r
102 LOGGER.debug("WI: " + bb.writerIndex());
\r
106 private static boolean checkOFHeader(short type, int length) {
\r
107 return !((type > MESSAGE_TYPES) || (length < OfFrameDecoder.LENGTH_OF_HEADER));
\r