Skip to content

Commit 5cb3d52

Browse files
committed
Raise exception for unexpected slave or function code in response.
For RTU links, the specification (section 2.4.1) says the following: "When a reply is received, the Master checks the reply before starting the data processing. The checking may result in an error, for example a reply from an unexpected slave, or an error in the received frame." Technically, such frame errors include a mismatch in the response CRC or slave address. The CRC is handled by uModbus, but the slave address is not checked. If the function code does not match the request, uModbus will also happily parse it and return data which is valid, but unrelated to the application's request. The latter two should be regarded as a failure in send_message() as well, which this change does by throwing a specific exception. The standard goes on to specify that the "Response time-out" should be kept running if a response comes from the wrong slave. However, no such mechanism exists in uModbus yet (relying on the serial port RX timeout). This simple approach does not fix that inconsistency with the spec, but still allows better error handling in the application.
1 parent f1128a7 commit 5cb3d52

File tree

2 files changed

+11
-0
lines changed

2 files changed

+11
-0
lines changed

umodbus/client/serial/rtu.py

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,7 @@
5353
WriteSingleRegister, WriteMultipleCoils,
5454
WriteMultipleRegisters)
5555
from umodbus.utils import recv_exactly
56+
from umodbus.exceptions import ModbusFrameError
5657

5758

5859
def _create_request_adu(slave_id, req_pdu):
@@ -217,6 +218,10 @@ def send_message(adu, serial_port):
217218
response_error_adu = recv_exactly(serial_port.read, exception_adu_size)
218219
raise_for_exception_adu(response_error_adu)
219220

221+
if response_error_adu[0:2] != adu[0:2]:
222+
# Mismatch in response's slave address or function code
223+
raise ModbusFrameError(response_error_adu)
224+
220225
expected_response_size = \
221226
expected_response_pdu_size_from_request_pdu(adu[1:-2]) + 3
222227
response_remainder = recv_exactly(

umodbus/exceptions.py

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,12 @@ class ModbusError(Exception):
33
pass
44

55

6+
class ModbusFrameError(ModbusError):
7+
"""Reply from an unexpected slave, or an error in the received frame."""
8+
9+
pass
10+
11+
612
class IllegalFunctionError(ModbusError):
713
""" The function code received in the request is not an allowable action for
814
the server.

0 commit comments

Comments
 (0)