fix(sim): bound 14a sim abort latency + detect teardown host-side

Bump firmware pin to 3b6201d97, which bounds the 14a sim button / host-stop
latency under continuous reader traffic (was multi-second, now ~10ms).

SimSession now treats an HF_MIFARE_SIMULATE (0x0610) reply as end-of-sim for
14a: the sim starts with HF_ISO14443A_SIMULATE but the firmware tears down
with HF_MIFARE_SIMULATE, so _trace_reader and _relay_loop watch for it and
flip _active off on a button-driven stop (previously the host never noticed).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
michael
2026-07-07 10:04:44 -07:00
parent 829f254194
commit 042f49a9ec
3 changed files with 14 additions and 4 deletions

View File

@@ -21,7 +21,7 @@ class FirmwarePin:
# The firmware/ submodule commit this pm3py build was developed and tested against.
FIRMWARE_PIN = FirmwarePin(sha="303bd5873")
FIRMWARE_PIN = FirmwarePin(sha="3b6201d97")
def matches(version_string: str, pin: FirmwarePin = FIRMWARE_PIN) -> bool:

View File

@@ -388,6 +388,15 @@ class SimSession:
resp = decode_response_frame(bytes(buf[:frame_len]))
buf = buf[frame_len:]
if resp["cmd"] == Cmd.HF_MIFARE_SIMULATE:
# 14a sim tore down (button press, host stop, or
# exit_after). The firmware starts the sim with
# HF_ISO14443A_SIMULATE (0x0384) but its teardown reply
# is HF_MIFARE_SIMULATE (0x0610) — watch for the latter.
self._active = False
print(f"[SimSession] 14a sim ended, status={resp['status']}")
return
if resp["cmd"] in _TRACE_CMDS:
protocol = _TRACE_CMDS[resp["cmd"]]
data = resp["data"]
@@ -442,8 +451,9 @@ class SimSession:
if resp is None:
continue
elif resp.cmd == Cmd.HF_ISO15693_SIMULATE:
# Sim ended (firmware sent final reply)
elif resp.cmd in (Cmd.HF_ISO15693_SIMULATE, Cmd.HF_MIFARE_SIMULATE):
# Sim ended (firmware sent final reply). 15693 replies with
# HF_ISO15693_SIMULATE; 14a tears down with HF_MIFARE_SIMULATE.
print(f"[SimSession] Sim ended, status={resp.status}")
self._active = False
break