Fix EF_SPDI decode crash: parse inner '80' TLVs, emit dict plmns
stk_test1 msg 14036 regression: READ BINARY of EF_SPDI returned
"No decoded data available" — _decode_spdi (added v1.16.0) parsed
the A3 container value as bare 3-byte records (missing the inner
'80' value TLVs) and returned a list of strings, while
_build_summary/_file_summary expects the EF_PLMNwAcT shape
(list of {mcc, mnc} dicts). The resulting TypeError aborted the
whole message decode — this was the source of the 28 "Decode
error ... string indices" messages seen across all sessions.
_decode_spdi now unwraps inner '80' TLVs (bare-records fallback
kept) and always returns {'plmns': [{mcc, mnc}...]}. Replay of all
33 sessions: decode exceptions 28 → 0 (2 remaining undecoded tpdu
are 1-byte truncated capture records, not decodable by nature).
Tests: +3 (standard inner-80 form, bare-records fallback, exact
stk_test1 regression via decode_message). 344 total. Version
1.17.1, SW cache simtrace-analyser-v25.
This commit is contained in:
1 parent
07deab9c26
commit
14445ae38f
7 files changed
+50
-16
No files matched your search
@@ -6,7 +6,7 @@ from .gsmtap import GsmtapSender, GsmtapReceiver
|
||||
from .pcap import PcapWriter
|
||||
from .dump import FileDumper, format_message
|
||||
|
||||
__version__ = '1.17.0'
|
||||
__version__ = '1.17.1'
|
||||
__all__ = [
|
||||
'SniffSession',
|
||||
'DeviceDisconnected',
|
||||
|
||||
@@ -3243,19 +3243,32 @@ def _decode_smsp(raw, p1=None):
|
||||
|
||||
|
||||
def _decode_spdi(raw, p1=None):
|
||||
"""EF_SPDI (§4.2.66): 'A3' container with PLMN records (§0.3)."""
|
||||
"""EF_SPDI (§4.2.66): 'A3' container (or bare '80' value tags) with
|
||||
3-byte PLMN records — same shape as EF_PLMNwAcT for _file_summary."""
|
||||
if all(b == 0xff for b in raw):
|
||||
return {'empty': True}
|
||||
plmns = []
|
||||
|
||||
def collect(value):
|
||||
for i in range(0, len(value) - 2, 3):
|
||||
plmn = _decode_plmn(value[i:i + 3])
|
||||
if plmn and plmn not in plmns:
|
||||
plmns.append(plmn)
|
||||
|
||||
for tag, _length, value in parse_tlv(raw):
|
||||
if tag == 0xA3:
|
||||
plmns = []
|
||||
for i in range(0, len(value) - 2, 3):
|
||||
plmn = _decode_plmn(value[i:i + 3])
|
||||
if plmn:
|
||||
plmns.append(f"{plmn['mcc']}-{plmn['mnc']}")
|
||||
if plmns:
|
||||
return {'plmns': plmns if len(plmns) > 1 else plmns[0]}
|
||||
return {'raw': raw.hex().upper()}
|
||||
got = False
|
||||
for t2, _l2, v2 in parse_tlv(value):
|
||||
if t2 == 0x80:
|
||||
collect(v2)
|
||||
got = True
|
||||
if not got:
|
||||
collect(value) # bare records inside A3
|
||||
elif tag == 0x80:
|
||||
collect(value)
|
||||
if not plmns:
|
||||
return {'raw': raw.hex().upper()}
|
||||
return {'plmns': plmns}
|
||||
|
||||
|
||||
def _decode_spn(raw, p1=None):
|
||||
|
||||
Reference in new issue
Block a user