fix: query the ELF listing with P1=10 first, fall back to P1=20 (v3.6.26)
GP 11.4.2.1 makes '10' the superset of '20' (Executable Load Files with their modules), yet the Explore queried '20' plus a separate '10' modules pass and merged the two. A live card answered 6A86 (incorrect P1-P2) to '20' while '10' worked (2026-09-28) - all four P1 values "shall be supported", so this is the guarded-fallback case, not a vendor branch. - Explore now queries '10' (with module parsing) and falls back to '20' (no module lists) only when it yields nothing; a successful fallback drops the primary failure from the result, and the primary error surfaces only when both fail. - The separate P1=10 "modules" pass and ramMergeElfData are gone. 656 frontend / 504 Python green; version 3.6.26; sw simple-v299.
This commit is contained in:
+18
-24
@@ -1713,7 +1713,7 @@
|
||||
// ===== Version =====
|
||||
// Single source of truth for the PWA version: shown in the header and used
|
||||
// by the server version check in pysimConnect().
|
||||
const SIMPLE_VERSION = '3.6.25';
|
||||
const SIMPLE_VERSION = '3.6.26';
|
||||
document.getElementById('app-version').textContent = 'v' + SIMPLE_VERSION;
|
||||
|
||||
// ===== Tab switching =====
|
||||
@@ -8838,22 +8838,6 @@ function ramFmtPrivileges(hex) {
|
||||
return privs.length ? privs.join(', ') : t('(none)');
|
||||
}
|
||||
|
||||
// Merge ELF-module entries (P1=10, carry module AIDs) into ELF entries (P1=20).
|
||||
// With TLV format (P2=02), module AIDs come from tag '84' inside E3 templates.
|
||||
// With raw format (P2=00), module AIDs are not available in the response.
|
||||
function ramMergeElfData(elfs, modules) {
|
||||
const byAid = {};
|
||||
elfs.forEach(e => { if (e.aid) byAid[e.aid] = e; });
|
||||
modules.forEach(m => {
|
||||
if (m.aid && byAid[m.aid]) {
|
||||
if (m.moduleAids && m.moduleAids.length) byAid[m.aid].moduleAids = m.moduleAids;
|
||||
} else if (m.aid) {
|
||||
elfs.push(m);
|
||||
}
|
||||
});
|
||||
return elfs;
|
||||
}
|
||||
|
||||
// Render the full explorer result as structured HTML
|
||||
function ramRenderExploreHtml(mem, isd, apps, elfs, fmt) {
|
||||
let html = '';
|
||||
@@ -8957,9 +8941,9 @@ async function ramExplore(sp) {
|
||||
let cntr = sp.cntr;
|
||||
const errors = [];
|
||||
const mem = { appCount: null, freeNV: null, freeV: null };
|
||||
const isd = [], apps = [], elfs = [], modules = [];
|
||||
const isd = [], apps = [], elfs = [];
|
||||
|
||||
async function paginate(p1, collector, parser, label) {
|
||||
async function paginate(p1, collector, parser, label, quiet) {
|
||||
// Compact listing format (GP 11.4.2.2: P2.b2=0) with the chained GET
|
||||
// RESPONSE - see ramGetStatusApdu(). The card's SCP80 layer runs both
|
||||
// commands, so the PoR carries the listing; ramListingSpi2() picks the
|
||||
@@ -9051,7 +9035,8 @@ async function ramExplore(sp) {
|
||||
}
|
||||
}
|
||||
// The compact error only surfaces when the expanded pass did not rescue it
|
||||
if (collector.length === before && compactError) errors.push(compactError);
|
||||
// (`quiet` lets a fallback query decide whether to report it).
|
||||
if (collector.length === before && compactError && !quiet) errors.push(compactError);
|
||||
}
|
||||
|
||||
ramShowProgress(t('Memory (GET DATA FF21)') + '...');
|
||||
@@ -9080,10 +9065,19 @@ async function ramExplore(sp) {
|
||||
// 80=ISD, 40=Applications, 20=Executable Load Files (ELFs), 10=ELF+modules
|
||||
await paginate('80', isd, ramParseAppStatus, t('ISD'));
|
||||
await paginate('40', apps, ramParseAppStatus, t('Apps'));
|
||||
await paginate('20', elfs, ramParseElfStatus, t('ELFs'));
|
||||
await paginate('10', modules, (hex) => ramParseElfStatus(hex, true), t('ELF Modules'));
|
||||
|
||||
ramMergeElfData(elfs, modules);
|
||||
// GP 11.4.2.1: '10' returns the ELFs *with* their modules - the superset of
|
||||
// '20' (ELFs only). All four P1 values shall be supported, but cards
|
||||
// deviate: the live card answered 6A86 (incorrect P1-P2) to '20' while
|
||||
// '10' works (2026-09-28). Query '10' first; fall back to '20' (no
|
||||
// module lists) only when it yields nothing, and report the primary
|
||||
// failure only when both fail.
|
||||
const elfErrorsBefore = errors.length;
|
||||
await paginate('10', elfs, (hex) => ramParseElfStatus(hex, true), t('ELFs'));
|
||||
if (!elfs.length) {
|
||||
const elfFailure = errors.splice(elfErrorsBefore);
|
||||
await paginate('20', elfs, ramParseElfStatus, t('ELFs'), true);
|
||||
if (!elfs.length) errors.push(...elfFailure);
|
||||
}
|
||||
// Only write the counter when a packet was actually accepted: a run whose
|
||||
// start value was stale must never lower the preset counter.
|
||||
if (cntr !== sp.cntr) ramSaveCntr(cntr);
|
||||
|
||||
+1
-1
@@ -1,4 +1,4 @@
|
||||
const CACHE = 'simple-v298';
|
||||
const CACHE = 'simple-v299';
|
||||
const URLS = [
|
||||
'index.html',
|
||||
'help.html',
|
||||
|
||||
+1
-1
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
|
||||
|
||||
[project]
|
||||
name = "pysim-simple-server"
|
||||
version = "3.6.25"
|
||||
version = "3.6.26"
|
||||
description = "HTTP REST server wrapping pysim for the SIMple PWA"
|
||||
requires-python = ">=3.8"
|
||||
# pysim is a git-only dependency installed explicitly by setup.bat/setup.sh.
|
||||
|
||||
@@ -31,7 +31,7 @@ from osmocom.tlv import BER_TLV_IE
|
||||
from osmocom.utils import rpad
|
||||
|
||||
|
||||
VERSION = '3.6.25'
|
||||
VERSION = '3.6.26'
|
||||
|
||||
MAX_ENVELOPE_SEGMENTS = 5 # max SMS segments for outgoing C-APDU in ENVELOPE
|
||||
|
||||
|
||||
Reference in New Issue
Block a user