v3.13.0: the Simulator's event forms honour the preset's CAT release
The consumption half of the release guard: the event-download forms hide the parameters introduced after the effective release and say so. - catEffectiveReleaseInfo(cards, iccid): the equipped card's preset (ICCID match, the same rule the SCP80 views use) resolved through presetRelease(), else the default Rel-12. - eventFieldsForRelease(cfg, rel): a field whose introduction release (`rel`) is above the effective one is hidden; a field without a known release is never hidden. The EVENT_FORMS annotations verified against the pinned specs/histories: the MT call IMS URI (Rel-12, CR 12.4.0 "URI support in MT Call event"), the CSG cell selection PLMN ID (Rel-12, 12.1.0), the IMS registration IMPU list + status code (Rel-11), the slices S-NSSAI-mapping and rejected objects (Rel-18). - The form notes what was hidden: "hidden parameters: N · introduced after Rel-12 · preset: X" (or "default release"), with a tooltip naming the source; the send path already skips absent fields, so no builder changes. - help EN/RU; sw cache simple-v369.
This commit is contained in:
@@ -511,7 +511,7 @@
|
|||||||
<li><strong>Data Connection Status Change</strong> (0x1D) — статус (successful / rejected / dropped-deactivated), тип соединения (PDP / PDN / PDU), необязательная причина (E/5G)SM, transaction identifier и location status, а также необязательные date-time, access technology, APN, тип PDP/PDN/PDU и location information (MCC/MNC + LAC + Cell ID) — TS 131 111 §7.5.25</li>
|
<li><strong>Data Connection Status Change</strong> (0x1D) — статус (successful / rejected / dropped-deactivated), тип соединения (PDP / PDN / PDU), необязательная причина (E/5G)SM, transaction identifier и location status, а также необязательные date-time, access technology, APN, тип PDP/PDN/PDU и location information (MCC/MNC + LAC + Cell ID) — TS 131 111 §7.5.25</li>
|
||||||
<li><strong>Poll Interval Negotiation</strong> (0x1C) — предлагает интервал опроса в виде Duration (единица + значение); после отправки показывается ответ UICC (принято / отклонено / изменено + длительность), а значение <em>изменено</em> становится интервалом фонового опроса (TS 102 223 §7.5.22). Форма появляется, когда карта подписана на это событие.</li>
|
<li><strong>Poll Interval Negotiation</strong> (0x1C) — предлагает интервал опроса в виде Duration (единица + значение); после отправки показывается ответ UICC (принято / отклонено / изменено + длительность), а значение <em>изменено</em> становится интервалом фонового опроса (TS 102 223 §7.5.22). Форма появляется, когда карта подписана на это событие.</li>
|
||||||
</ul>
|
</ul>
|
||||||
<p class="text-sm mb-3">Отправка события использует <code class="font-mono text-sm">ENVELOPE(Event Download)</code> по TS 102 223 / TS 131 111.</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> — релиза пресета подключённой карты (совпадение по ICCID) или Rel-12, если он не указан, — а примечание под формой называет источник и то, что было скрыто (релиз задаётся на вкладке «Карты»).</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 7-бит, UCS2, 8-бит) или как secured-пакет (TS 31.115) при TP-PID = <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">Хронологический список извлечённых проактивных команд. Каждая строка показывает время, код типа, имя и декодированный квалификатор (для команд, у которых он есть). Раскрытие строки показывает декодированную команду: текст и пункты 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 7-бит, UCS2, 8-бит) или как secured-пакет (TS 31.115) при TP-PID = <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>
|
||||||
|
|||||||
+1
-1
@@ -510,7 +510,7 @@
|
|||||||
<li><strong>Data Connection Status Change</strong> (0x1D) — status (successful / rejected / dropped-deactivated), connection type (PDP / PDN / PDU), optional (E/5G)SM cause, transaction identifier and location status, plus optional date-time, access technology, APN, PDP/PDN/PDU type and location information (MCC/MNC + LAC + Cell ID) — TS 131 111 §7.5.25</li>
|
<li><strong>Data Connection Status Change</strong> (0x1D) — status (successful / rejected / dropped-deactivated), connection type (PDP / PDN / PDU), optional (E/5G)SM cause, transaction identifier and location status, plus optional date-time, access technology, APN, PDP/PDN/PDU type and location information (MCC/MNC + LAC + Cell ID) — TS 131 111 §7.5.25</li>
|
||||||
<li><strong>Poll Interval Negotiation</strong> (0x1C) — proposes a poll interval as a Duration (unit + value); after sending, the UICC's answer is shown (accepted / rejected / modified + duration), and a <em>modified</em> duration becomes the background poll interval (TS 102 223 §7.5.22). The form appears when the card subscribed to this event.</li>
|
<li><strong>Poll Interval Negotiation</strong> (0x1C) — proposes a poll interval as a Duration (unit + value); after sending, the UICC's answer is shown (accepted / rejected / modified + duration), and a <em>modified</em> duration becomes the background poll interval (TS 102 223 §7.5.22). The form appears when the card subscribed to this event.</li>
|
||||||
</ul>
|
</ul>
|
||||||
<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.</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> — the equipped card preset's <code class="font-mono text-sm">CAT release</code> (matched by ICCID), or Rel-12 when unspecified — and a note under the form names the source and what was hidden (the release is set in the Cards tab).</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 — 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 7-bit, UCS2, 8-bit) or as a secured packet (TS 31.115) when TP-PID = <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). 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 — 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 7-bit, UCS2, 8-bit) or as a secured packet (TS 31.115) when TP-PID = <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>
|
||||||
|
|||||||
+52
-10
@@ -1877,7 +1877,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.12.0';
|
const SIMPLE_VERSION = '3.13.0';
|
||||||
document.getElementById('app-version').textContent = 'v' + SIMPLE_VERSION;
|
document.getElementById('app-version').textContent = 'v' + SIMPLE_VERSION;
|
||||||
|
|
||||||
// ===== Tab switching =====
|
// ===== Tab switching =====
|
||||||
@@ -9188,6 +9188,18 @@ function presetRelease(preset) {
|
|||||||
return (rel >= 4 && rel <= 18) ? rel : CAT_RELEASE_DEFAULT;
|
return (rel >= 4 && rel <= 18) ? rel : CAT_RELEASE_DEFAULT;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// The effective CAT release for the CAT views (the Simulator's event forms):
|
||||||
|
// the equipped card's preset (matched by ICCID, the same rule the SCP80 views
|
||||||
|
// use) resolved through presetRelease(), else the default. Pure - takes the
|
||||||
|
// preset list and the equipped card's ICCID.
|
||||||
|
function catEffectiveReleaseInfo(cardList, iccid) {
|
||||||
|
const list = cardList || [];
|
||||||
|
const norm = cardsNormIccid(iccid);
|
||||||
|
const idx = norm ? list.findIndex(c => cardsNormIccid(c.iccid) === norm) : -1;
|
||||||
|
if (idx >= 0) return { rel: presetRelease(list[idx]), source: 'preset', preset: list[idx] };
|
||||||
|
return { rel: CAT_RELEASE_DEFAULT, source: 'default', preset: null };
|
||||||
|
}
|
||||||
|
|
||||||
// Normalise an AID (strip spacing, uppercase) and reject malformed input;
|
// Normalise an AID (strip spacing, uppercase) and reject malformed input;
|
||||||
// '' when it cannot be an AID (5-16 bytes).
|
// '' when it cannot be an AID (5-16 bytes).
|
||||||
function jcAidNorm(aid) {
|
function jcAidNorm(aid) {
|
||||||
@@ -13731,7 +13743,7 @@ const EVENT_FORMS = {
|
|||||||
{ id: 'ton', label: 'Type of number', type: 'select',
|
{ id: 'ton', label: 'Type of number', type: 'select',
|
||||||
opts: [{v:0,l:'Unknown'},{v:1,l:'International'},{v:2,l:'National'},{v:3,l:'Network specific'}] },
|
opts: [{v:0,l:'Unknown'},{v:1,l:'International'},{v:2,l:'National'},{v:3,l:'Network specific'}] },
|
||||||
{ id: 'sub', label: 'Subaddress (optional, hex)', type: 'text', pattern: '[0-9A-Fa-f]{2,40}', placeholder: 'e.g. 1234' },
|
{ id: 'sub', label: 'Subaddress (optional, hex)', type: 'text', pattern: '[0-9A-Fa-f]{2,40}', placeholder: 'e.g. 1234' },
|
||||||
{ id: 'ims_uri', label: 'IMS URI (optional)', type: 'text', placeholder: 'e.g. sip:user@example.com' },
|
{ id: 'ims_uri', label: 'IMS URI (optional)', type: 'text', placeholder: 'e.g. sip:user@example.com', rel: 12 },
|
||||||
{ id: 'media', label: 'Media Type (optional)', type: 'select',
|
{ id: 'media', label: 'Media Type (optional)', type: 'select',
|
||||||
opts: [{v:'',l:'\u2014 not present \u2014'},{v:0,l:'00 \u2014 voice'},{v:1,l:'01 \u2014 video'}] },
|
opts: [{v:'',l:'\u2014 not present \u2014'},{v:0,l:'00 \u2014 voice'},{v:1,l:'01 \u2014 video'}] },
|
||||||
],
|
],
|
||||||
@@ -14033,8 +14045,8 @@ const EVENT_FORMS = {
|
|||||||
opts: [{v:'',l:'\u2014 not present \u2014'}].concat(ACCESSTECH) },
|
opts: [{v:'',l:'\u2014 not present \u2014'}].concat(ACCESSTECH) },
|
||||||
{ id: 'csg', label: 'CSG ID (optional, hex)', type: 'text', pattern: '[0-9A-Fa-f]{2,16}', placeholder: 'e.g. 00000001' },
|
{ id: 'csg', label: 'CSG ID (optional, hex)', type: 'text', pattern: '[0-9A-Fa-f]{2,16}', placeholder: 'e.g. 00000001' },
|
||||||
{ id: 'hnb', label: 'HNB name (optional)', type: 'text', placeholder: 'e.g. MyCSG' },
|
{ id: 'hnb', label: 'HNB name (optional)', type: 'text', placeholder: 'e.g. MyCSG' },
|
||||||
{ id: 'mcc', label: 'MCC (PLMN ID, optional)', type: 'text', pattern: '\\d{3}', placeholder: 'e.g. 250' },
|
{ id: 'mcc', label: 'MCC (PLMN ID, optional)', type: 'text', pattern: '\\d{3}', placeholder: 'e.g. 250', rel: 12 },
|
||||||
{ id: 'mnc', label: 'MNC', type: 'text', pattern: '\\d{2,3}', placeholder: 'e.g. 01' },
|
{ id: 'mnc', label: 'MNC', type: 'text', pattern: '\\d{2,3}', placeholder: 'e.g. 01', rel: 12 },
|
||||||
],
|
],
|
||||||
build(v) {
|
build(v) {
|
||||||
let d = '';
|
let d = '';
|
||||||
@@ -14058,8 +14070,8 @@ const EVENT_FORMS = {
|
|||||||
0x16: null,
|
0x16: null,
|
||||||
0x17: { title: 'IMS registration', src: '83',
|
0x17: { title: 'IMS registration', src: '83',
|
||||||
fields: [
|
fields: [
|
||||||
{ id: 'impu', label: 'IMPU URI(s) (optional)', type: 'text', placeholder: 'one or more, comma-separated' },
|
{ id: 'impu', label: 'IMPU URI(s) (optional)', type: 'text', placeholder: 'one or more, comma-separated', rel: 11 },
|
||||||
{ id: 'code', label: 'IMS status code (optional)', type: 'text', pattern: '\\d{3}', placeholder: 'e.g. 200' },
|
{ id: 'code', label: 'IMS status code (optional)', type: 'text', pattern: '\\d{3}', placeholder: 'e.g. 200', rel: 11 },
|
||||||
],
|
],
|
||||||
build(v) {
|
build(v) {
|
||||||
let d = '';
|
let d = '';
|
||||||
@@ -14198,11 +14210,11 @@ const EVENT_FORMS = {
|
|||||||
{v:0x82,l:'82 \u2014 partially rejected'}] },
|
{v:0x82,l:'82 \u2014 partially rejected'}] },
|
||||||
{ id: 'tech', label: 'Access Technology (optional)', type: 'select',
|
{ id: 'tech', label: 'Access Technology (optional)', type: 'select',
|
||||||
opts: [{v:'',l:'\u2014 not present \u2014'}].concat(ACCESSTECH) },
|
opts: [{v:'',l:'\u2014 not present \u2014'}].concat(ACCESSTECH) },
|
||||||
{ id: 'allowed_map', label: 'Allowed slices with S-NSSAI mapping (optional, hex)', type: 'text', pattern: '[0-9A-Fa-f]{2,80}', placeholder: 'TS 24.501 S-NSSAI-with-mapping elements' },
|
{ id: 'allowed_map', label: 'Allowed slices with S-NSSAI mapping (optional, hex)', type: 'text', pattern: '[0-9A-Fa-f]{2,80}', placeholder: 'TS 24.501 S-NSSAI-with-mapping elements', rel: 18 },
|
||||||
{ id: 'served', label: 'Served S-NSSAIs (optional, hex)', type: 'text', pattern: '[0-9A-Fa-f]{8,80}', placeholder: '4 bytes per S-NSSAI (SST + SD)' },
|
{ id: 'served', label: 'Served S-NSSAIs (optional, hex)', type: 'text', pattern: '[0-9A-Fa-f]{8,80}', placeholder: '4 bytes per S-NSSAI (SST + SD)' },
|
||||||
{ id: 'allowed', label: 'Allowed slices (optional, hex)', type: 'text', pattern: '[0-9A-Fa-f]{8,80}', placeholder: '4 bytes per S-NSSAI (SST + SD)' },
|
{ id: 'allowed', label: 'Allowed slices (optional, hex)', type: 'text', pattern: '[0-9A-Fa-f]{8,80}', placeholder: '4 bytes per S-NSSAI (SST + SD)' },
|
||||||
{ id: 'rejected_map', label: 'Rejected slices with S-NSSAI mapping (optional, hex)', type: 'text', pattern: '[0-9A-Fa-f]{2,80}', placeholder: 'TS 24.501 elements + rejection cause' },
|
{ id: 'rejected_map', label: 'Rejected slices with S-NSSAI mapping (optional, hex)', type: 'text', pattern: '[0-9A-Fa-f]{2,80}', placeholder: 'TS 24.501 elements + rejection cause', rel: 18 },
|
||||||
{ id: 'rejected', label: 'Rejected slices (optional, hex)', type: 'text', pattern: '[0-9A-Fa-f]{2,80}', placeholder: 'TS 24.501 rejected S-NSSAI elements' },
|
{ id: 'rejected', label: 'Rejected slices (optional, hex)', type: 'text', pattern: '[0-9A-Fa-f]{2,80}', placeholder: 'TS 24.501 rejected S-NSSAI elements', rel: 18 },
|
||||||
],
|
],
|
||||||
build(v) {
|
build(v) {
|
||||||
let d = '';
|
let d = '';
|
||||||
@@ -14631,6 +14643,20 @@ async function pysimEventsRender() {
|
|||||||
|
|
||||||
let _eventFormType = null;
|
let _eventFormType = null;
|
||||||
|
|
||||||
|
// The event form's fields available at a release (pure): a field whose
|
||||||
|
// introduction release is known and above the effective release is hidden -
|
||||||
|
// the card cannot have subscribed to an event newer than itself, so the
|
||||||
|
// event's own objects (no `rel`, or `rel` at the event's release) always stay.
|
||||||
|
// Unknown releases are never hidden. Returns {fields, hidden}.
|
||||||
|
function eventFieldsForRelease(cfg, rel) {
|
||||||
|
const fields = [], hidden = [];
|
||||||
|
((cfg && cfg.fields) || []).forEach(f => {
|
||||||
|
if (f.rel && f.rel > rel) hidden.push(f);
|
||||||
|
else fields.push(f);
|
||||||
|
});
|
||||||
|
return { fields: fields, hidden: hidden };
|
||||||
|
}
|
||||||
|
|
||||||
function pysimEventSendForm(eventType) {
|
function pysimEventSendForm(eventType) {
|
||||||
const modal = document.getElementById('event-send-modal');
|
const modal = document.getElementById('event-send-modal');
|
||||||
const title = document.getElementById('event-send-title');
|
const title = document.getElementById('event-send-title');
|
||||||
@@ -14660,8 +14686,12 @@ function pysimEventSendForm(eventType) {
|
|||||||
btn.classList.add('hidden');
|
btn.classList.add('hidden');
|
||||||
} else {
|
} else {
|
||||||
title.textContent = name + ' (' + t('Send') + ')';
|
title.textContent = name + ' (' + t('Send') + ')';
|
||||||
|
// The effective CAT release (the equipped card's preset, else Rel-12):
|
||||||
|
// parameters introduced after it are hidden - the note names the source.
|
||||||
|
const eff = catEffectiveReleaseInfo(cards, _pysimCardIccid);
|
||||||
|
const avail = eventFieldsForRelease(cfg, eff.rel);
|
||||||
let html = '';
|
let html = '';
|
||||||
cfg.fields.forEach(f => {
|
avail.fields.forEach(f => {
|
||||||
const rg = f.g ? f.g.split(',') : null;
|
const rg = f.g ? f.g.split(',') : null;
|
||||||
html += '<div class="event-field" data-groups="' + (f.g||'') + '" data-id="' + f.id + '">';
|
html += '<div class="event-field" data-groups="' + (f.g||'') + '" data-id="' + f.id + '">';
|
||||||
html += '<label class="block mb-1 text-xs font-medium text-gray-700 dark:text-slate-300">' + t(f.label) + '</label>';
|
html += '<label class="block mb-1 text-xs font-medium text-gray-700 dark:text-slate-300">' + t(f.label) + '</label>';
|
||||||
@@ -14678,6 +14708,13 @@ function pysimEventSendForm(eventType) {
|
|||||||
}
|
}
|
||||||
html += '</div>';
|
html += '</div>';
|
||||||
});
|
});
|
||||||
|
if (avail.hidden.length) {
|
||||||
|
const src = eff.preset ? t('preset:') + ' ' + eff.preset.name : t('default release');
|
||||||
|
html += '<p class="text-xs text-amber-600 dark:text-amber-400 mt-2" title="' +
|
||||||
|
esc(t('The effective release comes from the equipped card\'s preset (matched by ICCID); set the CAT release in the Cards tab.')) + '">' +
|
||||||
|
esc(t('hidden parameters:') + ' ' + avail.hidden.length + ' \u00b7 ' + t('introduced after') + ' ' +
|
||||||
|
catReleaseLabel(eff.rel) + ' \u00b7 ' + src) + '</p>';
|
||||||
|
}
|
||||||
body.innerHTML = html;
|
body.innerHTML = html;
|
||||||
btn.classList.remove('hidden');
|
btn.classList.remove('hidden');
|
||||||
if (eventType === 0x12) updateNetRejectionFields();
|
if (eventType === 0x12) updateNetRejectionFields();
|
||||||
@@ -20965,6 +21002,11 @@ const LANG_RU = {
|
|||||||
'(unspecified — Rel-12)': '(не указан — Rel-12)',
|
'(unspecified — Rel-12)': '(не указан — Rel-12)',
|
||||||
'pre-Rel-6': 'до Rel-6',
|
'pre-Rel-6': 'до Rel-6',
|
||||||
'The card\'s CAT (USAT) release. The Simulator hides event parameters introduced after it. Unspecified = Rel-12, safe for most modern cards.': 'Релиз CAT (USAT) карты. Симулятор скрывает параметры событий, появившиеся после него. Не указан = Rel-12, безопасно для большинства современных карт.',
|
'The card\'s CAT (USAT) release. The Simulator hides event parameters introduced after it. Unspecified = Rel-12, safe for most modern cards.': 'Релиз CAT (USAT) карты. Симулятор скрывает параметры событий, появившиеся после него. Не указан = Rel-12, безопасно для большинства современных карт.',
|
||||||
|
'preset:': 'пресет:',
|
||||||
|
'default release': 'релиз по умолчанию',
|
||||||
|
'hidden parameters:': 'скрытые параметры:',
|
||||||
|
'introduced after': 'появились после',
|
||||||
|
'The effective release comes from the equipped card\'s preset (matched by ICCID); set the CAT release in the Cards tab.': 'Действующий релиз берётся из пресета подключённой карты (совпадение по ICCID); релиз CAT задаётся на вкладке «Карты».',
|
||||||
'The first three rows are the fixed role TARs; add further TARs as needed.': 'Первые три строки — фиксированные роли TAR; дополнительные TAR добавляются по необходимости.',
|
'The first three rows are the fixed role TARs; add further TARs as needed.': 'Первые три строки — фиксированные роли TAR; дополнительные TAR добавляются по необходимости.',
|
||||||
'PIN/PUK codes must be 4-8 decimal digits': 'Коды PIN/PUK должны состоять из 4–8 десятичных цифр',
|
'PIN/PUK codes must be 4-8 decimal digits': 'Коды PIN/PUK должны состоять из 4–8 десятичных цифр',
|
||||||
'KIc/KID — counter': 'KIc/KID — счётчик',
|
'KIc/KID — counter': 'KIc/KID — счётчик',
|
||||||
|
|||||||
+1
-1
@@ -1,4 +1,4 @@
|
|||||||
const CACHE = 'simple-v368';
|
const CACHE = 'simple-v369';
|
||||||
const URLS = [
|
const URLS = [
|
||||||
'index.html',
|
'index.html',
|
||||||
'help.html',
|
'help.html',
|
||||||
|
|||||||
@@ -34,6 +34,8 @@ eval(extractBlock('const CAT_RELEASE = {', '// The display label of an introduct
|
|||||||
eval(extractFunc(html, 'catReleaseLabel'));
|
eval(extractFunc(html, 'catReleaseLabel'));
|
||||||
eval(extractBlock('const CAT_RELEASE_DEFAULT', 'function presetRelease').replace(/^const /gm, 'var '));
|
eval(extractBlock('const CAT_RELEASE_DEFAULT', 'function presetRelease').replace(/^const /gm, 'var '));
|
||||||
eval(extractFunc(html, 'presetRelease'));
|
eval(extractFunc(html, 'presetRelease'));
|
||||||
|
eval(extractFunc(html, 'cardsNormIccid'));
|
||||||
|
eval(extractFunc(html, 'catEffectiveReleaseInfo'));
|
||||||
eval(extractBlock('const EVENT_NAMES = {', 'const REJECTION_CAUSES = [').replace(/^const /gm, 'var '));
|
eval(extractBlock('const EVENT_NAMES = {', 'const REJECTION_CAUSES = [').replace(/^const /gm, 'var '));
|
||||||
|
|
||||||
test('CAT_RELEASE carries the introduction releases of the event list', () => {
|
test('CAT_RELEASE carries the introduction releases of the event list', () => {
|
||||||
@@ -91,3 +93,19 @@ test('presetRelease resolves unspecified presets to the default', () => {
|
|||||||
assert.strictEqual(presetRelease(p), CAT_RELEASE_DEFAULT, JSON.stringify(p));
|
assert.strictEqual(presetRelease(p), CAT_RELEASE_DEFAULT, JSON.stringify(p));
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
test('catEffectiveReleaseInfo resolves the equipped preset or the default', () => {
|
||||||
|
const list = [{ name: 'A', iccid: '89 70 1190 0000 4600 098', release: '17' },
|
||||||
|
{ name: 'B', iccid: '', release: '14' }];
|
||||||
|
const hit = catEffectiveReleaseInfo(list, '8970119000004600098');
|
||||||
|
assert.strictEqual(hit.rel, 17);
|
||||||
|
assert.strictEqual(hit.source, 'preset');
|
||||||
|
assert.strictEqual(hit.preset.name, 'A');
|
||||||
|
// an ICCID that matches no preset (and the empty one) resolves to the default
|
||||||
|
const miss = catEffectiveReleaseInfo(list, '8970119000004600099');
|
||||||
|
assert.strictEqual(miss.rel, CAT_RELEASE_DEFAULT);
|
||||||
|
assert.strictEqual(miss.source, 'default');
|
||||||
|
assert.strictEqual(miss.preset, null);
|
||||||
|
assert.strictEqual(catEffectiveReleaseInfo(list, '').source, 'default');
|
||||||
|
assert.strictEqual(catEffectiveReleaseInfo([], '8970119000004600098').rel, CAT_RELEASE_DEFAULT);
|
||||||
|
});
|
||||||
|
|||||||
@@ -34,6 +34,7 @@ eval(extractFunc(html, 'cmdQualifierShort'));
|
|||||||
eval(extractBlock('const EVENT_NAMES = {', 'const REJECTION_CAUSES = [').replace(/^const /gm, 'var '));
|
eval(extractBlock('const EVENT_NAMES = {', 'const REJECTION_CAUSES = [').replace(/^const /gm, 'var '));
|
||||||
eval(extractBlock('const REJECTION_CAUSES = [', 'const EVENT_FORMS = {').replace(/^const /gm, 'var '));
|
eval(extractBlock('const REJECTION_CAUSES = [', 'const EVENT_FORMS = {').replace(/^const /gm, 'var '));
|
||||||
eval(extractBlock('const EVENT_FORMS = {', 'const PLI_QUALIFIERS = [').replace(/^const /gm, 'var '));
|
eval(extractBlock('const EVENT_FORMS = {', 'const PLI_QUALIFIERS = [').replace(/^const /gm, 'var '));
|
||||||
|
eval(extractFunc(html, 'eventFieldsForRelease'));
|
||||||
eval(extractFunc(html, 'encPlmn'));
|
eval(extractFunc(html, 'encPlmn'));
|
||||||
eval(extractFunc(html, 'bytesToHex'));
|
eval(extractFunc(html, 'bytesToHex'));
|
||||||
|
|
||||||
@@ -249,3 +250,25 @@ test('the disconnected/rejection/CAG/slices events carry their extra objects', (
|
|||||||
rejected_map: '01020304', rejected: '01020304' })
|
rejected_map: '01020304', rejected: '01020304' })
|
||||||
.endsWith('F70401020304F80401020304D70401020304B10401020304'));
|
.endsWith('F70401020304F80401020304D70401020304B10401020304'));
|
||||||
});
|
});
|
||||||
|
|
||||||
|
test('event fields introduced after the effective release are hidden', () => {
|
||||||
|
// MT call: the IMS URI came with the Rel-12 URI support (12.4.0)
|
||||||
|
let r = eventFieldsForRelease(EVENT_FORMS[0x00], 11);
|
||||||
|
assert.deepStrictEqual(r.hidden.map(f => f.id), ['ims_uri']);
|
||||||
|
assert.ok(r.fields.some(f => f.id === 'ti'));
|
||||||
|
assert.strictEqual(eventFieldsForRelease(EVENT_FORMS[0x00], 12).hidden.length, 0);
|
||||||
|
// CSG cell selection: the PLMN ID came in 12.1.0
|
||||||
|
r = eventFieldsForRelease(EVENT_FORMS[0x15], 11);
|
||||||
|
assert.deepStrictEqual(r.hidden.map(f => f.id).sort(), ['mcc', 'mnc']);
|
||||||
|
// IMS registration: the IMPU list and the status code came in Rel-11
|
||||||
|
r = eventFieldsForRelease(EVENT_FORMS[0x17], 10);
|
||||||
|
assert.deepStrictEqual(r.hidden.map(f => f.id).sort(), ['code', 'impu']);
|
||||||
|
// slices: the mapping/rejected objects came in Rel-18
|
||||||
|
r = eventFieldsForRelease(EVENT_FORMS[0x1F], 16);
|
||||||
|
assert.deepStrictEqual(r.hidden.map(f => f.id).sort(), ['allowed_map', 'rejected', 'rejected_map']);
|
||||||
|
assert.strictEqual(eventFieldsForRelease(EVENT_FORMS[0x1F], 18).hidden.length, 0);
|
||||||
|
// a field without a known release is never hidden
|
||||||
|
r = eventFieldsForRelease(EVENT_FORMS[0x12], 4);
|
||||||
|
assert.strictEqual(r.hidden.length, 0);
|
||||||
|
assert.strictEqual(r.fields.length, EVENT_FORMS[0x12].fields.length);
|
||||||
|
});
|
||||||
|
|||||||
+1
-1
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
|
|||||||
|
|
||||||
[project]
|
[project]
|
||||||
name = "pysim-simple-server"
|
name = "pysim-simple-server"
|
||||||
version = "3.12.0"
|
version = "3.13.0"
|
||||||
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.
|
||||||
|
|||||||
@@ -32,7 +32,7 @@ from osmocom.tlv import BER_TLV_IE
|
|||||||
from osmocom.utils import rpad
|
from osmocom.utils import rpad
|
||||||
|
|
||||||
|
|
||||||
VERSION = '3.12.0'
|
VERSION = '3.13.0'
|
||||||
|
|
||||||
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
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user