private async Task ReadAsync(ModbusDevice device, ModbusFunctionCode functionCode, int zeroBasedOffset, int count, Action <MessageBufferSpan> actionWithReturnedBuffer, CancellationToken cancellationToken) { var requestContext = new ModbusTransportContext() { TransactionIdentifier = GetTransactionIdentifier() }; await ModbusTransport.SendMessageAsync(requestContext, (writer) => { writer.Push(device.Address); writer.Push((byte)functionCode); writer.Push((byte)((zeroBasedOffset >> 8) & 0xFF)); writer.Push((byte)((zeroBasedOffset >> 0) & 0xFF)); writer.Push((byte)((count >> 8) & 0xFF)); writer.Push((byte)((count >> 0) & 0xFF)); }, cancellationToken); MessageBufferSpan?receivedBuffer = null; var responseContext = await ModbusTransport.ReceiveMessageAsync( async (reader) => { if (await reader.PushByteFromStreamAsync(cancellationToken) != device.Address) { throw new InvalidOperationException(); } byte receivedFunctionCode = await reader.PushByteFromStreamAsync(cancellationToken); if (receivedFunctionCode == ((byte)functionCode | 0x80)) { var exceptionCode = (ModbusExceptionCode)await reader.PushByteFromStreamAsync(cancellationToken); throw new ModbusException(exceptionCode); } if (receivedFunctionCode != (byte)functionCode) { throw new InvalidOperationException(); } var byteCount = await reader.PushByteFromStreamAsync(cancellationToken); await reader.PushFromStreamAsync(byteCount, cancellationToken); receivedBuffer = new MessageBufferSpan(reader.Buffer, (ushort)(reader.Buffer.Length - byteCount), byteCount); }, cancellationToken); if (responseContext.TransactionIdentifier != requestContext.TransactionIdentifier) { throw new InvalidOperationException(); } actionWithReturnedBuffer(receivedBuffer !); }
private async Task <T> WriteAsync <T>(ModbusDevice device, ModbusFunctionCode functionCode, int zeroBasedOffset, Action <IMessageBufferWriter> writeAction, Func <IMessageBufferReader, Task <T> > readValueFunc, CancellationToken cancellationToken) { var requestContext = new ModbusTransportContext() { TransactionIdentifier = GetTransactionIdentifier() }; await ModbusTransport.SendMessageAsync(requestContext, (writer) => { writer.Push(device.Address); writer.Push((byte)functionCode); writer.Push((byte)((zeroBasedOffset >> 8) & 0xFF)); writer.Push((byte)((zeroBasedOffset >> 0) & 0xFF)); writeAction(writer); }, cancellationToken); T returnedValue = default; var responseContext = await ModbusTransport.ReceiveMessageAsync( async (reader) => { if (await reader.PushByteFromStreamAsync(cancellationToken) != device.Address) { throw new InvalidOperationException(); } byte receivedFunctionCode = await reader.PushByteFromStreamAsync(cancellationToken); if (receivedFunctionCode == ((byte)functionCode | 0x80)) { var exceptionCode = (ModbusExceptionCode)await reader.PushByteFromStreamAsync(cancellationToken); throw new ModbusException(exceptionCode); } if (receivedFunctionCode != (byte)functionCode) { throw new InvalidOperationException(); } if (await reader.PushByteFromStreamAsync(cancellationToken) != zeroBasedOffset) { throw new InvalidOperationException(); } returnedValue = await readValueFunc(reader); }, cancellationToken); if (requestContext.TransactionIdentifier != responseContext.TransactionIdentifier) { throw new InvalidOperationException(); } return(returnedValue !); }