Skip to content

Commit 4334930

Browse files
authored
Client more robust against faulty response. (#1547)
1 parent d347bc8 commit 4334930

File tree

3 files changed

+41
-0
lines changed

3 files changed

+41
-0
lines changed

pymodbus/framer/socket_framer.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -176,6 +176,7 @@ def _process(self, callback, tid, error=False):
176176
"""Process incoming packets irrespective error condition."""
177177
data = self.getRawFrame() if error else self.getFrame()
178178
if (result := self.decoder.decode(data)) is None:
179+
self.resetFrame()
179180
raise ModbusIOException("Unable to decode request")
180181
if error and result.function_code < 0x80:
181182
raise InvalidMessageReceivedException(result)
Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
"""Test server working as slave on a multidrop RS485 line."""
2+
from unittest import mock
3+
4+
import pytest
5+
6+
from pymodbus.exceptions import ModbusIOException
7+
from pymodbus.factory import ClientDecoder
8+
from pymodbus.framer import ModbusSocketFramer
9+
10+
11+
class TestFaultyResponses:
12+
"""Test that server works on a multidrop line."""
13+
14+
slaves = [0]
15+
16+
good_frame = b"\x00\x01\x00\x00\x00\x05\x00\x03\x02\x00\x01"
17+
18+
@pytest.fixture(name="framer")
19+
def fixture_framer(self):
20+
"""Prepare framer."""
21+
return ModbusSocketFramer(ClientDecoder())
22+
23+
@pytest.fixture(name="callback")
24+
def fixture_callback(self):
25+
"""Prepare dummy callback."""
26+
return mock.Mock()
27+
28+
def test_ok_frame(self, framer, callback):
29+
"""Test ok frame."""
30+
framer.processIncomingPacket(self.good_frame, callback, self.slaves)
31+
callback.assert_called_once()
32+
33+
def test_faulty_frame1(self, framer, callback):
34+
"""Test ok frame."""
35+
faulty_frame = b"\x00\x04\x00\x00\x00\x05\x00\x03\x0a\x00\x04"
36+
with pytest.raises(ModbusIOException):
37+
framer.processIncomingPacket(faulty_frame, callback, self.slaves)
38+
callback.assert_not_called()
39+
framer.processIncomingPacket(self.good_frame, callback, self.slaves)
40+
callback.assert_called_once()

0 commit comments

Comments
 (0)