コード例 #1
0
        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);
        }
コード例 #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);
        }
コード例 #3
0
        protected override async Task <IModbusResponse> ReadResponseAsync <TResponse>(CancellationToken token = default)
        {
            var buffer = await PipeResource.ReadAsync(token).ConfigureAwait(false);

            while (buffer.Length < MbapHeaderSizeOnResponse)
            {
                PipeResource.AdvanceTo(buffer.Start);
                buffer = await PipeResource.ReadAsync(token).ConfigureAwait(false);
            }

            var frameLength = (ushort)IPAddress.HostToNetworkOrder(NetCoreBitConverter.ToInt16(buffer.Slice(4, 2).ToSpan()));

            while (buffer.Length < MbapHeaderSizeOnResponse + frameLength)
            {
                PipeResource.AdvanceTo(buffer.Start);
                buffer = await PipeResource.ReadAsync(token).ConfigureAwait(false);
            }

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

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

            response.TransactionId = (ushort)IPAddress.NetworkToHostOrder(NetCoreBitConverter.ToInt16(buffer.Slice(0, 2).ToSpan()));

            PipeResource.AdvanceTo(processedSequence.End);

            return(response);
        }
コード例 #4
0
        protected override async Task WriteRequestAsync(IModbusRequest request, CancellationToken token = default)
        {
            using var memoryOwner = MemoryPool <byte> .Shared.Rent(MbapHeaderSizeOnRequest + request.ByteSize);

            var memory = memoryOwner.Memory;

            BitConverter.TryWriteBytes(memory.Slice(0, 2).Span, IPAddress.HostToNetworkOrder((short)request.TransactionId));
            memory.Span[2] = 0;
            memory.Span[3] = 0;
            BitConverter.TryWriteBytes(memory.Slice(4, 2).Span, IPAddress.HostToNetworkOrder((short)(request.ByteSize + 1)));
            memory.Span[6] = request.SlaveAddress;

            request.WriteTo(memory.Slice(MbapHeaderSizeOnRequest, request.ByteSize));

            await PipeResource.WriteAsync(memory.Slice(0, MbapHeaderSizeOnRequest + request.ByteSize), token).ConfigureAwait(false);
        }
コード例 #5
0
        protected override async Task WriteRequestAsync(IModbusRequest request, CancellationToken token = default)
        {
            var totalSize = SlaveAddressSize + CrcSize + request.ByteSize;

            using var memoryOwner = MemoryPool <byte> .Shared.Rent(totalSize);

            var memory = memoryOwner.Memory;

            memory.Span[0] = request.SlaveAddress;
            request.WriteTo(memory.Slice(SlaveAddressSize, request.ByteSize));

            ushort crc = crcCalculator.Calculate(memory.Slice(0, SlaveAddressSize + request.ByteSize));

            BitConverter.TryWriteBytes(memory.Slice(SlaveAddressSize + request.ByteSize, CrcSize).Span, crc);

            await PipeResource.WriteAsync(memory.Slice(0, totalSize), token).ConfigureAwait(false);
        }