From 85ba2a709d7b4436ced49da1c2ee7be94d28b95e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=90=D0=BD=D1=82=D0=BE=D0=BD=20=D0=A2=D1=80=D0=BE=D1=88?= =?UTF-8?q?=D0=B8=D0=BD?= Date: Mon, 28 Sep 2026 23:18:00 +0300 Subject: [PATCH] fix: explain the FF21 resource block and move the format line last (v3.6.27) The explorer's FF21 block was titled "Memory (GET DATA FF21)" although the tag is the Extended Card Resources Information (GP tag FF21, TS 102 226 8.2.1.7.2: installed applications, free non-volatile and free volatile memory), and the detected RAM command format line sat between the Free NV and Free Volatile lines. - Heading is now "Card resources (GET DATA FF21)" with a tooltip naming the tag and its three fields (EN/RU). - The "RAM command format:" line moved after the resource lines. - Help EN/RU spells out what FF21 returns; test asserts the format line follows the resource lines. 657 frontend / 504 Python green; version 3.6.27; sw simple-v300. --- frontend/help-ru.html | 2 +- frontend/help.html | 2 +- frontend/index.html | 11 ++++++----- frontend/sw.js | 2 +- frontend/tests/ram.test.js | 10 ++++++++++ pyproject.toml | 2 +- pysim_simple_server/server.py | 2 +- 7 files changed, 21 insertions(+), 10 deletions(-) diff --git a/frontend/help-ru.html b/frontend/help-ru.html index 1bc961d..cdec770 100644 --- a/frontend/help-ru.html +++ b/frontend/help-ru.html @@ -320,7 +320,7 @@ - +
ОперацияОписание
Обзор карты (все данные GP)Запрос GET STATUS для ISD, приложений, ELF и модулей ELF, а также GET DATA FF21 для информации о памяти. Если карта отвергает компактный формат листинга (P2.b2=0, устаревший по GP), запросы повторяются в расширенном формате E3; флажок Запрашивать расширенные данные реестра (E3) дополнительно запрашивает их и объединяет расширенные поля (привилегии, связи ELF/SD, списки модулей). Результаты отображаются в обзоре с кнопками Удалить для каждого элемента и определённым форматом команд RAM.
Обзор карты (все данные GP)Запрос GET STATUS для ISD, приложений, ELF и модулей ELF, а также GET DATA FF21 (расширенные ресурсы карты: число установленных приложений и свободная энергонезависимая/энергозависимая память). Если карта отвергает компактный формат листинга (P2.b2=0, устаревший по GP), запросы повторяются в расширенном формате E3; флажок Запрашивать расширенные данные реестра (E3) дополнительно запрашивает их и объединяет расширенные поля (привилегии, связи ELF/SD, списки модулей). Результаты отображаются в обзоре с кнопками Удалить для каждого элемента и определённым форматом команд RAM.
Установка пакета (.cap файл)Отправка .cap файла на карту через сервер: INSTALL[for load] → LOAD ×N → INSTALL[for install (+make selectable)]. Load-файл делится на LOAD APDU размера размер блока LOAD (1–240 байт полезной нагрузки, по умолчанию 240); каждый защищённый пакет доставляется одним SMS или, если он больше, конкатенированной SMS-PP загрузкой до 5 сегментов, так что большой .cap просто занимает несколько SMS. Сразу после выбора файл проверяется и в форме показывается оценка требований к памяти: требование NVRAM (образ кода + постоянные данные, сумма в стиле C6+C8 из GP Card Spec) и оценка RAM. Там же показаны библиотеки, с которыми слинкован CAP (его компонент Import: имя библиотеки, AID и минимальная версия ≥ x.y — имена стандартных библиотек и семейства подставляются, а где известно, даётся подсказка о версии Java Card), идентификаторы пакета и апплетов и разбивка по компонентам (размеры и доли в порядке load-файла) — всё сгруппировано по разделам Package, Requires, Memory и Components. Повреждённый файл не проходит анализ, и Execute остаётся недоступной до успешного анализа.
diff --git a/frontend/help.html b/frontend/help.html index 98e4d60..f6f0045 100644 --- a/frontend/help.html +++ b/frontend/help.html @@ -319,7 +319,7 @@ - +
OperationDescription
Explore Card (all GP data)Queries GET STATUS for ISD, Applications, ELFs, and ELF Modules, plus GET DATA FF21 for memory info. If a card rejects the compact listing (P2.b2=0, deprecated by GP) the queries are retried in the expanded E3 form; the Query expanded registry details (E3) checkbox also requests it as an extra pass and merges the expanded-only fields (privileges, ELF/SD associations, module lists). Results appear in an explorer view with per-item Delete buttons and the detected RAM command format.
Explore Card (all GP data)Queries GET STATUS for ISD, Applications, ELFs, and ELF Modules, plus GET DATA FF21 (Extended Card Resources: the number of installed applications and the free non-volatile/volatile memory). If a card rejects the compact listing (P2.b2=0, deprecated by GP) the queries are retried in the expanded E3 form; the Query expanded registry details (E3) checkbox also requests it as an extra pass and merges the expanded-only fields (privileges, ELF/SD associations, module lists). Results appear in an explorer view with per-item Delete buttons and the detected RAM command format.
Install Package (.cap file)Sends a .cap file to the card via the server: INSTALL[for load] → LOAD ×N → INSTALL[for install (+make selectable)]. The load file is split into LOAD APDUs of the LOAD block size (1–240 bytes of payload, 240 by default); each secured packet is delivered as a single SMS or, when larger, as a concatenated SMS-PP download of up to 5 segments, so a large .cap simply takes several SMS. As soon as the file is selected it is validated and its memory requirements are estimated in the form: the NVRAM requirement (the code image + persistent data, the GlobalPlatform Card Spec C6+C8 style total) and the RAM estimate. The same box reports the libraries the CAP is linked against (its Import component: library name, AID and the minimum version ≥ x.y, with standard names and families resolved and a Java Card SDK hint where known), the package/applet identity and the component breakdown (sizes and shares in load-file order) — grouped under the Package, Requires, Memory and Components headings. A corrupt or wrong-format file fails the analysis, and Execute stays disabled until a successful analysis.
diff --git a/frontend/index.html b/frontend/index.html index 294821b..55e72e8 100644 --- a/frontend/index.html +++ b/frontend/index.html @@ -1713,7 +1713,7 @@ // ===== Version ===== // Single source of truth for the PWA version: shown in the header and used // by the server version check in pysimConnect(). -const SIMPLE_VERSION = '3.6.26'; +const SIMPLE_VERSION = '3.6.27'; document.getElementById('app-version').textContent = 'v' + SIMPLE_VERSION; // ===== Tab switching ===== @@ -8843,11 +8843,11 @@ function ramRenderExploreHtml(mem, isd, apps, elfs, fmt) { let html = ''; if (mem && (mem.appCount != null || mem.freeNV != null || mem.freeV != null)) { html += '
'; - html += '
' + esc(t('Memory (GET DATA FF21)')) + '
'; + html += '
' + esc(t('Card resources (GET DATA FF21)')) + '
'; html += '
' + esc(t('Applications:')) + ' ' + (mem.appCount != null ? mem.appCount : '?') + '
'; html += '
' + esc(t('Free NV:')) + ' ' + (mem.freeNV != null ? mem.freeNV + ' B' : '?') + '
'; - if (fmt) html += '
' + esc(t('RAM command format:')) + ' ' + esc(fmt) + '
'; html += '
' + esc(t('Free Volatile:')) + ' ' + (mem.freeV != null ? mem.freeV + ' B' : '?') + '
'; + if (fmt) html += '
' + esc(t('RAM command format:')) + ' ' + esc(fmt) + '
'; html += '
'; } if (isd && isd.length) { @@ -9039,7 +9039,7 @@ async function ramExplore(sp) { if (collector.length === before && compactError && !quiet) errors.push(compactError); } - ramShowProgress(t('Memory (GET DATA FF21)') + '...'); + ramShowProgress(t('Card resources (GET DATA FF21)') + '...'); try { const memRes = await ramSendOta('80CAFF2100', Object.assign({}, sp, { spi2: '01' })); if (memRes.ram_format) sp.ram_format = memRes.ram_format; @@ -17555,7 +17555,8 @@ const LANG_RU = { 'KIc key and KID key are required': 'Укажите ключ KIc и ключ KID', 'RAM command format:': 'Формат команд RAM:', 'Query expanded registry details (E3)': 'Запрашивать расширенные данные реестра (E3)', - 'Memory (GET DATA FF21)': 'Память (GET DATA FF21)', + 'Card resources (GET DATA FF21)': 'Ресурсы карты (GET DATA FF21)', + 'Extended Card Resources (GP tag FF21, ETSI TS 102 226 8.2.1.7.2): installed applications, free non-volatile and free volatile memory': 'Расширенные ресурсы карты (тег GP FF21, ETSI TS 102 226 8.2.1.7.2): число установленных приложений, свободная энергонезависимая и свободная энергозависимая память', 'No secured packet to send. Generate a secure packet first.': 'Нет защищённого пакета для отправки. Сначала соберите пакет.', 'No secured packet to verify. Generate a secure packet first.': 'Нет защищённого пакета для проверки. Сначала соберите пакет.', 'Select': 'Выборка', diff --git a/frontend/sw.js b/frontend/sw.js index 9891839..bfee2fa 100644 --- a/frontend/sw.js +++ b/frontend/sw.js @@ -1,4 +1,4 @@ -const CACHE = 'simple-v299'; +const CACHE = 'simple-v300'; const URLS = [ 'index.html', 'help.html', diff --git a/frontend/tests/ram.test.js b/frontend/tests/ram.test.js index 3b74639..85a4ad0 100644 --- a/frontend/tests/ram.test.js +++ b/frontend/tests/ram.test.js @@ -180,6 +180,16 @@ test('STORE DATA ram-enc P1 values 00/40/80/C0/E0', () => { } }); +test('ramRenderExploreHtml puts the command format after the resource lines', () => { + global.t = s => s; + const out = ramRenderExploreHtml({ appCount: 5, freeNV: 100, freeV: 50 }, [], [], [], 'compact'); + delete global.t; + const iNv = out.indexOf('Free NV:'); + const iV = out.indexOf('Free Volatile:'); + const iFmt = out.indexOf('RAM command format:'); + assert.ok(iNv >= 0 && iV >= 0 && iFmt > iV, out); +}); + test('ramRenderExploreHtml localizes every label and button', () => { const seen = []; global.t = s => { seen.push(s); return 'XX' + s; }; diff --git a/pyproject.toml b/pyproject.toml index c6fc4db..54cacd3 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta" [project] name = "pysim-simple-server" -version = "3.6.26" +version = "3.6.27" description = "HTTP REST server wrapping pysim for the SIMple PWA" requires-python = ">=3.8" # pysim is a git-only dependency installed explicitly by setup.bat/setup.sh. diff --git a/pysim_simple_server/server.py b/pysim_simple_server/server.py index 5464964..b051791 100644 --- a/pysim_simple_server/server.py +++ b/pysim_simple_server/server.py @@ -31,7 +31,7 @@ from osmocom.tlv import BER_TLV_IE from osmocom.utils import rpad -VERSION = '3.6.26' +VERSION = '3.6.27' MAX_ENVELOPE_SEGMENTS = 5 # max SMS segments for outgoing C-APDU in ENVELOPE