TERMINAL PROFILE: device characteristics in list + detail views
- decode.py: _decode_terminal_profile (TS 102 223 §5.2, b1 = LSB per the spec tables): class (declared ND/NK at byte 14 b6/b7, strict likely/ handset rules), generation (positive-only 3G/HSDPA, 4G/E-UTRAN from byte 17 — never a 2G claim, real devices under-declare), BIP (byte 12 b1, byte 13 bearers/channels, byte 17 transports), standards family (byte 18 IMEISV/ESN), UI facts (soft keys/screen/markup), era band - list summary replaces raw hex: e.g. '3G/4G · BIP', 'modem · BIP', 'no BIP', fallback '<n>-byte profile' - detail view: tpRows() panel with class/reason, radio bits, BIP, standards, UI, profile length - body row label for TERMINAL PROFILE: 'TLV data' -> 'Profile' - tests: TERMINAL_PROFILE.md §10 regression anchors + synthetic declared-modem/handset vectors - Bump 1.22.21, SW cache v52->v53
This commit is contained in:
1 parent
2c373f50b7
commit
8441b56e99
7 files changed
+261
-6
No files matched your search
@@ -1006,6 +1006,79 @@ class TestPacketSummaries(unittest.TestCase):
|
||||
self.assertIsNone(self._dec('010100', 'vcc').get('summary'))
|
||||
|
||||
|
||||
class TestTerminalProfile(unittest.TestCase):
|
||||
"""TERMINAL PROFILE device characteristics (regression anchors from
|
||||
projects/docs/TERMINAL_PROFILE.md §10)."""
|
||||
|
||||
def _dec(self, profile_hex):
|
||||
data = bytes.fromhex(profile_hex)
|
||||
raw = '80100000%02x' % len(data) + profile_hex + '9000'
|
||||
return decode_message(bytes.fromhex(raw))
|
||||
|
||||
def test_xiaomi_mi_a1(self):
|
||||
r = self._dec('FFFFFFFF7F9F00DFFF03021FE2000000C3FB0007041178'
|
||||
'00710100000038428003')
|
||||
tp = r['tp']
|
||||
self.assertEqual(r['body']['label'], 'Profile')
|
||||
self.assertTrue(tp['bip'])
|
||||
self.assertEqual(tp['bip_channels'], 7)
|
||||
self.assertEqual(tp['bip_bearers'], ['GPRS'])
|
||||
self.assertEqual(tp['bip_transports'],
|
||||
['TCP client, remote', 'UDP client, remote'])
|
||||
self.assertTrue(tp['hsdpa'])
|
||||
self.assertTrue(tp['eutran'])
|
||||
self.assertEqual(tp['generation'], '3G/4G')
|
||||
self.assertTrue(tp['utran_ps'])
|
||||
self.assertEqual(tp['standards'], '3GPP + CDMA')
|
||||
self.assertEqual(tp['summary'], '3G/4G \u00b7 BIP')
|
||||
self.assertEqual(r['summary'], '3G/4G \u00b7 BIP')
|
||||
|
||||
def test_quectel_gsm_module(self):
|
||||
r = self._dec('FFFFFFFF7F1F007FFF00001F230811060700')
|
||||
tp = r['tp']
|
||||
self.assertTrue(tp['bip'])
|
||||
self.assertEqual(tp['bip_channels'], 1)
|
||||
self.assertEqual(tp['bip_bearers'], ['CSD', 'GPRS'])
|
||||
self.assertNotIn('generation', tp)
|
||||
self.assertEqual(tp['summary'], 'BIP')
|
||||
|
||||
def test_huawei_e173_underdeclared(self):
|
||||
# The E173 is a 3G modem yet leaves E-UTRAN/HSDPA clear — the TP
|
||||
# must not be read as "2G".
|
||||
r = self._dec('2965D7E11F90001FD50000000000000000E00000')
|
||||
tp = r['tp']
|
||||
self.assertIs(tp['bip'], False)
|
||||
self.assertNotIn('generation', tp)
|
||||
self.assertEqual(tp['standards'], '3GPP')
|
||||
self.assertEqual(tp['summary'], 'no BIP')
|
||||
|
||||
def test_nokia_7210(self):
|
||||
r = self._dec('FFFFFFFF7F3F00DFFF00001FE28A0D0203290000020040')
|
||||
tp = r['tp']
|
||||
self.assertTrue(tp['bip'])
|
||||
self.assertEqual(tp['bip_channels'], 7)
|
||||
self.assertEqual(tp['screen_h'], 10)
|
||||
self.assertEqual(tp['screen_w'], 13)
|
||||
self.assertNotIn('device_class', tp)
|
||||
self.assertEqual(tp['summary'], 'BIP')
|
||||
|
||||
def test_declared_headless_modem(self):
|
||||
# byte 14 b6 (0x20) = no display capability (class ND).
|
||||
r = self._dec('FFFFFFFF7F9F00DFFF03021F00' + '20' + '00' * 6)
|
||||
tp = r['tp']
|
||||
self.assertEqual(tp['device_class'], 'modem')
|
||||
self.assertIn('declared', tp['class_reason'])
|
||||
self.assertIn('no display', tp['class_reason'])
|
||||
self.assertEqual(tp['summary'], 'modem \u00b7 BIP')
|
||||
|
||||
def test_handset_class(self):
|
||||
r = self._dec('FFFFFFFF7F9F00DFFF03021FE208110000')
|
||||
tp = r['tp']
|
||||
self.assertEqual(tp['device_class'], 'handset')
|
||||
self.assertIn('screen 8\u00d717', tp['class_reason'])
|
||||
self.assertEqual(tp['summary'], 'handset \u00b7 BIP')
|
||||
|
||||
|
||||
class TestSummary(unittest.TestCase):
|
||||
def test_select_path_from_mf(self):
|
||||
r = decode_message(bytes.fromhex('a0a40804022fe29000'))
|
||||
|
||||
@@ -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__, '1.22.20')
|
||||
self.assertEqual(__version__, '1.22.21')
|
||||
|
||||
def test_status_includes_version(self):
|
||||
import os
|
||||
|
||||
Reference in new issue
Block a user