View Javadoc
1   /*
2    * This file is part of Waarp Project (named also Waarp or GG).
3    *
4    *  Copyright (c) 2019, Waarp SAS, 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 Waarp Project is free software: you can redistribute it and/or
9    * modify it under the terms of the GNU General Public License as published by
10   * the Free Software Foundation, either version 3 of the License, or (at your
11   * option) any later version.
12   *
13   * Waarp is distributed in the hope that it will be useful, but WITHOUT ANY
14   * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
15   * A PARTICULAR PURPOSE. See the GNU General Public License for more details.
16   *
17   *  You should have received a copy of the GNU General Public License along with
18   * Waarp . If not, see <http://www.gnu.org/licenses/>.
19   */
20  package org.waarp.openr66.proxy.network;
21  
22  import io.netty.buffer.ByteBuf;
23  import io.netty.channel.ChannelHandlerContext;
24  import io.netty.handler.codec.ByteToMessageCodec;
25  import org.waarp.common.utility.WaarpNettyUtil;
26  import org.waarp.openr66.protocol.exception.OpenR66ProtocolPacketException;
27  import org.waarp.openr66.protocol.localhandler.packet.KeepAlivePacket;
28  import org.waarp.openr66.protocol.localhandler.packet.LocalPacketCodec;
29  import org.waarp.openr66.protocol.localhandler.packet.LocalPacketFactory;
30  import org.waarp.openr66.protocol.networkhandler.packet.NetworkPacket;
31  import org.waarp.openr66.protocol.utils.ChannelUtils;
32  
33  import java.util.List;
34  
35  /**
36   * Packet Decoder
37   */
38  public class NetworkPacketCodec extends ByteToMessageCodec<NetworkPacket> {
39    @Override
40    protected void decode(final ChannelHandlerContext ctx, final ByteBuf buf,
41                          final List<Object> out) throws Exception {
42      // Make sure if the length field was received.
43      if (buf.readableBytes() < 4) {
44        // The length field was not received yet - return null.
45        // This method will be invoked again when more packets are
46        // received and appended to the buffer.
47        return;
48      }
49      // Mark the current buffer position
50      buf.markReaderIndex();
51      // Read the length field
52      final int length = buf.readInt();
53      if (length < 9) {
54        throw new OpenR66ProtocolPacketException(
55            "Incorrect decode first field in Network Packet: " + length + " < 9");
56      }
57      if (buf.readableBytes() < length) {
58        buf.resetReaderIndex();
59        return;
60      }
61      // Now we can read the two Ids
62      // Slight change in Proxy = first is remote and second is local!
63      final int remoteId = buf.readInt();
64      final int localId = buf.readInt();
65      final byte code = buf.readByte();
66      final int index = buf.readerIndex();
67      final ByteBuf buffer = buf.retainedSlice(index, length - 9);
68      buf.skipBytes(length - 9);
69      final NetworkPacket networkPacket =
70          new NetworkPacket(localId, remoteId, code, buffer);
71      if (code == LocalPacketFactory.KEEPALIVEPACKET) {
72        final KeepAlivePacket keepAlivePacket =
73            (KeepAlivePacket) LocalPacketCodec.decodeNetworkPacket(buffer);
74        WaarpNettyUtil.release(buffer);
75        if (keepAlivePacket.isToValidate()) {
76          keepAlivePacket.validate();
77          final NetworkPacket response =
78              new NetworkPacket(ChannelUtils.NOCHANNEL, ChannelUtils.NOCHANNEL,
79                                keepAlivePacket, null);
80          ctx.writeAndFlush(response.getNetworkPacket());
81        }
82        // Ignore Packet
83        final NetworkServerHandler nsh =
84            (NetworkServerHandler) ctx.pipeline().last();
85        nsh.resetKeepAlive();
86        return;
87      }
88      out.add(networkPacket);
89    }
90  
91    @Override
92    protected void encode(final ChannelHandlerContext ctx,
93                          final NetworkPacket msg, final ByteBuf out) {
94      final ByteBuf finalBuf = msg.getNetworkPacket();
95      // NetworkPacket in Proxy has bad writerIndex
96      finalBuf.writerIndex(finalBuf.capacity());
97      out.writeBytes(finalBuf);
98      WaarpNettyUtil.releaseCompletely(finalBuf);
99      // DO NOT clear msg
100   }
101 }