Пример #1
0
 public ChabuReceiver(ChabuReceiver receiver, AbortMessage localAbortMessage)
 {
     this.localAbortMessage = localAbortMessage;
     if (receiver == null)
     {
         recvBuf = new ByteBuffer(Constants.MAX_RECV_LIMIT_LOW);
         recvBuf.order(ByteOrder.BIG_ENDIAN);
         recvBuf.clear();
         recvBuf.limit(HEADER_RECV_SZ);
     }
     else
     {
         recvBuf    = receiver.recvBuf;
         packetSize = receiver.packetSize;
     }
 }
Пример #2
0
        protected override void processSeq(ByteChannel channel)
        {
            // is SEQ packet
            recvBuf.position(HEADER_RECV_SZ);
            int channelId = recvBuf.getInt(8);
            int seq       = recvBuf.getInt(12);
            int pls       = recvBuf.getInt(16);
            int padding   = packetSize - HEADER_RECV_SZ - pls;
            ChabuChannelImpl chabuChannel = channels.get(channelId);

            if (seqPacketIndex == 0)
            {
                // first processing
                Utils.ensure(padding >= 0 && padding < 4, ChabuErrorCode.ASSERT, "padding inplausible packetSize:{0} pls:{1}", packetSize, pls);
                chabuChannel.verifySeq(seq);
            }

            if (seqPacketIndex < pls)
            {
                int toBeHandledLimit = pls - seqPacketIndex;
                int handledBytes     = chabuChannel.handleRecvSeq(channel, toBeHandledLimit);
                seqPacketIndex += handledBytes;
            }

            if (seqPacketIndex >= pls && seqPacketIndex + ChabuImpl.SEQ_MIN_SZ < packetSize)
            {
                int paddingRemaining = packetSize - seqPacketIndex - ChabuImpl.SEQ_MIN_SZ;
                recvBufPadding.clear();
                Utils.ensure(paddingRemaining <= 3 && paddingRemaining > 0, ChabuErrorCode.ASSERT, "paddingRemaining inplausible {0} ({1}, {2})", paddingRemaining, seqPacketIndex, packetSize);
                recvBufPadding.limit(paddingRemaining);
                seqPacketIndex += channel.read(recvBufPadding);
            }

            if (seqPacketIndex + ChabuImpl.SEQ_MIN_SZ >= packetSize)
            {
                seqPacketIndex = 0;
                recvBuf.clear();
                recvBuf.limit(HEADER_RECV_SZ);
                packetType = PacketType.NONE;
            }
            else
            {
                Utils.ensure(recvBuf.position() == 20, ChabuErrorCode.ASSERT, "");
                Utils.ensure(recvBuf.limit() == 20, ChabuErrorCode.ASSERT, "");
            }
        }
Пример #3
0
        public void recv(ByteChannel channel)
        {
            cancelCurrentReceive = false;
            while (!cancelCurrentReceive)
            {
                if (packetType == PacketType.NONE)
                {
                    Utils.ensure(recvBuf.limit() >= HEADER_RECV_SZ, ChabuErrorCode.UNKNOWN, "unknown header size: {0}", recvBuf);
                    channel.read(recvBuf);
                    if (recvBuf.position() < 8)
                    {
                        break;
                    }

                    packetSize = recvBuf.getInt(0);
                    int packetTypeId = recvBuf.getInt(4) & 0xFF;
                    packetType = PacketTypeExtension.findPacketType(packetTypeId);
                    if (packetType == PacketType.NONE)
                    {
                        throw new ChabuException(string.Format("Packet type 0x{0:X2} unexpected: packetSize {1}", packetTypeId, packetSize));
                    }
                }

                if (packetType != PacketType.SEQ)
                {
                    Utils.ensure(packetSize <= Constants.MAX_RECV_LIMIT_LOW, ChabuErrorCode.UNKNOWN, "unknown header size");
                    if (packetSize > recvBuf.position())
                    {
                        recvBuf.limit(packetSize);
                        channel.read(recvBuf);
                        if (recvBuf.hasRemaining())
                        {
                            // not fully read, try next time
                            break;
                        }
                    }
                }
                else
                {
                    if (HEADER_RECV_SZ > recvBuf.position())
                    {
                        recvBuf.limit(HEADER_RECV_SZ);
                        channel.read(recvBuf);
                        if (recvBuf.hasRemaining())
                        {
                            // not fully read, try next time
                            break;
                        }
                    }
                }

                recvBuf.flip();
                recvBuf.position(8);

                if (packetType != PacketType.SEQ)
                {
                    Utils.ensure(packetSize <= Constants.MAX_RECV_LIMIT_LOW, ChabuErrorCode.UNKNOWN, "unknown header size");
                    switch (packetType)
                    {
                    case PacketType.SETUP: processRecvSetup();    break;

                    case PacketType.ACCEPT: processRecvAccept();   break;

                    case PacketType.ABORT: processRecvAbort();    break;

                    case PacketType.ARM: processRecvArm();      break;

                    case PacketType.DAVAIL: processRecvDavail();   break;

                    case PacketType.NOP: processRecvNop();      break;

                    case PacketType.RST_REQ: processRecvResetReq(); break;

                    case PacketType.RST_ACK: processRecvResetAck(); break;

                    default: break;
                    }
                    Utils.ensure(recvBuf.remaining() < HEADER_RECV_SZ, ChabuErrorCode.ASSERT, "After normal command, the remaining bytes must be below the HEADER_RECV_SZ limit, but is {0}", recvBuf.limit());
                    Utils.ensure(recvBuf.position() == packetSize, ChabuErrorCode.ASSERT, "After normal command, the remaining bytes must be below the HEADER_RECV_SZ limit, but is {0}", recvBuf.limit());
                    recvBuf.compact();
                    recvBuf.limit(HEADER_RECV_SZ);
                    packetType = PacketType.NONE;
                    continue;
                }
                else
                {
                    processSeq(channel);

                    bool isContinuingSeq = packetType == PacketType.SEQ;
                    if (isContinuingSeq)
                    {
                        break;
                    }

                    continue;
                }
            }
        }