feat: card-driven STATUS polling and the Poll Interval Negotiation event (v3.5.9)
- EVENT_NAMES (server + PWA) corrected against TS 102 223 v18.3.0 8.25: 0x14 is "Access technology change (multiple)" (not Change of UICC Access), 0x19 Profile container, 0x1A Void, 0x1B Secured profile container, 0x1C Poll interval negotiation, 0x20-0x22 reserved. Values the CAT spec leaves "Reserved for 3GPP" now carry the concrete TS 31.111 event name + clause (0x11 (I-)WLAN access status, 0x12 Network rejection, 0x15 CSG cell selection, 0x17 IMS registration, 0x18 Incoming IMS data, 0x1D Data connection status change, 0x1E CAG cell selection, 0x1F Slices status change). - Poll Interval Negotiation (0x1C) in the Phone tab: the form proposes a Duration (unit + interval) and the UICC's answer (TS 102 223 8.97 accepted / rejected / modified + optional Duration) is decoded and shown; a "modified" duration becomes the background poll interval. The form appears when the card subscribed to the event, like every other. - Polling emulation is card-driven: a POLL INTERVAL adopts its Duration (minutes/seconds/tenths -> 1..255 s, logged) for the background poll, is echoed in the TERMINAL RESPONSE (6.8.4) and clears a POLLING OFF suspension; POLLING OFF (6.4.14) suspends proactive polling until a new POLL INTERVAL - the manual Send STATUS button and presence detection are unaffected. /api/poll-status and /api/poll-toggle report card_disabled (+ a warning when enabling while suspended); the PWA shows it in amber. - Tests: tests/test_poll.py +7, test_proactive_names.py +3, frontend event_forms +2 and poll_ui (4). Help EN/RU, docs/api.md, AGENTS. 573 frontend / 439 Python green; version 3.5.9; sw cache simple-v262.
This commit is contained in:
@@ -7,7 +7,7 @@ missing entry makes the proactive log show the generic 'Cmd 0x01' fallback.
|
||||
|
||||
import unittest
|
||||
|
||||
from pysim_simple_server.server import PROACTIVE_TYPE_NAMES
|
||||
from pysim_simple_server.server import EVENT_NAMES, PROACTIVE_TYPE_NAMES
|
||||
|
||||
|
||||
class ProactiveTypeNamesTests(unittest.TestCase):
|
||||
@@ -34,5 +34,43 @@ class ProactiveTypeNamesTests(unittest.TestCase):
|
||||
self.assertTrue(isinstance(name, str) and name, hex(value))
|
||||
|
||||
|
||||
class EventNamesTests(unittest.TestCase):
|
||||
"""Event list names follow TS 102 223 v18.3.0 8.25; the values the CAT
|
||||
spec leaves "Reserved for 3GPP" carry the TS 31.111 event name."""
|
||||
|
||||
def test_reassigned_values_match_the_pinned_spec(self):
|
||||
for value, name in [
|
||||
(0x0B, 'Access technology change (single)'),
|
||||
(0x14, 'Access technology change (multiple)'),
|
||||
(0x19, 'Profile container'),
|
||||
(0x1A, 'Void'),
|
||||
(0x1B, 'Secured profile container'),
|
||||
(0x1C, 'Poll interval negotiation'),
|
||||
(0x20, 'Reserved for 3GPP (future usage)'),
|
||||
]:
|
||||
self.assertEqual(EVENT_NAMES[value], name, hex(value))
|
||||
|
||||
def test_3gpp_reserved_events_carry_their_3gpp_name(self):
|
||||
for value, fragment, clause in [
|
||||
(0x11, '(I-)WLAN access status', 'TS 31.111 7.5.1'),
|
||||
(0x12, 'Network rejection', 'TS 31.111 7.5.2'),
|
||||
(0x15, 'CSG cell selection', 'TS 31.111 7.5.3'),
|
||||
(0x17, 'IMS registration', 'TS 31.111 7.5.21'),
|
||||
(0x18, 'Incoming IMS data', 'TS 31.111 7.5.20'),
|
||||
(0x1D, 'Data connection status change', 'TS 31.111 7.5.25'),
|
||||
(0x1E, 'CAG cell selection', 'TS 31.111 7.5.26'),
|
||||
(0x1F, 'Slices status change', 'TS 31.111 7.5.27'),
|
||||
]:
|
||||
name = EVENT_NAMES[value]
|
||||
self.assertIn('Reserved for 3GPP', name, hex(value))
|
||||
self.assertIn(fragment, name, hex(value))
|
||||
self.assertIn(clause, name, hex(value))
|
||||
|
||||
def test_names_are_nonempty_strings(self):
|
||||
for value, name in EVENT_NAMES.items():
|
||||
self.assertIsInstance(value, int)
|
||||
self.assertTrue(isinstance(name, str) and name, hex(value))
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
unittest.main()
|
||||
|
||||
Reference in New Issue
Block a user