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