Skip to content

Commit 964d09f

Browse files
committed
RTU: Check CRC before signalling an exception response.
The first five response ADU bytes received are checked for a valid function code, assuming an error if it is unknown. The received ADU part is then treated as an exception frame. But even those must pass the CRC validation, otherwise the supposed "wrong" function code cannot even be trusted at all. This change adds the CRC check for the first five bytes, falling through to further processing when it fails. The overall CRC and function code is checked later in parse_response_adu(), so an invalid code will be detected again at that point. This is mainly relevant if the responses are received partially from the serial input buffer, which will cause many CRC and parsing failures. In those cases, the reported exception will likely be a CRCError or ValueError for the whole ADU, instead of an invalid function code based on only the first 5 bytes.
1 parent 4a818be commit 964d09f

File tree

1 file changed

+8
-1
lines changed

1 file changed

+8
-1
lines changed

umodbus/client/serial/rtu.py

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,7 @@
4545
import struct
4646

4747
from umodbus.client.serial.redundancy_check import get_crc, validate_crc
48+
from umodbus.client.serial.redundancy_check import CRCError
4849
from umodbus.functions import (create_function_from_response_pdu,
4950
expected_response_pdu_size_from_request_pdu,
5051
pdu_to_function_code_or_raise_error, ReadCoils,
@@ -199,7 +200,13 @@ def raise_for_exception_adu(resp_adu):
199200
:raises ModbusError: When a response contains an error code.
200201
"""
201202
resp_pdu = resp_adu[1:-2]
202-
pdu_to_function_code_or_raise_error(resp_pdu)
203+
try:
204+
validate_crc(resp_adu)
205+
pdu_to_function_code_or_raise_error(resp_pdu)
206+
except CRCError:
207+
# The response cannot be trusted at all, so ignore any
208+
# possibly invalid function code.
209+
pass
203210

204211

205212
def send_message(adu, serial_port):

0 commit comments

Comments
 (0)