diff --git a/pymodbus/framer/socket_framer.py b/pymodbus/framer/socket_framer.py index cb40debda..598a2c4d2 100644 --- a/pymodbus/framer/socket_framer.py +++ b/pymodbus/framer/socket_framer.py @@ -72,47 +72,25 @@ def frameProcessIncomingPacket(self, single, callback, slave, tid=None, **kwargs The processed and decoded messages are pushed to the callback function to process and send. """ - def check_frame(self): - """Check and decode the next frame.""" - if not self._buffer: - Log.debug("Frame check, no more data!") - return False - if not len(self._buffer) >= self._hsize +1: - Log.debug("Frame check failed, short frame {} >= {} !!", len(self._buffer), self._hsize+2) - return False - ( - self._header["tid"], - self._header["pid"], - self._header["len"], - self._header["uid"], - ) = struct.unpack(">HHHB", self._buffer[0 : self._hsize]) - if self._header["len"] == 2 and len(self._buffer) >= self._hsize + 2: - self._header["len"] = 3 - if self._header["len"] < 2: - length = self._hsize + self._header["len"] -1 - self._buffer = self._buffer[length:] - self._header = {"tid": 0, "pid": 0, "len": 0, "uid": 0} - elif len(self._buffer) - self._hsize + 1 >= self._header["len"]: - return True - Log.debug("Frame check failed, missing part of message len {}, MBAP len {} !!", len(self._buffer), self._header["len"]) - return False - while True: - if not check_frame(self): - return + used_len, use_tid, dev_id, data = self.message_handler.decode(self._buffer) + if not data: + if not used_len: + return + self._buffer = self._buffer[used_len :] + continue + self._header["uid"] = dev_id + self._header["tid"] = use_tid + self._header["pid"] = 0 if not self._validate_slave_id(slave, single): - header_txt = self._header["uid"] - Log.debug("Not a valid slave id - {}, ignoring!!", header_txt) + Log.debug("Not a valid slave id - {}, ignoring!!", dev_id) self.resetFrame() return - length = self._hsize + self._header["len"] -1 - data = self._buffer[self._hsize : length] if (result := self.decoder.decode(data)) is None: self.resetFrame() raise ModbusIOException("Unable to decode request") self.populateResult(result) - length = self._hsize + self._header["len"] -1 - self._buffer = self._buffer[length:] + self._buffer = self._buffer[used_len:] self._header = {"tid": 0, "pid": 0, "len": 0, "uid": 0} if tid and tid != result.transaction_id: self.resetFrame() diff --git a/pymodbus/framer/tls_framer.py b/pymodbus/framer/tls_framer.py index 8a8924012..5b88c1e34 100644 --- a/pymodbus/framer/tls_framer.py +++ b/pymodbus/framer/tls_framer.py @@ -35,7 +35,7 @@ def __init__(self, decoder, client=None): """ super().__init__(decoder, client) self._hsize = 0x0 - self.message_encoder = MessageTLS([0], True) + self.message_handler = MessageTLS([0], True) def decode_data(self, data): """Decode data.""" @@ -47,32 +47,28 @@ def decode_data(self, data): def frameProcessIncomingPacket(self, single, callback, slave, _tid=None, **kwargs): """Process new packet pattern.""" # no slave id for Modbus Security Application Protocol - def check_frame(self): - """Check and decode the next frame.""" - if len(self._buffer) > self._hsize: - # we have at least a complete message, continue - if len(self._buffer) - self._hsize >= 1: - return True - # we don't have enough of a message yet, wait - return False - - if not len(self._buffer) > self._hsize: - return - if not check_frame(self): - Log.debug("Frame check failed, ignoring!!") - self.resetFrame() - return - if not self._validate_slave_id(slave, single): - Log.debug("Not in valid slave id - {}, ignoring!!", slave) - self.resetFrame() - return - data = self._buffer[self._hsize :] - if (result := self.decoder.decode(data)) is None: - raise ModbusIOException("Unable to decode request") - self.populateResult(result) - self._buffer = b"" - self._header = {} - callback(result) # defer or push to a thread? + + while True: + used_len, use_tid, dev_id, data = self.message_handler.decode(self._buffer) + if not data: + if not used_len: + return + self._buffer = self._buffer[used_len :] + continue + self._header["uid"] = dev_id + self._header["tid"] = use_tid + self._header["pid"] = 0 + + if not self._validate_slave_id(slave, single): + Log.debug("Not in valid slave id - {}, ignoring!!", slave) + self.resetFrame() + return + if (result := self.decoder.decode(data)) is None: + raise ModbusIOException("Unable to decode request") + self.populateResult(result) + self._buffer = b"" + self._header = {} + callback(result) # defer or push to a thread? def buildPacket(self, message): """Create a ready to send modbus packet. @@ -80,5 +76,5 @@ def buildPacket(self, message): :param message: The populated request/response to send """ data = message.function_code.to_bytes(1,'big') + message.encode() - packet = self.message_encoder.encode(data, message.slave_id, message.transaction_id) + packet = self.message_handler.encode(data, message.slave_id, message.transaction_id) return packet