ui: rename the SCP81 script templates to Explore ISD / Delete AID (v3.1.3)

'Explore' and 'Delete' were ambiguous next to the other SCP81 actions.

- template selector: Explore -> Explore ISD, Delete -> Delete AID (EN/RU);
- a new Explore script is named 'Explore ISD'; the Delete template keeps
  its count-based name (e.g. 'Delete 2 AIDs');
- new scriptKindLabel() maps the stored kinds (unchanged:
  explore/delete/install/empty, so existing localStorage scripts keep
  working) to those labels and is now used for the scripts table kind
  column, which used to print the raw lowercase kind untranslated;
- docs: help EN/RU, README/RUS, docs/api.md examples, AGENTS;
- sw.js simple-v238.
This commit is contained in:
2026-09-22 22:07:57 +03:00
parent b87b3905ee
commit fa600cb45d
10 changed files with 41 additions and 21 deletions
+2 -2
View File
@@ -624,9 +624,9 @@ The **Scripts** pill manages named APDU lists stored in `localStorage` (`simple_
| Template | What it builds | | Template | What it builds |
|---|---| |---|---|
| **Empty** | an empty list | | **Empty** | an empty list |
| **Explore** | the reference administration sequence (`GET DATA FF21`, GET STATUS ISD/ELF/application listings, `GET DATA 0085`); long listings auto-continue through `SW 6310/CAFE` pages | | **Explore ISD** | the reference administration sequence (`GET DATA FF21`, GET STATUS ISD/ELF/application listings, `GET DATA 0085`); long listings auto-continue through `SW 6310/CAFE` pages |
| **Install from .cap** | INSTALL [for load] → LOAD ×N → INSTALL [for install] from a `.cap` (optional SD AID, install/STK parameters, make selectable) via `POST /api/scp81/gen-install`; the file is only used to generate the APDUs — it is not stored, not even its name | | **Install from .cap** | INSTALL [for load] → LOAD ×N → INSTALL [for install] from a `.cap` (optional SD AID, install/STK parameters, make selectable) via `POST /api/scp81/gen-install`; the file is only used to generate the APDUs — it is not stored, not even its name |
| **Delete** | DELETE APDUs from an AID list (one per line) with P2 = object only / object and related objects | | **Delete AID** | DELETE APDUs from an AID list (one per line) with P2 = object only / object and related objects |
The table lists each script with kind, APDU count and creation time; **Edit** opens the name + APDU editor and **Delete** removes it. Over a session the server serves one C-APDU per card POST and tracks execution: the card reports status in its next POST (`X-Admin-Script-Status`), a session that dies resends only the unexecuted APDUs (`X-Admin-Resume` continues, a fresh dialog restarts), and a completed script is closed with `204 No Content`. The Remote APDU → **RAM/GP** builder can feed a command chain straight into the run with **Queue in SCP81**. The table lists each script with kind, APDU count and creation time; **Edit** opens the name + APDU editor and **Delete** removes it. Over a session the server serves one C-APDU per card POST and tracks execution: the card reports status in its next POST (`X-Admin-Script-Status`), a session that dies resends only the unexecuted APDUs (`X-Admin-Resume` continues, a fresh dialog restarts), and a completed script is closed with `204 No Content`. The Remote APDU → **RAM/GP** builder can feed a command chain straight into the run with **Queue in SCP81**.
+2 -2
View File
@@ -595,9 +595,9 @@ Delivery PoR (SPI2 `01`) проще — карта возвращает PoR на
| Шаблон | Что строит | | Шаблон | Что строит |
|---|---| |---|---|
| **Empty** | пустой список | | **Empty** | пустой список |
| **Explore** | эталонная административная последовательность (`GET DATA FF21`, листинги GET STATUS ISD/ELF/приложений, `GET DATA 0085`); длинные листинги автоматически продолжаются страницами `SW 6310/CAFE` | | **Explore ISD** | эталонная административная последовательность (`GET DATA FF21`, листинги GET STATUS ISD/ELF/приложений, `GET DATA 0085`); длинные листинги автоматически продолжаются страницами `SW 6310/CAFE` |
| **Install from .cap** | INSTALL [for load] → LOAD ×N → INSTALL [for install] из `.cap` (опционально SD AID, параметры install/STK, make selectable) через `POST /api/scp81/gen-install`; файл используется только для генерации APDU — он не сохраняется, как и его имя | | **Install from .cap** | INSTALL [for load] → LOAD ×N → INSTALL [for install] из `.cap` (опционально SD AID, параметры install/STK, make selectable) через `POST /api/scp81/gen-install`; файл используется только для генерации APDU — он не сохраняется, как и его имя |
| **Delete** | APDU DELETE из списка AID (по одному в строке) с P2 = object only / object and related objects | | **Delete AID** | APDU DELETE из списка AID (по одному в строке) с P2 = object only / object and related objects |
Таблица показывает имя, тип, число APDU и время создания каждого скрипта; **Edit** открывает редактор имени и списка APDU, **Delete** удаляет скрипт. В ходе сессии сервер отдаёт по одному C-APDU на каждый POST карты и отслеживает выполнение: карта сообщает статус в следующем POST (`X-Admin-Script-Status`), оборвавшаяся сессия досылает только невыполненные APDU (`X-Admin-Resume` продолжает, новый диалог начинает заново), а завершённый скрипт закрывается ответом `204 No Content`. Конструктор RAM/GP вкладки Remote APDU может отправить цепочку команд прямо в прогон кнопкой **«В очередь SCP81»**. Таблица показывает имя, тип, число APDU и время создания каждого скрипта; **Edit** открывает редактор имени и списка APDU, **Delete** удаляет скрипт. В ходе сессии сервер отдаёт по одному C-APDU на каждый POST карты и отслеживает выполнение: карта сообщает статус в следующем POST (`X-Admin-Script-Status`), оборвавшаяся сессия досылает только невыполненные APDU (`X-Admin-Resume` продолжает, новый диалог начинает заново), а завершённый скрипт закрывается ответом `204 No Content`. Конструктор RAM/GP вкладки Remote APDU может отправить цепочку команд прямо в прогон кнопкой **«В очередь SCP81»**.
+2 -2
View File
@@ -788,7 +788,7 @@ Keys are never stored or logged.
{"action": "start", "mode": "tls", "host": "127.0.0.1", "port": 8443, {"action": "start", "mode": "tls", "host": "127.0.0.1", "port": 8443,
"psk_map": [{"identity": "89012345678901234567", "psk_map": [{"identity": "89012345678901234567",
"psk_hex": "00112233445566778899aabbccddeeff"}], "psk_hex": "00112233445566778899aabbccddeeff"}],
"script": ["80CAFF2100", "80F28002024F0000"], "script_kind": "Explore"} "script": ["80CAFF2100", "80F28002024F0000"], "script_kind": "Explore ISD"}
``` ```
`script` is the APDU list served to the card (an explicit list, or `none`); `script` is the APDU list served to the card (an explicit list, or `none`);
@@ -873,7 +873,7 @@ Returns the configured command script and the execution state:
```json ```json
{"script": ["80CAFF2100", "80F28002024F0000"], "next": 2, "total": 2, {"script": ["80CAFF2100", "80F28002024F0000"], "next": 2, "total": 2,
"done": [0, 1], "kind": "Explore", "done": [0, 1], "kind": "Explore ISD",
"pending": {"index": 17, "pos": null, "page": true, "apdu": "80F28003024F0000"}, "pending": {"index": 17, "pos": null, "page": true, "apdu": "80F28003024F0000"},
"pages": 11, "pages_queued": 0, "complete": false, "pages": 11, "pages_queued": 0, "complete": false,
"results": [{"index": 1, "pos": 0, "page": false, "sw": "9000", "results": [{"index": 1, "pos": 0, "page": false, "sw": "9000",
+2 -2
View File
@@ -338,9 +338,9 @@
<p class="text-sm mb-2">Именованные списки APDU хранятся локально (<code class="font-mono text-sm">simple_scripts</code>) и передаются серверу при старте слушателя. Каждый список — последовательность hex C-APDU (по одной в строке; допускаются комментарии <code class="font-mono text-sm">#</code>/<code class="font-mono text-sm">;</code>). Кнопка <strong>Новый</strong> создаёт список из шаблона:</p> <p class="text-sm mb-2">Именованные списки APDU хранятся локально (<code class="font-mono text-sm">simple_scripts</code>) и передаются серверу при старте слушателя. Каждый список — последовательность hex C-APDU (по одной в строке; допускаются комментарии <code class="font-mono text-sm">#</code>/<code class="font-mono text-sm">;</code>). Кнопка <strong>Новый</strong> создаёт список из шаблона:</p>
<ul class="list-disc list-inside text-sm space-y-1 mb-3"> <ul class="list-disc list-inside text-sm space-y-1 mb-3">
<li><strong>Empty</strong> — начать с пустого списка.</li> <li><strong>Empty</strong> — начать с пустого списка.</li>
<li><strong>Explore</strong> — эталонная административная последовательность (<code class="font-mono text-sm">GET DATA FF21</code>, листинги GET STATUS ISD/ELF/приложений, <code class="font-mono text-sm">GET DATA 0085</code>); длинные листинги автоматически продолжаются страницами <code class="font-mono text-sm">SW 6310/CAFE</code>.</li> <li><strong>Explore ISD</strong> — эталонная административная последовательность (<code class="font-mono text-sm">GET DATA FF21</code>, листинги GET STATUS ISD/ELF/приложений, <code class="font-mono text-sm">GET DATA 0085</code>); длинные листинги автоматически продолжаются страницами <code class="font-mono text-sm">SW 6310/CAFE</code>.</li>
<li><strong>Install from .cap</strong> — выберите <code class="font-mono text-sm">.cap</code>, при необходимости SD AID, параметры install/STK и <em>Make selectable</em>; кнопка <strong>Сгенерировать</strong> строит INSTALL [for load] &rarr; LOAD &times;N &rarr; INSTALL [for install]. Файл используется только для генерации APDU &mdash; он не сохраняется, как и его имя.</li> <li><strong>Install from .cap</strong> — выберите <code class="font-mono text-sm">.cap</code>, при необходимости SD AID, параметры install/STK и <em>Make selectable</em>; кнопка <strong>Сгенерировать</strong> строит INSTALL [for load] &rarr; LOAD &times;N &rarr; INSTALL [for install]. Файл используется только для генерации APDU &mdash; он не сохраняется, как и его имя.</li>
<li><strong>Delete</strong> — список AID (по одному в строке) и P2 (<em>object only</em> / <em>object and related objects</em>) &rarr; APDU DELETE.</li> <li><strong>Delete AID</strong> — список AID (по одному в строке) и P2 (<em>object only</em> / <em>object and related objects</em>) &rarr; APDU DELETE.</li>
</ul> </ul>
<p class="text-sm mb-3">Таблица показывает имя, тип, число APDU и время создания каждого скрипта, а также кнопки <strong>Редактировать</strong> и <strong>Удалить</strong>; в редакторе есть поле имени и текстовая область APDU. В ходе сессии сервер отдаёт по одному C-APDU на каждый POST карты и отслеживает выполнение: карта сообщает статус в следующем POST (<code class="font-mono text-sm">X-Admin-Script-Status</code>), оборвавшаяся сессия досылает только невыполненные APDU (<code class="font-mono text-sm">X-Admin-Resume</code> продолжает, новый диалог начинает заново), а завершённый скрипт закрывается ответом <code class="font-mono text-sm">204 No Content</code>. Конструктор RAM/GP вкладки Remote APDU может отправить цепочку команд прямо в прогон кнопкой <strong>&laquo;В очередь SCP81&raquo;</strong>.</p> <p class="text-sm mb-3">Таблица показывает имя, тип, число APDU и время создания каждого скрипта, а также кнопки <strong>Редактировать</strong> и <strong>Удалить</strong>; в редакторе есть поле имени и текстовая область APDU. В ходе сессии сервер отдаёт по одному C-APDU на каждый POST карты и отслеживает выполнение: карта сообщает статус в следующем POST (<code class="font-mono text-sm">X-Admin-Script-Status</code>), оборвавшаяся сессия досылает только невыполненные APDU (<code class="font-mono text-sm">X-Admin-Resume</code> продолжает, новый диалог начинает заново), а завершённый скрипт закрывается ответом <code class="font-mono text-sm">204 No Content</code>. Конструктор RAM/GP вкладки Remote APDU может отправить цепочку команд прямо в прогон кнопкой <strong>&laquo;В очередь SCP81&raquo;</strong>.</p>
</section> </section>
+2 -2
View File
@@ -338,9 +338,9 @@
<p class="text-sm mb-2">Named APDU lists stored locally (<code class="font-mono text-sm">simple_scripts</code>) and sent to the server when a listener starts. Each list is a sequence of hex C-APDUs (one per line; <code class="font-mono text-sm">#</code>/<code class="font-mono text-sm">;</code> comments allowed). <strong>New</strong> creates one from a template:</p> <p class="text-sm mb-2">Named APDU lists stored locally (<code class="font-mono text-sm">simple_scripts</code>) and sent to the server when a listener starts. Each list is a sequence of hex C-APDUs (one per line; <code class="font-mono text-sm">#</code>/<code class="font-mono text-sm">;</code> comments allowed). <strong>New</strong> creates one from a template:</p>
<ul class="list-disc list-inside text-sm space-y-1 mb-3"> <ul class="list-disc list-inside text-sm space-y-1 mb-3">
<li><strong>Empty</strong> — start from scratch.</li> <li><strong>Empty</strong> — start from scratch.</li>
<li><strong>Explore</strong> — the reference administration sequence (<code class="font-mono text-sm">GET DATA FF21</code>, GET STATUS ISD/ELF/application listings, <code class="font-mono text-sm">GET DATA 0085</code>); long listings auto-continue through the <code class="font-mono text-sm">SW 6310/CAFE</code> pages.</li> <li><strong>Explore ISD</strong> — the reference administration sequence (<code class="font-mono text-sm">GET DATA FF21</code>, GET STATUS ISD/ELF/application listings, <code class="font-mono text-sm">GET DATA 0085</code>); long listings auto-continue through the <code class="font-mono text-sm">SW 6310/CAFE</code> pages.</li>
<li><strong>Install from .cap</strong> — pick a <code class="font-mono text-sm">.cap</code> plus optional SD AID, install/STK parameters and <em>make selectable</em>; <strong>Generate</strong> builds INSTALL [for load] &rarr; LOAD &times;N &rarr; INSTALL [for install]. The file is only used to generate the APDUs &mdash; it is not stored, not even its name.</li> <li><strong>Install from .cap</strong> — pick a <code class="font-mono text-sm">.cap</code> plus optional SD AID, install/STK parameters and <em>make selectable</em>; <strong>Generate</strong> builds INSTALL [for load] &rarr; LOAD &times;N &rarr; INSTALL [for install]. The file is only used to generate the APDUs &mdash; it is not stored, not even its name.</li>
<li><strong>Delete</strong> — AID list (one per line) and P2 (<em>object only</em> / <em>object and related objects</em>) &rarr; DELETE APDUs.</li> <li><strong>Delete AID</strong> — AID list (one per line) and P2 (<em>object only</em> / <em>object and related objects</em>) &rarr; DELETE APDUs.</li>
</ul> </ul>
<p class="text-sm mb-3">The table lists each script with its kind, APDU count and creation time, plus <strong>Edit</strong> and <strong>Delete</strong>; the editor has a name field and the APDU textarea. Over a session the server serves one C-APDU per card POST and tracks execution: the card reports status in its next POST (<code class="font-mono text-sm">X-Admin-Script-Status</code>), a session that dies resends only the unexecuted APDUs (<code class="font-mono text-sm">X-Admin-Resume</code> continues, a fresh dialog restarts), and a completed script is closed with <code class="font-mono text-sm">204 No Content</code>. The Remote APDU tab's RAM/GP builder can feed a command chain straight into the run with <strong>Queue in SCP81</strong>.</p> <p class="text-sm mb-3">The table lists each script with its kind, APDU count and creation time, plus <strong>Edit</strong> and <strong>Delete</strong>; the editor has a name field and the APDU textarea. Over a session the server serves one C-APDU per card POST and tracks execution: the card reports status in its next POST (<code class="font-mono text-sm">X-Admin-Script-Status</code>), a session that dies resends only the unexecuted APDUs (<code class="font-mono text-sm">X-Admin-Resume</code> continues, a fresh dialog restarts), and a completed script is closed with <code class="font-mono text-sm">204 No Content</code>. The Remote APDU tab's RAM/GP builder can feed a command chain straight into the run with <strong>Queue in SCP81</strong>.</p>
</section> </section>
+17 -6
View File
@@ -1180,9 +1180,9 @@
<label class="block mb-1 text-xs font-medium text-gray-600 dark:text-slate-400" data-l10n="New script from">New script from</label> <label class="block mb-1 text-xs font-medium text-gray-600 dark:text-slate-400" data-l10n="New script from">New script from</label>
<select id="scripts-template" onchange="scriptsTemplateChanged()" class="border border-gray-300 dark:border-slate-600 text-sm rounded px-2 py-1.5 dark:bg-slate-800"> <select id="scripts-template" onchange="scriptsTemplateChanged()" class="border border-gray-300 dark:border-slate-600 text-sm rounded px-2 py-1.5 dark:bg-slate-800">
<option value="empty" data-l10n="Empty">Empty</option> <option value="empty" data-l10n="Empty">Empty</option>
<option value="explore" data-l10n="Explore">Explore</option> <option value="explore" data-l10n="Explore ISD">Explore ISD</option>
<option value="install" data-l10n="Install from .cap">Install from .cap</option> <option value="install" data-l10n="Install from .cap">Install from .cap</option>
<option value="delete" data-l10n="Delete">Delete</option> <option value="delete" data-l10n="Delete AID">Delete AID</option>
</select> </select>
</div> </div>
<button id="scripts-new-btn" onclick="scriptsNew()" class="px-3 py-1.5 text-sm rounded bg-blue-600 text-white hover:bg-blue-700" data-l10n="New">New</button> <button id="scripts-new-btn" onclick="scriptsNew()" class="px-3 py-1.5 text-sm rounded bg-blue-600 text-white hover:bg-blue-700" data-l10n="New">New</button>
@@ -1436,7 +1436,7 @@
// ===== Version ===== // ===== Version =====
// Single source of truth for the PWA version: shown in the header and used // Single source of truth for the PWA version: shown in the header and used
// by the server version check in pysimConnect(). // by the server version check in pysimConnect().
const SIMPLE_VERSION = '3.1.2'; const SIMPLE_VERSION = '3.1.3';
document.getElementById('app-version').textContent = 'v' + SIMPLE_VERSION; document.getElementById('app-version').textContent = 'v' + SIMPLE_VERSION;
// ===== Tab switching ===== // ===== Tab switching =====
@@ -9472,7 +9472,7 @@ function scriptsNew() {
const tpl = document.getElementById('scripts-template').value; const tpl = document.getElementById('scripts-template').value;
scriptsMsg(''); scriptsMsg('');
if (tpl === 'empty') { scriptsEdit(null, 'empty', '', []); return; } if (tpl === 'empty') { scriptsEdit(null, 'empty', '', []); return; }
if (tpl === 'explore') { scriptsEdit(null, 'explore', 'Explore', SCP81_EXPLORE_APDUS.slice()); return; } if (tpl === 'explore') { scriptsEdit(null, 'explore', 'Explore ISD', SCP81_EXPLORE_APDUS.slice()); return; }
// Install/delete: fill the parameter form above, then press Generate. // Install/delete: fill the parameter form above, then press Generate.
scriptsTemplateChanged(); scriptsTemplateChanged();
} }
@@ -9547,6 +9547,16 @@ function scriptsDelete(id) {
scriptsPersist(); scriptsPersist();
} }
// Script template kind -> display label. The stored kind stays
// 'explore'/'delete'/'install'/'empty' (existing localStorage scripts).
function scriptKindLabel(kind) {
const k = String(kind || '').toLowerCase();
if (k === 'explore') return t('Explore ISD');
if (k === 'delete') return t('Delete AID');
if (k === 'install') return t('Install from .cap');
return t('Empty');
}
function scriptsRender() { function scriptsRender() {
const tbody = document.getElementById('scripts-tbody'); const tbody = document.getElementById('scripts-tbody');
if (!tbody) return; if (!tbody) return;
@@ -9558,7 +9568,7 @@ function scriptsRender() {
for (const s of scripts) { for (const s of scripts) {
html += '<tr class="border-b border-gray-100 dark:border-slate-700">'; html += '<tr class="border-b border-gray-100 dark:border-slate-700">';
html += '<td class="py-1 px-2 font-medium">' + esc(s.name) + '</td>'; html += '<td class="py-1 px-2 font-medium">' + esc(s.name) + '</td>';
html += '<td class="py-1 px-2 text-xs text-gray-500 dark:text-slate-400">' + esc(t(s.kind || 'empty')) + '</td>'; html += '<td class="py-1 px-2 text-xs text-gray-500 dark:text-slate-400">' + esc(scriptKindLabel(s.kind)) + '</td>';
html += '<td class="py-1 px-2 font-mono text-xs">' + ((s.apdus || []).length) + '</td>'; html += '<td class="py-1 px-2 font-mono text-xs">' + ((s.apdus || []).length) + '</td>';
html += '<td class="py-1 px-2 text-xs">' + esc((s.created || '').slice(0, 10)) + '</td>'; html += '<td class="py-1 px-2 text-xs">' + esc((s.created || '').slice(0, 10)) + '</td>';
html += '<td class="py-1 px-2 whitespace-nowrap">' + html += '<td class="py-1 px-2 whitespace-nowrap">' +
@@ -13909,7 +13919,8 @@ const LANG_RU = {
'Listener': 'Слушатель', 'Listener': 'Слушатель',
'Scripts': 'Скрипты', 'Scripts': 'Скрипты',
'Empty': 'Пустой', 'Empty': 'Пустой',
'Explore': 'Обзор', 'Explore ISD': 'Обзор ISD',
'Delete AID': 'Удалить AID',
'New': 'Новый', 'New': 'Новый',
'New script from': 'Новый скрипт из', 'New script from': 'Новый скрипт из',
'Generate': 'Сгенерировать', 'Generate': 'Сгенерировать',
+1 -1
View File
@@ -1,4 +1,4 @@
const CACHE = 'simple-v237'; const CACHE = 'simple-v238';
const URLS = [ const URLS = [
'index.html', 'index.html',
'help.html', 'help.html',
+11 -2
View File
@@ -31,11 +31,20 @@ eval(extractFunc(html, 'scp81LogLine'));
eval(extractFunc(html, 'scp81LogEntryHtml')); eval(extractFunc(html, 'scp81LogEntryHtml'));
eval(extractFunc(html, 'scp81GroupResults')); eval(extractFunc(html, 'scp81GroupResults'));
eval(extractFunc(html, 'scp81ScriptStateText')); eval(extractFunc(html, 'scp81ScriptStateText'));
eval(extractFunc(html, 'scriptKindLabel'));
global.esc = (s) => String(s == null ? '' : s) global.esc = (s) => String(s == null ? '' : s)
.replace(/&/g, '&amp;').replace(/</g, '&lt;').replace(/>/g, '&gt;').replace(/"/g, '&quot;'); .replace(/&/g, '&amp;').replace(/</g, '&lt;').replace(/>/g, '&gt;').replace(/"/g, '&quot;');
test('explore template is the reference administration sequence', () => { test('scriptKindLabel maps the stored kinds to the template labels', () => {
const m = /const SCP81_EXPLORE_APDUS = \[(.*?)\];/s.exec(html); assert.strictEqual(scriptKindLabel('explore'), 'Explore ISD');
assert.strictEqual(scriptKindLabel('Explore'), 'Explore ISD');
assert.strictEqual(scriptKindLabel('delete'), 'Delete AID');
assert.strictEqual(scriptKindLabel('install'), 'Install from .cap');
assert.strictEqual(scriptKindLabel('empty'), 'Empty');
assert.strictEqual(scriptKindLabel(undefined), 'Empty');
});
test('explore template is the reference administration sequence', () => { const m = /const SCP81_EXPLORE_APDUS = \[(.*?)\];/s.exec(html);
assert.ok(m, 'SCP81_EXPLORE_APDUS not found'); assert.ok(m, 'SCP81_EXPLORE_APDUS not found');
const apdus = [...m[1].matchAll(/'([0-9A-F]+)'/g)].map(x => x[1]); const apdus = [...m[1].matchAll(/'([0-9A-F]+)'/g)].map(x => x[1]);
assert.deepStrictEqual(apdus, ['80CAFF2100', '80F28002024F0000', '80CA008500', assert.deepStrictEqual(apdus, ['80CAFF2100', '80F28002024F0000', '80CA008500',
+1 -1
View File
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
[project] [project]
name = "pysim-simple-server" name = "pysim-simple-server"
version = "3.1.2" version = "3.1.3"
description = "HTTP REST server wrapping pysim for the SIMple PWA" description = "HTTP REST server wrapping pysim for the SIMple PWA"
requires-python = ">=3.8" requires-python = ">=3.8"
# pysim is a git-only dependency installed explicitly by setup.bat/setup.sh. # pysim is a git-only dependency installed explicitly by setup.bat/setup.sh.
+1 -1
View File
@@ -28,7 +28,7 @@ from osmocom.tlv import BER_TLV_IE
from osmocom.utils import rpad from osmocom.utils import rpad
VERSION = '3.1.2' VERSION = '3.1.3'
MAX_ENVELOPE_SEGMENTS = 5 # max SMS segments for outgoing C-APDU in ENVELOPE MAX_ENVELOPE_SEGMENTS = 5 # max SMS segments for outgoing C-APDU in ENVELOPE