1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21 package openr66.protocol.networkhandler.packet;
22
23 import goldengate.common.exception.InvalidArgumentException;
24
25 import openr66.protocol.localhandler.packet.KeepAlivePacket;
26 import openr66.protocol.localhandler.packet.LocalPacketCodec;
27 import openr66.protocol.localhandler.packet.LocalPacketFactory;
28 import openr66.protocol.localhandler.packet.NoOpPacket;
29 import openr66.protocol.networkhandler.NetworkServerHandler;
30 import openr66.protocol.utils.ChannelUtils;
31
32 import org.jboss.netty.buffer.ChannelBuffer;
33 import org.jboss.netty.channel.Channel;
34 import org.jboss.netty.channel.ChannelDownstreamHandler;
35 import org.jboss.netty.channel.ChannelEvent;
36 import org.jboss.netty.channel.ChannelHandlerContext;
37 import org.jboss.netty.channel.Channels;
38 import org.jboss.netty.channel.MessageEvent;
39 import org.jboss.netty.handler.codec.frame.FrameDecoder;
40
41
42
43
44
45
46 public class NetworkPacketCodec extends FrameDecoder implements
47 ChannelDownstreamHandler {
48
49
50
51
52
53
54
55
56 @Override
57 protected Object decode(ChannelHandlerContext ctx, Channel channel,
58 ChannelBuffer buf) throws Exception {
59
60 if (buf.readableBytes() < 4) {
61
62
63
64 return null;
65 }
66
67 buf.markReaderIndex();
68
69 final int length = buf.readInt();
70 if (buf.readableBytes() < length) {
71 buf.resetReaderIndex();
72 return null;
73 }
74
75 final int localId = buf.readInt();
76 final int remoteId = buf.readInt();
77 final byte code = buf.readByte();
78 int readerInder = buf.readerIndex();
79 ChannelBuffer buffer = buf.slice(readerInder, length-9);
80 buf.skipBytes(length-9);
81 NetworkPacket networkPacket = new NetworkPacket(localId, remoteId, code, buffer);
82 if (code == LocalPacketFactory.KEEPALIVEPACKET) {
83 KeepAlivePacket keepAlivePacket = (KeepAlivePacket)
84 LocalPacketCodec.decodeNetworkPacket(networkPacket.getBuffer());
85 if (keepAlivePacket.isToValidate()) {
86 keepAlivePacket.validate();
87 NetworkPacket response =
88 new NetworkPacket(ChannelUtils.NOCHANNEL,
89 ChannelUtils.NOCHANNEL, keepAlivePacket);
90 Channels.write(channel, response);
91 }
92
93 networkPacket = new NetworkPacket(localId, remoteId, new NoOpPacket());
94 NetworkServerHandler nsh = (NetworkServerHandler)ctx.getPipeline().getLast();
95 nsh.setKeepAlivedSent();
96 }
97 return networkPacket;
98 }
99
100 @Override
101 public void handleDownstream(ChannelHandlerContext ctx, ChannelEvent e)
102 throws Exception {
103 if (e instanceof MessageEvent) {
104 final MessageEvent evt = (MessageEvent) e;
105 Object msg = evt.getMessage();
106 if (!(msg instanceof NetworkPacket)) {
107 throw new InvalidArgumentException("Incorrect write object: " +
108 msg.getClass().getName());
109 }
110 final NetworkPacket packet = (NetworkPacket) msg;
111 final ChannelBuffer finalBuf = packet.getNetworkPacket();
112 Channels.write(ctx, evt.getFuture(), finalBuf);
113 } else {
114 ctx.sendDownstream(e);
115 }
116 }
117
118 }