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