Skip to main content
Home
for DLMS smart meters
Open source solutions for DLMS smart metering

Main navigation

  • Home
  • Products
  • About us
  • Open Source
  • Community
  • Forum
  • Downloads
User account menu
  • Log in

Breadcrumb

  1. Home
  2. Node
  3. SN ReadResponse Returns All-null Values When Response Spans Multiple HDLC Frames

SN ReadResponse returns all-null values when response spans multiple HDLC frames

By L0uisc_iot , 8 September, 2026
Forums
Gurux.DLMS

Environment:

- Gurux.DLMS.NET 9.0.2605.2801 (latest release at time of writing), Gurux.Net 8.4.2604.201, .NET 8
- HDLC over TCP, SN (short-name) referencing (UseLogicalNameReferencing = false)
- Landis+Gyr E650, HDLC negotiated MaxInfoTX=128 / MaxInfoRX=62, window size 1

Symptom:
A single ReadList/Read-Request with a list of ~12 or more short names comes back with every value null — no per-item DataAccessResult error, no exception, TotalCount correct, just every entry in the returned object[] is null. The same call with a smaller list (e.g. 2–3 items) returns correct, real values every time.

Confirmed this is not a meter/network issue:
I captured the raw HDLC bytes for a failing 30-item read and decoded them independently in GXDLMSDirector's DLMS Translator. The meter's response is complete and correct — ReadResponse Qty="1E" with 30 valid Data elements (real Int32/UInt32/UInt8 values, no DataAccessError entries). So the meter is answering correctly; the client is misparsing a good reply.

I also reproduced this from a bare-metal script driving GXDLMSClient directly (no application code of ours in the loop) against the same meter, with the exact 30 short names from the capture — same result: correct request goes out, meter responds correctly (confirmed via the translator decode of the same session), client-side result comes back all-null.

Suspected root cause (reading through Gurux.DLMS.GXDLMS.HandleReadResponse in this version):

private static bool HandleReadResponse(GXDLMSSettings settings, GXReplyData reply, int index)
{
int num = reply.TotalCount;
bool flag = num == 0 || reply.CommandType == 2;
if (flag)
{
num = (reply.TotalCount = GXCommon.GetObjectCount(reply.Data));
}
...
if (num != 1)
{
if (reply.IsMoreData)
{
GetDataFromBlock(reply.Data, 0);
return false;
}
if (!flag)
{
reply.Data.Position = 0;
}
...
}
...
for (int i = 0; i != num; i++)
{
SingleReadResponse singleReadResponse;
if (flag)
{
singleReadResponse = (SingleReadResponse)reply.Data.GetUInt8(); // consumes per-item tag
reply.CommandType = (byte)singleReadResponse;
}
else
{
singleReadResponse = (SingleReadResponse)reply.CommandType; // does NOT consume it
}
...
}

When the response arrives in one HDLC frame, flag is true on the (only) call, TotalCount is parsed, and each item's SingleReadResponse tag byte is correctly consumed per-iteration.

When the response is segmented across multiple frames, HandleReadResponse is invoked once per frame. On the first call (IsMoreData == true), it only extracts TotalCount and returns early — no items are parsed yet. On the final call (IsMoreData == false), flag is now false (since TotalCount is already nonzero from the earlier call), which means:

reply.Data.Position = 0 resets the cursor to the start of the entire accumulated buffer (including the already-consumed count-prefix byte from the first call), and
the per-item loop takes the else branch for every iteration, which never consumes the per-item tag byte — it just reuses whatever reply.CommandType was cached from the very first call.

The net effect looks like a stream misalignment: the loop ends up reading GetValueFromData at the wrong offsets for the whole pass, and every item decodes as null/garbage rather than the correct value. This matches what I'm seeing exactly: batches small enough to arrive in one HDLC frame always work; batches that force segmentation always come back all-null, regardless of the actual values on the wire.

This looks structurally related to the HandleGetResponseWithList bug fixed in commit 918b84a (a segmented list response misparsing null values due to a position-tracking issue) — but that fix only touches HandleGetResponseWithList, the LN Get-Request-With-List path. HandleReadResponse, the SN Read-Request path, doesn't appear to have received an equivalent fix and still shows this behavior in the current 9.0.2605.2801 release.

Repro conditions, if useful for a test case:

SN referencing, any meter/simulator that supports multi-item Read-Request
A list of short names large enough that the reply requires more than one HDLC frame (in my case, a small negotiated MaxInfoRX of 62 bytes made this easy to hit at ~12 items with 6-byte-per-item Int32 responses)
Compare a request that fits in one frame vs. one that doesn't — the former always works, the latter always returns nulls

Happy to share the exact capture bytes and my trace if that helps track it down

L0uisc_iot

14 hours 22 min ago

I'm looking into…

I'm looking into implementing a fix. Will send PR if I get it working.

L0uisc_iot

13 hours 19 min ago

PR created: https://github…

PR created: https://github.com/Gurux/Gurux.DLMS.Net/pull/13

  • Log in or register to post comments
  • Create new account
  • Reset your password

Hire Us!

Latest Releases

  • Wed, 08/26/2026 - 09:04
    Gurux.DLMS.Python 1.0.203
  • Mon, 08/17/2026 - 11:28
    Gurux.DLMS.Python 1.0.202
  • Mon, 08/17/2026 - 09:47
    gurux.dlms.cpp 9.0.2608.1701
  • Mon, 08/17/2026 - 09:25
    gurux.dlms.c 9.0.2608.1701
  • Mon, 07/27/2026 - 12:37
    gurux.dlms.cpp 9.0.2607.2701

New forum topics

  • SN ReadResponse returns all-null values when response spans multiple HDLC frames
  • Gurux.Serial.Android 3.0.6 – CH340 (HL-340) USB-Serial Adapter Not Working,
  • Trying to talk to a L&G E360 meter (Using Python Gurux)
  • Reading PushSetupObject attr 10 error
  • addCaptureObject as Class ID=01 (Data) (not 03 (Register))
More
RSS feed
Privacy FAQ GXDN Issues Contact
Follow Gurux on Twitter Follow Gurux on Linkedin