feat(modbus-rtu): Modbus RTU-over-TCP transport (Wave 1) #495

Open
dohertj2 wants to merge 15 commits from feat/modbus-rtu-driver into master
3 changed files with 16 additions and 4 deletions
Showing only changes of commit fcc7ed698e - Show all commits
@@ -105,8 +105,9 @@ public static class ModbusRtuFraming
}
else
{
// Write-echo response (FC 05/06/15/16) or any other length-less fixed shape:
// fixed 4 payload bytes + CRC(2).
// Fixed 4-byte echo: correct for the write FCs this driver emits (05/06/0F/10). A future
// variable-length response FC outside 01-04 (e.g. FC23) would be mis-sized here and
// surface as a desync — revisit the FC-shape table if the driver starts emitting one.
trailing = 4 + 2;
}
@@ -16,7 +16,11 @@ public static class ModbusTransportFactory
/// </summary>
/// <param name="options">Driver configuration options.</param>
/// <returns>A <see cref="ModbusRtuOverTcpTransport"/> when <see cref="ModbusTransportMode.RtuOverTcp"/>
/// is selected; otherwise a <see cref="ModbusTcpTransport"/> (also the default/unrecognized fallback).</returns>
/// is selected; a <see cref="ModbusTcpTransport"/> when <see cref="ModbusTransportMode.Tcp"/> is selected.</returns>
/// <exception cref="ArgumentOutOfRangeException">
/// <paramref name="options"/>.<see cref="ModbusDriverOptions.Transport"/> is not a recognized
/// <see cref="ModbusTransportMode"/> member — fail loudly rather than silently falling back to TCP/MBAP.
/// </exception>
public static IModbusTransport Create(ModbusDriverOptions options)
{
ArgumentNullException.ThrowIfNull(options);
@@ -27,11 +31,13 @@ public static class ModbusTransportFactory
keepAlive: options.KeepAlive,
idleDisconnect: options.IdleDisconnectTimeout,
reconnect: options.Reconnect),
_ => new ModbusTcpTransport(
ModbusTransportMode.Tcp => new ModbusTcpTransport(
options.Host, options.Port, options.Timeout, options.AutoReconnect,
keepAlive: options.KeepAlive,
idleDisconnect: options.IdleDisconnectTimeout,
reconnect: options.Reconnect),
_ => throw new ArgumentOutOfRangeException(
nameof(options), options.Transport, "Unknown Modbus transport mode."),
};
}
}
@@ -19,4 +19,9 @@ public sealed class ModbusTransportFactoryTests
public void Default_options_build_tcp_transport()
=> ModbusTransportFactory.Create(new ModbusDriverOptions())
.ShouldBeOfType<ModbusTcpTransport>();
[Fact]
public void Unknown_transport_mode_throws()
=> Should.Throw<ArgumentOutOfRangeException>(
() => ModbusTransportFactory.Create(new ModbusDriverOptions { Transport = (ModbusTransportMode)999 }));
}