scp81 passthru, proactive decoders, ADM badge, file manager layout (v2.2.1)
SCP81: - New listener mode "passthru": no local listener - the card's BIP channels connect straight to a configured external platform (host/port required), which terminates TLS and runs the dialog. The status API reports mode/target (_SCP81_MODE/_SCP81_TARGET) and clears them on stop. PWA mode select, hint, Start validation; TLS PSK stays the default. Proactive command decoding (Phone tab log): - SEND SHORT MESSAGE (0x13) is now decoded: alpha, address (TON/NPI + number), 3GPP-SMS TPDU (type, TP-MR, TP-DA, TP-PID 0x7F flagged as SIM data download, TP-DCS, TP-VP, TP-UDL), UDH concatenation IEs, and the TP-UD as text (GSM-7 with a septet unpacker, UCS2, 8-bit) or as a TS 31.115 secured packet for PID 0x7F; malformed TPDUs fall back to the raw hex line. - PROVIDE LOCAL INFORMATION qualifier names completed per TS 102 223 V18.3.0: ESN (07), MEID (0B), Supported RATs (1A); 05 relabelled "Reserved for GSM (Timing Advance)". Fixed in the server dict and both frontend tables. Header: - Compact ADM badge next to the card indicator: "ADM ✓" green when pySim's adm_verified is set, "ADM ✗" red otherwise, hidden without a card session or when the server is down; updated ahead of the card state-key early return so it never disturbs the connect/reset flow. File manager: - Sort pills (FID/Name), Probe all files button and progress line are pinned above the tree instead of scrolling with it; the tree box cap grows from 420px to 65vh. SW cache otaman-v165; help EN/RU updated; tests 234 Python + 361 frontend.
This commit is contained in:
@@ -682,6 +682,38 @@ class BipControlTest(unittest.TestCase):
|
||||
self.assertFalse(resp['ok'])
|
||||
self.assertIn('unsupported mode', resp['error'])
|
||||
|
||||
def test_passthru_mode_targets_the_external_server(self):
|
||||
resp = server._scp81_bip_control({'action': 'start', 'mode': 'passthru',
|
||||
'host': '10.11.12.13', 'port': 10174})
|
||||
self.assertTrue(resp['ok'], resp)
|
||||
self.assertIsNone(server._SCP81_LISTENER) # no local listener
|
||||
self.assertEqual(resp['listener']['mode'], 'passthru')
|
||||
self.assertEqual(resp['listener']['host'], '10.11.12.13')
|
||||
self.assertEqual(resp['listener']['port'], 10174)
|
||||
self.assertEqual(resp['listener']['target'], '10.11.12.13:10174')
|
||||
self.assertTrue(resp['bip']['enabled'])
|
||||
self.assertEqual(server._BIP.target, ('10.11.12.13', 10174))
|
||||
# the status endpoint sees the passthru mode while it runs ...
|
||||
self.assertEqual(server._scp81_listener_status()['mode'], 'passthru')
|
||||
# ... and stopping clears it (no stale listener in the status)
|
||||
server._scp81_bip_control({'action': 'stop'})
|
||||
self.assertIsNone(server._scp81_listener_status())
|
||||
self.assertFalse(server._BIP.enabled)
|
||||
|
||||
def test_passthru_mode_requires_an_explicit_target(self):
|
||||
# No defaults for a remote platform: the target must be configured.
|
||||
resp = server._scp81_bip_control({'action': 'start', 'mode': 'passthru'})
|
||||
self.assertFalse(resp['ok'])
|
||||
self.assertIn('host and port', resp['error'])
|
||||
resp = server._scp81_bip_control({'action': 'start', 'mode': 'passthru',
|
||||
'host': '10.0.0.1'})
|
||||
self.assertFalse(resp['ok'])
|
||||
resp = server._scp81_bip_control({'action': 'start', 'mode': 'passthru',
|
||||
'port': 1234})
|
||||
self.assertFalse(resp['ok'])
|
||||
self.assertIsNone(server._SCP81_LISTENER)
|
||||
self.assertFalse(server._BIP.enabled)
|
||||
|
||||
def test_start_accepts_explicit_script_list(self):
|
||||
server._SCP81_PSKS = {}
|
||||
server._SCP81_PSK_LEGACY = None
|
||||
|
||||
Reference in New Issue
Block a user