feat: offline file list + SELECT picker for the SIM/USIM RFM builders (v3.4.0)

The SELECT rows (compact RFM chains and the Expanded Script C-APDU picker,
which shares the row editor) now have a file picker instead of typing FIDs,
paths or chains by hand.

Data:
- `pysim_simple_server/uicc_files.py` builds the standard file list cardless
  from pySim's profiles and application classes (CardProfileUICC + CardProfileSIM
  for the MF tree, every concrete CardApplication subclass for the ADFs) and
  writes `frontend/uicc_files.json` (490 entries: canonical FID path, symbolic
  name, fid, kind, root, ADF AID).  `tests/test_uicc_files.py` regenerates it
  and fails when pySim adds or renames files.  The asset is precached by the
  service worker, so the builders keep working offline.

Picker:
- Sources merged per canonical path: the loaded file-manager tree (card names
  and probed presence; probed-absent files hidden), custom files, and the
  shipped standard list (specs-default until "Probe all files" has run).
- Default list shows what the current method can express; "all files" reveals
  the rest, and picking one auto-switches the method - preferring path (one
  SELECT) over chain - with a note line explaining the switch.  A "starts in"
  selector sets the implicit current DF (UICC shared-FS RFM app starts in MF,
  an ADF RFM app in its ADF, TS 102 226 7.2/7.3 - the TAR decides; default per
  builder, overridable per row).
- Fill rules: by FID only for direct children of the current DF; path = FID
  sequence from MF without the MF identifier (ISO 7816-4) or the relative tail
  (USIM P1=09); chain stays relative and follows the TS 102 221 11.1.1.2 FID
  search order (children, parent, siblings), so no hop to the common ancestor.
  ADF roots are not pickable (selection is by AID; TS 102 226 7.1 forbids
  P1=04 for RFM) - the By AID method stays manual.

Tests/docs: frontend/tests/uicc_files.test.js (asset shape, merge/priority/
exclusion, fill matrix, relative chains, session-context tracking, option
grouping); help 2.1/2.2 EN+RU, READMEs, AGENTS.  sw cache -> simple-v242.
This commit is contained in:
2026-09-23 08:20:10 +03:00
parent 7aee1818b8
commit b8734189cf
12 changed files with 4762 additions and 5 deletions
+9
View File
@@ -94,6 +94,15 @@
<p class="text-sm mb-3">For record commands, the P2 mode is <strong>Absolute (04)</strong>, <strong>Next (02)</strong>, or <strong>Previous (03)</strong>. When a Case&nbsp;4 command is immediately followed by a GET RESPONSE row, the chain builder strips its trailing Le byte automatically (ETSI TS 102 226 &sect;5.1.1). A conversion panel is embedded in the right column (IMSI, MSISDN, ICCID, SPN, PLMN, nibble swap). See <a href="#conversion" class="text-blue-600 dark:text-blue-400 hover:underline">&sect;2.5</a>.</p>
<p class="text-sm mb-3"><strong>&rarr; Expanded Script</strong> sends the built chain to the Expanded Script builder as C-APDU rows (GET RESPONSE hops are dropped &mdash; the expanded format does not use them, TS 102 226 &sect;5.2.1.1). The UICC Shared File System RFM application (TAR <code class="font-mono text-sm">B00000</code>) is reachable with either the compact or the expanded format &mdash; unless the TAR is configured for automatic format detection, the two use different TAR values (TS 102 226 &sect;7.0/&sect;5.3).</p>
<h4 id="rfm-file-picker" class="font-medium mb-1">SELECT file picker</h4>
<p class="text-sm mb-2">Every SELECT row has a file picker below the method fields: a filter box, an <strong>all files</strong> toggle, the session start root with the current DF, and the file list grouped by root (<code class="font-mono text-sm">MF</code>, <code class="font-mono text-sm">ADF.USIM</code>, &hellip;). Picking a file fills the fields for the current method; when the method cannot express the selection the picker switches to one that can &mdash; preferring <strong>path</strong> (one SELECT), else <strong>chain</strong> &mdash; and says so in the note line, e.g. a file under another DF becomes <code class="font-mono text-sm">7F106F40</code> (path from MF) or <code class="font-mono text-sm">7F20,6F46</code> (relative FID chain).</p>
<ul class="list-disc list-inside text-sm space-y-1 mb-3">
<li><strong>List source</strong>: with a card equipped the loaded file-manager tree wins (card names and probed presence; probed-absent files are hidden). Without a card, or for branches the tree has not loaded, the shipped standard list is used &mdash; <code class="font-mono text-sm">uicc_files.json</code>, generated from pySim's profiles/application classes by <code class="font-mono text-sm">pysim_simple_server/uicc_files.py</code> and kept in sync by a test. The list is specs-default until you run <strong>Probe all files</strong> in the file manager. Custom files are always merged.</li>
<li><strong>Session start</strong>: the implicit current DF depends on the <em>TAR</em> the secured packet is sent to &mdash; the UICC Shared File System RFM application starts in MF (TS 102 226 &sect;7.2), an ADF RFM application in its ADF (&sect;7.3). The picker defaults to MF for this builder and ADF.USIM for USIM RFM (matching the preset TARs) and can be changed per row.</li>
<li><strong>Path</strong> is the FID sequence from MF <em>without</em> the MF identifier (ISO 7816-4: &ldquo;select from the MF &mdash; path without the MF identifier&rdquo;); the USIM <strong>from current DF</strong> variant uses the relative tail. <strong>Chain</strong> stays relative to the current DF and follows the FID search order of TS 102 221 &sect;11.1.1.2 (children &rarr; parent &rarr; siblings), so it never needs a hop to the common ancestor itself.</li>
<li>ADF roots are not pickable: an application is selected by AID, which the <strong>By AID</strong> method keeps manual (TS 102 226 &sect;7.1 forbids P1=<code class="font-mono text-sm">04</code> for RFM).</li>
</ul>
<h3 id="usim-rfm" class="text-lg font-medium mb-2">2.2 USIM RFM</h3>
<p class="mb-2">CLA = <code class="font-mono text-sm">00</code> (ETSI TS 102 221). Same chain builder and command set as SIM, plus the UICC administrative commands, and the TS 102 221 forms of SEARCH RECORD / INCREASE:</p>
<ul class="list-disc list-inside text-sm space-y-1 mb-3">