View Javadoc
1   /**
2      This file is part of GoldenGate Project (named also GoldenGate or GG).
3   
4      Copyright 2009, Frederic Bregier, and individual contributors by the @author
5      tags. See the COPYRIGHT.txt in the distribution for a full listing of
6      individual contributors.
7   
8      All GoldenGate Project is free software: you can redistribute it and/or 
9      modify it under the terms of the GNU General Public License as published 
10     by the Free Software Foundation, either version 3 of the License, or
11     (at your option) any later version.
12  
13     GoldenGate is distributed in the hope that it will be useful,
14     but WITHOUT ANY WARRANTY; without even the implied warranty of
15     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16     GNU General Public License for more details.
17  
18     You should have received a copy of the GNU General Public License
19     along with GoldenGate .  If not, see <http://www.gnu.org/licenses/>.
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   * Packet Decoder
43   *
44   * @author Frederic Bregier
45   */
46  public class NetworkPacketCodec extends FrameDecoder implements
47          ChannelDownstreamHandler {
48      /*
49       * (non-Javadoc)
50       *
51       * @see
52       * org.jboss.netty.handler.codec.frame.FrameDecoder#decode(org.jboss.netty
53       * .channel.ChannelHandlerContext, org.jboss.netty.channel.Channel,
54       * org.jboss.netty.buffer.ChannelBuffer)
55       */
56      @Override
57      protected Object decode(ChannelHandlerContext ctx, Channel channel,
58              ChannelBuffer buf) throws Exception {
59          // Make sure if the length field was received.
60          if (buf.readableBytes() < 4) {
61              // The length field was not received yet - return null.
62              // This method will be invoked again when more packets are
63              // received and appended to the buffer.
64              return null;
65          }
66          // Mark the current buffer position
67          buf.markReaderIndex();
68          // Read the length field
69          final int length = buf.readInt();
70          if (buf.readableBytes() < length) {
71              buf.resetReaderIndex();
72              return null;
73          }
74          // Now we can read the two Ids
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              // Replaced by a NoOp packet
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 }