diff --git a/frontend/index.html b/frontend/index.html index 87080db..ee873da 100644 --- a/frontend/index.html +++ b/frontend/index.html @@ -630,7 +630,9 @@ function filter_label(msg) { const d = msg.decoded; if (d) { if (d.ins_name === 'ENVELOPE') return 'ENVELOPE'; - if (d.ins_name === 'FETCH' || d.ins_name === 'TERMINAL RESPONSE') return 'FETCH: ANY PROACTIVE'; + // Every command keeps its own label (the filter is multi-select, so + // FETCH and TERMINAL RESPONSE are picked individually — or through + // the proactive preset's SW 91xx rule). if (d.ins_name) return d.ins_name; } return _fallback_label(msg); @@ -2348,12 +2350,12 @@ const FILTER_PRESETS = [ id: 'preset:proactive', name: 'Proactive sessions', // FETCH / TERMINAL PROFILE plus every proactive-session initiator: // a command the card answers with SW 91xx. - labels: ['FETCH: ANY PROACTIVE', 'TERMINAL PROFILE'], + labels: ['FETCH', 'TERMINAL PROFILE'], test: m => _sw1(m) === 0x91, }, { id: 'preset:proactive-events', name: 'Proactive + events', - labels: ['FETCH: ANY PROACTIVE', 'TERMINAL PROFILE', 'ENVELOPE'], + labels: ['FETCH', 'TERMINAL PROFILE', 'ENVELOPE'], test: m => _sw1(m) === 0x91, }, { @@ -3344,7 +3346,7 @@ function onSearchChange() { } // ──────────────────── Versioning ──────────────────── -const PWA_VERSION = '2.7.0'; +const PWA_VERSION = '2.7.1'; const MIN_SERVER_VERSION = '2.3.0'; function parseVersion(v) { diff --git a/frontend/sw.js b/frontend/sw.js index 32e0e8c..7b0fe97 100644 --- a/frontend/sw.js +++ b/frontend/sw.js @@ -1,4 +1,4 @@ -const CACHE = 'simtrace-analyser-v80'; +const CACHE = 'simtrace-analyser-v81'; const PRECACHE = [ 'index.html', diff --git a/frontend/tests/filter.test.js b/frontend/tests/filter.test.js index 237c327..6748d56 100644 --- a/frontend/tests/filter.test.js +++ b/frontend/tests/filter.test.js @@ -26,6 +26,8 @@ eval( ); let el = () => ({}); +function filterLabelOf(m) { return filter_label(m); } + const INS = { SELECT: 'a4', 'READ BINARY': 'b0', 'READ RECORD': 'b2', 'UPDATE BINARY': 'd6', 'UPDATE RECORD': 'dc', @@ -73,15 +75,31 @@ test('the GET RESPONSE linkage follows the selected commands', () => { test('the proactive preset: FETCH, TERMINAL PROFILE and SW 91xx initiators', () => { const set = new Set(['preset:proactive']); assert.equal(matchesFilter(msg('FETCH'), 0, set), true); - assert.equal(matchesFilter(msg('TERMINAL RESPONSE'), 0, set), true); assert.equal(matchesFilter(msg('TERMINAL PROFILE'), 0, set), true); + // A TERMINAL RESPONSE comes along through its 91xx answer, not its name. + assert.equal(matchesFilter(msg('TERMINAL RESPONSE', { sw1: '91', sw2: '00' }), 0, set), true); assert.equal(matchesFilter(msg('ENVELOPE', { sw1: '91', sw2: '30' }), 0, set), true); assert.equal(matchesFilter(msg('UPDATE BINARY', { sw1: '91', sw2: '00' }), 0, set), true); - // Novelties: a plain ENVELOPE (90 00) and unrelated commands stay out. + // A plain ENVELOPE/TERMINAL RESPONSE (90 00) and unrelated commands stay out. assert.equal(matchesFilter(msg('ENVELOPE'), 0, set), false); + assert.equal(matchesFilter(msg('TERMINAL RESPONSE'), 0, set), false); assert.equal(matchesFilter(msg('SELECT'), 0, set), false); }); +test('FETCH and TERMINAL RESPONSE are separate commands now', () => { + // Every command keeps its own label; the multi-select filter (or the + // preset's SW 91xx rule) covers the combinations. + assert.equal(filterLabelOf(msg('FETCH')), 'FETCH'); + assert.equal(filterLabelOf(msg('TERMINAL RESPONSE')), 'TERMINAL RESPONSE'); + const set = new Set(['cmd:FETCH']); + assert.equal(matchesFilter(msg('FETCH'), 0, set), true); + assert.equal(matchesFilter(msg('TERMINAL RESPONSE'), 0, set), false); + // The FETCH's GET RESPONSE (the proactive command itself) follows it. + const gr = msg('GET RESPONSE', { response_for: 'FETCH' }); + STATE = { messages: [msg('FETCH'), gr] }; + assert.equal(matchesFilter(gr, 1, set), true); +}); + test('the proactive+events preset adds ENVELOPE', () => { const set = new Set(['preset:proactive-events']); assert.equal(matchesFilter(msg('ENVELOPE'), 0, set), true); diff --git a/pyproject.toml b/pyproject.toml index 3aa9b9e..19a70ce 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -4,7 +4,7 @@ build-backend = "setuptools.backends._legacy:_Backend" [project] name = "simtrace-analyser" -version = "2.7.0" +version = "2.7.1" description = "SIMtrace Analyser — APDU trace analyser for GSMTAP/PCAP captures (bundles the simtrace2-pysniff utility)" readme = {file = "README.md", content-type = "text/markdown"} license = {text = "GPL-2.0-or-later"} diff --git a/simtrace_analyser/version.py b/simtrace_analyser/version.py index c7c7ffb..ab1dba1 100644 --- a/simtrace_analyser/version.py +++ b/simtrace_analyser/version.py @@ -1,3 +1,3 @@ """Single source of truth for the SIMtrace Analyser version.""" -__version__ = '2.7.0' +__version__ = '2.7.1' diff --git a/tests/test_pcap_import.py b/tests/test_pcap_import.py index f3525ce..ea50f0a 100644 --- a/tests/test_pcap_import.py +++ b/tests/test_pcap_import.py @@ -224,7 +224,7 @@ class TestImportEndpoint(unittest.TestCase): class TestVersion(unittest.TestCase): def test_package_version(self): from simtrace2_pysniff import __version__ - self.assertEqual(__version__, '2.7.0') + self.assertEqual(__version__, '2.7.1') def test_status_includes_version(self): import os