v3.30.2: the batch RU wording sweep completed
The v3.30.1 review follow-up. The sweep fixed the two batch-state strings but two more shared (kind-independent) batch strings were still install-specific, so a delete/reinstall batch started under an "install" label: - 'Start batch' was «Запустить пакетную установку» - the ram-batch-start button starts every kind - now «Запустить пакетную операцию» (aligning with the optgroup «Пакетные операции (по картам)»). - the shared panel hint's «...перезапустите пакетную установку» is now «...перезапустите пакетную операцию» (the EN was already neutral). The RU help quoted the old button label: its install row now says «Запустить пакетную операцию не требует карты», and the row's other generic "the batch" statements (never retries, the test-run exclusion) are neutral too; the genuinely install-specific ones (the workflow, the shared install form) stay. The v3.30.1 notes were corrected: the counts labels do follow the last run's kind after a clear (the values stay zero) - the AGENTS entry and the _ramBatchLastKind/ramBatchRender comments say so now. The cleared-title test seeds the state before opening the modal (no reliance on the previous test's sandbox leftovers). 930 frontend + 945 Python; sw cache simple-v452.
This commit is contained in:
1 parent
19dc0c7d56
commit
3db6f59e69
6 files changed
+14
-12
No files matched your search
@@ -323,7 +323,7 @@
|
||||
<tbody>
|
||||
<tr class="border-b border-gray-200 dark:border-slate-700"><td class="py-1 px-2">Обзор карты (все данные GP)</td><td class="py-1 px-2">Запрос GET STATUS для ISD, приложений, ELF и модулей ELF, а также GET DATA FF21 (расширенные ресурсы карты: число установленных приложений и свободная энергонезависимая/энергозависимая память). Компактный листинг содержит только AID, состояние жизненного цикла и привилегии (версии в устаревшем формате нет); если карта отвергает его (<code class="font-mono text-sm">P2.b2=0</code>, устаревший по GP), запросы повторяются в расширенном формате <code class="font-mono text-sm">E3</code>, а флажок <strong>Запрашивать расширенные данные реестра (связи load-файла и SD)</strong> дополнительно запрашивает их и объединяет расширенные поля: версию исполняемого load-файла, AID load-файла, AID Security Domain, списки модулей, пункты меню STK апплета (SCP Registry Data, TS 102 226 8.2.1.6) и любые другие объекты реестра, которые вернула карта (показываются как есть, без потерь) — он стоит несколько дополнительных защищённых пакетов на каждый обзор и <strong>включён по умолчанию</strong> (запоминается в браузере; снимите флажок, чтобы пропустить). Карты различаются в том, что принимают, поэтому расширенный запрос пробуется в трёх формах — эталонный список тегов (с <code class="font-mono text-sm">EA</code> по TS 102 226), тот же список без <code class="font-mono text-sm">EA</code> и вовсе без списка тегов (форма GlobalPlatformPro) — а обзор сообщает, какая форма сработала и где выполнен откат к компактному списку (версии пакетов тогда недоступны). Если строки ELF всё ещё без версий, формы со списком тегов повторяются для обоих P1=10 и P1=20, пропуская уже отклонённые комбинации, и обход останавливается, как только версия найдена. Результаты отображаются в обзоре (строка успеха минимальна, счётчики — в заголовках разделов) с кнопками <strong>Удалить</strong> для каждого элемента и определённым форматом команд RAM (подсказка при наведении объясняет compact и expanded).</td></tr>
|
||||
<tr><td class="py-1 px-2">Установка пакета (.cap файл)</td><td class="py-1 px-2">Отправка <code class="font-mono text-sm">.cap</code> файла на карту через сервер: INSTALL[for load] → LOAD ×N → INSTALL[for install (+make selectable)]. Load-файл делится на LOAD APDU размера <strong>размер блока LOAD</strong> (1–240 байт полезной нагрузки, по умолчанию 240); каждый защищённый пакет доставляется одним SMS или, если он больше, конкатенированной SMS-PP загрузкой до 5 сегментов, так что большой <code>.cap</code> просто занимает несколько SMS. Сразу после выбора файл проверяется и в форме показывается <strong>оценка требований к памяти</strong>: <strong>требование NVRAM</strong> (образ кода + постоянные данные, сумма в стиле C6+C8 из GP Card Spec) и оценка RAM. Там же показаны <strong>библиотеки, с которыми слинкован CAP</strong> (его компонент Import: имя библиотеки, AID и минимальная версия <code class="font-mono text-sm">≥ x.y</code> — имена стандартных библиотек и семейства подставляются, а где известно, даётся подсказка о версии Java Card), идентификаторы пакета и апплетов и разбивка по компонентам (размеры и доли в порядке load-файла) — всё сгруппировано по разделам <strong>Package</strong>, <strong>Requires</strong>, <strong>Memory</strong> и <strong>Components</strong>. Строка <strong>Platform</strong> показывает минимальный уровень Java Card, который должна предоставить карта (выводится из импорта <code class="font-mono text-sm">javacard.framework</code>; флаг <code class="font-mono text-sm">int</code> в заголовке дополнительно требует поддержки int — Java Card 2.2+), и <strong>релиз ETSI</strong>, из которого пришли импорты UICC API (версия <code class="font-mono text-sm">uicc.toolkit</code> → REL-N по корпусу <code class="font-mono text-sm">sim-tools</code> в рабочем каталоге; основание показано в скобках): JCRE проверяет каждый импорт по своим пакетам при верификации load-файла (JC VM spec 4.5.2), поэтому карта со старой платформой отклоняет LOAD сразу после завершения компонента <strong>Import</strong> (в строке шага виден remote SW карты и компонент, который завершил блок, например <em>завершает Import</em>): подсказка при ошибке и попап предлагают <strong>тест совместимости CAP</strong> (в один клик — тот же <code class="font-mono text-sm">.cap</code> уже выбран), чтобы найти отсутствующий пакет и версию; меньший размер блока LOAD помогает только если блок превышает буфер карты. Повреждённый файл не проходит анализ, и <strong>Execute</strong> остаётся недоступной до успешного анализа. Оценка носит справочный характер и никогда не используется при установке: NVRAM — это образ кода плюс постоянные данные (сумма в стиле C6+C8 по GP Table 11-48; управление памятью карты, округление и запись в реестре не учитываются, а образ статических полей входит в обе части); рекомендуемый <strong>C6</strong> следует за load-файлом, а рекомендуемые квоты — это десятичные значения в байтах (шестнадцатеричное значение в скобках — это кодирование параметров установки C7/C8: C6 — энергонезависимый код, C7 — энергозависимая RAM, C8 — энергонезависимые данные). Флажок <strong>Удалить пакет перед установкой (с его приложениями)</strong> добавляет перед цепочкLine truncated
|
||||
<tr class="border-b border-gray-200 dark:border-slate-700"><td class="py-1 px-2">Пакетная установка (.cap на множество карт)</td><td class="py-1 px-2">Массовый сценарий: один <code class="font-mono text-sm">.cap</code> и один набор параметров установки, применяемые карта за картой. <strong>Запустить пакетную установку</strong> не требует карты — цикл ведёт сервер: он ждёт карту, устанавливает сразу после завершения equip и затем ждёт следующую. Для каждой карты <strong>пресет находится по ICCID</strong> и задаёт keyset (по умолчанию из ролевой записи ISD TAR, v3.26.0), ключи и счётчик; карта без подходящего пресета или без пригодного keyset ISD TAR отмечается и пропускается. Каждая попытка попадает в список со временем, ICCID, пресетом, вердиктом и длительностью; при ошибке показаны шаг, на котором она произошла, и удалённый статусный байт — пакетная установка никогда не повторяет попытку и не останавливается при ошибке (ошибки остаются на ваше усмотрение). Карта обрабатывается <strong>один раз за запуск</strong>: повторная установка карты даёт «уже обработана» — для повтора перезапустите пакетную установку. <strong>Остановить</strong> завершает работу после окончания обработки текущей карты (прерванная цепочка LOAD может оставить полузагруженный пакет), а затем завершает запуск; <strong>Очистить</strong> удаляет отчёт завершённого запуска. Цикл работает на сервере, поэтому закрытие вкладки, переключение представлений или перезагрузка страницы его не прерывают; перезапуск сервера завершает запуск. Пакетная установка и тест-скрипт исключают друг друга. Пакетная установка использует ту же форму, поэтому параметр <strong>Удалить пакет перед установкой</strong> применяется к каждой карте.</td></tr>
|
||||
<tr class="border-b border-gray-200 dark:border-slate-700"><td class="py-1 px-2">Пакетная установка (.cap на множество карт)</td><td class="py-1 px-2">Массовый сценарий: один <code class="font-mono text-sm">.cap</code> и один набор параметров установки, применяемые карта за картой. <strong>Запустить пакетную операцию</strong> не требует карты — цикл ведёт сервер: он ждёт карту, устанавливает сразу после завершения equip и затем ждёт следующую. Для каждой карты <strong>пресет находится по ICCID</strong> и задаёт keyset (по умолчанию из ролевой записи ISD TAR, v3.26.0), ключи и счётчик; карта без подходящего пресета или без пригодного keyset ISD TAR отмечается и пропускается. Каждая попытка попадает в список со временем, ICCID, пресетом, вердиктом и длительностью; при ошибке показаны шаг, на котором она произошла, и удалённый статусный байт — пакетная операция никогда не повторяет попытку и не останавливается при ошибке (ошибки остаются на ваше усмотрение). Карта обрабатывается <strong>один раз за запуск</strong>: повторная установка карты даёт «уже обработана» — для повтора перезапустите пакетную операцию. <strong>Остановить</strong> завершает работу после окончания обработки текущей карты (прерванная цепочка LOAD может оставить полузагруженный пакет), а затем завершает запуск; <strong>Очистить</strong> удаляет отчёт завершённого запуска. Цикл работает на сервере, поэтому закрытие вкладки, переключение представлений или перезагрузка страницы его не прерывают; перезапуск сервера завершает запуск. Пакетная операция и тест-скрипт исключают друг друга. Пакетная установка использует ту же форму, поэтому параметр <strong>Удалить пакет перед установкой</strong> применяется к каждой карте.</td></tr>
|
||||
<tr class="border-b border-gray-200 dark:border-slate-700"><td class="py-1 px-2">Пакетная переустановка приложения (по картам)</td><td class="py-1 px-2">Сценарий исправления: для каждой карты удаляется экземпляр приложения (с допуском «не найдено») и заново выполняется INSTALL [for install] из уже загруженного пакета — без <code class="font-mono text-sm">.cap</code> и без LOAD. Поля — параметры одиночного INSTALL [for install] (Load File / Module / Instance AID, привилегии, параметры toolkit/STK, <em>make selectable</em>); пресет, keyset и счётчик берутся из пресета каждой карты, как в остальных пакетных операциях, а список попыток показывает оба вердикта (удаление и установка).</td></tr>
|
||||
<tr class="border-b border-gray-200 dark:border-slate-700"><td class="py-1 px-2">Пакетное удаление (по картам)</td><td class="py-1 px-2">Удаляет один объект на каждой карте: приложение (только экземпляр, P2=<code class="font-mono text-sm">0x00</code>) или пакет с его приложениями (каскадно, P2=<code class="font-mono text-sm">0x80</code>). Поля: AID и цель. Результат «не найдено» (объект уже отсутствует) отмечается как таковой и считается успешным; любая другая ошибка показывается со статусным словом карты.</td></tr>
|
||||
<tr class="border-b border-gray-200 dark:border-slate-700"><td class="py-1 px-2">Проверка совместимости CAP</td><td class="py-1 px-2">Отвечает на один вопрос, ничего не устанавливая: <strong>может ли эта карта удовлетворить список импортов CAP?</strong> Сервер выполняет проверку формата, INSTALL[for load] и блоки LOAD только до блока, завершающего компонент <strong>Import</strong> — именно там JCRE проверяет список импортов — и останавливается: без флага последнего блока и без INSTALL[for install], поэтому ничего не фиксируется и удалять после этого ничего не нужно. Список <strong>«Версии импортов для проверки»</strong> предзаполняется из анализа CAP: <code class="font-mono text-sm">AID=version</code> переписывает запрошенную версию импорта, <code class="font-mono text-sm">+AID=version</code> добавляет синтетический импорт (запрос возможностей карты: LOAD проходит, только если карта экспортирует этот пакет версии ≥ указанной), а <strong>«Все 0.0»</strong> снимает все требования. Использование в два шага: нажмите «Все 0.0» — если проверка проходит, причиной был список импортов; затем возвращайте по одной строке, чтобы найти пакет и версию, которых не хватает карте. Вердикт явно указывает, что проверяется только <strong>этап LOAD/импортов</strong>: этап связывания (наличие реально вызываемых API) проверяет настоящая установка на INSTALL[for install]. Запуск и результат показываются в окне (как при установке): строки шагов, вердикт и блок деталей по каждому AID — при отказе он называет раздел CAP, который покрывает неудачный блок (диапазон байтов load-файла и компоненты, и завершает ли этот блок <strong>Import</strong>), SW команды с его значением, список импортов ровно в том виде, в каком он проверялся (версии CAP, правки пробы, добавленные синтетические записи, строки без совпадений) и что означает состояние пробы; при успехе — список импортов, который прошёл проверку.</td></tr>
|
||||
|
||||
+7
-6
@@ -1932,7 +1932,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.30.1';
|
||||
const SIMPLE_VERSION = '3.30.2';
|
||||
document.getElementById('app-version').textContent = 'v' + SIMPLE_VERSION;
|
||||
|
||||
// ===== view history (the browser Back/Forward buttons) =====
|
||||
@@ -10192,8 +10192,8 @@ let _ramBatchSummary = null; // /api/status.ram_batch
|
||||
let _ramBatchProgress = null; // /api/status.ram_progress
|
||||
let _ramBatchModalShown = false; // the batch status modal is open (v3.30.0)
|
||||
let _ramBatchLastKind = null; // the last seen run kind: a cleared report
|
||||
// (kind: null) keeps the modal's title right
|
||||
// (v3.30.1)
|
||||
// (kind: null) keeps the modal's title and the
|
||||
// counts labels on that kind (v3.30.1)
|
||||
// A fetch that never settled must not block the report forever (v3.28.7).
|
||||
const RAM_BATCH_FETCH_STALE_MS = 10000;
|
||||
|
||||
@@ -10351,7 +10351,8 @@ function ramBatchRender() {
|
||||
const phase = st.phase || (active ? 'waiting_card' : 'idle');
|
||||
// The success labels follow the operation (v3.29.0): the counts bucket is
|
||||
// 'installed' for every kind - "the operation succeeded". The last seen
|
||||
// kind is remembered for the modal's title (v3.30.1).
|
||||
// kind is remembered for the modal's title and these labels, so a cleared
|
||||
// report keeps the run's kind (v3.30.1).
|
||||
if (st.kind) _ramBatchLastKind = st.kind;
|
||||
const kind = st.kind || _ramBatchLastKind || 'install-cap';
|
||||
const okLabel = kind === 'delete' ? t('Deleted')
|
||||
@@ -24681,7 +24682,7 @@ const LANG_RU = {
|
||||
'Delete the package before installing (with its applications)': 'Удалить пакет перед установкой (с его приложениями)',
|
||||
'AID must be 5-16 bytes of hex': 'AID должен быть 5-16 байт hex',
|
||||
'not found': 'не найдено',
|
||||
'Start batch': 'Запустить пакетную установку',
|
||||
'Start batch': 'Запустить пакетную операцию',
|
||||
'Stopping...': 'Остановка…',
|
||||
'Batch stopped': 'Пакетная операция остановлена',
|
||||
'Batch finished': 'Пакетная операция завершена',
|
||||
@@ -24696,7 +24697,7 @@ const LANG_RU = {
|
||||
'Skipped': 'Пропущено',
|
||||
'attempts': 'попыток',
|
||||
'No cards processed yet.': 'Карты ещё не обрабатывались.',
|
||||
'The preset, keyset and counter come from each card\'s own preset (matched by ICCID). A card is attempted once per run: re-equipping it reports it as already processed - restart the batch to retry. Stop finishes the current card first.': 'Пресет, keyset и счётчик берутся из пресета каждой карты (совпадение по ICCID). Карта обрабатывается один раз за запуск: повторная установка карты отмечается как уже обработанная — для повтора перезапустите пакетную установку. «Остановить» завершает работу после окончания обработки карты.',
|
||||
'The preset, keyset and counter come from each card\'s own preset (matched by ICCID). A card is attempted once per run: re-equipping it reports it as already processed - restart the batch to retry. Stop finishes the current card first.': 'Пресет, keyset и счётчик берутся из пресета каждой карты (совпадение по ICCID). Карта обрабатывается один раз за запуск: повторная установка карты отмечается как уже обработанная — для повтора перезапустите пакетную операцию. «Остановить» завершает работу после окончания обработки карты.',
|
||||
'Do not close or reload this window while the operation is running.': 'Не закрывайте и не перезагружайте окно, пока операция выполняется.',
|
||||
'Working...': 'Выполняется...',
|
||||
'APDU hex': 'APDU (hex)',
|
||||
|
||||
+1
-1
@@ -1,4 +1,4 @@
|
||||
const CACHE = 'simple-v451';
|
||||
const CACHE = 'simple-v452';
|
||||
const URLS = [
|
||||
'index.html',
|
||||
'help.html',
|
||||
|
||||
@@ -578,10 +578,11 @@ test('a cleared report keeps the run kind in the modal title (v3.30.1)', () => {
|
||||
setModalEls();
|
||||
setPanelEls();
|
||||
app.setSummary(null);
|
||||
app.ramBatchModalOpen();
|
||||
// the state is seeded before the window opens: no reliance on the sandbox
|
||||
// leftovers of the previous test (the modal opens into the run's kind)
|
||||
app.setLast({ kind: 'delete', active: false, phase: 'finished', attempts: [],
|
||||
counts: { installed: 2 }, attempts_total: 2 });
|
||||
app.ramBatchRender();
|
||||
app.ramBatchModalOpen();
|
||||
assert.strictEqual(els['ram-op-title'].textContent, 'Batch delete (per card)');
|
||||
// Clear empties the state (kind: null): the title must not flip to install
|
||||
app.setLast({ kind: null, active: false, phase: 'idle', attempts: [],
|
||||
|
||||
+1
-1
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
|
||||
|
||||
[project]
|
||||
name = "pysim-simple-server"
|
||||
version = "3.30.1"
|
||||
version = "3.30.2"
|
||||
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.
|
||||
|
||||
@@ -37,7 +37,7 @@ from osmocom.tlv import BER_TLV_IE
|
||||
from osmocom.utils import rpad
|
||||
|
||||
|
||||
VERSION = '3.30.1'
|
||||
VERSION = '3.30.2'
|
||||
|
||||
MAX_ENVELOPE_SEGMENTS = 5 # max SMS segments for outgoing C-APDU in ENVELOPE
|
||||
|
||||
|
||||
Reference in new issue
Block a user