You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@plc4x.apache.org by hu...@apache.org on 2024/04/12 04:21:10 UTC

(plc4x) branch develop updated: fix(plc4py): Use packet length estimator to be able to handle multiple packets in a queue

This is an automated email from the ASF dual-hosted git repository.

hutcheb pushed a commit to branch develop
in repository https://gitbox.apache.org/repos/asf/plc4x.git


The following commit(s) were added to refs/heads/develop by this push:
     new 7196f34dd6 fix(plc4py): Use packet length estimator to be able to handle multiple packets in a queue
     new 4df2438426 Merge remote-tracking branch 'origin/develop' into develop
7196f34dd6 is described below

commit 7196f34dd6769d2bdc21fe4748a47a19a0559ec4
Author: Ben Hutcheson <be...@gmail.com>
AuthorDate: Fri Apr 12 06:20:40 2024 +0200

    fix(plc4py): Use packet length estimator to be able to handle multiple packets in a queue
---
 plc4py/plc4py/drivers/modbus/ModbusProtocol.py | 26 +++++++++++++++++---------
 1 file changed, 17 insertions(+), 9 deletions(-)

diff --git a/plc4py/plc4py/drivers/modbus/ModbusProtocol.py b/plc4py/plc4py/drivers/modbus/ModbusProtocol.py
index 8ad0c0796f..8bd38f24b1 100644
--- a/plc4py/plc4py/drivers/modbus/ModbusProtocol.py
+++ b/plc4py/plc4py/drivers/modbus/ModbusProtocol.py
@@ -33,20 +33,28 @@ from plc4py.utils.GenericTypes import ByteOrder
 class ModbusProtocol(Plc4xBaseProtocol):
     messages: Dict[int, Future] = field(default_factory=lambda: {})
 
+    def packet_length_estimator(self, read_buffer: ReadBufferByteBased):
+        current_position = read_buffer.position
+        read_buffer.position = 8 * 4
+        packet_length: int = read_buffer.read_unsigned_short()
+        read_buffer.position = current_position
+        return packet_length + current_position < len(read_buffer.bb)
+
     def data_received(self, data):
         """Unpack the adu and return the pdu"""
         read_buffer = ReadBufferByteBased(
             bytearray(data), byte_order=ByteOrder.BIG_ENDIAN
         )
-        adu: ModbusTcpADU = ModbusTcpADU.static_parse_builder(
-            read_buffer, DriverType.MODBUS_TCP, True
-        ).build(True)
-        if adu.transaction_identifier in self.messages:
-            self.messages[adu.transaction_identifier].set_result(adu.pdu)
-            self.messages.pop(adu.transaction_identifier)
-        else:
-            logging.error("Unsolicited message returned")
-            self.close()
+        while self.packet_length_estimator(read_buffer):
+            adu: ModbusTcpADU = ModbusTcpADU.static_parse_builder(
+                read_buffer, DriverType.MODBUS_TCP, True
+            ).build(True)
+            if adu.transaction_identifier in self.messages:
+                self.messages[adu.transaction_identifier].set_result(adu.pdu)
+                self.messages.pop(adu.transaction_identifier)
+            else:
+                logging.error("Unsolicited message returned")
+                self.close()
 
     def write_wait_for_response(self, data, transport, transaction_id, message_future):
         """Writes a message to the wire and records the identifier to identify and route the response"""