diff --git a/pysim_simple_server/__main__.py b/pysim_simple_server/__main__.py index a46acdf..4dab33d 100644 --- a/pysim_simple_server/__main__.py +++ b/pysim_simple_server/__main__.py @@ -18,7 +18,7 @@ from . import presets from . import test_scripts from . import test_suites from . import testscript -from .server import PysimHandler, StderrApduTracer, _LoggingApduTracer, VERSION, _send_terminal_profile, _DefaultProactiveHandler, _handle_proactive_chain, _send_status, _init_proactive_session, _timing_on, _tlog, _set_menu_timeout, start_card_monitor, set_auto_equip, _read_iccid, _netstate_read, _netstate_install, _LineFilter, _test_command_type, migrate_scripts_to_suites +from .server import PysimHandler, StderrApduTracer, _LoggingApduTracer, VERSION, _send_terminal_profile, _DefaultProactiveHandler, _handle_proactive_chain, _send_status, _init_proactive_session, _timing_on, _tlog, _set_menu_timeout, start_card_monitor, set_auto_equip, _read_iccid, _read_arr, _netstate_read, _netstate_install, _LineFilter, _test_command_type, migrate_scripts_to_suites _server_start = 0 @@ -220,6 +220,7 @@ def main(): fastinit.install(app) iccid = None netstate_files = None + arr_files = None if scc and card is not None and hasattr(scc, '_tp'): scc._tp.apdu_tracer = _LoggingApduTracer() try: @@ -235,6 +236,13 @@ def main(): netstate_files = _netstate_read(app) except Exception: netstate_files = None + # EF.ARR (the FCP '8B' references): read here too - a card + # present at server start never runs _apply_equipped_card, + # which owns this read on a later equip. + arr_files = _read_arr(app) + if arr_files: + sys.stderr.write('INIT: EF.ARR %s\n' % ', '.join( + '%s (%d rec)' % (a['fid'], a['num_records']) for a in arr_files)) t_phase = time.time() sys.stderr.write('INIT: sending TERMINAL PROFILE %s (CLA=%s)\n' % (opts.terminal_profile, scc.cat_cla)) sm, el = _send_terminal_profile(scc, opts.terminal_profile) @@ -317,6 +325,9 @@ def main(): server.card_present = card is not None server.card_session = 1 if card is not None else 0 server.iccid = iccid + # EF.ARR cache (v3.24.0): read by the startup init above (a card present + # at server start); a later equip refreshes it in _apply_equipped_card. + server.arr = arr_files # Network state monitor: install the state read during the startup init # (right after the ICCID, before the TERMINAL PROFILE). No readable # ICCID means the card is considered unusable - give up. diff --git a/tests/test_arr.py b/tests/test_arr.py index 80c0aed..0eba3c0 100644 --- a/tests/test_arr.py +++ b/tests/test_arr.py @@ -147,6 +147,16 @@ class CacheTests(unittest.TestCase): seg = SRC[SRC.index("elif self.path == '/api/write':"):SRC.index("elif self.path == '/api/tree':")] self.assertIn('_arr_refresh_after_write', seg) + def test_the_startup_init_reads_the_arr(self): + # a card present at server start never runs _apply_equipped_card, so + # the startup init reads the ARR in its own CAT-free window (v3.24.0 + # review - the cache was empty on a startup-equipped card) + src = (ROOT / 'pysim_simple_server' / '__main__.py').read_text(encoding='utf-8') + self.assertIn('arr_files = _read_arr(app)', src) + self.assertIn('server.arr = arr_files', src) + imp = src[src.index('from .server import'):] + self.assertIn('_read_arr', imp[:imp.index('\n')]) + class ArrRouteTests(unittest.TestCase): """GET /api/arr serves the session cache without touching the card."""