v3.23.7: the proactive log survives a TERMINAL PROFILE re-send

Pressing the Phone tab's Send (or Rescue) re-sends the profile and starts a
new CAT session.  The log was cleared with the rest of the session state,
losing the only record of the card's proactive commands - a common
tweak-the-profile-and-resend loop wiped the history every time.

_resend_terminal_profile now calls _mark_proactive_session(
'terminal-profile') instead: the entries stay, _PROACTIVE_SESSION_START
restarts (so the new session's elapsed values begin at 0) and a boundary
marker entry is appended.  The PWA renders the marker as a
'- TERMINAL PROFILE re-sent - new CAT session -' divider (EN/RU).

Equip / disconnect keep the full clear (a card change); the pending-command
cancel, menu timeout and event list reset are unchanged.

Tests: the marker keeps the entries and restarts the timer, the reset still
clears, the re-send path pinned by source (Python) and the renderer's marker
branch (Node).  857 frontend + 842 Python; sw cache simple-v420.
This commit is contained in:
2026-10-08 00:20:06 +03:00
parent 9fb46b786f
commit c9ab15c392
8 changed files with 85 additions and 8 deletions
+1 -1
View File
@@ -514,7 +514,7 @@
<p class="text-sm mb-3">Отправка события использует <code class="font-mono text-sm">ENVELOPE(Event Download)</code> по TS 102 223 / TS 131 111. Форма скрывает параметры, появившиеся после <strong>действующего релиза CAT</strong> &mdash; релиза пресета подключённой карты (совпадение по ICCID) или Rel-12, если он не указан, &mdash; а примечание под формой называет источник и то, что было скрыто (релиз задаётся на вкладке «Карты»). Каждая форма также показывает точные <strong>данные события (hex)</strong>, которые будут отправлены, обновляя их по мере правки полей &mdash; скопируйте их в сырой шаг <em>Envelope</em> тест-скрипта, если у события нет семантической формы. Информация о срезах отправляется в одном <code class="font-mono text-sm">ENVELOPE</code> (не более 252 байт внутренних данных) &mdash; доставка цепочкой из нескольких ENVELOPE не реализована, поэтому данные должны помещаться в один конверт; конверт с partial NSSAI автоматически помечается как Last Envelope.</p> <p class="text-sm mb-3">Отправка события использует <code class="font-mono text-sm">ENVELOPE(Event Download)</code> по TS 102 223 / TS 131 111. Форма скрывает параметры, появившиеся после <strong>действующего релиза CAT</strong> &mdash; релиза пресета подключённой карты (совпадение по ICCID) или Rel-12, если он не указан, &mdash; а примечание под формой называет источник и то, что было скрыто (релиз задаётся на вкладке «Карты»). Каждая форма также показывает точные <strong>данные события (hex)</strong>, которые будут отправлены, обновляя их по мере правки полей &mdash; скопируйте их в сырой шаг <em>Envelope</em> тест-скрипта, если у события нет семантической формы. Информация о срезах отправляется в одном <code class="font-mono text-sm">ENVELOPE</code> (не более 252 байт внутренних данных) &mdash; доставка цепочкой из нескольких ENVELOPE не реализована, поэтому данные должны помещаться в один конверт; конверт с partial NSSAI автоматически помечается как Last Envelope.</p>
<h3 id="proactive-log" class="text-lg font-medium mb-2">8.3 Журнал проактивных команд</h3> <h3 id="proactive-log" class="text-lg font-medium mb-2">8.3 Журнал проактивных команд</h3>
<p class="text-sm mb-2">Хронологический список извлечённых проактивных команд. Каждая строка показывает время, код типа, имя и декодированный квалификатор (для команд, у которых он есть). Раскрытие строки показывает декодированную команду: текст и пункты DISPLAY TEXT / SELECT ITEM / SET UP MENU, параметры BIP-каналов, действия TIMER MANAGEMENT, названия квалификаторов PROVIDE LOCAL INFORMATION (все стандартные, включая ESN 07, MEID 0B и Supported RATs 1A) и SEND SHORT MESSAGE — разбирается SMS TPDU (тип, TP-MR, TP-DA, TP-PID, TP-DCS, срок действия, TP-UDL), а пользовательские данные показываются как текст для текстовых кодировок (GSM&nbsp;7-бит, UCS2, 8-бит) или как secured-пакет (TS&nbsp;31.115) при TP-PID&nbsp;=&nbsp;<code class="font-mono text-sm">7F</code> (SIM data download); заголовки конкатенации UDH декодируются. Для команд с данными ответа показывается строка <code class="font-mono text-sm">Ответ:</code> с байтами TERMINAL RESPONSE (без служебных TLV); ответы PROVIDE LOCAL INFORMATION декодируются через словарь данных PLI.</p> <p class="text-sm mb-2">Хронологический список извлечённых проактивных команд. Каждая строка показывает время, код типа, имя и декодированный квалификатор (для команд, у которых он есть). Повторная отправка TERMINAL PROFILE (<strong>Отправить</strong> или <strong>Rescue</strong>) начинает новую CAT-сессию, но список сохраняется: её отмечает разделительная строка, а отсчёт времени начинается заново (подключение другой карты список очищает). Раскрытие строки показывает декодированную команду: текст и пункты DISPLAY TEXT / SELECT ITEM / SET UP MENU, параметры BIP-каналов, действия TIMER MANAGEMENT, названия квалификаторов PROVIDE LOCAL INFORMATION (все стандартные, включая ESN 07, MEID 0B и Supported RATs 1A) и SEND SHORT MESSAGE — разбирается SMS TPDU (тип, TP-MR, TP-DA, TP-PID, TP-DCS, срок действия, TP-UDL), а пользовательские данные показываются как текст для текстовых кодировок (GSM&nbsp;7-бит, UCS2, 8-бит) или как secured-пакет (TS&nbsp;31.115) при TP-PID&nbsp;=&nbsp;<code class="font-mono text-sm">7F</code> (SIM data download); заголовки конкатенации UDH декодируются. Для команд с данными ответа показывается строка <code class="font-mono text-sm">Ответ:</code> с байтами TERMINAL RESPONSE (без служебных TLV); ответы PROVIDE LOCAL INFORMATION декодируются через словарь данных PLI.</p>
<h3 id="terminal-profile" class="text-lg font-medium mb-2">8.4 TERMINAL PROFILE</h3> <h3 id="terminal-profile" class="text-lg font-medium mb-2">8.4 TERMINAL PROFILE</h3>
<p class="text-sm mb-3">Блок <strong>TERMINAL PROFILE</strong> (рядом с «STATUS и опрос») содержит кнопки <strong>«Отправить»</strong> (повторная отправка, как «Спасение») и <strong>«Настроить»</strong>. В диалоге настройки: селектор пресетов (модели устройств, например профиль BIP-совместимого аппарата из этого проекта), поле hex и форма с флажком на каждый бит профиля по <strong>TS 102 223 §5.2</strong> / <strong>TS 31.111 §5.2</strong> (байты 1&ndash;39; для битов 3GPP используются имена из TS 31.111); каждый байт — вертикальный список битов в порядке спецификации (<strong>b1 — младший бит, первая строка таблицы</strong>); биты, образующие числовое поле по спецификации (байт 11 — число soft keys, байт 13 — число BIP-каналов, байты 14/15 — высота/ширина экрана, байт 16 — уменьшение ширины в меню, байт 19 — версия TIA/EIA-136, байт 24 — максимум кадров), показываются одним числовым полем на весь диапазон битов, а в подсказке байта 11 отмечено зарезервированное значение <code class="font-mono text-sm">'FF'</code>; блоки размещены фиксированными группами (байты 1–12 в 2 колонки, 13–16 в 4, 17–18 в 2, 19–21 в 3, 22–25 в 2, 26–28 в 3, 29–30 в 2, далее по одному в строке); переключение бита обновляет hex, а правка hex перерисовывает форму &mdash; поле hex основное, неизвестные байты и биты сохраняются. Кнопка <strong>«Применить»</strong> отправляет новое значение на сервер (и далее на карту), сбрасывая STK-сессию как «Спасение»; изменение хранится только в памяти (значение <code class="font-mono text-sm">--terminal-profile</code> — стартовое по умолчанию). Правила вывода характеристик устройства из TP (поколение связи, бездисплейные модемы, семейство стандартов) собраны в <code class="font-mono text-sm">docs/TERMINAL_PROFILE.md</code>.</p> <p class="text-sm mb-3">Блок <strong>TERMINAL PROFILE</strong> (рядом с «STATUS и опрос») содержит кнопки <strong>«Отправить»</strong> (повторная отправка, как «Спасение») и <strong>«Настроить»</strong>. В диалоге настройки: селектор пресетов (модели устройств, например профиль BIP-совместимого аппарата из этого проекта), поле hex и форма с флажком на каждый бит профиля по <strong>TS 102 223 §5.2</strong> / <strong>TS 31.111 §5.2</strong> (байты 1&ndash;39; для битов 3GPP используются имена из TS 31.111); каждый байт — вертикальный список битов в порядке спецификации (<strong>b1 — младший бит, первая строка таблицы</strong>); биты, образующие числовое поле по спецификации (байт 11 — число soft keys, байт 13 — число BIP-каналов, байты 14/15 — высота/ширина экрана, байт 16 — уменьшение ширины в меню, байт 19 — версия TIA/EIA-136, байт 24 — максимум кадров), показываются одним числовым полем на весь диапазон битов, а в подсказке байта 11 отмечено зарезервированное значение <code class="font-mono text-sm">'FF'</code>; блоки размещены фиксированными группами (байты 1–12 в 2 колонки, 13–16 в 4, 17–18 в 2, 19–21 в 3, 22–25 в 2, 26–28 в 3, 29–30 в 2, далее по одному в строке); переключение бита обновляет hex, а правка hex перерисовывает форму &mdash; поле hex основное, неизвестные байты и биты сохраняются. Кнопка <strong>«Применить»</strong> отправляет новое значение на сервер (и далее на карту), сбрасывая STK-сессию как «Спасение»; изменение хранится только в памяти (значение <code class="font-mono text-sm">--terminal-profile</code> — стартовое по умолчанию). Правила вывода характеристик устройства из TP (поколение связи, бездисплейные модемы, семейство стандартов) собраны в <code class="font-mono text-sm">docs/TERMINAL_PROFILE.md</code>.</p>
+1 -1
View File
@@ -513,7 +513,7 @@
<p class="text-sm mb-3">Sending an event uses <code class="font-mono text-sm">ENVELOPE(Event Download)</code> per TS 102 223 / TS 131 111. The form hides the parameters introduced after the <strong>effective CAT release</strong> &mdash; the equipped card preset's <code class="font-mono text-sm">CAT release</code> (matched by ICCID), or Rel-12 when unspecified &mdash; and a note under the form names the source and what was hidden (the release is set in the Cards tab). Each form also shows the exact <strong>event data (hex)</strong> it will send, updated as the fields change &mdash; copy it into a raw <em>Envelope</em> test-script step when an event has no semantic form. Slice information is sent in a single <code class="font-mono text-sm">ENVELOPE</code> (max 252 bytes of inner data) &mdash; chained (multi-envelope) delivery is not implemented, so the data must fit one envelope; an envelope carrying the partial NSSAI is marked as the Last Envelope automatically.</p> <p class="text-sm mb-3">Sending an event uses <code class="font-mono text-sm">ENVELOPE(Event Download)</code> per TS 102 223 / TS 131 111. The form hides the parameters introduced after the <strong>effective CAT release</strong> &mdash; the equipped card preset's <code class="font-mono text-sm">CAT release</code> (matched by ICCID), or Rel-12 when unspecified &mdash; and a note under the form names the source and what was hidden (the release is set in the Cards tab). Each form also shows the exact <strong>event data (hex)</strong> it will send, updated as the fields change &mdash; copy it into a raw <em>Envelope</em> test-script step when an event has no semantic form. Slice information is sent in a single <code class="font-mono text-sm">ENVELOPE</code> (max 252 bytes of inner data) &mdash; chained (multi-envelope) delivery is not implemented, so the data must fit one envelope; an envelope carrying the partial NSSAI is marked as the Last Envelope automatically.</p>
<h3 id="proactive-log" class="text-lg font-medium mb-2">8.3 Proactive command log</h3> <h3 id="proactive-log" class="text-lg font-medium mb-2">8.3 Proactive command log</h3>
<p class="text-sm mb-2">Chronological list of fetched proactive commands. Each row shows the elapsed time, type code, name, and a decoded qualifier (for commands that have one). Expanding a row shows the decoded command: DISPLAY TEXT / SELECT ITEM / SET UP MENU text and items, BIP channel parameters, TIMER MANAGEMENT actions, PROVIDE LOCAL INFORMATION qualifier names (all standard qualifiers, including ESN 07, MEID 0B and Supported RATs 1A), and SEND SHORT MESSAGE &mdash; the SMS TPDU is parsed (type, TP-MR, TP-DA, TP-PID, TP-DCS, validity period, TP-UDL) with the user data shown as text for text codings (GSM&nbsp;7-bit, UCS2, 8-bit) or as a secured packet (TS&nbsp;31.115) when TP-PID&nbsp;=&nbsp;<code class="font-mono text-sm">7F</code> (SIM data download); UDH concatenation headers are decoded. Commands with response data show a <code class="font-mono text-sm">Response:</code> line with the TERMINAL RESPONSE bytes (boilerplate TLVs stripped); PROVIDE LOCAL INFORMATION responses are decoded using the PLI data dictionary decoders.</p> <p class="text-sm mb-2">Chronological list of fetched proactive commands. Each row shows the elapsed time, type code, name, and a decoded qualifier (for commands that have one). Re-sending the TERMINAL PROFILE (<strong>Send</strong> or <strong>Rescue</strong>) starts a new CAT session but keeps the list: a boundary line marks it and the elapsed times restart (equipping another card clears the list). Expanding a row shows the decoded command: DISPLAY TEXT / SELECT ITEM / SET UP MENU text and items, BIP channel parameters, TIMER MANAGEMENT actions, PROVIDE LOCAL INFORMATION qualifier names (all standard qualifiers, including ESN 07, MEID 0B and Supported RATs 1A), and SEND SHORT MESSAGE &mdash; the SMS TPDU is parsed (type, TP-MR, TP-DA, TP-PID, TP-DCS, validity period, TP-UDL) with the user data shown as text for text codings (GSM&nbsp;7-bit, UCS2, 8-bit) or as a secured packet (TS&nbsp;31.115) when TP-PID&nbsp;=&nbsp;<code class="font-mono text-sm">7F</code> (SIM data download); UDH concatenation headers are decoded. Commands with response data show a <code class="font-mono text-sm">Response:</code> line with the TERMINAL RESPONSE bytes (boilerplate TLVs stripped); PROVIDE LOCAL INFORMATION responses are decoded using the PLI data dictionary decoders.</p>
<h3 id="terminal-profile" class="text-lg font-medium mb-2">8.4 TERMINAL PROFILE</h3> <h3 id="terminal-profile" class="text-lg font-medium mb-2">8.4 TERMINAL PROFILE</h3>
<p class="text-sm mb-3">The <strong>TERMINAL PROFILE</strong> block (next to STATUS and Polling) offers <strong>Send</strong> (re-sends it, like Rescue) and <strong>Configure</strong>. The Configure dialog has a preset selector (device models, e.g. this project's BIP-capable handset profile), a hex field and a form with one checkbox per profile bit decoded per <strong>TS 102 223 &sect;5.2</strong> / <strong>TS 31.111 &sect;5.2</strong> (bytes 1&ndash;39, 3GPP-defined bits use the TS 31.111 names), each byte is a vertical list of its bits in spec order (<strong>b1 is the least significant bit and the first table row</strong>); bits that form a numeric value field per the spec (byte 11 soft keys, byte 13 BIP channels, byte 14/15 screen height/width, byte 16 menu width reduction, byte 19 TIA/EIA-136 version, byte 24 max frames) are shown as a single number input for the whole bit range, with the byte 11 <code class="font-mono text-sm">'FF'</code> reserved value noted in the hint; placed in fixed column groups (bytes 1-12 in 2 columns, 13-16 in 4, 17-18 in 2, 19-21 in 3, 22-25 in 2, 26-28 in 3, 29-30 in 2, later bytes one per row); toggling a bit updates the hex and editing the hex re-renders the form &mdash; the hex field is authoritative and unknown bytes/bits are preserved. <strong>Apply</strong> sends the new value to the server (and on to the card), resetting the STK session like Rescue; the change is in-memory only (the <code class="font-mono text-sm">--terminal-profile</code> CLI value is the startup default). The rules for inferring device characteristics from a TP (radio generation, headless modems, standards family) are collected in <code class="font-mono text-sm">docs/TERMINAL_PROFILE.md</code>.</p> <p class="text-sm mb-3">The <strong>TERMINAL PROFILE</strong> block (next to STATUS and Polling) offers <strong>Send</strong> (re-sends it, like Rescue) and <strong>Configure</strong>. The Configure dialog has a preset selector (device models, e.g. this project's BIP-capable handset profile), a hex field and a form with one checkbox per profile bit decoded per <strong>TS 102 223 &sect;5.2</strong> / <strong>TS 31.111 &sect;5.2</strong> (bytes 1&ndash;39, 3GPP-defined bits use the TS 31.111 names), each byte is a vertical list of its bits in spec order (<strong>b1 is the least significant bit and the first table row</strong>); bits that form a numeric value field per the spec (byte 11 soft keys, byte 13 BIP channels, byte 14/15 screen height/width, byte 16 menu width reduction, byte 19 TIA/EIA-136 version, byte 24 max frames) are shown as a single number input for the whole bit range, with the byte 11 <code class="font-mono text-sm">'FF'</code> reserved value noted in the hint; placed in fixed column groups (bytes 1-12 in 2 columns, 13-16 in 4, 17-18 in 2, 19-21 in 3, 22-25 in 2, 26-28 in 3, 29-30 in 2, later bytes one per row); toggling a bit updates the hex and editing the hex re-renders the form &mdash; the hex field is authoritative and unknown bytes/bits are preserved. <strong>Apply</strong> sends the new value to the server (and on to the card), resetting the STK session like Rescue; the change is in-memory only (the <code class="font-mono text-sm">--terminal-profile</code> CLI value is the startup default). The rules for inferring device characteristics from a TP (radio generation, headless modems, standards family) are collected in <code class="font-mono text-sm">docs/TERMINAL_PROFILE.md</code>.</p>
+9 -1
View File
@@ -1905,7 +1905,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.23.6'; const SIMPLE_VERSION = '3.23.7';
document.getElementById('app-version').textContent = 'v' + SIMPLE_VERSION; document.getElementById('app-version').textContent = 'v' + SIMPLE_VERSION;
// ===== view history (the browser Back/Forward buttons) ===== // ===== view history (the browser Back/Forward buttons) =====
@@ -16859,6 +16859,13 @@ async function pysimProactiveLogRender() {
} }
let html = ''; let html = '';
log.forEach((e, i) => { log.forEach((e, i) => {
// a session boundary marker (a TERMINAL PROFILE re-send keeps the
// history): everything above is the previous CAT session
if (e.marker) {
html += '<div data-log-id="' + e.id + '" class="py-1 text-center text-xs text-gray-400 dark:text-slate-500">'
+ '\u2014 ' + esc(t('TERMINAL PROFILE re-sent \u2014 new CAT session')) + ' \u2014</div>';
return;
}
const name = CMD_NAMES[e.type_hex] const name = CMD_NAMES[e.type_hex]
|| (e.type_name && e.type_name !== 'UNKNOWN' ? e.type_name : 'Cmd 0x' + e.type_hex.toUpperCase()); || (e.type_name && e.type_name !== 'UNKNOWN' ? e.type_name : 'Cmd 0x' + e.type_hex.toUpperCase());
let qual = ''; let qual = '';
@@ -23058,6 +23065,7 @@ const LANG_RU = {
'Text': 'Текст', 'Text': 'Текст',
'id': 'id', 'id': 'id',
'text': 'текст', 'text': 'текст',
'TERMINAL PROFILE re-sent \u2014 new CAT session': 'TERMINAL PROFILE отправлен заново \u2014 новая CAT-сессия',
'manual input': 'ручной ввод', 'manual input': 'ручной ввод',
'Additional information (optional hex byte)': 'Дополнительная информация (необязательный hex-байт)', 'Additional information (optional hex byte)': 'Дополнительная информация (необязательный hex-байт)',
'TERMINAL RESPONSE result must be two hex digits': 'Результат TERMINAL RESPONSE — ровно два hex-символа', 'TERMINAL RESPONSE result must be two hex digits': 'Результат TERMINAL RESPONSE — ровно два hex-символа',
+1 -1
View File
@@ -1,4 +1,4 @@
const CACHE = 'simple-v419'; const CACHE = 'simple-v420';
const URLS = [ const URLS = [
'index.html', 'index.html',
'help.html', 'help.html',
+11
View File
@@ -226,3 +226,14 @@ test('SELECT by FID SIM (CLA A0): no Le anywhere', () => {
const apdu = setup('sim', { cmd: 'select', selMethod: 'fid', fid: '6FC5' }); const apdu = setup('sim', { cmd: 'select', selMethod: 'fid', fid: '6FC5' });
assert.strictEqual(apdu, 'A0A40000026FC5'); assert.strictEqual(apdu, 'A0A40000026FC5');
}); });
test('the proactive log renders a session boundary marker', () => {
// v3.23.7: a TERMINAL PROFILE re-send keeps the log history and appends a
// marker entry - the renderer draws it as a boundary line, not a command
// row (and the marker branch must run before the normal row builder)
const src = extractFunc(html, 'pysimProactiveLogRender');
assert.ok(src.includes('if (e.marker)'), src.slice(0, 300));
assert.ok(src.includes("t('TERMINAL PROFILE re-sent \\u2014 new CAT session')"), src);
assert.ok(src.indexOf('if (e.marker)') < src.indexOf('CMD_NAMES[e.type_hex]'),
'the marker branch must run before the normal row');
});
+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.23.6" version = "3.23.7"
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.
+21 -3
View File
@@ -36,7 +36,7 @@ from osmocom.tlv import BER_TLV_IE
from osmocom.utils import rpad from osmocom.utils import rpad
VERSION = '3.23.6' VERSION = '3.23.7'
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
@@ -4880,6 +4880,22 @@ def _reset_proactive_log():
_PROACTIVE_SESSION_START = time.time() _PROACTIVE_SESSION_START = time.time()
def _mark_proactive_session(reason='terminal-profile'):
"""A new CAT session without losing the history: restart the elapsed
timer and append a boundary marker entry. Used by the TERMINAL PROFILE
re-send (/api/terminal-profile and /api/rescue) - a card change still
clears the log (_reset_proactive_log)."""
global _PROACTIVE_SESSION_START, _PROACTIVE_ENTRY_ID
_PROACTIVE_SESSION_START = time.time()
_PROACTIVE_ENTRY_ID += 1
_PROACTIVE_LOG.append({
'id': _PROACTIVE_ENTRY_ID,
'marker': reason,
'elapsed': 0.0,
'bytes': 0,
})
def _send_status(scc): def _send_status(scc):
"""STATUS (F2) with correct P3 per card type: SIM=0x23, UICC=0x00. """STATUS (F2) with correct P3 per card type: SIM=0x23, UICC=0x00.
P2=0C mirrors phone behavior - no FCP of the selected DF returned P2=0C mirrors phone behavior - no FCP of the selected DF returned
@@ -5657,12 +5673,14 @@ def _validate_tp_hex(hex_str):
def _resend_terminal_profile(server, scc): def _resend_terminal_profile(server, scc):
"""Re-send the current TERMINAL PROFILE and reset the STK session state. """Re-send the current TERMINAL PROFILE and reset the STK session state.
Shared by /api/rescue and the runtime profile update; the value lives in Shared by /api/rescue and the runtime profile update; the value lives in
server.terminal_profile (CLI default, overridable at runtime).""" server.terminal_profile (CLI default, overridable at runtime). The
proactive log history is kept - a boundary marker entry records the new
session (v3.23.7)."""
server.stk_pending = None server.stk_pending = None
server.menu_active = False server.menu_active = False
_cancel_menu_timeout() _cancel_menu_timeout()
server.event_list = None server.event_list = None
_reset_proactive_log() _mark_proactive_session('terminal-profile')
sm, el = _send_terminal_profile(scc, server.terminal_profile) sm, el = _send_terminal_profile(scc, server.terminal_profile)
server.sim_menu = sm server.sim_menu = sm
server.event_list = el server.event_list = el
+40
View File
@@ -1066,6 +1066,46 @@ class TestProactiveDecode(unittest.TestCase):
_record_tr(entry, bytes.fromhex('810303260082028181')) _record_tr(entry, bytes.fromhex('810303260082028181'))
self.assertNotIn('tr_result', entry) self.assertNotIn('tr_result', entry)
def test_the_session_marker_keeps_the_proactive_history(self):
# v3.23.7: a TERMINAL PROFILE re-send keeps the log and appends a
# boundary marker; only the elapsed timer restarts
import time as _time
import pysim_simple_server.server as srv
srv._PROACTIVE_LOG.clear()
srv._init_proactive_session()
srv._log_proactive(0x21, b'\x00')
before = len(srv._PROACTIVE_LOG)
t0 = srv._PROACTIVE_SESSION_START
_time.sleep(0.01)
srv._mark_proactive_session('terminal-profile')
self.assertEqual(len(srv._PROACTIVE_LOG), before + 1)
marker = srv._PROACTIVE_LOG[-1]
self.assertEqual(marker['marker'], 'terminal-profile')
self.assertEqual(marker['elapsed'], 0.0)
self.assertGreater(srv._PROACTIVE_SESSION_START, t0)
# the new session's entries restart their elapsed values
srv._log_proactive(0x21, b'\x00')
self.assertLess(srv._PROACTIVE_LOG[-1]['elapsed'], 1.0)
srv._reset_proactive_log()
def test_the_log_reset_still_clears(self):
# equip / disconnect keep the full reset (a card change)
import pysim_simple_server.server as srv
srv._PROACTIVE_LOG.clear()
srv._init_proactive_session()
srv._log_proactive(0x21, b'\x00')
srv._reset_proactive_log()
self.assertEqual(srv._PROACTIVE_LOG, [])
def test_the_terminal_profile_resend_marks_the_session(self):
# the Send button / Rescue share _resend_terminal_profile: it must
# mark (not clear) - a source pin, since calling it needs a card
import inspect
import pysim_simple_server.server as srv
src = inspect.getsource(srv._resend_terminal_profile)
self.assertIn("_mark_proactive_session('terminal-profile')", src)
self.assertNotIn('_reset_proactive_log()', src)
class TestEventDownload(unittest.TestCase): class TestEventDownload(unittest.TestCase):
"""ENVELOPE (EVENT DOWNLOAD) assembly, TS 102 223 7.5.11.""" """ENVELOPE (EVENT DOWNLOAD) assembly, TS 102 223 7.5.11."""