fix: emit wire-shaped TPDUs in the GSMTAP stream (v3.1.1)

The GSMTAP stream sent logical APDUs, so a receiver (SIMtrace Analyser,
Wireshark) flagged almost every packet: case-4 commands carried their Le
byte ('length_mismatch: excessive') and responses were headerless packets
decoded as bogus commands ('truncated').  The ATR also arrived in the
middle of the stream.

- gsmtap.py: the tracer now emits wire-shaped TPDUs, matching a hardware
  sniffer capture: case 4 -> the command without Le plus the 61XX 'bytes
  available' SW (derived from the real response length), then the data as
  a GET RESPONSE TPDU (00C00000<len> + data + SW, chunked at 255); case
  1/2/3 -> one packet cmd + data + SW; unparseable APDUs fall back to raw
  command/response packets.
- No ATR/VCC/RST/PPS events at all (no line-level access over PC/SC);
  the ATR sending helper and the server-side plumbing were removed.
- Verified by replaying the bad capture's exchanges through the new
  tracer: 116 packets, zero decoder warnings (previously nearly all).
- tests: the per-case wire forms, chunking, fallbacks; README/AGENTS
  document the wire shape and its limits; version 3.1.1, sw simple-v236.
This commit is contained in:
2026-09-22 07:56:21 +03:00
parent a387cdc1b6
commit 7fd3a3c973
9 changed files with 137 additions and 91 deletions
+1 -5
View File
@@ -14,7 +14,7 @@ from pySim.cards import UiccCardBase
from .shell import load_pysim_app
from . import fastinit
from . import gsmtap
from .server import PysimHandler, StderrApduTracer, _LoggingApduTracer, VERSION, _send_terminal_profile, _DefaultProactiveHandler, _handle_proactive_chain, _send_status, _init_proactive_session, _timing_on, _tlog, _set_menu_timeout, start_card_monitor, set_auto_equip, _read_iccid, _netstate_read, _netstate_install, _send_gsmtap_atr, _LineFilter
from .server import PysimHandler, StderrApduTracer, _LoggingApduTracer, VERSION, _send_terminal_profile, _DefaultProactiveHandler, _handle_proactive_chain, _send_status, _init_proactive_session, _timing_on, _tlog, _set_menu_timeout, start_card_monitor, set_auto_equip, _read_iccid, _netstate_read, _netstate_install, _LineFilter
_server_start = 0
@@ -267,10 +267,6 @@ def main():
server.card_present = card is not None
server.card_session = 1 if card is not None else 0
server.iccid = iccid
server.gsmtap = gsmtap_sender
# Stream the ATR so a GSMTAP receiver (SIMtrace Analyser, Wireshark) has
# the session context before the first APDU of this session.
_send_gsmtap_atr(server)
# Network state monitor: install the state read during the startup init
# (right after the ICCID, before the TERMINAL PROFILE). No readable
# ICCID means the card is considered unusable - give up.