Fixed wrong 'following bytes' information in TCP proxy
This commit is contained in:
@@ -1,9 +1,9 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Threading.Tasks;
|
|
||||||
using System.Threading;
|
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
|
using System.Threading;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
namespace AMWD.Protocols.Modbus.Common.Contracts
|
namespace AMWD.Protocols.Modbus.Common.Contracts
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -1,6 +1,8 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Diagnostics.CodeAnalysis;
|
using System.Diagnostics.CodeAnalysis;
|
||||||
|
#if !NET8_0_OR_GREATER
|
||||||
using System.Runtime.Serialization;
|
using System.Runtime.Serialization;
|
||||||
|
#endif
|
||||||
|
|
||||||
namespace AMWD.Protocols.Modbus.Common
|
namespace AMWD.Protocols.Modbus.Common
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -1,4 +1,6 @@
|
|||||||
using System;
|
#if NET6_0_OR_GREATER
|
||||||
|
using System;
|
||||||
|
#endif
|
||||||
|
|
||||||
namespace AMWD.Protocols.Modbus.Common
|
namespace AMWD.Protocols.Modbus.Common
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -10,7 +10,9 @@ namespace AMWD.Protocols.Modbus.Common.Protocols
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
/// <remarks>
|
/// <remarks>
|
||||||
/// The Modbus RTU over Modbus TCP is rarely used.
|
/// The Modbus RTU over Modbus TCP is rarely used.
|
||||||
/// It is a non-standard variant of Modbus TCP that includes wrapps a Modbus RTU message within a Modbus TCP message.
|
/// It is a non-standard variant:
|
||||||
|
/// You can define it as RTU message with an additional TCP header
|
||||||
|
/// or as TCP message with an additional CRC16 checksum at the end (header not included!).
|
||||||
/// <br/>
|
/// <br/>
|
||||||
/// Definition found on <see href="https://www.fernhillsoftware.com/help/drivers/modbus/modbus-protocol.html">Fernhill Software</see>.
|
/// Definition found on <see href="https://www.fernhillsoftware.com/help/drivers/modbus/modbus-protocol.html">Fernhill Software</see>.
|
||||||
/// </remarks>
|
/// </remarks>
|
||||||
|
|||||||
@@ -370,7 +370,7 @@ namespace AMWD.Protocols.Modbus.Proxy
|
|||||||
responseBytes.Add((byte)ModbusErrorCode.SlaveDeviceFailure);
|
responseBytes.Add((byte)ModbusErrorCode.SlaveDeviceFailure);
|
||||||
}
|
}
|
||||||
|
|
||||||
return [.. responseBytes];
|
return ReturnResponse(responseBytes);
|
||||||
}
|
}
|
||||||
|
|
||||||
private async Task<byte[]> HandleReadDiscreteInputsAsync(byte[] requestBytes, CancellationToken cancellationToken)
|
private async Task<byte[]> HandleReadDiscreteInputsAsync(byte[] requestBytes, CancellationToken cancellationToken)
|
||||||
@@ -409,7 +409,7 @@ namespace AMWD.Protocols.Modbus.Proxy
|
|||||||
responseBytes.Add((byte)ModbusErrorCode.SlaveDeviceFailure);
|
responseBytes.Add((byte)ModbusErrorCode.SlaveDeviceFailure);
|
||||||
}
|
}
|
||||||
|
|
||||||
return [.. responseBytes];
|
return ReturnResponse(responseBytes);
|
||||||
}
|
}
|
||||||
|
|
||||||
private async Task<byte[]> HandleReadHoldingRegistersAsync(byte[] requestBytes, CancellationToken cancellationToken)
|
private async Task<byte[]> HandleReadHoldingRegistersAsync(byte[] requestBytes, CancellationToken cancellationToken)
|
||||||
@@ -443,7 +443,7 @@ namespace AMWD.Protocols.Modbus.Proxy
|
|||||||
responseBytes.Add((byte)ModbusErrorCode.SlaveDeviceFailure);
|
responseBytes.Add((byte)ModbusErrorCode.SlaveDeviceFailure);
|
||||||
}
|
}
|
||||||
|
|
||||||
return [.. responseBytes];
|
return ReturnResponse(responseBytes);
|
||||||
}
|
}
|
||||||
|
|
||||||
private async Task<byte[]> HandleReadInputRegistersAsync(byte[] requestBytes, CancellationToken cancellationToken)
|
private async Task<byte[]> HandleReadInputRegistersAsync(byte[] requestBytes, CancellationToken cancellationToken)
|
||||||
@@ -477,7 +477,7 @@ namespace AMWD.Protocols.Modbus.Proxy
|
|||||||
responseBytes.Add((byte)ModbusErrorCode.SlaveDeviceFailure);
|
responseBytes.Add((byte)ModbusErrorCode.SlaveDeviceFailure);
|
||||||
}
|
}
|
||||||
|
|
||||||
return [.. responseBytes];
|
return ReturnResponse(responseBytes);
|
||||||
}
|
}
|
||||||
|
|
||||||
private async Task<byte[]> HandleWriteSingleCoilAsync(byte[] requestBytes, CancellationToken cancellationToken)
|
private async Task<byte[]> HandleWriteSingleCoilAsync(byte[] requestBytes, CancellationToken cancellationToken)
|
||||||
@@ -494,7 +494,8 @@ namespace AMWD.Protocols.Modbus.Proxy
|
|||||||
{
|
{
|
||||||
responseBytes[7] |= 0x80;
|
responseBytes[7] |= 0x80;
|
||||||
responseBytes.Add((byte)ModbusErrorCode.IllegalDataValue);
|
responseBytes.Add((byte)ModbusErrorCode.IllegalDataValue);
|
||||||
return [.. responseBytes];
|
|
||||||
|
return ReturnResponse(responseBytes);
|
||||||
}
|
}
|
||||||
|
|
||||||
try
|
try
|
||||||
@@ -524,7 +525,7 @@ namespace AMWD.Protocols.Modbus.Proxy
|
|||||||
responseBytes.Add((byte)ModbusErrorCode.SlaveDeviceFailure);
|
responseBytes.Add((byte)ModbusErrorCode.SlaveDeviceFailure);
|
||||||
}
|
}
|
||||||
|
|
||||||
return [.. responseBytes];
|
return ReturnResponse(responseBytes);
|
||||||
}
|
}
|
||||||
|
|
||||||
private async Task<byte[]> HandleWriteSingleRegisterAsync(byte[] requestBytes, CancellationToken cancellationToken)
|
private async Task<byte[]> HandleWriteSingleRegisterAsync(byte[] requestBytes, CancellationToken cancellationToken)
|
||||||
@@ -564,7 +565,7 @@ namespace AMWD.Protocols.Modbus.Proxy
|
|||||||
responseBytes.Add((byte)ModbusErrorCode.SlaveDeviceFailure);
|
responseBytes.Add((byte)ModbusErrorCode.SlaveDeviceFailure);
|
||||||
}
|
}
|
||||||
|
|
||||||
return [.. responseBytes];
|
return ReturnResponse(responseBytes);
|
||||||
}
|
}
|
||||||
|
|
||||||
private async Task<byte[]> HandleWriteMultipleCoilsAsync(byte[] requestBytes, CancellationToken cancellationToken)
|
private async Task<byte[]> HandleWriteMultipleCoilsAsync(byte[] requestBytes, CancellationToken cancellationToken)
|
||||||
@@ -583,7 +584,8 @@ namespace AMWD.Protocols.Modbus.Proxy
|
|||||||
{
|
{
|
||||||
responseBytes[7] |= 0x80;
|
responseBytes[7] |= 0x80;
|
||||||
responseBytes.Add((byte)ModbusErrorCode.IllegalDataValue);
|
responseBytes.Add((byte)ModbusErrorCode.IllegalDataValue);
|
||||||
return [.. responseBytes];
|
|
||||||
|
return ReturnResponse(responseBytes);
|
||||||
}
|
}
|
||||||
|
|
||||||
try
|
try
|
||||||
@@ -623,7 +625,7 @@ namespace AMWD.Protocols.Modbus.Proxy
|
|||||||
responseBytes.Add((byte)ModbusErrorCode.SlaveDeviceFailure);
|
responseBytes.Add((byte)ModbusErrorCode.SlaveDeviceFailure);
|
||||||
}
|
}
|
||||||
|
|
||||||
return [.. responseBytes];
|
return ReturnResponse(responseBytes);
|
||||||
}
|
}
|
||||||
|
|
||||||
private async Task<byte[]> HandleWriteMultipleRegistersAsync(byte[] requestBytes, CancellationToken cancellationToken)
|
private async Task<byte[]> HandleWriteMultipleRegistersAsync(byte[] requestBytes, CancellationToken cancellationToken)
|
||||||
@@ -642,7 +644,8 @@ namespace AMWD.Protocols.Modbus.Proxy
|
|||||||
{
|
{
|
||||||
responseBytes[7] |= 0x80;
|
responseBytes[7] |= 0x80;
|
||||||
responseBytes.Add((byte)ModbusErrorCode.IllegalDataValue);
|
responseBytes.Add((byte)ModbusErrorCode.IllegalDataValue);
|
||||||
return [.. responseBytes];
|
|
||||||
|
return ReturnResponse(responseBytes);
|
||||||
}
|
}
|
||||||
|
|
||||||
try
|
try
|
||||||
@@ -679,7 +682,7 @@ namespace AMWD.Protocols.Modbus.Proxy
|
|||||||
responseBytes.Add((byte)ModbusErrorCode.SlaveDeviceFailure);
|
responseBytes.Add((byte)ModbusErrorCode.SlaveDeviceFailure);
|
||||||
}
|
}
|
||||||
|
|
||||||
return [.. responseBytes];
|
return ReturnResponse(responseBytes);
|
||||||
}
|
}
|
||||||
|
|
||||||
private async Task<byte[]> HandleEncapsulatedInterfaceAsync(byte[] requestBytes, CancellationToken cancellationToken)
|
private async Task<byte[]> HandleEncapsulatedInterfaceAsync(byte[] requestBytes, CancellationToken cancellationToken)
|
||||||
@@ -691,7 +694,8 @@ namespace AMWD.Protocols.Modbus.Proxy
|
|||||||
{
|
{
|
||||||
responseBytes[7] |= 0x80;
|
responseBytes[7] |= 0x80;
|
||||||
responseBytes.Add((byte)ModbusErrorCode.IllegalFunction);
|
responseBytes.Add((byte)ModbusErrorCode.IllegalFunction);
|
||||||
return [.. responseBytes];
|
|
||||||
|
return ReturnResponse(responseBytes);
|
||||||
}
|
}
|
||||||
|
|
||||||
var firstObject = (ModbusDeviceIdentificationObject)requestBytes[10];
|
var firstObject = (ModbusDeviceIdentificationObject)requestBytes[10];
|
||||||
@@ -699,7 +703,8 @@ namespace AMWD.Protocols.Modbus.Proxy
|
|||||||
{
|
{
|
||||||
responseBytes[7] |= 0x80;
|
responseBytes[7] |= 0x80;
|
||||||
responseBytes.Add((byte)ModbusErrorCode.IllegalDataAddress);
|
responseBytes.Add((byte)ModbusErrorCode.IllegalDataAddress);
|
||||||
return [.. responseBytes];
|
|
||||||
|
return ReturnResponse(responseBytes);
|
||||||
}
|
}
|
||||||
|
|
||||||
var category = (ModbusDeviceIdentificationCategory)requestBytes[9];
|
var category = (ModbusDeviceIdentificationCategory)requestBytes[9];
|
||||||
@@ -707,7 +712,8 @@ namespace AMWD.Protocols.Modbus.Proxy
|
|||||||
{
|
{
|
||||||
responseBytes[7] |= 0x80;
|
responseBytes[7] |= 0x80;
|
||||||
responseBytes.Add((byte)ModbusErrorCode.IllegalDataValue);
|
responseBytes.Add((byte)ModbusErrorCode.IllegalDataValue);
|
||||||
return [.. responseBytes];
|
|
||||||
|
return ReturnResponse(responseBytes);
|
||||||
}
|
}
|
||||||
|
|
||||||
try
|
try
|
||||||
@@ -764,7 +770,8 @@ namespace AMWD.Protocols.Modbus.Proxy
|
|||||||
|
|
||||||
bodyBytes[5] = numberOfObjects;
|
bodyBytes[5] = numberOfObjects;
|
||||||
responseBytes.AddRange(bodyBytes);
|
responseBytes.AddRange(bodyBytes);
|
||||||
return [.. responseBytes];
|
|
||||||
|
return ReturnResponse(responseBytes);
|
||||||
}
|
}
|
||||||
|
|
||||||
bodyBytes.AddRange(objBytes);
|
bodyBytes.AddRange(objBytes);
|
||||||
@@ -773,13 +780,15 @@ namespace AMWD.Protocols.Modbus.Proxy
|
|||||||
|
|
||||||
bodyBytes[5] = numberOfObjects;
|
bodyBytes[5] = numberOfObjects;
|
||||||
responseBytes.AddRange(bodyBytes);
|
responseBytes.AddRange(bodyBytes);
|
||||||
return [.. responseBytes];
|
|
||||||
|
return ReturnResponse(responseBytes);
|
||||||
}
|
}
|
||||||
catch
|
catch
|
||||||
{
|
{
|
||||||
responseBytes[7] |= 0x80;
|
responseBytes[7] |= 0x80;
|
||||||
responseBytes.Add((byte)ModbusErrorCode.SlaveDeviceFailure);
|
responseBytes.Add((byte)ModbusErrorCode.SlaveDeviceFailure);
|
||||||
return [.. responseBytes];
|
|
||||||
|
return ReturnResponse(responseBytes);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -863,6 +872,16 @@ namespace AMWD.Protocols.Modbus.Proxy
|
|||||||
return [.. result];
|
return [.. result];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static byte[] ReturnResponse(List<byte> response)
|
||||||
|
{
|
||||||
|
ushort followingBytes = (ushort)(response.Count - 6);
|
||||||
|
byte[] bytes = followingBytes.ToBigEndianBytes();
|
||||||
|
response[4] = bytes[0];
|
||||||
|
response[5] = bytes[1];
|
||||||
|
|
||||||
|
return [.. response];
|
||||||
|
}
|
||||||
|
|
||||||
#endregion Request Handling
|
#endregion Request Handling
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -107,9 +107,7 @@ namespace AMWD.Protocols.Modbus.Serial
|
|||||||
set => _serialPort.PortName = value;
|
set => _serialPort.PortName = value;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <inheritdoc cref="SerialPort.BaudRate" />
|
||||||
/// Gets or sets the serial baud rate.
|
|
||||||
/// </summary>
|
|
||||||
public virtual BaudRate BaudRate
|
public virtual BaudRate BaudRate
|
||||||
{
|
{
|
||||||
get => (BaudRate)_serialPort.BaudRate;
|
get => (BaudRate)_serialPort.BaudRate;
|
||||||
@@ -118,7 +116,11 @@ namespace AMWD.Protocols.Modbus.Serial
|
|||||||
|
|
||||||
/// <inheritdoc cref="SerialPort.DataBits" />
|
/// <inheritdoc cref="SerialPort.DataBits" />
|
||||||
/// <remarks>
|
/// <remarks>
|
||||||
/// Should be 7 for ASCII mode and 8 for RTU mode.
|
/// From the Specs:
|
||||||
|
/// <br/>
|
||||||
|
/// On <see cref="AsciiProtocol"/> it can be 7 or 8.
|
||||||
|
/// <br/>
|
||||||
|
/// On <see cref="RtuProtocol"/> it has to be 8.
|
||||||
/// </remarks>
|
/// </remarks>
|
||||||
public virtual int DataBits
|
public virtual int DataBits
|
||||||
{
|
{
|
||||||
@@ -159,9 +161,9 @@ namespace AMWD.Protocols.Modbus.Serial
|
|||||||
/// <remarks>
|
/// <remarks>
|
||||||
/// From the Specs:
|
/// From the Specs:
|
||||||
/// <br/>
|
/// <br/>
|
||||||
/// Should be <see cref="StopBits.One"/> for <see cref="Parity.Even"/> or <see cref="Parity.Odd"/> and
|
/// Should be <see cref="StopBits.One"/> for <see cref="Parity.Even"/> or <see cref="Parity.Odd"/>.
|
||||||
/// <br/>
|
/// <br/>
|
||||||
/// should be <see cref="StopBits.Two"/> for <see cref="Parity.None"/>.
|
/// Should be <see cref="StopBits.Two"/> for <see cref="Parity.None"/>.
|
||||||
/// </remarks>
|
/// </remarks>
|
||||||
public virtual StopBits StopBits
|
public virtual StopBits StopBits
|
||||||
{
|
{
|
||||||
@@ -188,7 +190,6 @@ namespace AMWD.Protocols.Modbus.Serial
|
|||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
_processingTask.Wait();
|
|
||||||
_processingTask.Dispose();
|
_processingTask.Dispose();
|
||||||
}
|
}
|
||||||
catch
|
catch
|
||||||
|
|||||||
@@ -11,6 +11,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|||||||
|
|
||||||
- The `ModbusTcpProxy.ReadWriteTimeout` has a default value of 100 seconds (same default as a `HttpClient` has).
|
- The `ModbusTcpProxy.ReadWriteTimeout` has a default value of 100 seconds (same default as a `HttpClient` has).
|
||||||
|
|
||||||
|
### Fixed
|
||||||
|
|
||||||
|
- Wrong _following bytes_ calculation in `ModbusTcpProxy`.
|
||||||
|
|
||||||
|
|
||||||
## [v0.3.2] (2024-09-04)
|
## [v0.3.2] (2024-09-04)
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user