The TR's response objects are all Min = N in the spec's own table, and
6.8.0 says such objects "should set the CR flag to comprehension not
required" - so the builders now emit the base tag forms:
- device identities 82 -> 02 (every builder)
- PLI data 93/94/AD/AE/BF/E2/E5 -> 13/14/2D/2E/3F/62/65 (26/63 already
base); the PWA inline codecs follow
- POLL INTERVAL Duration 84 -> 04
- GET INKEY/INPUT Text string 8D -> 0D
- SELECT ITEM Item identifier 90 -> 10
- Timer identifier/value A4/A5 -> 24/25
(_bip_tr already used the reference traces' 01/02/03.)
The command details now echo the command's tag form (01/81) besides
its qualifier - 6.8.1 requires the object to be identical to the
command's "including the comprehension required flag": the parser
returns cd_tag and _build_tr, _handle_timer_command,
_handle_bip_command, the menu pendings and testscript.build_tr carry
it. The Result keeps 03/83 (Min = Y). _tr_data_only strips both tag
styles and the POLL Duration decode accepts 04.
Tests: the base forms per builder + the echo + the PWA drift guards;
883 frontend + 866 Python; sw cache simple-v426.
An unconfigured PLI dictionary answered result-ok with no data object,
which confuses applications that expect data. The dictionary now has a
base layer of sensible defaults for the qualifiers the pinned ETSI specs
define (TS 102 223 8.x, tags per TS 101 220 V18.3.0 Table 7.23):
- location as the test network 001/01 + LAC 0000 (8.19),
- the classic test IMEI 490154203237518 as F-padded BCD (8.20) and its
IMEISV (8.74),
- language 'en' (8.45), Timing Advance (2E/AE), E-UTRAN (8.61; UTRAN +
E-UTRAN for the multiple-technology qualifier 0E),
- automatic search mode (8.75), a full battery (8.76).
An override set through /api/pli-dict wins, and clearing a field restores
its default (the PWA's Save re-renders the effective values; the GET returns
the override or the default for the full qualifier set). The date/time
qualifier stays empty so the host clock keeps answering it; the
3GPP/3GPP2-specific qualifiers (NMR, ESN, MEID, CSG/HNB, WLAN, slices,
CAG, ...) stay empty - the ETSI specs define no contents for them, and a
fabricated object would mislead the application more than no answer.
Verifying the values against the pinned tag table exposed pre-existing bugs
in the PWA's PLI inline codecs, fixed here:
- Timing Advance used C6 (a 3GPP2 tag) -> 2E/AE;
- IMEISV used 94 (the IMEI tag) -> 62/E2;
- Network Search Mode used AD (the Language tag) -> 65/E5, and its labels
were swapped ('00' Manual / '01' Automatic per 8.75);
- the battery field was a percentage where 8.76 is an enum ('00' very low
... '04' full, 'FE'/'FF');
- encImeiPli padded the odd 15th digit with 0 instead of F (TS 124 008).
Docs: help EN/RU, api.md, the guide. Tests: the defaults + the resolution
order (Python), the HTTP endpoint's defaults/override/clearing, the codec
tags/labels and a server-defaults drift guard (Node). 846 frontend +
829 Python; sw cache simple-v414.
Live finding (Network rejection events): the card asks the terminal for the
current date and time (PROVIDE LOCAL INFORMATION, qualifier 03) and our TR
answered "performed successfully" with no data. TS 102 223 6.4.15 says the
terminal shall return the current date and time, and the 6.8.0 TR structure
requires the Date-Time and Time zone object (8.39) for that qualifier.
- _pli_data_hex(qual): the TR Config dictionary entry wins; when it is empty
the date/time qualifier is answered from the host clock via _encode_scts
(the SMS timestamp builder, TP-SCTS coding).
- _build_tr and _DefaultProactiveHandler put the command-specific data objects
after the Result TLV per the 6.8.0 order (the POLL INTERVAL Duration echo
too; real terminal responses pin the order: 8103010300 02028281 030100
0402011E).
- _decode_tr decodes qualifier 03 with the same 8.39 coding (swapped
semi-octet BCD digits, time-zone sign bit 0x08, 'FF' = unknown); it read
plain decimal bytes and a 0x80 sign before.
- The PWA PLI dictionary codec for the date/time entry writes the same coding
(it wrote plain hex bytes and a 0x80 sign), and the TR Config panel notes
the empty-entry default. sw cache simple-v351.
Tests: builder vectors (east/west/unknown zone) + dictionary override + the
empty non-date/time qualifier + the object order (PLI and POLL INTERVAL) + the
handler path + the TR decode + a frontend codec round-trip test.