From bf83074de84a7ca9ffc7ca7ec6345e14419cffee Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=90=D0=BD=D1=82=D0=BE=D0=BD=20=D0=A2=D1=80=D0=BE=D1=88?= =?UTF-8?q?=D0=B8=D0=BD?= Date: Sun, 23 Aug 2026 15:16:40 +0300 Subject: [PATCH] Drop fabricated SET UP IDLE MODE TEXT qualifier decode; bump to 1.15.1 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Spec verification against UICC_SPECS.md / TS 102 223 V18.3.0 §8.6 showed the Command Qualifier for SET UP IDLE MODE TEXT is RFU ("this byte is RFU") — no icon self-explanatory bit exists in any generation (GSM 11.14 predates the command; TS 31.111 does not override it). The v1.11.0 _idle_text_qualifier decoded bit 1 as "icon self-explanatory" from an unverified source. Remove the decoder; the command now uses generic RFU handling (hidden at '00', raw hex otherwise). Tests updated accordingly. Version 1.15.1, SW cache v21. --- frontend/index.html | 2 +- frontend/sw.js | 2 +- pyproject.toml | 2 +- simtrace2_pysniff/__init__.py | 2 +- simtrace2_pysniff/server/decode.py | 17 +++-------------- tests/test_decode.py | 6 ++++-- tests/test_pcap_import.py | 2 +- 7 files changed, 12 insertions(+), 21 deletions(-) diff --git a/frontend/index.html b/frontend/index.html index 4847cf0..5bbbc7d 100644 --- a/frontend/index.html +++ b/frontend/index.html @@ -1881,7 +1881,7 @@ function onFilterChange() { } // ──────────────────── Versioning ──────────────────── -const PWA_VERSION = '1.15.0'; +const PWA_VERSION = '1.15.1'; const MIN_SERVER_VERSION = '1.0.0'; function parseVersion(v) { diff --git a/frontend/sw.js b/frontend/sw.js index 0c16157..2c3a8eb 100644 --- a/frontend/sw.js +++ b/frontend/sw.js @@ -1,4 +1,4 @@ -const CACHE = 'simtrace-analyser-v20'; +const CACHE = 'simtrace-analyser-v21'; const PRECACHE = [ 'index.html', diff --git a/pyproject.toml b/pyproject.toml index 882998e..6ae3e51 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -4,7 +4,7 @@ build-backend = "setuptools.backends._legacy:_Backend" [project] name = "simtrace2-pysniff" -version = "1.15.0" +version = "1.15.1" 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 4c6bc5f..fc0124e 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.15.0' +__version__ = '1.15.1' __all__ = [ 'SniffSession', 'DeviceDisconnected', diff --git a/simtrace2_pysniff/server/decode.py b/simtrace2_pysniff/server/decode.py index d344cfb..95a7f26 100644 --- a/simtrace2_pysniff/server/decode.py +++ b/simtrace2_pysniff/server/decode.py @@ -1069,20 +1069,9 @@ COMMAND_QUALIFIERS = { 0x01: REFRESH_MODES, # REFRESH 0x26: PLI_QUALIFIERS, # PROVIDE LOCAL INFORMATION } - - -def _idle_text_qualifier(qualifier): - """SET UP IDLE MODE TEXT (TS 102 223 §6.6.13): bit 1 = icon - self-explanatory flag, all other bits RFU.""" - if qualifier & ~0x01: - return f'0x{qualifier:02X}' - if qualifier & 0x01: - return 'icon self-explanatory' - return None - - -# TS 102 223 §6.6.13 — SET UP IDLE MODE TEXT -COMMAND_QUALIFIERS[0x28] = _idle_text_qualifier +# NOTE: SET UP IDLE MODE TEXT ('28') has no entry — its Command Qualifier +# is RFU per TS 102 223 V18.3.0 §8.6 ("this byte is RFU"); the generic +# fallback (hidden at '00', raw hex otherwise) applies. # ──────────────────── §8.6 bitmask qualifier decoders ──────────────────── diff --git a/tests/test_decode.py b/tests/test_decode.py index 491c0cc..803507c 100644 --- a/tests/test_decode.py +++ b/tests/test_decode.py @@ -1556,14 +1556,16 @@ class TestIdleModeText(unittest.TestCase): bytes.fromhex('80120000%02x' % len(body)) + body + b'\x90\x00') def test_8bit_text_icon_qualifier(self): - # "Hello" 8-bit + icon record 5 + qualifier bit 1 (self-explanatory) + # "Hello" 8-bit + icon record 5 + qualifier 0x01 (RFU byte — no + # icon bit exists per TS 102 223 V18.3.0 §8.6) r = self._fetch( '810301280182028182' # cmd details (qual 0x01) + device ids '8d060448656c6c6f' # Text String: DCS 0x04 (8-bit), "Hello" '1e0105') # Icon Identifier: record 5 self.assertEqual(r['cat_command'], 'SET UP IDLE MODE TEXT') self.assertEqual(r['cmd']['text'], 'Hello') - self.assertEqual(r['cmd']['qualifier'], 'icon self-explanatory') + # Qualifier byte is RFU per V18.3.0 §8.6 — non-zero shows raw + self.assertEqual(r['cmd']['qualifier'], '0x01') self.assertEqual(r['cmd']['icon_id'], 5) def test_ucs2_text(self): diff --git a/tests/test_pcap_import.py b/tests/test_pcap_import.py index 2dc33f9..9219d2f 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.15.0') + self.assertEqual(__version__, '1.15.1') def test_status_includes_version(self): import os