2 Commits
Author SHA1 Message Date
catarrh 0231df905c equip/init: read the selected EF directly, bound the startup drain
pySim's scc.read_binary/read_record call select_path(ef) first, so the
ICCID, network-state, EF.ARR and EF.PBR readers - which had already made a
parent-scoped selection and hold its FCP - sent a second SELECT per file
and per record.  _read_selected_ef() issues READ BINARY (chunked at
max_cmd_len from the FCP file size) / READ RECORD (b2<rec>04<len> at the
FCP record length) directly; the pySim helpers stay as the fallback when
the FCP lacks the value.

The startup TERMINAL PROFILE drain now breaks on the chain's idle SW
instead of polling STATUS once more.

Measured on the last startup: ~3.4 s traced init (netstate/ARR/PBR 271
APDUs / 1.26 s incl. 169 SELECTs; the card's own TP processing 1.58 s);
the change removes ~0.7-0.8 s of the read phase without touching any data
or the TP.

v3.38.1; tests: tests/test_read_selected.py (direct reads, chunking, the
fallback and the drain source pin) and the ARR/PBR/ICCID/netstate fakes.
1067 Python + 1075 frontend.  sw cache simple-v482.
2026-10-24 18:54:31 +03:00
catarrh 9ae9c39e55 v3.31.0: the EF_PBR (phonebook reference) support
EF_PBR ('4F30', TS 31.102 4.4.2.1) lists the phonebook's files as
BER-TLVs, and those files are not in pySim's model - so they were
invisible in the file tree.

- The PWA gains the decoder (efDecPbr, registered as EF.PBR/4f30): the
  'A8'/'A9'/'AA' type-1/2/3 containers, the 'C0'-'CC' kinds, the 02/03
  value lengths (FID / FID+SFI) and the master EF (the first FID after
  the first 'A8'), tolerant of FF padding, truncation, unknown tags and
  the spec's vague 'AA' path form (kept raw + noted, never a throw).
- The server reads the three PBR copies once per card session
  (best-effort, exactly like EF.ARR) into server.pbr and serves the raw
  records from the card-free GET /api/pbr.
- The file tree is populated SERVER-SIDE (no frontend involvement): a
  small Python parser reads the cached records and /api/tree appends the
  referenced files as children of the DF that holds the PBR
  ({'name','fid','isDir':false,'pbr':true,'sfi'}, deduplicated against
  the model), and /api/tree|select|read|write auto-allow the probe for
  exactly those FIDs, so the injected nodes are clickable without any
  PWA flag.  The node-to-PBR match is by the requested node's normalised
  path: a leading MF before an ADF segment is dropped and an ADF
  addressed by AID (the Profiler's walk) folds onto its name, so both
  DF_PHONEBOOK copies resolve to their own PBR; a full path never falls
  back to another DF's copy, and an ambiguous bare 5F3A injects nothing.
- Drift guard: the JS and Python parsers share
  frontend/tests/pbr_vectors.json, which includes the TS 31.102 Annex G
  record (its printed A8 length is internally inconsistent - 10
  primitives x 5 bytes = 0x32, not the printed 0x2D - so the corrected
  length is used, noted in the case name).

Docs: api.md (/api/pbr, the tree children, the auto-probe, the AA path
form), the repo AGENTS.  953 frontend + 989 Python; sw simple-v455.
2026-10-18 01:47:04 +03:00