Skip to content

Commit

Permalink
Update async code
Browse files Browse the repository at this point in the history
  • Loading branch information
Apollo3zehn committed Aug 23, 2024
1 parent 51664a6 commit 6ca7cab
Show file tree
Hide file tree
Showing 8 changed files with 72 additions and 80 deletions.
1 change: 1 addition & 0 deletions src/FluentModbus/Client/ModbusClient.cs
Original file line number Diff line number Diff line change
Expand Up @@ -206,6 +206,7 @@ public void WriteMultipleRegisters(byte unitIdentifier, ushort startingAddress,
writer.WriteReverse(startingAddress); // 08-09 Starting Address
writer.WriteReverse((ushort)quantity); // 10-11 Quantity of Registers
}

else
{
writer.Write(startingAddress); // 08-09 Starting Address
Expand Down
11 changes: 5 additions & 6 deletions src/FluentModbus/Client/ModbusClientAsync.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@

/* This is automatically translated code. */
/* This is automatically translated code. */

#pragma warning disable CS1998

Expand Down Expand Up @@ -114,13 +114,12 @@ await TransceiveFrameAsync(unitIdentifier, ModbusFunctionCode.WriteMultipleRegis
{
writer.WriteReverse(startingAddress); // 08-09 Starting Address
writer.WriteReverse((ushort)quantity); // 10-11 Quantity of Registers

}

else
{
writer.Write(startingAddress); // 08-09 Starting Address
writer.Write((ushort)quantity); // 10-11 Quantity of Registers

}

writer.Write((byte)(quantity * 2)); // 12 Byte Count = Quantity of Registers * 2
Expand Down Expand Up @@ -350,7 +349,7 @@ await TransceiveFrameAsync(unitIdentifier, ModbusFunctionCode.WriteSingleRegiste
/// <param name="startingAddress">The coil register start address for the write operation.</param>
/// <param name="values">The values to write to the server.</param>
/// <param name="cancellationToken">The token to monitor for cancellation requests. The default value is <see cref="CancellationToken.None"/>.</param>
public void WriteMultipleCoilsAsync(int unitIdentifier, int startingAddress, bool[] values, CancellationToken cancellationToken = default)
public async Task WriteMultipleCoilsAsync(int unitIdentifier, int startingAddress, bool[] values, CancellationToken cancellationToken = default)
{
var unitIdentifier_converted = ConvertUnitIdentifier(unitIdentifier);
var startingAddress_converted = ConvertUshort(startingAddress);
Expand All @@ -361,7 +360,7 @@ public void WriteMultipleCoilsAsync(int unitIdentifier, int startingAddress, boo
new BitArray(values)
.CopyTo(convertedData, 0);

TransceiveFrameAsync(unitIdentifier_converted, ModbusFunctionCode.WriteMultipleCoils, writer =>
await TransceiveFrameAsync(unitIdentifier_converted, ModbusFunctionCode.WriteMultipleCoils, writer =>
{
writer.Write((byte)ModbusFunctionCode.WriteMultipleCoils); // 07 Function Code

Expand All @@ -380,7 +379,7 @@ public void WriteMultipleCoilsAsync(int unitIdentifier, int startingAddress, boo
writer.Write((byte)byteCount); // 12 Byte Count = Outputs

writer.Write(convertedData);
}, cancellationToken);
}, cancellationToken).ConfigureAwait(false);
}

/// <summary>
Expand Down
9 changes: 6 additions & 3 deletions src/FluentModbus/Client/ModbusClientAsync.tt
Original file line number Diff line number Diff line change
Expand Up @@ -4,14 +4,17 @@
<#@ import namespace="System.Text.RegularExpressions" #>

<#
var csstring = File.ReadAllText("src/FluentModbus/Client/ModbusClient.cs");
var methodsToConvert = Regex.Matches(csstring, @" \/{3}.*?(\n }|extendFrame\);)", RegexOptions.Singleline);
var csstring = File
.ReadAllText("src/FluentModbus/Client/ModbusClient.cs")
.Replace("\r\n", "\n");

var methodsToConvert = Regex.Matches(csstring, @" \/{3}(?:.(?!\n\n))*?(?:extendFrame\);|\).*?\n })", RegexOptions.Singleline);
#>
/* This is automatically translated code. */
/* This is automatically translated code. */

#pragma warning disable CS1998

using System.Collections;
using System.Runtime.InteropServices;

namespace FluentModbus
Expand Down
23 changes: 10 additions & 13 deletions src/FluentModbus/Client/ModbusRtuClientAsync.cs
Original file line number Diff line number Diff line change
@@ -1,19 +1,15 @@

/* This is automatically translated code. */
/* This is automatically translated code. */

namespace FluentModbus
{
public partial class ModbusRtuClient
{
///<inheritdoc/>
public partial class ModbusRtuClient
{
///<inheritdoc/>
protected override async Task<Memory<byte>> TransceiveFrameAsync(byte unitIdentifier, ModbusFunctionCode functionCode, Action<ExtendedBinaryWriter> extendFrame, CancellationToken cancellationToken = default)
{
// WARNING: IF YOU EDIT THIS METHOD, REFLECT ALL CHANGES ALSO IN TransceiveFrameAsync!

int frameLength;
byte rawFunctionCode;
ushort crc;

// build request
if (!(0 <= unitIdentifier && unitIdentifier <= 247))
throw new ModbusException(ErrorMessage.ModbusClient_InvalidUnitIdentifier);
Expand All @@ -38,10 +34,11 @@ protected override async Task<Memory<byte>> TransceiveFrameAsync(byte unitIdenti
_frameBuffer.Writer.Seek(0, SeekOrigin.Begin);
_frameBuffer.Writer.Write(unitIdentifier); // 00 Unit Identifier
extendFrame(_frameBuffer.Writer);
frameLength = (int)_frameBuffer.Writer.BaseStream.Position;

var frameLength = (int)_frameBuffer.Writer.BaseStream.Position;

// add CRC
crc = ModbusUtils.CalculateCRC(_frameBuffer.Buffer.AsMemory()[..frameLength]);
var crc = ModbusUtils.CalculateCRC(_frameBuffer.Buffer.AsMemory()[..frameLength]);
_frameBuffer.Writer.Write(crc);
frameLength = (int)_frameBuffer.Writer.BaseStream.Position;

Expand Down Expand Up @@ -75,7 +72,7 @@ protected override async Task<Memory<byte>> TransceiveFrameAsync(byte unitIdenti
}

_ = _frameBuffer.Reader.ReadByte();
rawFunctionCode = _frameBuffer.Reader.ReadByte();
var rawFunctionCode = _frameBuffer.Reader.ReadByte();

if (rawFunctionCode == (byte)ModbusFunctionCode.Error + (byte)functionCode)
ProcessError(functionCode, (ModbusExceptionCode)_frameBuffer.Buffer[2]);
Expand All @@ -84,6 +81,6 @@ protected override async Task<Memory<byte>> TransceiveFrameAsync(byte unitIdenti
throw new ModbusException(ErrorMessage.ModbusClient_InvalidResponseFunctionCode);

return _frameBuffer.Buffer.AsMemory(1, frameLength - 3);
}
}
}
}
}
27 changes: 9 additions & 18 deletions src/FluentModbus/Client/ModbusRtuOverTcpClientAsync.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@

/* This is automatically translated code. */
/* This is automatically translated code. */

namespace FluentModbus
{
Expand All @@ -10,18 +10,9 @@ protected override async Task<Memory<byte>> TransceiveFrameAsync(byte unitIdenti
{
// WARNING: IF YOU EDIT THIS METHOD, REFLECT ALL CHANGES ALSO IN TransceiveFrameAsync!

int frameLength;
byte rawFunctionCode;

ModbusFrameBuffer frameBuffer;
ExtendedBinaryWriter writer;
ExtendedBinaryReader reader;

frameBuffer = _frameBuffer;
writer = _frameBuffer.Writer;
reader = _frameBuffer.Reader;

ushort crc;
var frameBuffer = _frameBuffer;
var writer = _frameBuffer.Writer;
var reader = _frameBuffer.Reader;

// build request
if (!(0 <= unitIdentifier && unitIdentifier <= 247))
Expand All @@ -47,10 +38,11 @@ protected override async Task<Memory<byte>> TransceiveFrameAsync(byte unitIdenti
writer.Seek(0, SeekOrigin.Begin);
writer.Write(unitIdentifier); // 00 Unit Identifier
extendFrame(writer);
frameLength = (int)writer.BaseStream.Position;

var frameLength = (int)writer.BaseStream.Position;

// add CRC
crc = ModbusUtils.CalculateCRC(frameBuffer.Buffer.AsMemory()[..frameLength]);
var crc = ModbusUtils.CalculateCRC(frameBuffer.Buffer.AsMemory()[..frameLength]);
writer.Write(crc);
frameLength = (int)writer.BaseStream.Position;

Expand Down Expand Up @@ -116,7 +108,7 @@ protected override async Task<Memory<byte>> TransceiveFrameAsync(byte unitIdenti
}

_ = reader.ReadByte();
rawFunctionCode = reader.ReadByte();
var rawFunctionCode = reader.ReadByte();

if (rawFunctionCode == (byte)ModbusFunctionCode.Error + (byte)functionCode)
ProcessError(functionCode, (ModbusExceptionCode)_frameBuffer.Buffer[2]);
Expand All @@ -125,7 +117,6 @@ protected override async Task<Memory<byte>> TransceiveFrameAsync(byte unitIdenti
throw new ModbusException(ErrorMessage.ModbusClient_InvalidResponseFunctionCode);

return _frameBuffer.Buffer.AsMemory(1, frameLength - 3);
}

}
}
}
4 changes: 3 additions & 1 deletion src/FluentModbus/Client/ModbusTcpClient.cs
Original file line number Diff line number Diff line change
Expand Up @@ -245,6 +245,8 @@ protected override Span<byte> TransceiveFrame(byte unitIdentifier, ModbusFunctio

while (true)
{
int partialLength;

// ASYNC-ONLY: using var timeoutCts = new CancellationTokenSource(_networkStream.ReadTimeout);
// ASYNC-ONLY:
// ASYNC-ONLY: // https://stackoverflow.com/a/62162138
Expand All @@ -254,7 +256,7 @@ protected override Span<byte> TransceiveFrame(byte unitIdentifier, ModbusFunctio
// ASYNC-ONLY: {
// ASYNC-ONLY: try
// ASYNC-ONLY: {
var partialLength = _networkStream.Read(frameBuffer.Buffer, frameLength, frameBuffer.Buffer.Length - frameLength);
partialLength = _networkStream.Read(frameBuffer.Buffer, frameLength, frameBuffer.Buffer.Length - frameLength);
// ASYNC-ONLY: }
// ASYNC-ONLY: catch (OperationCanceledException) when (cancellationToken.IsCancellationRequested)
// ASYNC-ONLY: {
Expand Down
60 changes: 25 additions & 35 deletions src/FluentModbus/Client/ModbusTcpClientAsync.cs
Original file line number Diff line number Diff line change
@@ -1,66 +1,56 @@

/* This is automatically translated code. */
/* This is automatically translated code. */

namespace FluentModbus
{
public partial class ModbusTcpClient
{
///<inheritdoc/>
public partial class ModbusTcpClient
{
///<inheritdoc/>
protected override async Task<Memory<byte>> TransceiveFrameAsync(byte unitIdentifier, ModbusFunctionCode functionCode, Action<ExtendedBinaryWriter> extendFrame, CancellationToken cancellationToken = default)
{
// WARNING: IF YOU EDIT THIS METHOD, REFLECT ALL CHANGES ALSO IN TransceiveFrameAsync!

int frameLength;
int partialLength;
ushort bytesFollowing = 0;

ushort protocolIdentifier;
ushort bytesFollowing;

byte rawFunctionCode;

bool isParsed;

ModbusFrameBuffer frameBuffer;
ExtendedBinaryWriter writer;
ExtendedBinaryReader reader;

bytesFollowing = 0;
frameBuffer = _frameBuffer;
writer = _frameBuffer.Writer;
reader = _frameBuffer.Reader;
var frameBuffer = _frameBuffer;
var writer = _frameBuffer.Writer;
var reader = _frameBuffer.Reader;

// build request
writer.Seek(7, SeekOrigin.Begin);
extendFrame(writer);
frameLength = (int)writer.BaseStream.Position;
var frameLength = (int)writer.BaseStream.Position;

writer.Seek(0, SeekOrigin.Begin);

if (BitConverter.IsLittleEndian)
{
writer.WriteReverse(GetTransactionIdentifier()); // 00-01 Transaction Identifier
writer.WriteReverse((ushort)0); // 02-03 Protocol Identifier
writer.WriteReverse((ushort)(frameLength - 6)); // 04-05 Length
writer.WriteReverse(GetTransactionIdentifier()); // 00-01 Transaction Identifier
writer.WriteReverse((ushort)0); // 02-03 Protocol Identifier
writer.WriteReverse((ushort)(frameLength - 6)); // 04-05 Length
}

else
{
writer.Write(GetTransactionIdentifier()); // 00-01 Transaction Identifier
writer.Write((ushort)0); // 02-03 Protocol Identifier
writer.Write((ushort)(frameLength - 6)); // 04-05 Length
writer.Write(GetTransactionIdentifier()); // 00-01 Transaction Identifier
writer.Write((ushort)0); // 02-03 Protocol Identifier
writer.Write((ushort)(frameLength - 6)); // 04-05 Length
}

writer.Write(unitIdentifier); // 06 Unit Identifier
writer.Write(unitIdentifier); // 06 Unit Identifier

// send request
await _networkStream.WriteAsync(frameBuffer.Buffer, 0, frameLength, cancellationToken).ConfigureAwait(false);

// wait for and process response
frameLength = 0;
isParsed = false;
var isParsed = false;
reader.BaseStream.Seek(0, SeekOrigin.Begin);

while (true)
{
int partialLength;

using var timeoutCts = new CancellationTokenSource(_networkStream.ReadTimeout);

// https://stackoverflow.com/a/62162138
Expand All @@ -70,7 +60,7 @@ protected override async Task<Memory<byte>> TransceiveFrameAsync(byte unitIdenti
{
try
{
partialLength = await _networkStream.ReadAsync(frameBuffer.Buffer, frameLength, frameBuffer.Buffer.Length - frameLength, cancellationToken).ConfigureAwait(false);
partialLength = await _networkStream.ReadAsync(frameBuffer.Buffer, frameLength, frameBuffer.Buffer.Length - frameLength, cancellationToken).ConfigureAwait(false);
}
catch (OperationCanceledException) when (cancellationToken.IsCancellationRequested)
{
Expand Down Expand Up @@ -106,7 +96,7 @@ protected override async Task<Memory<byte>> TransceiveFrameAsync(byte unitIdenti
{
// read MBAP header
_ = reader.ReadUInt16Reverse(); // 00-01 Transaction Identifier
protocolIdentifier = reader.ReadUInt16Reverse(); // 02-03 Protocol Identifier
var protocolIdentifier = reader.ReadUInt16Reverse(); // 02-03 Protocol Identifier
bytesFollowing = reader.ReadUInt16Reverse(); // 04-05 Length
_ = reader.ReadByte(); // 06 Unit Identifier

Expand All @@ -122,7 +112,7 @@ protected override async Task<Memory<byte>> TransceiveFrameAsync(byte unitIdenti
}
}

rawFunctionCode = reader.ReadByte();
var rawFunctionCode = reader.ReadByte();

if (rawFunctionCode == (byte)ModbusFunctionCode.Error + (byte)functionCode)
ProcessError(functionCode, (ModbusExceptionCode)frameBuffer.Buffer[8]);
Expand All @@ -131,6 +121,6 @@ protected override async Task<Memory<byte>> TransceiveFrameAsync(byte unitIdenti
throw new ModbusException(ErrorMessage.ModbusClient_InvalidResponseFunctionCode);

return frameBuffer.Buffer.AsMemory(7, frameLength - 7);
}
}
}
}
}
17 changes: 13 additions & 4 deletions src/FluentModbus/FluentModbus.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -39,14 +39,18 @@
<LastGenOutput>ModbusClientAsync.cs</LastGenOutput>
<Generator>TextTemplatingFileGenerator</Generator>
</None>
<None Update="Client\ModbusRtuClientAsync.tt">
<LastGenOutput>ModbusRtuClientAsync.cs</LastGenOutput>
<Generator>TextTemplatingFileGenerator</Generator>
</None>
<None Update="Client\ModbusRtuOverTcpClientAsync.tt">
<LastGenOutput>ModbusRtuOverTcpClientAsync.cs</LastGenOutput>
<Generator>TextTemplatingFileGenerator</Generator>
</None>
<None Update="Client\ModbusTcpClientAsync.tt">
<LastGenOutput>ModbusTcpClientAsync.cs</LastGenOutput>
<Generator>TextTemplatingFileGenerator</Generator>
</None>
<None Update="Client\ModbusRtuClientAsync.tt">
<LastGenOutput>ModbusRtuClientAsync.cs</LastGenOutput>
<Generator>TextTemplatingFileGenerator</Generator>
</None>
</ItemGroup>

<ItemGroup>
Expand All @@ -55,6 +59,11 @@
<AutoGen>True</AutoGen>
<DependentUpon>ModbusClientAsync.tt</DependentUpon>
</Compile>
<Compile Update="Client\ModbusRtuOverTcpClientAsync.cs">
<DesignTime>True</DesignTime>
<AutoGen>True</AutoGen>
<DependentUpon>ModbusRtuOverTcpClientAsync.tt</DependentUpon>
</Compile>
<Compile Update="Client\ModbusTcpClientAsync.cs">
<DesignTime>True</DesignTime>
<AutoGen>True</AutoGen>
Expand Down

0 comments on commit 6ca7cab

Please sign in to comment.