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; } }
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, ""); } }
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; } } }