internal int handleRecvSeq(ByteChannel byteChannel, int recvByteCount) { int allowedRecv = this.recvArm - this.recvSeq; int remainingBytes = recvByteCount; Utils.ensure(remainingBytes <= allowedRecv, ChabuErrorCode.PROTOCOL_DATA_OVERFLOW, "Channel[{0}] received more data ({1}) as it can take ({2}). Violation of the ARM value.", channelId, remainingBytes, allowedRecv); int summedReadBytes = 0; while (remainingBytes > 0) { if (recvTargetBuffer == null) { recvTargetBuffer = recvTarget.GetRecvBuffer(remainingBytes); Utils.ensure(recvTargetBuffer != null, ChabuErrorCode.ASSERT, "Channel[{0}] recvTargetBuffer is null.", channelId); Utils.ensure(recvTargetBuffer.remaining() <= remainingBytes, ChabuErrorCode.ASSERT, "Channel[{0}] recvTargetBuffer has more remaining ({1}) as requested ({2}).", channelId, recvTargetBuffer.remaining(), remainingBytes); Utils.ensure(recvTargetBuffer.remaining() > 0, ChabuErrorCode.ASSERT, "Channel[{0}] recvTargetBuffer cannot take data.", channelId); } int readBytes = byteChannel.read(recvTargetBuffer); summedReadBytes += readBytes; remainingBytes -= readBytes; recvSeq += readBytes; recvPosition += readBytes; if (!recvTargetBuffer.hasRemaining()) { recvTargetBuffer = null; recvTarget.RecvCompleted(); } if (readBytes == 0) { // could not read => try next time break; } } return(summedReadBytes); }
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; } } }