blob: 1697539fb188698729ee64dc2690b07786ce1251 [file] [log] [blame]
Thomas Vachuska24c849c2014-10-27 09:53:05 -07001/*
Thomas Vachuska4f1a60c2014-10-28 13:39:07 -07002 * Copyright 2014 Open Networking Laboratory
Thomas Vachuska24c849c2014-10-27 09:53:05 -07003 *
Thomas Vachuska4f1a60c2014-10-28 13:39:07 -07004 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
Thomas Vachuska24c849c2014-10-27 09:53:05 -07007 *
Thomas Vachuska4f1a60c2014-10-28 13:39:07 -07008 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
Thomas Vachuska24c849c2014-10-27 09:53:05 -070015 */
Madan Jampaniab6d3112014-10-02 16:30:14 -070016package org.onlab.netty;
17
Madan Jampani86ed0552014-10-03 16:45:42 -070018import static com.google.common.base.Preconditions.checkState;
19import io.netty.buffer.ByteBuf;
20import io.netty.channel.ChannelHandlerContext;
21import io.netty.handler.codec.ReplayingDecoder;
22
Madan Jampaniab6d3112014-10-02 16:30:14 -070023import java.util.List;
24
Madan Jampani2e5f87b2015-02-22 10:37:15 -080025import org.onlab.packet.IpAddress;
26import org.onlab.packet.IpAddress.Version;
Madan Jampani29e5dfd2014-10-07 17:26:25 -070027import org.slf4j.Logger;
28import org.slf4j.LoggerFactory;
29
Madan Jampani938aa432014-10-04 17:37:23 -070030/**
31 * Decoder for inbound messages.
32 */
33public class MessageDecoder extends ReplayingDecoder<DecoderState> {
Madan Jampaniab6d3112014-10-02 16:30:14 -070034
Madan Jampani29e5dfd2014-10-07 17:26:25 -070035 private final Logger log = LoggerFactory.getLogger(getClass());
36
Madan Jampaniab6d3112014-10-02 16:30:14 -070037 private final NettyMessagingService messagingService;
Madan Jampani53e44e62014-10-07 12:39:51 -070038
Madan Jampani2e5f87b2015-02-22 10:37:15 -080039 private long messageId;
40 private Version ipVersion;
41 private IpAddress senderIp;
42 private int senderPort;
Madan Jampani938aa432014-10-04 17:37:23 -070043 private int contentLength;
Madan Jampani2e5f87b2015-02-22 10:37:15 -080044 private long messageType;
Madan Jampani938aa432014-10-04 17:37:23 -070045
Madan Jampani53e44e62014-10-07 12:39:51 -070046 public MessageDecoder(NettyMessagingService messagingService) {
Madan Jampani2e5f87b2015-02-22 10:37:15 -080047 super(DecoderState.READ_MESSAGE_ID);
Madan Jampaniab6d3112014-10-02 16:30:14 -070048 this.messagingService = messagingService;
Madan Jampaniab6d3112014-10-02 16:30:14 -070049 }
50
51 @Override
Madan Jampani86ed0552014-10-03 16:45:42 -070052 protected void decode(
53 ChannelHandlerContext context,
54 ByteBuf buffer,
55 List<Object> out) throws Exception {
Madan Jampaniab6d3112014-10-02 16:30:14 -070056
Yuta HIGUCHI5e8ceb42014-11-04 17:22:26 -080057 switch (state()) {
Madan Jampani2e5f87b2015-02-22 10:37:15 -080058 case READ_MESSAGE_ID:
59 messageId = buffer.readLong();
60 checkpoint(DecoderState.READ_SENDER_IP_VERSION);
61 case READ_SENDER_IP_VERSION:
62 ipVersion = buffer.readByte() == 0x0 ? Version.INET : Version.INET6;
63 checkpoint(DecoderState.READ_SENDER_IP);
64 case READ_SENDER_IP:
65 byte[] octects = new byte[IpAddress.byteLength(ipVersion)];
66 buffer.readBytes(octects);
67 senderIp = IpAddress.valueOf(ipVersion, octects);
68 checkpoint(DecoderState.READ_SENDER_PORT);
69 case READ_SENDER_PORT:
70 senderPort = buffer.readInt();
71 checkpoint(DecoderState.READ_MESSAGE_TYPE);
72 case READ_MESSAGE_TYPE:
73 messageType = buffer.readLong();
Madan Jampani938aa432014-10-04 17:37:23 -070074 checkpoint(DecoderState.READ_CONTENT_LENGTH);
75 case READ_CONTENT_LENGTH:
76 contentLength = buffer.readInt();
Madan Jampani938aa432014-10-04 17:37:23 -070077 checkpoint(DecoderState.READ_CONTENT);
78 case READ_CONTENT:
Madan Jampani2e5f87b2015-02-22 10:37:15 -080079 byte[] payload = new byte[contentLength];
80 buffer.readBytes(payload);
81 InternalMessage message = new InternalMessage(
82 messageId,
83 new Endpoint(senderIp, senderPort),
84 messageType,
85 payload);
Madan Jampani938aa432014-10-04 17:37:23 -070086 message.setMessagingService(messagingService);
87 out.add(message);
Madan Jampani2e5f87b2015-02-22 10:37:15 -080088 checkpoint(DecoderState.READ_MESSAGE_ID);
Madan Jampani938aa432014-10-04 17:37:23 -070089 break;
90 default:
91 checkState(false, "Must not be here");
92 }
Madan Jampaniab6d3112014-10-02 16:30:14 -070093 }
Madan Jampani29e5dfd2014-10-07 17:26:25 -070094
95 @Override
96 public void exceptionCaught(ChannelHandlerContext context, Throwable cause) {
97 log.error("Exception inside channel handling pipeline.", cause);
98 context.close();
99 }
Madan Jampaniab6d3112014-10-02 16:30:14 -0700100}