protected override async Task <IModbusResponse> ReadResponseAsync <TResponse>(CancellationToken token = default)
        {
            var buffer = await PipeResource.ReadAsync(MbapHeaderSizeOnResponse, token).ConfigureAwait(false);

            var frameDataLength = (ushort)IPAddress.HostToNetworkOrder(BitConverter.ToInt16(buffer.Slice(4, 2).ToSpan()));
            var totalLength     = MbapHeaderSizeOnResponse + frameDataLength;

            if (buffer.Length < totalLength)
            {
                PipeResource.MarkExamined(buffer);
                buffer = await PipeResource.ReadAsync(totalLength, token).ConfigureAwait(false);
            }

            var processedSequence = buffer.Slice(0, MbapHeaderSizeOnResponse + frameDataLength);

            var response = ModbusResponseFactory.CreateResponse <TResponse>(
                processedSequence
                .Slice(MbapHeaderSizeOnResponse, processedSequence.Length - MbapHeaderSizeOnResponse)
                .ToSpan());

            response.TransactionId = (ushort)IPAddress.NetworkToHostOrder(BitConverter.ToInt16(processedSequence.Slice(0, 2).ToSpan()));
            PipeResource.MarkConsumed(processedSequence);

            return(response);
        }
Exemple #2
0
        protected override async Task <IModbusResponse> ReadResponseAsync <TResponse>(CancellationToken token = default)
        {
            var buffer = await PipeResource.ReadAsync(ResponseFrameStartSize, token).ConfigureAwait(false);

            var lengthSequence = buffer.Slice(0, ResponseFrameStartSize);

            var frameDataLength = GetResponseDataSize(lengthSequence.ToSpan());
            var totalLength     = ResponseFrameStartSize + frameDataLength + CrcSize;

            if (buffer.Length < totalLength)
            {
                PipeResource.MarkExamined(lengthSequence);
                buffer = await PipeResource.ReadAsync(totalLength, token).ConfigureAwait(false);
            }

            var processedSequence = buffer.Slice(0, totalLength);

            var expectedCrc = crcCalculator.Calculate(processedSequence.Slice(0, totalLength - CrcSize).ToMemory());
            var actualCrc   = BitConverter.ToUInt16(processedSequence.Slice(totalLength - CrcSize, CrcSize).ToSpan());

            if (actualCrc != expectedCrc)
            {
                PipeResource.MarkConsumed(processedSequence);
                throw new IOException($"Received unexpected CRC. Expected: {expectedCrc}. Received: {actualCrc}.");
            }

            var response = ModbusResponseFactory.CreateResponse <TResponse>(processedSequence.ToSpan());

            PipeResource.MarkConsumed(processedSequence);

            return(response);
        }