diff --git a/frontend/index.html b/frontend/index.html index 3a7a223..61a6480 100644 --- a/frontend/index.html +++ b/frontend/index.html @@ -1277,14 +1277,33 @@ function cmdRows(cmd) { const kids = apdu.children || []; const insKid = kids.find(k => k.label === 'INS'); const name = insKid ? (insKid.desc || '') : apdu.label; - rows.push(['C-APDU #' + n + ' — ' + (name || apdu.label), - apdu.hex || '' + (apdu.label === 'APDU (implied CLA)' ? ' (implied CLA)' : '')]); + rows.push(['C-APDU #' + n + ' — ' + (name || apdu.label) + + (apdu.label.includes('implied CLA') ? ' (implied CLA)' : ''), + apdu.hex || '']); + // Compact layout: pair CLA+INS and P1+P2; skip a + // desc that merely repeats the hex value. + const fmtKid = k => { + let v = k.hex || ''; + if (k.desc && k.desc !== k.hex) v += ' — ' + k.desc; + return v; + }; + const byLabel = {}; + for (const k of kids) byLabel[k.label] = k; + const pairs = [['CLA', 'INS'], ['P1', 'P2']]; + const done = new Set(); + for (const [a, b] of pairs) { + if (byLabel[a] && byLabel[b]) { + rows.push(['· ' + a + ', ' + b, + fmtKid(byLabel[a]) + ', ' + fmtKid(byLabel[b])]); + done.add(a); + done.add(b); + } + } for (const k of kids) { - rows.push(['· ' + k.label, - (k.hex || '') + (k.desc ? ' — ' + k.desc : '')]); + if (done.has(k.label)) continue; + rows.push(['· ' + k.label, fmtKid(k)]); if (k.children) for (const c of k.children) { - rows.push(['· · ' + c.label, - (c.hex || '') + (c.desc ? ' — ' + c.desc : '')]); + rows.push(['· · ' + c.label, fmtKid(c)]); } } } @@ -2465,7 +2484,7 @@ function onFilterChange() { } // ──────────────────── Versioning ──────────────────── -const PWA_VERSION = '1.20.1'; +const PWA_VERSION = '1.20.2'; const MIN_SERVER_VERSION = '1.0.0'; function parseVersion(v) { diff --git a/frontend/sw.js b/frontend/sw.js index a11734f..d8ce4b6 100644 --- a/frontend/sw.js +++ b/frontend/sw.js @@ -1,4 +1,4 @@ -const CACHE = 'simtrace-analyser-v29'; +const CACHE = 'simtrace-analyser-v30'; const PRECACHE = [ 'index.html', diff --git a/pyproject.toml b/pyproject.toml index 02a2500..61bf353 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -4,7 +4,7 @@ build-backend = "setuptools.backends._legacy:_Backend" [project] name = "simtrace2-pysniff" -version = "1.20.1" +version = "1.20.2" description = "Python-based sniffing tool for SIMtrace2 hardware (SIM card communication sniffer)" readme = {file = "README.md", content-type = "text/markdown"} license = {text = "GPL-2.0-or-later"} diff --git a/simtrace2_pysniff/__init__.py b/simtrace2_pysniff/__init__.py index 61651b8..bbcf1ce 100644 --- a/simtrace2_pysniff/__init__.py +++ b/simtrace2_pysniff/__init__.py @@ -6,7 +6,7 @@ from .gsmtap import GsmtapSender, GsmtapReceiver from .pcap import PcapWriter from .dump import FileDumper, format_message -__version__ = '1.20.1' +__version__ = '1.20.2' __all__ = [ 'SniffSession', 'DeviceDisconnected', diff --git a/tests/test_pcap_import.py b/tests/test_pcap_import.py index 7e5dada..db050f4 100644 --- a/tests/test_pcap_import.py +++ b/tests/test_pcap_import.py @@ -197,7 +197,7 @@ class TestImportEndpoint(unittest.TestCase): class TestVersion(unittest.TestCase): def test_package_version(self): from simtrace2_pysniff import __version__ - self.assertEqual(__version__, '1.20.1') + self.assertEqual(__version__, '1.20.2') def test_status_includes_version(self): import os