simula/pysim · issue #2 (mirror of upstream osmocom pysim) · branch feature/2-mbim-apdu-source
The reporter asked whether pysim can decode APDUs from a Wireshark capture of their cellular modem talking to an eSIM over MBIM. pysim already has the same shape for GSMTAP (pyshark_gsmtap.py) and Osmocom RSPRO (pyshark_rspro.py). MBIM slots straight into that pattern. This branch ships the starter implementation as pyshark_mbim.py.
The reporter was tinkering with the embedded eSIM in their modem, captured the USB traffic with Wireshark, and noticed MBIM frames carrying what looked like raw SIM APDUs. They couldn't find a way to decode them in Wireshark itself and asked the obvious question.
pysim already has a clean abstraction for "pcap dialect → APDU stream":
Adding pyshark_mbim.py slots straight into that pattern. The MBIM service ID for SIM access (MS_UICC_LOW_LEVEL_ACCESS, UUID c2f6588e-f037-4bc9-8665-f4d44bd09367) and the relevant CIDs (UICC_APDU = 4, UICC_RESET = 6, …) are stable across vendors, so the dissector path is well-defined.
The new file is intentionally close in shape to pyshark_gsmtap.py so a follow-up PR can refactor the shared scaffolding without churn.
flowchart LR Pcap[pcap file - MBIM traffic] --> Filter["pyshark.FileCapture
display_filter='mbim'"] Filter --> Loop[for each MBIM frame] Loop --> Service{service_id == UICC_LLA UUID?} Service -- no --> Skip[skip frame] Service -- yes --> Cid{mbim.cid} Cid -- "UICC_APDU (4)" --> Apdu[_hex_field uicc_apdu_command] Apdu --> Parse["ApduCommands.parse_cmd_bytes
(shared with GSMTAP adapter)"] Cid -- "UICC_RESET (6)" --> Atr[_hex_field uicc_atr] Atr --> Reset["CardReset(atr_bytes)"] Cid -- "other (OPEN/CLOSE_CHANNEL, ...)" --> Debug[debug-log, skip]
The _hex_field helper normalises Wireshark's two output conventions (colon-separated hex vs bare hex; use_json=True vs the default XML mode) so a capture from either toolchain decodes without per-version glue at the call site.
CardReset(h2b(atr_hex))) when the field is present, but no real reset trace was on hand to validate.UICC_APDU messages. The starter assumes single-frame APDUs because every MBIM capture the issue's reproducer pcap contains is in that regime; a follow-up should add the reassembly state machine.tshark -i wwanX. Adding PysharkMbimLive is one ~10-line subclass once the file variant is exercised against real captures.pyshark_gsmtap.py, pyshark_rspro.py) ship without their own unit tests for the same reason: a meaningful test needs an actual pcap to exercise tshark, and that means committing a binary fixture and running a tshark subprocess in CI. Happy to ship a small fixture pcap + tests/apdu_source/test_pyshark_mbim.py in a follow-up if the maintainer wants it.Local branch feature/2-mbim-apdu-source, commit 4fa939c. The repository's canonical home is on Osmocom's gitea (gitea.osmocom.org/sim-card/pysim); the simula/pysim GitHub mirror is where issue #2 was filed.
simtrace@lists.osmocom.org)Osmocom takes patches on gitea or on the list; mailing list is more responsive for a sole maintainer (Harald Welte).
Realistic odds for this lead alone: ~25-40% conversation (osmocom is small but responsive), ~5% contract (it's a non-profit). The more likely win condition is a referral to sysmocom, the commercial entity behind osmocom, who do contract embedded / cellular infrastructure work.