Skip to content
SHARUR
Search Sign in

World

Topics from outside of this forum. Views and opinions represented here may not reflect those of this forum and its members.

A world of content at your fingertips…

Think of this as your global discovery feed. It brings together interesting discussions from across the web and other communities, all in one place.

While you can browse what's trending now, the best way to use this feed is to make it your own. By creating an account, you can follow specific creators and topics to filter out the noise and see only what matters to you.

Ready to dive in? Create an account to start following others, get notified when people reply to you, and save your favorite finds.

Register Login
  • S

    Reducing Overhead with Compact Array (Class 24)

    Standard DLMS responses repeat ASN.1 type tags for every element in an array, wasting significant bandwidth over cellular or PLC networks.

    Standard Array vs Compact Array

    • Standard Array (0x01): Contains [Type, Value] for every single field.
      • Example: Reading 100 integer values requires $100 \times 3 = 300$ bytes.
    • Compact Array (0x13): Defines a Single Type Template Header followed by raw contiguous byte payload.
      • Example: Header (4 bytes) + $100 \times 2$ bytes = 204 bytes (32% reduction in bandwidth!).

    Class 24 is particularly valuable for rapid instantaneous profile polling where data structure is strictly fixed.


    We tested Compact Array across 10,000 cellular smart meters polling hourly voltages. It reduced monthly cellular SIM data consumption from 12 MB/meter to 7.8 MB/meter.
  • S

    Understanding the Status Octet in Class 4 Energy Registers

    Class 4 (Extended Register) couples measurement values with a status byte and capture timestamp.

    Standard Status Bitmask (DLMS Blue Book Ed. 14)

    Bit 0: Invalid Data (Value calculation corrupted or sensor offline)
    Bit 1: Doubtful Value (Uncertain measurement precision)
    Bit 2: Measurement Value Modified (Manual adjustment or calibration)
    Bit 3: Power Failure (Occurred during integration period)
    Bit 4: Clock Synchronized (RTC synchronized via external time server)
    Bit 5: Daylight Saving Time Active
    Bit 6: Overflow (Energy register counter rollover)
    Bit 7: Reverse Energy Flow Detected (Indicates possible reverse wiring/tamper)
    

    Checking Bit 7 on Active Energy Import registers immediately detects field wiring inversion errors!


    In the meter metrology core, reverse power detection triggers an internal tamper counter and logs the event to the metrological audit log (0.0.96.11.0.255).
  • E

    Decoding DLMS/COSEM Data-Access-Result and Confirmed-Service-Error Codes

    When a GET, SET, or ACTION fails, the meter returns a numeric error code. Here is the definitive reference:

    Code Data-Access-Result Root Cause & Resolution
    0 success Operation completed successfully
    1 hardware-fault Memory or peripheral communication failure in meter
    2 temporary-failure Meter is busy (e.g. executing flash write or billing calculation)
    3 read-write-denied Insufficient permissions in current Association LN
    4 object-undefined Requested OBIS code does not exist in meter firmware
    9 object-class-inconsistent Class ID in request does not match device model
    11 type-unmatched Data type in SET request differs from attribute specification
    12 scope-of-access-violated Selective access range or entry exceeds valid buffer bounds
    13 data-block-unavailable Block transfer index requested is out of range

    Use this lookup matrix to automate error handling in your HES drivers!


    For code 11 (type-unmatched), always double check whether the attribute expects an octet-string vs visible-string. Passing ASCII text as raw visible-string when octet-string is required is a frequent source of type mismatch.
  • D

    Orchestrating Multi-Object Actions with Script Tables (Class 9)

    Class 9 (Script Table) allows the meter to bundle multiple internal actions into a single atomic routine triggered by a single ACTION request.

    Standard Script Objects

    • 0.0.10.0.0.255: Global Meter Reset Scripts
    • 0.0.10.0.1.255: End of Billing Period (Billing Reset / Snapshot Script)
    • 0.0.10.0.100.255: Tariff Switching Scripts

    Billing Snapshot Trigger Example

    Executing Script ID 1 on 0.0.10.0.1.255 snapshots all cumulative energy registers (1.0.1.8.0.255 -> 1.0.1.8.1.255), increments the billing counter, and resets the monthly maximum demand register.


    Meter firmware tip: Always ensure scripts execute within an atomic hardware transaction so partial register snapshots never occur if power is interrupted.
  • S

    Holiday and National Event Tariff Management (Class 11)

    Class 11 (Special Days Table, OBIS 0.0.11.0.0.255) enables smart meters to treat holidays (e.g. New Year, National Day) as Sunday off-peak billing schedules.

    Entry Structure

    Structure {
        index: Long-Unsigned,
        special_day_date: Octet-String (5 bytes: Year, Month, Day, DayOfWeek),
        day_id: Unsigned (References Day Profile ID in Activity Calendar)
    }
    

    When the real-time clock reaches the special day date, the meter overrides the normal week schedule and runs the designated day_id profile for 24 hours.


    In our utility HES, we sync the annual holiday calendar on December 15th across all meters in a single automated batch job.
  • A

    Updating Global Encryption Keys (GUEK / GAK) in the Field

    To rotate encryption keys remotely without exposing plaintext material over the air, DLMS utilizes NIST SP 800-38F / RFC 3394 AES Key Wrap.

    Key Renewal Procedure

    1. Establish an authenticated and encrypted session using the current Master Key (KEK - Key Encrypting Key).
    2. Wrap the new 128-bit Global Unicast Encryption Key (GUEK) using AES Key Wrap with the KEK.
    3. Invoke Method 1 (key_transfer) on the Security Setup object (0.0.43.0.0.255😞
      • Data parameter: Structure containing key_id (e.g., 0 for Global Encryption Key) and wrapped key octet-string (24 bytes).
    4. The meter decrypts and verifies the wrapped key. Upon success, all subsequent associations must use the newly installed GUEK.

    In meter firmware, always perform an atomic commit: If the new key verification passes, save to secure NVM and trigger an audit event log in Class 7 (Security Event Log). If power is lost mid-transfer, fallback safely to the previous key.
  • C

    Field Troubleshooting: DLMS over G3-PLC and PRIME Networks

    Power Line Communication (PLC) carries DLMS/COSEM data directly over low-voltage electrical distribution cables. High-frequency noise from inverter air conditioners and solar PV inverters frequently degrades SNR.

    Key Diagnosed Issues

    1. High Packet Fragmentation: G3-PLC 6LoWPAN adaptation layer fragments 1024-byte DLMS PDUs into multiple 128-byte MAC frames. If 1 fragment is lost due to noise, the entire DLMS APDU is dropped.
    2. Mitigation: Reduce max_pdu_size to 256 or 384 bytes in AARQ. Smaller PDUs fit within 2-3 PLC hops with significantly higher completion probability.
    3. Timeout Tuning: Increase gateway application response timeout (t_response) from 3.0s to 12.0s when routing through multi-hop mesh repeaters.

    Adjusting max_pdu_size to 384 bytes on noisy LV feeders increased our daily automated meter reading (AMR) success rate from 81% to 98.6%.
  • A

    Managing Role-Based Access Control (RBAC) in Smart Meters

    Class 15 (Association LN) defines which objects and methods an authenticated client can access.

    object_list Structure (Attribute 2)

    Each entry in the Association View contains:

    Structure {
        class_id: Long-Unsigned (e.g. 3 for Register),
        version: Unsigned (e.g. 0),
        logical_name: Octet-String (e.g. 1.0.32.7.0.255),
        access_rights: Structure {
            attribute_access: Array of {
                attribute_id: Integer8,
                access_mode: Enum (0=No Access, 1=Read Only, 2=Write Only, 3=Read/Write),
                access_selectors: Array of Integer8
            },
            method_access: Array of {
                method_id: Integer8,
                access_mode: Enum (0=No Access, 1=Access Allowed)
            }
        }
    }
    

    If a Management client attempts to execute SET on a billing register that is marked as Read Only in its Association LN, the meter returns Data-Access-Result: read-write-denied (Code 3).


    Always fetch the complete Association LN (0.0.40.0.X.255) right after login to dynamically discover which OBIS objects and methods your client credentials are permitted to invoke.
  • S

    Decoding 12-Byte and 5-Byte COSEM Date/Time Formats

    COSEM defines two standard timestamp representations: date_time (12 bytes) and time (4 bytes) / date (5 bytes).

    12-Byte Date/Time Structure

    Byte 0-1: Year (High byte, Low byte: 0x07EA = 2026, 0xFFFF = not specified)
    Byte 2:   Month (1-12, 0xFE = Daylight saving start, 0xFD = Daylight saving end, 0xFF = not specified)
    Byte 3:   DayOfMonth (1-31, 0xFD = 2nd from end, 0xFE = last day, 0xFF = not specified)
    Byte 4:   DayOfWeek (1=Monday...7=Sunday, 0xFF = not specified)
    Byte 5:   Hour (0-23, 0xFF = not specified)
    Byte 6:   Minute (0-59, 0xFF = not specified)
    Byte 7:   Second (0-59, 0xFF = not specified)
    Byte 8:   Hundredths of second (0-99, 0xFF = not specified)
    Byte 9-10:Deviation in minutes (Signed 16-bit, 0x8000 = not specified, e.g. +120 min = 0x0078)
    Byte 11:  Clock Status (Bit 0: invalid, Bit 1: doubtful, Bit 2: different clock base, Bit 3: invalid status, Bit 7: daylight_saving_active)
    

    Python Parser Implementation

    import struct
    from datetime import datetime, timezone, timedelta
    
    def parse_cosem_datetime(raw_bytes: bytes) -> str:
        if len(raw_bytes) != 12:
            raise ValueError("Invalid length for COSEM date_time")
        
        year, month, day, dow, hour, minute, sec, hundredths, dev, status = struct.unpack(
            ">HBBBBBBBhB", raw_bytes
        )
        
        tz = timezone(timedelta(minutes=dev)) if dev != -32768 else timezone.utc
        dt = datetime(year, month, day, hour, minute, sec, hundredths * 10000, tzinfo=tz)
        return dt.isoformat()
    
    # Example: 2026-08-22 14:30:00 UTC+8 (dev = +480 = 0x01E0)
    raw = bytes.fromhex("07EA 08 16 FF 0E 1E 00 00 01E0 00")
    print(parse_cosem_datetime(raw))
    # Output: 2026-08-22T14:30:00+08:00
    

    Be careful with the sign of Deviation: In DLMS, positive deviation means the local time is ahead of UTC (e.g. UTC+8 is +480 minutes). In some older proprietary systems, people mistakenly inverted the deviation sign.
  • A

    Dissecting Encrypted DLMS APDUs

    When security is applied at the application layer, the plaintext COSEM APDU is encapsulated in a General-Ciphering (0xDB) structure.

    Wire Format (APDU Tag 0xDB)

    DB 08 47 55 52 55 58 31 32 33 21 00 00 00 42 A1 12 ... 89 AB CD EF 01 23 45 67 89 AB CD EF
    

    Field Breakdown

    1. Tag: DB (general-ciphering)
    2. System Title Length & Value: 08 followed by 8 bytes (47 55 52 55 58 31 32 33 = GURUX123)
    3. Security Control Byte: 21
      • Bit 4-5 (10b = 0x20): Authentication + Encryption (AES-GCM)
      • Bit 0-3 (0001b = 0x01): Security Suite 0 / Key Set 1
    4. Invocation Counter: 00 00 00 42 (4 bytes, decimal 66)
    5. Ciphertext: A1 12 ...
    6. Authentication Tag (GMAC Tag): Last 12 bytes (96-bit or 128-bit ICV)

    AES-GCM Initialization Vector (IV) Construction (12 bytes)

    • Bytes 0-7: System Title (8 bytes)
    • Bytes 8-11: Invocation Counter (4 bytes in Big-Endian)

    The Additional Authenticated Data (AAD) for AES-GCM decryption consists of: AAD = Security_Control_Byte (1 byte) || Authentication_Key (16 bytes, if AK is distinct from EK) If AAD is omitted or formatted with the wrong key during tag computation, the GCM tag validation fails with deciphering-failed.
  • E

    Class 71 (Limiter) Configuration Guide

    Class 71 provides autonomous on-meter monitoring to protect distribution transformers from local consumer overloads.

    Architecture

    • Monitored Value (Attribute 2): References Class 3/4 register, e.g. Active Power (+P) 1.0.1.7.0.255.
    • Threshold Normal (Attribute 3): e.g. 10000 W (10 kW).
    • Threshold Emergency (Attribute 4): e.g. 15000 W (15 kW during grid emergencies).
    • Min Over Threshold Duration (Attribute 5): e.g. 30 seconds (avoids tripping on motor inrush current).
    • Action Over Threshold (Attribute 7): Calls script to open contactor (Class 70).
    • Action Under Threshold (Attribute 😎: Calls script to reconnect or signal availability.

    Configuring the debounce duration properly is critical to prevent nuisance tripping during air-conditioner startup spikes.


    We set min_over_threshold_duration to 45 seconds in our residential prepaid deployments. It successfully allows heat pump startup surges while cutting off sustained illicit overloads.
  • C

    Substation Case Study: 64-Meter RS-485 Daisy Chain Failures

    During commissioning of an industrial metering gateway polling 64 DLMS meters over an 800-meter RS-485 bus, we observed intermittent framing errors (CRC-16 HCS/FCS mismatch) when polling meters located beyond meter #40.

    Oscilloscope Measurements

    • Differential Voltage ($V_A - V_B$): Ringing amplitudes exceeded 1.8V during signal transitions.
    • Idle Bus State: Floating between -50mV and +80mV, falling into the RS-485 receiver indeterminate zone (-200mV to +200mV).

    Corrective Engineering Measures

    1. 120-Ohm Termination Resistors: Installed strictly at the physical two extreme ends of the daisy chain (Gateway and Meter #64). Removed intermediate termination switches from middle meters.
    2. Fail-Safe Biasing: Added 680-ohm pull-up on Line A (+5V) and 680-ohm pull-down on Line B (GND) at the gateway master to hold idle voltage at $+250\text{ mV}$.
    3. Baud Rate Optimization: Standardized at 9600 bps, 8N1 with shielded twisted pair (STP, 24 AWG, $120,\Omega$ characteristic impedance).

    Result: 100% packet success rate across all 64 nodes over continuous 72-hour run.


    Proper biasing is essential! Without fail-safe bias resistors, when the transmitter driver enters high-impedance tri-state mode between frames, ambient electrical noise triggers spurious start bits on UART controllers, generating Invalid Opening Flag errors.
  • S

    Managing Time-of-Use (TOU) Rates via Class 20

    Configuring complex Time-of-Use (Peak, Off-Peak, Shoulder) electricity billing in DLMS meters relies on Class 20 (Activity Calendar).

    Key Attributes

    • OBIS Code: 0.0.13.0.0.255 (Activity Calendar 1)
    • Attribute 2 (calendar_name_active): Currently running tariff schedule name
    • Attribute 3 (season_profile_active): Active seasonal date transitions
    • Attribute 4 (week_profile_table_active): Active Monday-Sunday day profile mappings
    • Attribute 5 (day_profile_table_active): Hourly tariff switching schedule
    • Attribute 6-9 (*_passive): Staged schedule for future activation
    • Attribute 10 (activate_passive_calendar_time): Execution timestamp

    Two-Step Safe Activation Pattern

    1. Write new season, week, and day profiles into the Passive attributes (Attributes 6, 7, 8).
    2. Set activate_passive_calendar_time (Attribute 10) to the scheduled rollout datetime (e.g., 2026-10-01 00:00:00) or execute activate_passive_calendar (Method 1) for immediate activation.

    Meter firmware tip: When writing day_profile_table_passive, ensure script selectors match the IDs in the Script Table (0.0.10.0.100.255) for tariff register switching. If a script ID is invalid, the meter returns object-undefined on write.
  • S

    Understanding the 24-bit Conformance Block in AARQ

    During Association establishment, the client proposes a set of service capabilities in the Proposed-Conformance bit-string. The meter responds with Negotiated-Conformance, which is the bitwise AND of supported features.

    Conformance Bit Allocations (DLMS Green Book 10th Ed.)

    Bit 0:  reserved
    Bit 1:  reserved
    Bit 2:  read (obsolete)
    Bit 3:  write (obsolete)
    Bit 4:  unconfirmed-write
    Bit 5:  multipurpose-service
    Bit 6:  read-access
    Bit 7:  write-access
    Bit 8:  variable-access-specification
    Bit 9:  information-report
    Bit 10: reserved
    Bit 11: reserved
    Bit 12: get (LN)
    Bit 13: set (LN)
    Bit 14: selective-access
    Bit 15: event-notification
    Bit 16: action
    Bit 17: reserved
    Bit 18: block-transfer-with-get
    Bit 19: block-transfer-with-set
    Bit 20: block-transfer-with-action
    Bit 21: multiple-references
    Bit 22: information-report-with-data
    Bit 23: access-data
    

    Standard 24-bit Proposed Conformance for Logical Name (LN) Referencing

    00 7E 1F in hex:

    • Enables: GET, SET, ACTION, SELECTIVE-ACCESS, BLOCK-TRANSFER-WITH-GET, BLOCK-TRANSFER-WITH-SET, BLOCK-TRANSFER-WITH-ACTION.

    If your client forgets to set bit 14 (selective-access), any subsequent attempt to read profile buffers by date range will be rejected with Service-Error: service-not-supported!


    Excellent summary Sarah! A common mistake when writing custom client drivers is hardcoding Short Name (SN) conformance bits (Bit 6: read, Bit 7: write) while attempting to connect to a Logical Name (LN) referencing association. This causes immediate AARQ rejection (result: rejected-permanent, result-source-diagnostic: application-context-name-not-supported).
  • D

    Engineering Guide: Disconnect Control (Class 70)

    Managing internal contactors for demand limiting or prepayment requires strict adherence to the Class 70 state machine defined in IEC 62056-62.

    Object Identification

    • OBIS Code: 0.0.96.3.10.255 (Disconnect Control 1)
    • Class ID: 70

    Control Methods

    • Method 1 (remote_disconnect): Opens the contactor (Disconnects supply).
    • Method 2 (remote_reconnect): Closes the contactor or enters 'Ready for Reconnection' state.

    Output State Validation (Attribute 2)

    Control State Value Meaning Physical Contactor Status
    0 Disconnected Open (No power)
    1 Connected Closed (Power active)
    2 Ready_For_Reconnection Open (Awaiting manual button press on meter)

    [!IMPORTANT]
    Safety regulations in many jurisdictions forbid immediate remote closure if someone is working on site. Setting control_mode = 2 transitions the meter to state 2, requiring the consumer to press the meter physical push-button to complete the circuit.


    In the meter firmware, contactor pulse duration is controlled via Attribute 4 (output_signal). We configure a 200ms pulse for the magnetic latching relay to prevent coil overheating.
  • M

    Architecture & Implementation

    In modern smart metering deployments, meters autonomously push alarm events and hourly load readings using COSEM Class 40 (Push Setup) and Class 41 (Data Notification), instead of relying on round-robin polling from the Head-End System.

    Push APDU Format over TCP Wrapper (Port 4059)

    00 01 00 01 00 01 00 28 0F 00 00 00 01 00 00 01 02 02 09 0C 07 EA 08 16 ...
    

    Wrapper Header Analysis (8 bytes)

    • 00 01: Protocol Version (0x0001 for DLMS TCP Wrapper)
    • 00 01: Source WPort (Meter Logical Client ID)
    • 00 01: Destination WPort (HES Receiver Server ID)
    • 00 28: PDU Length (40 bytes)
    • 0F: APDU Tag -> Data-Notification (Tag 0x0F / 15)

    Key Considerations

    1. Unsolicited Connection Management: The HES TCP server must maintain asynchronous socket listeners capable of handling thousands of simultaneous incoming TCP connections without blocking.
    2. Association Context: Push notifications are often sent without full AARQ authentication handshake. The meter uses predefined ciphering parameters (General-Ciphering 0xDB or General-Signing 0xDF) with Dedicated Encryption Key (DEK).

    For encrypted Push notifications (0xDB tag), the HES receiver must extract the System Title and Invocation Counter from the ciphered APDU header, lookup the corresponding Global Unicast Encryption Key (GUEK) in the HSM / Key Vault, and decrypt using AES-GCM-128.
  • E

    Firmware Upgrade (OTA) Engineering Notes

    When performing Over-The-Air (OTA) firmware upgrades on NB-IoT / Cellular smart meters using COSEM Class 18 (Image Transfer), we encountered two major challenges:

    1. Block Size Throttling: Negotiating a block size larger than 512 bytes on high-latency cellular connections causes packet fragmentation and retransmissions.
    2. Image Verification Failure: Calling method image_verify (Method 3) returned temporary-failure or hardware-fault.

    Recommended Block Size by Media

    Communication Media Optimal Block Size Max Window Size
    Optical Probe / Serial 512 - 1024 bytes 1
    RS-485 Multi-drop 256 - 512 bytes 1
    NB-IoT / LTE-M 192 - 256 bytes 1
    Ethernet / TCP-IP 1024 - 2048 bytes 4

    Verification Root Cause

    In Class 18, before invoking image_verify, the client must check attribute 7 (image_to_verify_image_signature). If your build system prepends a proprietary header to the raw binary file that is not part of the meter's cryptographic hash signature, the on-chip bootloader hash check will fail.


    We implemented block-level resume in our Head-End System. For a 500 KB firmware image with 256-byte blocks (2000 blocks), resuming dropped packets reduced total OTA upgrade bandwidth by 78% on cellular meters.
  • C

    Field Troubleshooting Case

    When connecting an optical probe to legacy IEC/DLMS hybrid meters, the sign-on handshake succeeds at 300 bps (7E1 parity), but switching to high-speed HDLC mode at 9600 bps or 19200 bps fails, terminating the session.

    Optical Sign-on Trace (300 Baud, 7E1)

    1. Client -> Meter: /?!<CR><LF> (2F 3F 21 0D 0A)
    2. Meter -> Client: /LGZ4ZMD4104400.B34<CR><LF>
      • Identification character: Z (Baud rate identification)
      • Mode character: 2 (Mode E - transition to DLMS/HDLC)
    3. Client -> Meter: ACK/Option Select: <ACK> 2 5 2 <CR><LF> (06 32 35 32 0D 0A)
      • 2: Normal protocol mode
      • 5: Baud rate 9600 bps
      • 2: Mode E (HDLC)

    The Failure

    After sending the ACK message, the gateway switched the serial port baud rate to 9600 bps immediately without inserting the required delay $T_a$, causing the first HDLC SNRM frame to be sent while the meter optical receiver was still re-configuring its UART clock.


    Also note that during Mode E sign-on, the parity changes: Initial handshake is 300 baud, 7 data bits, Even parity, 1 stop bit (7E1). Once the baud rate switch occurs for DLMS/HDLC, the UART MUST switch to 8 data bits, No parity, 1 stop bit (8N1).
  • M

    Issue Description

    When requesting 15-minute Load Profile data from Class 7 (Profile Generic) object 1.0.99.1.0.255 using RangeDescriptor (Selective Access Type 1), the meter responds with an empty buffer (01 00 -> Array with 0 entries), even though the buffer holds 30 days of data.

    Request Parameters

    • Restricting Object: 0.0.1.0.0.255 (Clock, Attribute 2 - date_time)
    • From Value: 2026-08-20 00:00:00.000 (Octet-String 12 bytes)
    • To Value: 2026-08-21 00:00:00.000 (Octet-String 12 bytes)

    Why the Read Returns Empty

    In the DLMS date_time structure (12 bytes):

    07 EA 08 14 FF 00 00 00 00 80 00 00
    
    • Bytes 0-1: Year (0x07EA = 2026)
    • Byte 2: Month (0x08)
    • Byte 3: DayOfMonth (0x14 = 20)
    • Byte 4: DayOfWeek (0xFF = not specified)
    • Byte 5: Hour (0x00)
    • Byte 6: Minute (0x00)
    • Byte 7: Second (0x00)
    • Byte 8: Hundredths (0x00)
    • Bytes 9-10: Deviation (0x8000 = not specified)
    • Byte 11: Clock status (0x00)

    The culprit: In our request, Byte 4 (DayOfWeek) was populated with the actual day of week (0x04 for Thursday), and Clock Status (Byte 11) was set to 0x80. Many meter implementations require wildcard (0xFF) for DayOfWeek and 0x00 or 0xFF for Clock Status in range filters, otherwise the equality match against the captured buffer timestamps fails!


    Also verify that the first capture object in capture_objects (Attribute 3) of the Profile Generic is indeed the Clock object (0.0.1.0.0.255, class_id: 8, attr_index: 2). If the meter firmware captured the status register first, restricting_object must reference index 1 instead of index 2.
  • A

    Scenario

    When establishing an Application Association using High-Level Security Suite 0 (AES-GCM-128 / HLS 5 with GMAC authentication), the meter rejects the association during the AARQ/AARE handshake, returning Association-Result: 0x01 (rejected-permanent).

    AARQ APDU Hex Dump

    60 36 A1 09 06 07 60 85 74 05 08 01 03 A6 0A 04 08 47 55 52 55 58 31 32 33 BE 10 04 0E 01 00 00 00 06 5F 1F 04 00 00 7E 1F
    

    Handshake Parameters

    • Application Context Name: 2.16.756.5.8.1.3 (Logical Name referencing with Ciphering)
    • Calling Authentication Value: GURUX123 (8-byte Client System Title)
    • Security Mechanism Name: 2.16.756.5.8.2.5 (Mechanism ID 5 - GMAC)

    Root Cause Diagnostics

    1. System Title Length: The calling system title must be exactly 8 bytes.
    2. Invocation Counter / Frame Counter Mismatch: When the client creates the GMAC authentication tag, the client's Invocation Counter must be strictly greater than the last stored counter in the meter's Security Setup object (0.0.43.0.0.255).
    3. If the meter was rebooted or if multiple clients share the same System Title, the invocation counter on the client will fall behind, triggering instant rejection for replay attack prevention.

    Confirmed! Reading the Invocation Counter beforehand and incrementing locally solved the issue. Also note that for HLS 7 (ECDSA), the ephemeral public key exchange must strictly follow the P-256 / SHA-256 curve parameters in Green Book 10th Edition.
Page 3 of 4