fix: accept comprehension-required tag variants everywhere (v3.6.40)
The TERMINAL PROFILE chain parsed the SET UP MENU title with 'tag == 0x05' only, so the live Alfa card's title (CR-set 0x85, 'Alfa Mobile') was dropped: /api/menu returned items without a title and the PWA showed 'No menu set by the card' - card-specific only because cards pick the tag variant (this one sends plain 0x8F items and a CR-set title in the same command). - _parse_setup_menu_command (pure, tested with the live FETCH bytes) replaces the inline parse; the PWA shows a title-less menu as 'STK: Menu' instead of 'No menu set by the card' (stkMenuLabel, pure). - _cmd_tlv is now the single lookup helper: exact tag, then tag ^ 0x80 (bit 8 is the CR flag, TS 101 220 7.1.1); the old '| 0x80'-only helper and the duplicate _cmd_tlv_any are gone. - Remaining single-style checks fixed: _parse_setup_menu_items (0x8F/0x0F), _parse_select_item title (0x85/0x05), _find_sms_tpdu (0x8B/0x0B - the plain variant lost the SEND SHORT MESSAGE PoR TPDU), the response scripting parsers (R-APDU 0x23/0xA3, executed count 0x80/0x00) and the FF21 resource tags (0x81-0x83/0x01-0x03). - tests/test_tag_variants.py flips the CR flag on every top-level tag of real command fixtures and asserts identical parse results for all parsers (verified to fail when a single-style lookup is reintroduced). sw cache simple-v313; tests: 524 Python / 675 Node.
This commit is contained in:
@@ -49,6 +49,7 @@ from pysim_simple_server.server import (
|
||||
_menu_send_response,
|
||||
_parse_get_input,
|
||||
_parse_get_inkey,
|
||||
_parse_setup_menu_command,
|
||||
_input_text_tlv,
|
||||
_validate_input_response,
|
||||
_pack_gsm7,
|
||||
@@ -1805,6 +1806,35 @@ class StkInputTests(unittest.TestCase):
|
||||
self.assertIn('04020103', server.scc._tp.sent[0].upper())
|
||||
|
||||
|
||||
class SetupMenuParseTests(unittest.TestCase):
|
||||
"""SET UP MENU parsing must accept both TLV tag styles (v3.6.40)."""
|
||||
|
||||
# The live Alfa card's SET UP MENU as fetched during the TERMINAL PROFILE
|
||||
# chain (2026-09-29): the title is the CR-set tag 0x85, the items 0x8F.
|
||||
LIVE_FETCH = bytes.fromhex(
|
||||
'd03c810301250082028182850b416c6661204d6f62696c65'
|
||||
'8f16808112089db0c1c2c0beb9bab82f53657474696e6773'
|
||||
'8f0881810400d4e5f3f418020021')
|
||||
|
||||
def test_live_card_title_and_items_are_parsed(self):
|
||||
menu = _parse_setup_menu_command(self.LIVE_FETCH)
|
||||
self.assertEqual(menu['command_number'], 1)
|
||||
self.assertEqual(menu['title'], 'Alfa Mobile')
|
||||
self.assertEqual(menu['items'][0], {'id': 0x80, 'text': 'Настройки/Settings'})
|
||||
self.assertEqual(menu['items'][1],
|
||||
{'id': 0x81, 'text': 'Test', 'nai': 0x21, 'nai_name': 'DISPLAY TEXT'})
|
||||
|
||||
def test_plain_tag_variants_are_accepted(self):
|
||||
# same command with the plain title tag 0x05 and a plain 0x0F item
|
||||
raw = bytes.fromhex('d012810301250082028182850b416c6661204d6f62696c650f00')
|
||||
menu = _parse_setup_menu_command(raw)
|
||||
self.assertEqual(menu['title'], 'Alfa Mobile')
|
||||
self.assertEqual(menu['items'], [])
|
||||
# a command that is not SET UP MENU has no menu
|
||||
self.assertIsNone(_parse_setup_menu_command(bytes.fromhex('d009810301260182028182')))
|
||||
self.assertIsNone(_parse_setup_menu_command(b''))
|
||||
|
||||
|
||||
class RamProgressTests(unittest.TestCase):
|
||||
"""Live RAM-operation progress exposed in /api/status (v3.6.34)."""
|
||||
|
||||
|
||||
Reference in New Issue
Block a user