blob: edb2d52522248948d60afc725fe0df8cf66ee2ad [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 Jampani49115e92015-03-14 10:43:33 -070030import com.google.common.base.Charsets;
31
Madan Jampani938aa432014-10-04 17:37:23 -070032/**
33 * Decoder for inbound messages.
34 */
35public class MessageDecoder extends ReplayingDecoder<DecoderState> {
Madan Jampaniab6d3112014-10-02 16:30:14 -070036
Madan Jampani29e5dfd2014-10-07 17:26:25 -070037 private final Logger log = LoggerFactory.getLogger(getClass());
38
Madan Jampaniab6d3112014-10-02 16:30:14 -070039 private final NettyMessagingService messagingService;
Madan Jampani53e44e62014-10-07 12:39:51 -070040
Madan Jampani2e5f87b2015-02-22 10:37:15 -080041 private long messageId;
42 private Version ipVersion;
43 private IpAddress senderIp;
44 private int senderPort;
Madan Jampani49115e92015-03-14 10:43:33 -070045 private int messageTypeLength;
46 private String messageType;
Madan Jampani938aa432014-10-04 17:37:23 -070047 private int contentLength;
48
Madan Jampani53e44e62014-10-07 12:39:51 -070049 public MessageDecoder(NettyMessagingService messagingService) {
Madan Jampani2e5f87b2015-02-22 10:37:15 -080050 super(DecoderState.READ_MESSAGE_ID);
Madan Jampaniab6d3112014-10-02 16:30:14 -070051 this.messagingService = messagingService;
Madan Jampaniab6d3112014-10-02 16:30:14 -070052 }
53
54 @Override
Madan Jampani86ed0552014-10-03 16:45:42 -070055 protected void decode(
56 ChannelHandlerContext context,
57 ByteBuf buffer,
58 List<Object> out) throws Exception {
Madan Jampaniab6d3112014-10-02 16:30:14 -070059
Yuta HIGUCHI5e8ceb42014-11-04 17:22:26 -080060 switch (state()) {
Madan Jampani2e5f87b2015-02-22 10:37:15 -080061 case READ_MESSAGE_ID:
62 messageId = buffer.readLong();
63 checkpoint(DecoderState.READ_SENDER_IP_VERSION);
64 case READ_SENDER_IP_VERSION:
65 ipVersion = buffer.readByte() == 0x0 ? Version.INET : Version.INET6;
66 checkpoint(DecoderState.READ_SENDER_IP);
67 case READ_SENDER_IP:
68 byte[] octects = new byte[IpAddress.byteLength(ipVersion)];
69 buffer.readBytes(octects);
70 senderIp = IpAddress.valueOf(ipVersion, octects);
71 checkpoint(DecoderState.READ_SENDER_PORT);
72 case READ_SENDER_PORT:
73 senderPort = buffer.readInt();
Madan Jampani49115e92015-03-14 10:43:33 -070074 checkpoint(DecoderState.READ_MESSAGE_TYPE_LENGTH);
75 case READ_MESSAGE_TYPE_LENGTH:
76 messageTypeLength = buffer.readInt();
Madan Jampani2e5f87b2015-02-22 10:37:15 -080077 checkpoint(DecoderState.READ_MESSAGE_TYPE);
78 case READ_MESSAGE_TYPE:
Madan Jampani49115e92015-03-14 10:43:33 -070079 byte[] messageTypeBytes = new byte[messageTypeLength];
80 buffer.readBytes(messageTypeBytes);
81 messageType = new String(messageTypeBytes, Charsets.UTF_8);
Madan Jampani938aa432014-10-04 17:37:23 -070082 checkpoint(DecoderState.READ_CONTENT_LENGTH);
83 case READ_CONTENT_LENGTH:
84 contentLength = buffer.readInt();
Madan Jampani938aa432014-10-04 17:37:23 -070085 checkpoint(DecoderState.READ_CONTENT);
86 case READ_CONTENT:
Madan Jampani2e5f87b2015-02-22 10:37:15 -080087 byte[] payload = new byte[contentLength];
88 buffer.readBytes(payload);
89 InternalMessage message = new InternalMessage(
90 messageId,
91 new Endpoint(senderIp, senderPort),
92 messageType,
93 payload);
Madan Jampani938aa432014-10-04 17:37:23 -070094 message.setMessagingService(messagingService);
95 out.add(message);
Madan Jampani2e5f87b2015-02-22 10:37:15 -080096 checkpoint(DecoderState.READ_MESSAGE_ID);
Madan Jampani938aa432014-10-04 17:37:23 -070097 break;
98 default:
99 checkState(false, "Must not be here");
100 }
Madan Jampaniab6d3112014-10-02 16:30:14 -0700101 }
Madan Jampani29e5dfd2014-10-07 17:26:25 -0700102
103 @Override
104 public void exceptionCaught(ChannelHandlerContext context, Throwable cause) {
105 log.error("Exception inside channel handling pipeline.", cause);
106 context.close();
107 }
Madan Jampaniab6d3112014-10-02 16:30:14 -0700108}