Apollo3zehn / FluentModbus

Lightweight and fast client and server implementation of the Modbus protocol (TCP/RTU).
MIT License
188 stars 69 forks source link

Unit ID in TCP? #84

Closed maxreb closed 1 year ago

maxreb commented 1 year ago

I got a tool called GridVis which tries to connect to the server, but it fails with the error message:

Modbus-Antwort enthält Falsche ID für Einheit

which means translated:

Modbus Response Contains Wrong Unit ID

I am not that expert in Modbus, but I always thought that the Unit ID isn't needed for TCP/IP (as it uses the IP as identifier) so it seems like there is a bug in the other Software. But is there a possibility to respond with the unit ID the client wants?

Apollo3zehn commented 1 year ago

The Modbus TCP spec says to the unit identifer:

The MODBUS ‘slave address’ field usually used on MODBUS Serial Line is replaced by a single byte ‘Unit Identifier’ within the MBAP Header. The ‘Unit Identifier’ is used to communicate via devices such as bridges, routers and gateways that use a single IP address to support multiple independent MODBUS end units.

Regarding the value of the Unit identifier, the spec says:

grafik

So 0x00 and 0xFF both are acceptable values.

By default, the Modbus TCP server has a list of unit identifiers with a single entry equal to 0 and it also always returns 0 in response (https://github.com/Apollo3zehn/FluentModbus/blob/master/src/FluentModbus/Server/ModbusTcpRequestHandler.cs).

You have the option to derive from the original ModbusTcpServer and implement your own which supports unit identifiers other than 0. The following links show a sample implementation where the important bits are

1) handleUnitIdentifiers: true: https://github.com/Apollo3zehn/FluentModbus/blob/40b6a56c98ad78e595964f585b82b060a44f4522/tests/FluentModbus.Tests/Support/SimpleMultiUnitTcpServer.cs#L30

2) Call AddUnit() to add the desired unit identifier: https://github.com/Apollo3zehn/FluentModbus/blob/40b6a56c98ad78e595964f585b82b060a44f4522/tests/FluentModbus.Tests/Support/SimpleMultiUnitTcpServer.cs#L49

However, I am a little confused now: What I see in the code is that by default only the unit identifer = 0 is accepted and also only that unit identifier is returned because handleUnitIdentifiers = false: https://github.com/Apollo3zehn/FluentModbus/blob/40b6a56c98ad78e595964f585b82b060a44f4522/src/FluentModbus/Server/ModbusTcpRequestHandler.cs#L23

So your applications sends a 0 and gets a 0 in response and complains. That really looks like a bug. To be able to really help you I need to know which unit identifier your applications actually expects (maybe 0xFF?).

maxreb commented 1 year ago

Mhh you are right, this is really strange. Thank you so much for your investigation. I will contact the vendor and will close this issue for now. If I, after further investigation, should find out that there is a issue with this repository I will reopen it. Thanks again!