snapshots: measure SELECT / READ commands and show timing stats

Server measures every classified APDU (A4 select, B0 read binary, B2 read
record) from command to response: _collect_apdu_times() enables the tracer
(reattaching it if pySim nulled it) and /api/select + /api/read return
'apdu_times': [{type, ms}]. Collection is safe: handlers hold _CARD_LOCK.

Snapshots store per-file {select_ms, read_ms}, a ms value per record and
snapshot-level stats {select, read_binary, read_record}: {min, max, avg,
count} plus total_ms (wall time of the scan). The snapshot view gets a
summary under the title (files/records counts, scan time, min/avg/max per
command type) and shows select/read per file and read time per record.
Timings are display-only: checks, snapshots comparison and imports ignore
them (old snapshots simply show 'No timing data').

Tests: Python classifier/collection (tests/test_apdu_timing.py) and
frontend stats/accumulator/format/build-file/summary. SW cache v99 ->
v100; help, README and docs/api.md updated.
This commit is contained in:
2026-09-12 14:56:59 +03:00
parent a261675aad
commit 6d30e7095e
11 changed files with 391 additions and 44 deletions
+1 -1
View File
@@ -529,7 +529,7 @@ The scan dialog asks for a profile name and offers the FCP/FCI mode described ab
#### Card snapshots
The list view has two tabs — **Profiles** and **Card snapshots**. A snapshot is an immutable capture of the card filesystem: for every existing file it stores the path, symbolic name, file type, size (or record length/count), the raw FCI from the SELECT response, and the contents whenever the file is readable (no ignore list, no masking). The ICCID is decoded from EF.ICCID and shown next to the snapshot name.
The list view has two tabs — **Profiles** and **Card snapshots**. A snapshot is an immutable capture of the card filesystem: for every existing file it stores the path, symbolic name, file type, size (or record length/count), the raw FCI from the SELECT response, and the contents whenever the file is readable (no ignore list, no masking). The ICCID is decoded from EF.ICCID and shown next to the snapshot name. The scan also measures every card command (SELECT / READ BINARY / READ RECORD) from command to response and stores min/avg/max per type plus the total scan time; the snapshot view shows these in the summary and the select/read time per file (read time per record). Timings are display-only and ignored by checks/comparisons.
- **New snapshot** scans the card; **Import snapshot** loads JSON.
- Each snapshot row has **Open** (all captured data read-only, raw FCI with decoded FCI and contents; only the name is editable), **Export**, and **Delete**.