diff --git a/README.md b/README.md index 46d60f1..3a50bf8 100644 --- a/README.md +++ b/README.md @@ -82,7 +82,7 @@ CLA = `A0` (GSM 11.11 / ISO 7816-4). Every SELECT row offers a file picker: a filter box, an **all files** toggle, the session start root with the current DF, and the file list grouped by root (`MF`, `ADF.USIM`, ...). Picking a file fills the fields for the current method; when the method cannot express the selection the picker switches to one that can - preferring **path** (one SELECT), then **chain** - and says so, e.g. `7F106F40` (path from MF) or `7F20,6F46` (relative FID chain). - **List source**: with a card equipped the loaded file-manager tree wins (card names, probed presence; probed-absent files are hidden). Without a card, or for branches the tree has not loaded, the shipped standard list is used: `uicc_files.json`, generated from pySim's profiles/application classes by `pysim_simple_server/uicc_files.py` and drift-guarded by `tests/test_uicc_files.py`. It is specs-default until **Probe all files** runs in the file manager. Custom files are always merged. -- **Session start**: the implicit current DF follows the TAR the secured packet is sent to (UICC Shared File System RFM -> MF, TS 102 226 §7.2; ADF RFM -> its ADF, §7.3). Defaults: MF here, ADF.USIM for USIM RFM; changeable per row. +- **Session start**: the implicit current DF follows the TAR the secured packet is sent to (UICC Shared File System RFM -> MF, TS 102 226 §7.2; ADF RFM -> its ADF, §7.3). Defaults: MF for both builders; changeable per row (pick the ADF to work in an ADF session). - **Path** is the FID sequence from MF without the MF identifier (ISO 7816-4); the USIM "from current DF" variant uses the relative tail. **Chain** stays relative to the current DF and follows the TS 102 221 §11.1.1.2 FID search order (children, parent, siblings). - ADF roots are not pickable - an application is selected by AID, which the **By AID** method keeps manual (TS 102 226 §7.1 forbids P1=`04` for RFM). diff --git a/README_RUS.md b/README_RUS.md index 63aed67..9fb03e0 100644 --- a/README_RUS.md +++ b/README_RUS.md @@ -82,7 +82,7 @@ CLA = `A0` (GSM 11.11 / ISO 7816-4). У каждой строки SELECT есть выбор файла: поле фильтра, переключатель **all files**, корень начала сессии с текущим DF и список файлов по корням (`MF`, `ADF.USIM`, ...). Выбор файла заполняет поля текущего метода; если метод не может выразить выбор, помощник переключается на подходящий - предпочитая **path** (один SELECT), затем **chain** - и сообщает об этом, например `7F106F40` (путь от MF) или `7F20,6F46` (относительная цепочка FID). - **Источник списка**: при подключённой карте приоритет у загруженного дерева файлового менеджера (имена карты, проверенное наличие; отсутствующие скрываются). Без карты и для незагруженных ветвей используется поставляемый стандартный список: `uicc_files.json`, собранный из профилей/классов приложений pySim скриптом `pysim_simple_server/uicc_files.py` и проверяемый `tests/test_uicc_files.py`. До запуска **«Проверить все файлы»** список соответствует спецификациям. Пользовательские файлы добавляются всегда. -- **Начало сессии**: неявный текущий DF зависит от TAR, на который отправляется защищённый пакет (UICC Shared File System RFM -> MF, TS 102 226 §7.2; ADF RFM -> свой ADF, §7.3). По умолчанию: MF здесь и ADF.USIM для USIM RFM; меняется для каждой строки. +- **Начало сессии**: неявный текущий DF зависит от TAR, на который отправляется защищённый пакет (UICC Shared File System RFM -> MF, TS 102 226 §7.2; ADF RFM -> свой ADF, §7.3). По умолчанию: MF для обоих конструкторов; меняется для каждой строки (выберите ADF для работы в сессии ADF). - **Path** - последовательность FID от MF без идентификатора MF (ISO 7816-4); вариант USIM «from current DF» использует относительный хвост. **Chain** остаётся относительным к текущему DF и следует порядку поиска FID из TS 102 221 §11.1.1.2 (дети, родитель, соседи). - Корни ADF не выбираются - приложение выбирается по AID, и метод **By AID** остаётся ручным (TS 102 226 §7.1 запрещает P1=`04` для RFM). diff --git a/frontend/help-ru.html b/frontend/help-ru.html index 5dbe109..19488c3 100644 --- a/frontend/help-ru.html +++ b/frontend/help-ru.html @@ -98,7 +98,7 @@

У каждой строки SELECT под полями метода есть выбор файла: поле фильтра, переключатель all files, корень начала сессии с текущим DF и список файлов, сгруппированный по корню (MF, ADF.USIM, …). Выбор файла заполняет поля текущего метода; если метод не может выразить выбор, помощник переключается на подходящий — предпочитая path (один SELECT), затем chain — и пишет об этом в строке примечания, например файл из другого DF становится 7F106F40 (путь от MF) или 7F20,6F46 (относительная цепочка FID).

diff --git a/frontend/help.html b/frontend/help.html index 138f045..a240f16 100644 --- a/frontend/help.html +++ b/frontend/help.html @@ -98,7 +98,7 @@

Every SELECT row has a file picker below the method fields: a filter box, an all files toggle, the session start root with the current DF, and the file list grouped by root (MF, ADF.USIM, …). Picking a file fills the fields for the current method; when the method cannot express the selection the picker switches to one that can — preferring path (one SELECT), else chain — and says so in the note line, e.g. a file under another DF becomes 7F106F40 (path from MF) or 7F20,6F46 (relative FID chain).

diff --git a/frontend/index.html b/frontend/index.html index 4605e63..e505743 100644 --- a/frontend/index.html +++ b/frontend/index.html @@ -3311,7 +3311,10 @@ function rfmFileEntries() { // packet is sent to, not on the builder, so the picker lets it be changed. function rfmStartDf(chainId) { if (!_rfmStartDf[chainId]) { - _rfmStartDf[chainId] = chainKind(chainId) === 'usim' ? 'ADF.USIM' : 'MF'; + // MF for both builders: the real implicit DF follows the TAR the + // secured packet is sent to (TS 102 226 7.2/7.3), so the picker + // starts neutral and the per-row selector covers ADF sessions. + _rfmStartDf[chainId] = 'MF'; } return _rfmStartDf[chainId]; } diff --git a/frontend/sw.js b/frontend/sw.js index cb6daa2..35b11d8 100644 --- a/frontend/sw.js +++ b/frontend/sw.js @@ -1,4 +1,4 @@ -const CACHE = 'simple-v243'; +const CACHE = 'simple-v244'; const URLS = [ 'index.html', 'help.html', diff --git a/frontend/tests/uicc_files.test.js b/frontend/tests/uicc_files.test.js index a20eff5..f388d12 100644 --- a/frontend/tests/uicc_files.test.js +++ b/frontend/tests/uicc_files.test.js @@ -112,8 +112,10 @@ test('rfmSelectFill prefers path when the method has to switch', () => { assert.deepStrictEqual(fill, { method: 'path', fields: { path: '7F106F40', base: 'mf' }, switched: true }); // ADF entry cannot be reached from MF by FID/path/chain. assert.strictEqual(rfmSelectFill('chain-sim', 0, entry('ADF.USIM/6F07'), rfmFileEntries()), null); - // USIM RFM starts in ADF.USIM: its files are direct children, deep ones use - // the relative path from the current DF. + // USIM RFM in an ADF session (the picker defaults to MF for both + // builders, so the ADF context is selected explicitly): ADF files are + // direct children, deep ones use the relative path from the current DF. + rfmSetStartDf('chain-usim', 'ADF.USIM'); setChain('chain-usim', [row('select', { method: 'fid' })]); fill = rfmSelectFill('chain-usim', 0, entry('ADF.USIM/6F07'), rfmFileEntries()); assert.deepStrictEqual(fill, { method: 'fid', fields: { fid: '6F07' }, switched: false }); @@ -131,6 +133,7 @@ test('rfmSelectFill falls back to chain when path cannot express it', () => { // DF.GSM-ACCESS branch is not under the current DF and not in the MF tree, // so only the relative chain works. const list = rfmFileEntries(); + rfmSetStartDf('chain-usim', 'ADF.USIM'); setChain('chain-usim', [row('select', { method: 'path', path: '5F3A', base: 'df' })]); const fill = rfmSelectFill('chain-usim', 1, entry('ADF.USIM/5F3B/4F20'), list); assert.strictEqual(fill.method, 'chain'); @@ -153,6 +156,10 @@ test('rfmCurrentDf tracks the session context across rows', () => { assert.strictEqual(rfmCurrentDf('chain-sim', 2, list), 'MF/7F10'); // A path select sets the DF to the file's parent. assert.strictEqual(rfmCurrentDf('chain-sim', 3, list), 'MF/7F10'); + // The picker defaults to MF for both builders; an ADF session is explicit. + delete _rfmStartDf['chain-usim']; + assert.strictEqual(rfmStartDf('chain-usim'), 'MF'); + rfmSetStartDf('chain-usim', 'ADF.USIM'); setChain('chain-usim', [ row('select', { method: 'path', path: '5F3A', base: 'df' }), row('select', { method: 'chain', chain: '4F22' }), @@ -196,6 +203,7 @@ test('rfmFileEntries merges card tree, custom files and the standard list', () = test('rfmFileOptionsHtml labels files with their path within the root', () => { const list = rfmFileEntries(); + rfmSetStartDf('chain-usim', 'ADF.USIM'); setChain('chain-usim', [row('select', { method: 'fid' })]); const opts = rfmFileOptionsHtml('chain-usim', 0, list); // ADF.USIM session: EF.IMSI is a direct child of the root.