Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • World
  • Users
  • Groups
Skins
  • Light
  • Dark

Collapse
SHARUR
Community Wiki DLMS/COSEM Tools
Search Sign in

Why does AARQ Conformance Bit 19 (General Block Transfer - GBT) mismatch cause streaming deadlocks during large buffer reads?

Scheduled Pinned Locked Moved General Discussion
dlmscosemconformance-bitgbtblock-transfer
10 Posts 5 Posters 45 Views 1 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
  • M Offline
    M Offline
    marcus_vance
    wrote on last edited by
    #1

    [!WARNING]
    Technical Redaction & Safe Harbor Notice:
    All communication captures, system titles, and cryptographic parameters in this thread have been sanitized and neutralized. Real utility meter identifiers, production encryption keys (GUEK/GAK/MK), SIM IMSIs, and proprietary network envelopes have been substituted with standard IEC 62056 synthetic test vectors. Do not post unredacted production captures or live cryptographic keys.

    We are integrating a modern DLMS Head-End System (HES) with newly deployed smart meters over IEC 62056-47 TCP Wrapper. When reading small scalar registers (e.g. Instantaneous Voltage 1.0.32.7.0.255, Class 3), communications succeed immediately with Get-Response-Normal (0xC4 0x01).

    However, when reading large Profile Generic buffers (OBIS 1.0.99.1.0.255, Class 7) exceeding 2048 bytes, the meter does NOT return standard Get-Response-With-Datablock (0xC4 0x02). Instead, it responds with an unexpected APDU tag 0xDB wrapping a General Block Transfer (GBT) streaming control header (0xE0 0x00 ...).

    Our HES client parser expects normal xDLMS datablocks, fails to recognize the GBT header, and stalls until timeout.

    Here is the AARQ Conformance Block sent by HES:

    5F 1F 04 00 00 7E 1F 04 00
    
    • Conformance BitString (24 bits): 00 7E 1F

    And here is the meter's AARE Negotiated Conformance:

    5F 1F 04 00 00 7E 5F 04 00
    

    Why is the meter forcing GBT framing when our HES client did not request it?

    1 Reply Last reply
    0
    • D Offline
      D Offline
      david_miller
      wrote on last edited by
      #2

      Marcus, look closely at your Conformance BitString in AARQ vs AARE!

      Per DLMS Green Book 10th Ed Section 9.2.2 (Negotiated Conformance Block) and IEC 62056-53 Section 8.3.2:
      The 24-bit Conformance Block defines which xDLMS services are supported:

      Bit Position Service Name Meaning
      Bit 0 read GET service
      Bit 1 write SET service
      Bit 2 unconfirmed-write Unconfirmed write
      Bit 19 general-block-transfer (GBT) General Block Transfer Service
      Bit 20 delta-c-get Delta-C get
      Bit 23 multiple-references Read/Write multiple objects

      In your AARQ:
      00 7E 1F => 0000 0000 0111 1110 0001 1111b.
      Notice byte 3 is 0x1F (0001 1111b). Bit 19 is 0 (GBT disabled).

      However, in your meter's AARE:
      00 7E 5F => 0000 0000 0111 1110 0101 1111b.
      Notice byte 3 is 0x5F (0101 1111b). Bit 19 is SET to 1 (general-block-transfer)!

      According to Green Book rules, negotiated conformance is the bitwise AND of proposed and accepted conformance ($C_{\text{neg}} = C_{\text{prop}} \land C_{\text{acc}}$).
      If the meter firmware unilaterally enables Bit 19 in its response even when the client proposed Bit 19 = 0, the meter violates the negotiation contract and assumes GBT mode!

      1 Reply Last reply
      0
      • E Offline
        E Offline
        elena_rostova
        wrote on last edited by
        #3

        David is spot on. Many smart meter firmware stacks (especially European IDIS / SMETS compliant builds) are configured to force GBT for any payload larger than max-pdu-size because GBT provides streaming windowing with bidirectional acknowledgment, unlike standard stop-and-wait datablocks.

        How GBT (General Block Transfer) Works:

        Per DLMS Green Book Section 9.2.5.4:
        GBT encapsulates arbitrary APDUs inside a streaming sub-header:

        • 0xE0: General-Block-Transfer tag
        • Byte 1: Control byte (Bit 7 = Last Block, Bit 6 = Streaming, Bits 0-5 = Window size / Block Number)
        • Byte 2-3: Block Number ($0 \dots 65535$)

        When your HES receives 0xE0 inside 0xDB, it must process the GBT sub-layer rather than expecting 0xC4 0x02.

        1 Reply Last reply
        0
        • S Offline
          S Offline
          sarah_jenkins
          wrote on last edited by
          #4

          Let's compare the efficiency of GBT vs Traditional DataBlocks:

          1. Traditional DataBlock (0xC4 0x02):
            • Strictly 1-by-1 stop-and-wait.
            • For every 1024-byte block, HES must send Get-Request-Next (0xC0 0x02). Over cellular LTE-M with 200ms latency, transferring 500 KB takes 100+ seconds!
          2. General Block Transfer (GBT):
            • Supports Sliding Window Streaming (e.g. Window Size = 4).
            • Meter streams 4 consecutive blocks before requiring a single GBT ACK from HES, cutting transfer time by 75%!

          However, if the HES stack does not implement the GBT state machine, communication deadlocks immediately.

          1 Reply Last reply
          0
          • A Offline
            A Offline
            alex_turner
            wrote on last edited by
            #5

            From the cryptographic standpoint, GBT introduces a critical security difference:

            In Traditional DataBlock, each datablock is ciphered as an individual application chunk or ciphered at the outer APDU level.
            In GBT, the entire multi-block stream shares a single outer ciphering context or ciphers per GBT block with rolling Invocation Counters ($IC$).

            If your HES does not parse GBT, it fails to extract the underlying plain Get-Response-Normal payload.

            1 Reply Last reply
            0
            • M Offline
              M Offline
              marcus_vance
              wrote on last edited by
              #6

              So we have two actionable solutions:

              Solution A: Disable GBT via Strict Conformance Negotiation

              If HES does not support GBT, ensure HES proposes proposed-conformance with Bit 19 = 0 (0x007E1F), and if the meter's AARE returns Bit 19 = 1, HES should send RLRQ or enforce standard block mode.

              Solution B: Implement Native GBT Support in HES

              Update the HES Netty pipeline to handle tag 0xE0 and transmit GBT acknowledgments (0xE0 0x00 [block_num]).

              1 Reply Last reply
              0
              • E Offline
                E Offline
                elena_rostova
                wrote on last edited by
                #7

                Here is the verified GBT response frame structure returned by the meter:

                00 01 00 01 00 01 04 08 DB 08 53 48 41 00 00 00 00 01 30 00 00 00 15 E0 00 00 01 [1024 bytes payload] 9B E1 4C 8D 23 AA 12 90 77 1B C0 44
                

                Dissecting the GBT header:

                • E0: GBT Tag
                • 00: Control byte (last_block = false, window = 0)
                • 00 01: Block number 1
                • Followed by the chunked COSEM payload.
                1 Reply Last reply
                0
                • D Offline
                  D Offline
                  david_miller
                  wrote on last edited by
                  #8

                  And here is the HES GBT Acknowledgment frame to fetch Block #2:

                  00 01 00 01 00 01 00 0C DB 08 53 48 41 00 00 00 00 01 30 00 00 00 16 E0 00 00 01
                  

                  The meter immediately streams Block #2 upon receiving this ACK.

                  1 Reply Last reply
                  0
                  • S Offline
                    S Offline
                    sarah_jenkins
                    wrote on last edited by
                    #9

                    Notice how clean this is: GBT operates as a transport bridge below the COSEM APDU, allowing full backward compatibility with any COSEM object.

                    1 Reply Last reply
                    0
                    • M Offline
                      M Offline
                      marcus_vance
                      wrote on last edited by
                      #10

                      To synthesize for the community, here is the Python Gurux snippet demonstrating how to configure Conformance Bitstrings to enable or disable GBT cleanly:

                      from gurux_dlms.enums import Conformance
                      
                      def configure_conformance_bits(client, enable_gbt=False):
                          # Base Conformance: Read, Write, UnconfirmedWrite, ParameterizedAccess
                          client.proposed_conformance = (
                              Conformance.READ | 
                              Conformance.WRITE | 
                              Conformance.UN_CONFIRMED_WRITE | 
                              Conformance.SELECTIVE_ACCESS
                          )
                          
                          if enable_gbt:
                              # Enable Bit 19 (General Block Transfer) for high-speed streaming
                              client.proposed_conformance |= Conformance.GENERAL_BLOCK_TRANSFER
                              print("[+] GBT (General Block Transfer) enabled in AARQ Conformance.")
                          else:
                              # Strict Traditional DataBlock mode
                              client.proposed_conformance &= ~Conformance.GENERAL_BLOCK_TRANSFER
                              print("[+] Strict Traditional DataBlock mode enforced.")
                      

                      Summary Checklist for Conformance Negotiation:

                      1. Bit 19 Inspection: Check byte 3 bit 5 of the Conformance BitString in AARQ/AARE.
                      2. GBT Capability: If HES lacks GBT parser, explicitly clear Bit 19 in AARQ.
                      3. Firmware Conformance: Validate that meter respects bitwise AND negotiation ($C_{\text{neg}} = C_{\text{prop}} \land C_{\text{acc}}$).
                      1 Reply Last reply
                      0

                      Hello! It looks like you're interested in this conversation, but you don't have an account yet.

                      Getting fed up of having to scroll through the same posts each visit? When you register for an account, you'll always come back to exactly where you were before, and choose to be notified of new replies (either via email, or push notification). You'll also be able to save bookmarks and upvote posts to show your appreciation to other community members.

                      With your input, this post could be even better 💗

                      Register Login
                      Reply
                      • Reply as topic
                      Log in to reply
                      • Oldest to Newest
                      • Newest to Oldest
                      • Most Votes


                      • Login

                      • Don't have an account? Register

                      • Login or register to search.
                      Powered by NodeBB Contributors
                      • First post
                        Last post
                      0
                      • Categories
                      • Recent
                      • Tags
                      • Popular
                      • World
                      • Users
                      • Groups