You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
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:
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
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.
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
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).
Implementation is stacked on PR #208, which already added dialect-aware getters/setters and pure-getter verification but still rejected every action TLV.
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.
Activity
niko-kriznik-globtim commentedon Sep 16, 2026
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 foundConfigurationNotVerifiablecomparison result — sent-side analysis is the right layer; getter-only payloads remain observableAccepted actions: Tag XL
0x80(len 2) and0x81–0x83(len 0); Smart Label v20x81–0x83(len 0).niko-kriznik-globtim commentedon Sep 16, 2026
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
AnalyzeConfigurationclassifies observable setter/getter requirements vs actions. A fourth comparison enum is unnecessary. Getter-only payloads stay observable.Accepted actions:
0x80length 2,0x81–0x84length 00x81–0x84length 00x80stays rejectedWipe-all
0x84is 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
niko-kriznik-globtim commentedon Sep 21, 2026
#211