From 35946ffc959ae12ab9fcb264ecaf1b188cfa680c Mon Sep 17 00:00:00 2001 From: Stefan Andrejevic Date: Thu, 6 Aug 2026 15:36:07 +0200 Subject: [PATCH 1/2] fix(hdlc): preserve generated transport frame sequences Return the complete transport frame sequence generated for protected requests instead of truncating it to the first transport frame. Large protected APDUs may span multiple HDLC transport frames. Returning only the first generated frame causes incomplete request transmission over Serial HDLC. This change preserves the generated frame sequence so callers can transmit every generated transport frame. --- Gurux.DLMS.python/gurux_dlms/GXDLMS.py | 4 +++- Gurux.DLMS.python/gurux_dlms/GXDLMSClient.py | 2 +- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/Gurux.DLMS.python/gurux_dlms/GXDLMS.py b/Gurux.DLMS.python/gurux_dlms/GXDLMS.py index 3c83273..39626c0 100644 --- a/Gurux.DLMS.python/gurux_dlms/GXDLMS.py +++ b/Gurux.DLMS.python/gurux_dlms/GXDLMS.py @@ -183,7 +183,9 @@ def receiverReady(cls, settings, reply): None, ) reply = GXDLMS.getSnMessages(p) - return reply[0] + # Protected next-block requests can span multiple HDLC frames. + # Return the full frame list so the caller can transmit every frame. + return reply # # Reserved for internal use. diff --git a/Gurux.DLMS.python/gurux_dlms/GXDLMSClient.py b/Gurux.DLMS.python/gurux_dlms/GXDLMSClient.py index e624a9a..67b84ea 100644 --- a/Gurux.DLMS.python/gurux_dlms/GXDLMSClient.py +++ b/Gurux.DLMS.python/gurux_dlms/GXDLMSClient.py @@ -1036,7 +1036,7 @@ def getObjectsRequest(self): name = "0.0.40.0.0.255" else: name = int(0xFA00) - return self._read(name, ObjectType.ASSOCIATION_LOGICAL_NAME, 2)[0] + return self._read(name, ObjectType.ASSOCIATION_LOGICAL_NAME, 2) def method(self, item, index, data, type_): return self.__method(item.name, item.objectType, index, data, type_) From 16daa9a4770e6cb84639d9c127e618e2ae5ace97 Mon Sep 17 00:00:00 2001 From: Stefan Andrejevic Date: Thu, 6 Aug 2026 15:37:37 +0200 Subject: [PATCH 2/2] fix(reader): preserve reply state across fragmented frames Preserve the same GXReplyData instance while processing fragmented transport frames. Removing reply.clear() prevents previously received protocol state from being discarded before the complete request or response exchange has been processed. This aligns the example client with the transport layer behavior when protected requests span multiple HDLC frames. --- Gurux.DLMS.Client.Example.python/GXDLMSReader.py | 2 -- 1 file changed, 2 deletions(-) diff --git a/Gurux.DLMS.Client.Example.python/GXDLMSReader.py b/Gurux.DLMS.Client.Example.python/GXDLMSReader.py index b2bec94..510b03a 100644 --- a/Gurux.DLMS.Client.Example.python/GXDLMSReader.py +++ b/Gurux.DLMS.Client.Example.python/GXDLMSReader.py @@ -164,7 +164,6 @@ def readDLMSPacket(self, data, reply=None): self.readDLMSPacket2(data, reply) elif data: for it in data: - reply.clear() self.readDLMSPacket2(it, reply) def readDLMSPacket2(self, data, reply): @@ -228,7 +227,6 @@ def readDataBlock(self, data, reply): if data: if isinstance(data, (list)): for it in data: - reply.clear() self.readDataBlock(it, reply) return reply.error == 0 else: