Skip to content

fix(tagxl/v1): configuration comparison rejects action TLVs (0x81-0x84) #209

Closed

Description

@michaelbeutler

Summary

tagxlv1.CompareConfiguration returns errConfigurationUnsupportedCommand for any Tag XL settings downlink that carries a device action TLV. Such a campaign can therefore never produce a comparison result — only an error.

Detail

parseConfigurationSent looks every TLV of the sent downlink up in setterSpecs and hard-fails on a miss — pkg/decoder/tagxl/v1/configuration_match.go:117:

spec, ok := setterSpecs[tag]
if !ok {
    return "", nil, errConfigurationUnsupportedCommand
}

setterSpecs (pkg/decoder/tagxl/v1/port151.go:81) holds only the setter tags 0x20–0x28. The firmware's action tags are absent:

Tag Action (ts2 app/tracker/lorawan_proto.h)
0x81 kLoraWanTlvTagResetDevice
0x82 kLoraWanTlvTagScanNow
0x83 kLoraWanTlvTagClearStorage
0x84 kLoraWanTlvTagWipeAll

So a valid downlink such as 4c 0a 02 21 04 0078 0e10 81 00 (set intervals + reset) errors out instead of being compared. The current behaviour is pinned for 0x80 by configuration_match_test.go:186.

Why this surfaces now

A pending Tag XL firmware fix (ts2) makes the device emit its port-151 settings reply before it reboots, and makes TLV order within a frame irrelevant. Previously a reset-bearing downlink produced no reply at all, so the comparator never got the chance to be wrong. Now the evidence arrives and the comparator throws it away.

Proposed change

  1. Add an action-tag set alongside setterSpecs. parseConfigurationSent consumes and length-checks them (all zero-length) but does not append them to requestedSetters nor to the reconstructed TLV payload — they carry no observable state. Keep rejecting duplicates.
  2. Add a fourth outcome to ConfigurationComparison, e.g. ConfigurationNotVerifiable, for a payload that parses cleanly but contains no setter. Today that is errConfigurationNoSetter (configuration_match.go:138), which callers cannot tell apart from a malformed payload. A reset-only campaign is exactly this case.

Tests to add

  • setter + action mixed payload matches against the echo (4c...21 04 0078 0e10 81 00 vs 4c...41 04 0078 0e10)
  • action-only payload returns not-verifiable rather than an error
  • an unknown, non-action tag still errors

Activity

  1. niko-kriznik-globtim commented on Sep 16, 2026

    @niko-kriznik-globtim
    Contributor

    Investigated independently of the proposed fix.

    Parent PR #208 already added dialect-aware getter/setter comparison and pure-getter verification, but still rejects action TLVs. The stacked draft is #210.

    Rejected from the original proposal:

    • 0x84 — declared in firmware, no handler found
    • a fourth ConfigurationNotVerifiable comparison result — sent-side analysis is the right layer; getter-only payloads remain observable
    • treating “no setter” as not verifiable — that would break getter-only campaigns

    Accepted actions: Tag XL 0x80 (len 2) and 0x81–0x83 (len 0); Smart Label v2 0x81–0x83 (len 0).

  2. niko-kriznik-globtim commented on Sep 16, 2026

    @niko-kriznik-globtim
    Contributor

    Implementation is stacked on PR #208, which already added dialect-aware getters/setters and pure-getter verification but still rejected every action TLV.

    Draft PR: #210

    AnalyzeConfiguration classifies observable setter/getter requirements vs actions. A fourth comparison enum is unnecessary. Getter-only payloads stay observable.

    Accepted actions:

    • Tag XL: 0x80 length 2, 0x81–0x84 length 0
    • Smart Label v2: 0x81–0x84 length 0
    • Smart Label 0x80 stays rejected

    Wipe-all 0x84 is accepted even though current firmware has no handler. Campaigns can queue it for delivery; this does not claim the device will run it. Reset-count verification was not implemented.

    API follow-up: https://github.com/truvami/api/pull/1022

  3. niko-kriznik-globtim commented on Sep 21, 2026

    @niko-kriznik-globtim
    Contributor
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Labels

tagxl/v1Affects decoder for tag XL v1

Type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions