STATUS list entries: suppress raw hex when empty, describe FCP data

- decode.py: _build_summary emits 'Data: N bytes — FCP of <file> (...)' for
  STATUS responses with data (FCP already decoded into decoded.response);
  _fcp_brief builds the 'FCP of MF (DF or ADF)' / 'FCP of EF_xxx (...)'
  fragment
- index.html: cmd_description suppresses the raw-hex fallback for
  body-less STATUS rows (nothing to describe beyond type + SW)
- tests: no-data STATUS summary None; DF/EF FCP summaries; pluralization
- Bump 1.22.19, SW cache v50->v51
This commit is contained in:
catarrh committed 2026-09-19 00:10:09 +03:00
1 parent 39ee173a7d
commit ccbb3f231b
7 files changed
+87 -6

No files matched your search

+1 -1
View File
@@ -6,7 +6,7 @@ from .gsmtap import GsmtapSender, GsmtapReceiver
from .pcap import PcapWriter
from .dump import FileDumper, format_message
__version__ = '1.22.18'
__version__ = '1.22.19'
__all__ = [
'SniffSession',
'DeviceDisconnected',
+43
View File
@@ -3629,6 +3629,39 @@ def _fcp_summary(response_for, fd, response):
return label
def _fcp_brief(response):
"""Build a short "what this FCP describes" fragment for STATUS entries.
E.g. ``FCP of MF (DF or ADF)`` or ``FCP of EF_ICCID (Working EF,
transparent, 10 B)``.
"""
fd = response.get('file_descriptor') or {}
fid = response.get('file_id')
name = response.get('file_id_name')
what = name or (fid.upper() if fid else None)
if not what and not fd:
return None
label = f'FCP of {what}' if what else 'FCP'
details = []
ft = fd.get('file_type')
if ft:
details.append(ft)
if ft and ft != 'DF or ADF':
struct = fd.get('structure')
if struct:
details.append(struct)
nrec = fd.get('num_records')
rlen = fd.get('record_length')
fsize = response.get('file_size') or response.get('total_file_size')
if nrec and rlen:
details.append(f'{nrec} rec \u00d7 {rlen} B')
elif fsize:
details.append(f'{fsize} B')
if details:
label += f" ({', '.join(details)})"
return label
def _build_summary(result):
"""Build a concise human-readable description of a decoded command.
@@ -3685,6 +3718,16 @@ def _build_summary(result):
if bodytxt:
parts.append(bodytxt)
if ins == 'f2' and body:
# STATUS response data is the FCP of the current DF/EF (seen in a
# TPDU capture as the bytes after the 5-byte command header).
size = body.get('size') or 0
txt = f"Data: {size} byte{'s' if size != 1 else ''}"
brief = _fcp_brief(result.get('response') or {})
if brief:
txt += f' \u2014 {brief}'
parts.append(txt)
cmd = result.get('cmd')
if cmd:
if cmd.get('context'):