v3.25.2: the TR tag-form alignment with TS 102 223 6.8.0/6.8.1

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.
This commit is contained in:
2026-10-11 13:31:49 +03:00
parent beb001846f
commit 547ea61708
12 changed files with 238 additions and 161 deletions
+9 -8
View File
@@ -701,7 +701,7 @@ def _encode_text(text, dcs):
def build_tr(cmd_num, cmd_type, dev_dst, dev_src, respond, answer_tlvs=None,
cmd_qual=None):
cmd_qual=None, cd_tag=None):
"""Flat COMPREHENSION-TLV TERMINAL RESPONSE payload (TS 102 223 6.8) in the
6.8.0 object order: command details, device identities, Result, then the
command-specific objects (the terminal's own `answer_tlvs` - the PLI data
@@ -709,11 +709,12 @@ def build_tr(cmd_num, cmd_type, dev_dst, dev_src, respond, answer_tlvs=None,
Text string for GET INKEY/GET INPUT, the Item identifier for SELECT ITEM)
and any extra raw TLVs. Matches the interactive menu TR layout; the
runner passes the terminal objects the script did not override. The
command details echo the command's qualifier (TS 102 223 6.8.1: the
object shall be identical to the command's)."""
out = bytearray([0x81, 0x03, cmd_num & 0xFF, cmd_type & 0xFF,
command details echo the command's tag form and qualifier (TS 102 223
6.8.1: the object shall be identical to the command's); the response
objects use the base (CR=0) forms per 6.8.0 (Min = N) - v3.25.2."""
out = bytearray([(cd_tag or 0x81), 0x03, cmd_num & 0xFF, cmd_type & 0xFF,
(cmd_qual or 0) & 0xFF])
out += bytes([0x82, 0x02, dev_dst & 0xFF, dev_src & 0xFF])
out += bytes([0x02, 0x02, dev_dst & 0xFF, dev_src & 0xFF])
result = int(respond.get('result', 0))
add_info = int(respond.get('additional_info', 0) or 0)
out += bytes([0x83, 0x02, result & 0xFF, add_info & 0xFF])
@@ -723,13 +724,13 @@ def build_tr(cmd_num, cmd_type, dev_dst, dev_src, respond, answer_tlvs=None,
text = str(respond['text'])
if text == '':
# TS 102 223 8.15: a null text string is Length 00, no value part
out += bytes([0x8D, 0x00])
out += bytes([0x0D, 0x00])
else:
dcs = int(respond.get('dcs', 0x00))
body = _encode_text(text, dcs)
out += bytes([0x8D, len(body) + 1, dcs]) + body
out += bytes([0x0D, len(body) + 1, dcs]) + body
if respond.get('item_id') is not None and result == 0x00:
out += bytes([0x90, 0x01, respond['item_id'] & 0xFF])
out += bytes([0x10, 0x01, respond['item_id'] & 0xFF])
if respond.get('raw'):
out += bytes.fromhex(respond['raw'])
return bytes(out)