ui: Push commands sub-pills — one form at a time (v3.5.0)

The Push commands pill now switches between four sub-pills - Trigger (Push
SMS), Store (SD admin params), BIP / CAT_TP trigger, TCP trigger - and shows
only the selected form:

- Trigger/Store share one GP administration form (fields unchanged); the mode
  only changes the payload wrapping and the form heading, which now carries
  the HTTP OTA prefix: "HTTP OTA Administrative session trigger (Push SMS)"
  / "HTTP OTA Administrative session store data (SD admin params)".
- BIP/CAT_TP and TCP keep their own headings ("... (TS 102 226 §9)") and
  their "not the administration session" note.
- hotaSetForm() owns the pill styling and form visibility and delegates to
  hotaSetMode() (Trigger/Store) or pushUpdate() (SS9 forms); the view always
  opens on Trigger, nothing is persisted.
sw cache -> simple-v247; help 2.7 EN/RU, READMEs and AGENTS updated.
This commit is contained in:
2026-09-23 09:10:45 +03:00
parent f17e7cb8da
commit c011c02f8e
6 changed files with 50 additions and 14 deletions
+1 -1
View File
@@ -359,7 +359,7 @@ Pastes raw APDU hex and renders a collapsible tree. It auto-detects the containe
### Push commands
Groups the commands that make the card dial out: the GlobalPlatform HTTP administration session trigger (and its Store mode) plus the ETSI TS 102 226 §9 PUSH variants. They are delivered differently - the administration trigger is a TLV message for the Security Domain, a §9 PUSH is a C-APDU (`80 EC 01 P2`) for an application that supports BIP/CAT_TP.
Groups the commands that make the card dial out. Four sub-pills switch between the forms - Trigger (Push SMS), Store (SD admin params), BIP / CAT_TP trigger and TCP trigger - and only the selected one is shown (the two GP forms share their fields). They are delivered differently - the administration trigger is a TLV message for the Security Domain, a §9 PUSH is a C-APDU (`80 EC 01 P2`) for an application that supports BIP/CAT_TP.
#### Administration session (HTTP OTA)
+1 -1
View File
@@ -333,7 +333,7 @@ CLA = `80` (GlobalPlatform v2.3.1). Удалённое управление со
### Пуш/триггер
Объединяет команды, заставляющие карту выйти в сеть: триггер административной сессии HTTP (GlobalPlatform) с режимом записи параметров и варианты команды PUSH из ETSI TS 102 226 §9. Доставляются они по-разному — триггер администрирования это TLV-сообщение для Security Domain, а PUSH §9 это C-APDU (`80 EC 01 P2`) для приложения с поддержкой BIP/CAT_TP.
Объединяет команды, заставляющие карту выйти в сеть. Четыре подвкладки переключают формы — Trigger (Push SMS), Store (SD admin params), BIP / CAT_TP trigger и TCP trigger — показывается только выбранная (обе формы GP используют один набор полей). Доставляются они по-разному — триггер администрирования это TLV-сообщение для Security Domain, а PUSH §9 это C-APDU (`80 EC 01 P2`) для приложения с поддержкой BIP/CAT_TP.
#### Сессия администрирования (HTTP OTA)
+1 -1
View File
@@ -231,7 +231,7 @@
<p class="text-sm mb-3">Вставка raw APDU hex и отображение сворачиваемого дерева. Автоматически определяет контейнер: <strong>Expanded Script</strong> (начало <code class="font-mono text-sm">AA</code> или <code class="font-mono text-sm">AE80</code>, декодируется по ETSI TS 102 226 &sect;5.2.1) или <strong>Compact C-APDU chain</strong> (последовательность C-APDU ISO 7816). Каждый узел показывает метку, hex и краткое описание; родительские узлы раскрываются в подэлементы.</p>
<h3 id="push-commands" class="text-lg font-medium mb-2">2.7 Пуш/триггер</h3>
<p class="text-sm mb-3">Объединяет команды, заставляющие карту выйти в сеть: триггер административной сессии HTTP (GlobalPlatform) с режимом записи параметров и варианты команды PUSH из ETSI TS 102 226 &sect;9 (открытие BIP-канала, соединение CAT_TP, TCP-соединение, пакет идентификации). Они из разных спецификаций и доставляются по-разному &mdash; триггер администрирования это TLV-сообщение для Security Domain, а PUSH &sect;9 это C-APDU (<code class="font-mono text-sm">80 EC 01 P2</code>) для приложения с поддержкой BIP и/или CAT_TP.</p>
<p class="text-sm mb-3">Объединяет команды, заставляющие карту выйти в сеть. Четыре подвкладки переключают формы &mdash; <strong>Trigger (Push SMS)</strong>, <strong>Store (SD admin params)</strong>, <strong>BIP / CAT_TP trigger</strong> и <strong>TCP trigger</strong> &mdash; показывается только выбранная форма; обе формы GP используют один набор полей (режим меняет только обёртку payload&rsquo;а, а заголовок формы указывает режим). Они из разных спецификаций и доставляются по-разному: триггер администрирования это TLV-сообщение для Security Domain (HTTP OTA), а PUSH &sect;9 это C-APDU (<code class="font-mono text-sm">80 EC 01 P2</code>) для приложения с поддержкой BIP и/или CAT_TP.</p>
<h4 id="http-ota" class="font-medium mb-1">Сессия администрирования (HTTP OTA)</h4>
<p class="text-sm mb-3">Сборка payload&rsquo;ов Remote Application Management over HTTP по GlobalPlatform <strong>GPC v2.2 Amendment B v1.1</strong> (&sect;4.7). Два режима:</p>
+1 -1
View File
@@ -230,7 +230,7 @@
<p class="text-sm mb-3">Pastes raw APDU hex and renders a collapsible tree. It auto-detects the container: an <strong>Expanded Script</strong> (leading <code class="font-mono text-sm">AA</code> or <code class="font-mono text-sm">AE80</code>, decoded per ETSI TS 102 226 &sect;5.2.1) or a <strong>Compact C-APDU chain</strong> (a sequence of ISO 7816 C-APDUs). Each node shows its label, hex and a short description; parent nodes expand to reveal their sub-elements.</p>
<h3 id="push-commands" class="text-lg font-medium mb-2">2.7 Push commands</h3>
<p class="text-sm mb-3">Groups the commands that make the card dial out: the GlobalPlatform HTTP administration session trigger (and its Store mode) plus the ETSI TS 102 226 &sect;9 PUSH variants (BIP channel opening, CAT_TP link, TCP connection, identification packet). They come from different specs and are delivered differently &mdash; the administration trigger is a TLV message for the Security Domain, a &sect;9 PUSH is a C-APDU (<code class="font-mono text-sm">80 EC 01 P2</code>) for an application that supports BIP and/or CAT_TP.</p>
<p class="text-sm mb-3">Groups the commands that make the card dial out. Four sub-pills switch between the forms &mdash; <strong>Trigger (Push SMS)</strong>, <strong>Store (SD admin params)</strong>, <strong>BIP / CAT_TP trigger</strong> and <strong>TCP trigger</strong> &mdash; and only the selected form is shown; the two GP forms share one set of fields (the mode only changes how the payload is wrapped, and the form heading says which one). They come from different specs and are delivered differently: the administration trigger is a TLV message for the Security Domain (HTTP OTA), a &sect;9 PUSH is a C-APDU (<code class="font-mono text-sm">80 EC 01 P2</code>) for an application that supports BIP and/or CAT_TP.</p>
<h4 id="http-ota" class="font-medium mb-1">Administration session (HTTP OTA)</h4>
<p class="text-sm mb-3">Builds the Remote Application Management over HTTP payloads defined in GlobalPlatform <strong>GPC v2.2 Amendment B v1.1</strong> (&sect;4.7). Two modes:</p>
+45 -9
View File
@@ -182,12 +182,17 @@
</div>
<div id="c-apdu-sub-httpota" class="hidden">
<h3 class="text-base font-medium mb-3" data-l10n="Administrative session — administration trigger (HTTP OTA)">Administrative session — administration trigger (HTTP OTA)</h3>
<div class="flex gap-2 mb-3">
<button id="hota-mode-trigger" onclick="hotaSetMode('trigger')" class="px-4 py-1.5 text-sm rounded-full bg-blue-600 text-white" data-l10n="Trigger (Push SMS)">Trigger (Push SMS)</button>
<button id="hota-mode-store" onclick="hotaSetMode('store')" class="px-4 py-1.5 text-sm rounded-full bg-gray-200 dark:bg-slate-700 text-gray-700 dark:text-slate-300 hover:bg-gray-300 dark:hover:bg-slate-600" data-l10n="Store (SD admin params)">Store (SD admin params)</button>
<div class="flex flex-wrap gap-2 mb-3">
<button id="hota-form-btn-trigger" onclick="hotaSetForm('trigger')" class="px-4 py-1.5 text-sm rounded-full bg-blue-600 text-white" data-l10n="Trigger (Push SMS)">Trigger (Push SMS)</button>
<button id="hota-form-btn-store" onclick="hotaSetForm('store')" class="px-4 py-1.5 text-sm rounded-full bg-gray-200 dark:bg-slate-700 text-gray-700 dark:text-slate-300 hover:bg-gray-300 dark:hover:bg-slate-600" data-l10n="Store (SD admin params)">Store (SD admin params)</button>
<button id="hota-form-btn-bip" onclick="hotaSetForm('bip')" class="px-4 py-1.5 text-sm rounded-full bg-gray-200 dark:bg-slate-700 text-gray-700 dark:text-slate-300 hover:bg-gray-300 dark:hover:bg-slate-600" data-l10n="BIP / CAT_TP trigger">BIP / CAT_TP trigger</button>
<button id="hota-form-btn-tcp" onclick="hotaSetForm('tcp')" class="px-4 py-1.5 text-sm rounded-full bg-gray-200 dark:bg-slate-700 text-gray-700 dark:text-slate-300 hover:bg-gray-300 dark:hover:bg-slate-600" data-l10n="TCP trigger">TCP trigger</button>
</div>
<div id="hota-form-gp">
<h3 id="hota-heading-trigger" class="text-base font-medium mb-3" data-l10n="HTTP OTA Administrative session trigger (Push SMS)">HTTP OTA Administrative session trigger (Push SMS)</h3>
<h3 id="hota-heading-store" class="text-base font-medium mb-3 hidden" data-l10n="HTTP OTA Administrative session store data (SD admin params)">HTTP OTA Administrative session store data (SD admin params)</h3>
<div id="hota-store-tag-row" class="mb-3 hidden">
<label class="block mb-1 text-sm font-medium text-gray-700 dark:text-slate-300" data-l10n="SD params tag">SD params tag</label>
<select id="hota-store-tag" onchange="hotaUpdatePreview()" class="w-full border border-gray-300 dark:border-slate-600 text-sm rounded px-2 py-1.5 dark:bg-slate-800">
@@ -294,8 +299,10 @@
<textarea id="hota-preview" rows="5" readonly oninput="hotaPreviewEdited()" class="w-full font-mono border border-gray-300 dark:border-slate-600 text-sm rounded px-3 py-1.5 bg-gray-100 dark:bg-slate-800 mb-3" placeholder="RAM-over-HTTP payload will appear here..."></textarea>
<button onclick="packToSp('hota-preview')" id="hota-pack-btn" disabled class="mb-3 px-5 py-2.5 bg-emerald-600 text-white text-sm font-medium rounded hover:bg-emerald-700 disabled:opacity-40 disabled:cursor-not-allowed" data-l10n="Pack into Secured packet">Pack into Secured packet</button>
</div>
<h3 class="text-base font-medium mt-4 mb-2" data-l10n="BIP / CAT_TP trigger (TS 102 226 §9)">BIP / CAT_TP trigger (TS 102 226 §9)</h3>
<div id="push-form-bip" class="hidden">
<h3 class="text-base font-medium mb-2" data-l10n="BIP / CAT_TP trigger (TS 102 226 §9)">BIP / CAT_TP trigger (TS 102 226 §9)</h3>
<p class="text-xs text-gray-500 dark:text-slate-400 mb-2" data-l10n="Not the administration session — a C-APDU for an app that supports BIP/CAT_TP">Not the administration session — a C-APDU for an app that supports BIP/CAT_TP</p>
<div class="border border-gray-300 dark:border-slate-600 rounded p-3 bg-gray-50 dark:bg-slate-800 mb-3">
<div class="mb-2">
@@ -325,8 +332,10 @@
<textarea id="push-bip-preview" rows="2" readonly class="w-full font-mono border border-gray-300 dark:border-slate-600 text-sm rounded px-3 py-1.5 bg-gray-100 dark:bg-slate-800 mb-2" placeholder="C-APDU (TS 102 226 §9)"></textarea>
<button onclick="packToSp('push-bip-preview')" id="push-bip-pack-btn" disabled class="mb-3 px-5 py-2.5 bg-emerald-600 text-white text-sm font-medium rounded hover:bg-emerald-700 disabled:opacity-40 disabled:cursor-not-allowed" data-l10n="Pack into Secured packet">Pack into Secured packet</button>
<button onclick="pushToExpanded('push-bip-preview')" id="push-bip-exp-btn" disabled class="mb-3 px-5 py-2.5 bg-violet-600 text-white text-sm font-medium rounded hover:bg-violet-700 disabled:opacity-40 disabled:cursor-not-allowed" data-l10n="→ Expanded Script">→ Expanded Script</button>
</div>
<h3 class="text-base font-medium mt-4 mb-2" data-l10n="TCP trigger (TS 102 226 §9)">TCP trigger (TS 102 226 §9)</h3>
<div id="push-form-tcp" class="hidden">
<h3 class="text-base font-medium mb-2" data-l10n="TCP trigger (TS 102 226 §9)">TCP trigger (TS 102 226 §9)</h3>
<p class="text-xs text-gray-500 dark:text-slate-400 mb-2" data-l10n="Not the administration session — a C-APDU for an app that supports BIP/CAT_TP">Not the administration session — a C-APDU for an app that supports BIP/CAT_TP</p>
<div class="border border-gray-300 dark:border-slate-600 rounded p-3 bg-gray-50 dark:bg-slate-800 mb-3">
<div class="mb-2">
@@ -359,6 +368,7 @@
<textarea id="push-tcp-preview" rows="2" readonly class="w-full font-mono border border-gray-300 dark:border-slate-600 text-sm rounded px-3 py-1.5 bg-gray-100 dark:bg-slate-800 mb-2" placeholder="C-APDU (TS 102 226 §9)"></textarea>
<button onclick="packToSp('push-tcp-preview')" id="push-tcp-pack-btn" disabled class="mb-3 px-5 py-2.5 bg-emerald-600 text-white text-sm font-medium rounded hover:bg-emerald-700 disabled:opacity-40 disabled:cursor-not-allowed" data-l10n="Pack into Secured packet">Pack into Secured packet</button>
<button onclick="pushToExpanded('push-tcp-preview')" id="push-tcp-exp-btn" disabled class="mb-3 px-5 py-2.5 bg-violet-600 text-white text-sm font-medium rounded hover:bg-violet-700 disabled:opacity-40 disabled:cursor-not-allowed" data-l10n="→ Expanded Script">→ Expanded Script</button>
</div>
</div>
<div id="c-apdu-sub-response" class="hidden">
@@ -1925,6 +1935,7 @@ async function esimSetProfile(iccid, isdpAid, action) {
// ===== HTTP OTA constructor =====
let _hotaMode = 'trigger';
let _hotaForm = 'trigger';
function _hotaHex(s) { return (s || '').replace(/[^0-9a-fA-F]/g, '').toUpperCase(); }
function _hotaAsciiHex(s) { return (s || '').split('').map(c => c.charCodeAt(0).toString(16).padStart(2, '0')).join('').toUpperCase(); }
function _hotaBerLen(n) {
@@ -2011,13 +2022,34 @@ function hotaBuild(mode, conn, sec, retry, httpPost, storeTag, expanded) {
function hotaSetMode(mode) {
_hotaMode = mode;
document.getElementById('hota-mode-trigger').className = 'px-4 py-1.5 text-sm rounded-full ' + (mode === 'trigger' ? 'bg-blue-600 text-white' : 'bg-gray-200 dark:bg-slate-700 text-gray-700 dark:text-slate-300 hover:bg-gray-300 dark:hover:bg-slate-600');
document.getElementById('hota-mode-store').className = 'px-4 py-1.5 text-sm rounded-full ' + (mode === 'store' ? 'bg-blue-600 text-white' : 'bg-gray-200 dark:bg-slate-700 text-gray-700 dark:text-slate-300 hover:bg-gray-300 dark:hover:bg-slate-600');
document.getElementById('hota-heading-trigger').classList.toggle('hidden', mode !== 'trigger');
document.getElementById('hota-heading-store').classList.toggle('hidden', mode !== 'store');
document.getElementById('hota-store-tag-row').classList.toggle('hidden', mode !== 'store');
document.getElementById('hota-expanded-row').classList.toggle('hidden', mode !== 'trigger');
hotaUpdatePreview();
}
// The Push commands pill shows one form at a time: Trigger and Store share the
// GP administration form (different payload mode), BIP/CAT_TP and TCP have
// their own TS 102 226 §9 form.
function hotaSetForm(form) {
_hotaForm = form;
['trigger', 'store', 'bip', 'tcp'].forEach(f => {
const btn = document.getElementById('hota-form-btn-' + f);
if (!btn) return;
btn.className = 'px-4 py-1.5 text-sm rounded-full ' + (f === form
? 'bg-blue-600 text-white'
: 'bg-gray-200 dark:bg-slate-700 text-gray-700 dark:text-slate-300 hover:bg-gray-300 dark:hover:bg-slate-600');
});
const visible = form === 'bip' ? 'push-form-bip' : (form === 'tcp' ? 'push-form-tcp' : 'hota-form-gp');
['hota-form-gp', 'push-form-bip', 'push-form-tcp'].forEach(id => {
const el = document.getElementById(id);
if (el) el.classList.toggle('hidden', id !== visible);
});
if (form === 'trigger' || form === 'store') hotaSetMode(form);
else pushUpdate(form);
}
function hotaToggleConn() {
const on = document.getElementById('hota-include-conn').checked;
document.getElementById('hota-conn-tlvs').classList.toggle('hidden', !on);
@@ -2180,6 +2212,7 @@ function pushToExpanded(sourceId) {
function pushInit() {
['bip', 'tcp'].forEach(pushUpdate);
hotaSetForm('trigger');
}
pushInit();
@@ -14884,7 +14917,10 @@ const LANG_RU = {
'HTTP OTA': 'HTTP OTA',
'Trigger (Push SMS)': 'Триггер (Push SMS)',
'Push commands': 'Пуш/триггер',
'Administrative session — administration trigger (HTTP OTA)': 'Сессия администрирования — триггер (HTTP OTA)',
'HTTP OTA Administrative session trigger (Push SMS)': 'HTTP OTA — триггер административной сессии (Push SMS)',
'HTTP OTA Administrative session store data (SD admin params)': 'HTTP OTA — запись данных административной сессии (параметры SD)',
'BIP / CAT_TP trigger': 'Триггер BIP / CAT_TP',
'TCP trigger': 'Триггер TCP',
'BIP / CAT_TP trigger (TS 102 226 §9)': 'Триггер BIP / CAT_TP (TS 102 226 §9)',
'TCP trigger (TS 102 226 §9)': 'Триггер TCP (TS 102 226 §9)',
'Not the administration session — a C-APDU for an app that supports BIP/CAT_TP': 'C-APDU для приложения с поддержкой BIP/CAT_TP (не admin session!)',
+1 -1
View File
@@ -1,4 +1,4 @@
const CACHE = 'simple-v246';
const CACHE = 'simple-v247';
const URLS = [
'index.html',
'help.html',