Skip to content

Commit 1cfc681

Browse files
committed
SOCKET/TLS framer using message decode(). (#2129)
1 parent b187401 commit 1cfc681

File tree

2 files changed

+35
-61
lines changed

2 files changed

+35
-61
lines changed

pymodbus/framer/socket_framer.py

Lines changed: 11 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -72,47 +72,25 @@ def frameProcessIncomingPacket(self, single, callback, slave, tid=None, **kwargs
7272
The processed and decoded messages are pushed to the callback
7373
function to process and send.
7474
"""
75-
def check_frame(self):
76-
"""Check and decode the next frame."""
77-
if not self._buffer:
78-
Log.debug("Frame check, no more data!")
79-
return False
80-
if not len(self._buffer) >= self._hsize +1:
81-
Log.debug("Frame check failed, short frame {} >= {} !!", len(self._buffer), self._hsize+2)
82-
return False
83-
(
84-
self._header["tid"],
85-
self._header["pid"],
86-
self._header["len"],
87-
self._header["uid"],
88-
) = struct.unpack(">HHHB", self._buffer[0 : self._hsize])
89-
if self._header["len"] == 2 and len(self._buffer) >= self._hsize + 2:
90-
self._header["len"] = 3
91-
if self._header["len"] < 2:
92-
length = self._hsize + self._header["len"] -1
93-
self._buffer = self._buffer[length:]
94-
self._header = {"tid": 0, "pid": 0, "len": 0, "uid": 0}
95-
elif len(self._buffer) - self._hsize + 1 >= self._header["len"]:
96-
return True
97-
Log.debug("Frame check failed, missing part of message len {}, MBAP len {} !!", len(self._buffer), self._header["len"])
98-
return False
99-
10075
while True:
101-
if not check_frame(self):
102-
return
76+
used_len, use_tid, dev_id, data = self.message_handler.decode(self._buffer)
77+
if not data:
78+
if not used_len:
79+
return
80+
self._buffer = self._buffer[used_len :]
81+
continue
82+
self._header["uid"] = dev_id
83+
self._header["tid"] = use_tid
84+
self._header["pid"] = 0
10385
if not self._validate_slave_id(slave, single):
104-
header_txt = self._header["uid"]
105-
Log.debug("Not a valid slave id - {}, ignoring!!", header_txt)
86+
Log.debug("Not a valid slave id - {}, ignoring!!", dev_id)
10687
self.resetFrame()
10788
return
108-
length = self._hsize + self._header["len"] -1
109-
data = self._buffer[self._hsize : length]
11089
if (result := self.decoder.decode(data)) is None:
11190
self.resetFrame()
11291
raise ModbusIOException("Unable to decode request")
11392
self.populateResult(result)
114-
length = self._hsize + self._header["len"] -1
115-
self._buffer = self._buffer[length:]
93+
self._buffer = self._buffer[used_len:]
11694
self._header = {"tid": 0, "pid": 0, "len": 0, "uid": 0}
11795
if tid and tid != result.transaction_id:
11896
self.resetFrame()

pymodbus/framer/tls_framer.py

Lines changed: 24 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ def __init__(self, decoder, client=None):
3535
"""
3636
super().__init__(decoder, client)
3737
self._hsize = 0x0
38-
self.message_encoder = MessageTLS([0], True)
38+
self.message_handler = MessageTLS([0], True)
3939

4040
def decode_data(self, data):
4141
"""Decode data."""
@@ -47,38 +47,34 @@ def decode_data(self, data):
4747
def frameProcessIncomingPacket(self, single, callback, slave, _tid=None, **kwargs):
4848
"""Process new packet pattern."""
4949
# no slave id for Modbus Security Application Protocol
50-
def check_frame(self):
51-
"""Check and decode the next frame."""
52-
if len(self._buffer) > self._hsize:
53-
# we have at least a complete message, continue
54-
if len(self._buffer) - self._hsize >= 1:
55-
return True
56-
# we don't have enough of a message yet, wait
57-
return False
58-
59-
if not len(self._buffer) > self._hsize:
60-
return
61-
if not check_frame(self):
62-
Log.debug("Frame check failed, ignoring!!")
63-
self.resetFrame()
64-
return
65-
if not self._validate_slave_id(slave, single):
66-
Log.debug("Not in valid slave id - {}, ignoring!!", slave)
67-
self.resetFrame()
68-
return
69-
data = self._buffer[self._hsize :]
70-
if (result := self.decoder.decode(data)) is None:
71-
raise ModbusIOException("Unable to decode request")
72-
self.populateResult(result)
73-
self._buffer = b""
74-
self._header = {}
75-
callback(result) # defer or push to a thread?
50+
51+
while True:
52+
used_len, use_tid, dev_id, data = self.message_handler.decode(self._buffer)
53+
if not data:
54+
if not used_len:
55+
return
56+
self._buffer = self._buffer[used_len :]
57+
continue
58+
self._header["uid"] = dev_id
59+
self._header["tid"] = use_tid
60+
self._header["pid"] = 0
61+
62+
if not self._validate_slave_id(slave, single):
63+
Log.debug("Not in valid slave id - {}, ignoring!!", slave)
64+
self.resetFrame()
65+
return
66+
if (result := self.decoder.decode(data)) is None:
67+
raise ModbusIOException("Unable to decode request")
68+
self.populateResult(result)
69+
self._buffer = b""
70+
self._header = {}
71+
callback(result) # defer or push to a thread?
7672

7773
def buildPacket(self, message):
7874
"""Create a ready to send modbus packet.
7975
8076
:param message: The populated request/response to send
8177
"""
8278
data = message.function_code.to_bytes(1,'big') + message.encode()
83-
packet = self.message_encoder.encode(data, message.slave_id, message.transaction_id)
79+
packet = self.message_handler.encode(data, message.slave_id, message.transaction_id)
8480
return packet

0 commit comments

Comments
 (0)