From a385648a808f29c32cd43091c7e7d8f551c13bcf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=90=D0=BD=D1=82=D0=BE=D0=BD=20=D0=A2=D1=80=D0=BE=D1=88?= =?UTF-8?q?=D0=B8=D0=BD?= Date: Tue, 27 Oct 2026 10:48:42 +0300 Subject: [PATCH] README: install/start first, remove history-heavy sections - Move installation/startup to the top (after a short intro): download (Linux tar.gz / Windows zip) and source checkout, each ending with the setup/start commands. - Usage (start options, wiring, pin mapping, clock modes, troubleshooting, raw sigrok-cli) follows the install section instead of preceding it. - Remove "Robustness against noisy signals" (decoder internals, not end-user information). - Remove historical explanations (early-version failures, "used to", before/after fix counts) from troubleshooting, clock modes, capture scenarios, cold-boot, validation and data-rate notes. - Rewrite live-capture troubleshooting: early stopping (especially on Windows) is commonly the wrong USB driver - the Saleae Logic driver works only with Saleae Logic software, sigrok needs WinUSB (Zadig) - with links to sigrok's Windows/FX2 documentation; keep the current device-not-found, USB-bandwidth and auto-restart guidance. - Move the tap photos below Usage; features/reference/development sections follow. Russian README mirrors the same structure and edits. Docs only; no decoder or release change. --- README.md | 731 ++++++++++++++++++++---------------------------- README_RUS.md | 761 +++++++++++++++++++++----------------------------- 2 files changed, 617 insertions(+), 875 deletions(-) diff --git a/README.md b/README.md index 571df81..5a0b4ee 100644 --- a/README.md +++ b/README.md @@ -18,6 +18,262 @@ recommended tool for visualising live traces and viewing saved captures — it can also import/export GSMTAP pcap files (including the PCAP written by this decoder's `pcap_file=` option). +## Install and start + +Both ways install the same decoder — pick one: + +- **Download (recommended)** — a release archive. Nothing to clone and no git + history: extract it, run `setup`, then `start`. Best if you only want to + capture. +- **Source checkout** — a `git clone`. The same runtime plus the development + material: `tests/` and the trace/baseline tools (`tools/capture_baseline.sh`, + `tools/compare_baseline.sh`, `tools/vs_reader.py`). Example traces + (`examples/`) are gitignored and stay local in either case. Release archives + do not contain `tests/`, the dev tools or `examples/`. + +### Download (recommended) + +Grab the latest archive from +[Releases](https://github.com/anttro/sigrok_iso7816_stream/releases/latest): + +- `sigrok_iso7816_stream-.tar.gz` — Linux +- `sigrok_iso7816_stream-.zip` — Windows + +Each release also publishes `SHA256SUMS`, which lists **both** archives; keep +it next to the file you downloaded and verify: + +```bash +sha256sum -c --ignore-missing SHA256SUMS # GNU coreutils (Linux) +``` + +On Windows run `certutil -hashfile sigrok_iso7816_stream-.zip SHA256` +and compare the output with the `.zip` line in `SHA256SUMS`. + +#### Linux (download) + +```bash +tar xzf sigrok_iso7816_stream-.tar.gz +cd sigrok_iso7816_stream- +./setup.sh +./start.sh +``` + +`setup.sh` verifies sigrok-cli and the FX2 firmware package +(`sigrok-firmware-fx2lafw`) are installed, symlinks the project directory into +`~/.local/share/libsigrokdecode/decoders/iso7816` (user-local decoders shadow +system-wide ones), and probes the connected device for its maximum supported +samplerate. + +#### Windows (download) + +Prerequisites: + +1. **sigrok-cli** Windows installer (0.7.2 x86_64) from + [sigrok.org/wiki/Downloads](https://sigrok.org/wiki/Downloads) — the tested + release. Nightly Windows installers are also published on that page; they + may change the sigrok-cli syntax or the decoder API, so the 0.7.2 release + installer remains the supported version. + If sigrok-cli fails to start with error `0xc0150002`, install the + [Visual C++ 2010 Redistributable](https://www.microsoft.com/en-us/download/details.aspx?id=26999) + (`msvcr100.dll` is required by the bundled Python runtime). +2. fx2lafw firmware ships bundled with the installer — no separate download. + +Driver setup (FX2 dongles need WinUSB, the vendor driver won't work): + +- Run **Zadig**, which ships *inside* the sigrok-cli installation directory + (also reachable from the Start menu). Select the FX2 device in its dropdown + and install the **WinUSB** driver. +- After firmware upload the device re-enumerates with a different VID/PID — + if it still isn't found, run Zadig a **second time** for the re-enumerated + entry. +- Windows binds drivers per USB port when no serial number is present: + moving the dongle to another port may require repeating Zadig. + +Then extract the release `.zip` (right-click → Extract All in Explorer) and +run, inside the extracted folder: + +```bat +setup.bat +start.bat +``` + +`setup.bat` verifies sigrok-cli and bundled firmware, registers this project's +decoder via a junction into `%LOCALAPPDATA%\libsigrokdecode\decoders\iso7816` +(confirmed by `sigrok-cli -L` listing `iso7816`), and probes the device's +accepted samplerates. The release zip ships the batch files with CRLF line +endings, so no conversion is needed. `start.bat --help` lists its options +(the core subset of `start.sh`: channels, samplerate, clock, host/port, pcap, +protocol, debug). + +### Source checkout + +#### Linux (source checkout) + +```bash +git clone git@github.com:anttro/sigrok_iso7816_stream.git +cd sigrok_iso7816_stream +./setup.sh +./start.sh +``` + +`setup.sh` performs the same checks and symlink as above. + +#### Windows (source checkout) + +The Windows prerequisites (sigrok-cli + the Visual C++ 2010 Redistributable, +the bundled fx2lafw firmware, and the Zadig/WinUSB driver setup) are the same +as in [Windows (download)](#windows-download) above. + +```bat +git clone git@github.com:anttro/sigrok_iso7816_stream.git +cd sigrok_iso7816_stream +setup.bat +start.bat +``` + +`setup.bat` performs the same checks and junction registration as above. +`start.bat` supports the core option subset; the space form is the primary +one, and `--clk=CH` also works (`start.bat --help` lists them): + +```bat +start.bat --clk D1 --data D6 +``` + +Note: batch files need CRLF line endings; the repo enforces this via +`.gitattributes`, so a fresh clone on Windows is already correct (the release +zip ships the same CRLF files). + +## Usage + +`start.sh` captures continuously at 16 MHz until Ctrl+C (`rc=130`) and streams +GSMTAP to 127.0.0.1:4729. Defaults: pins D5=CLK, D0=I/O, D4=RST, D2=VCC. +Override via args: + +```bash +./start.sh --clk=D1 --data=D6 # different wiring +./start.sh --no-rst --no-vcc # CLK+I/O only +./start.sh --host=10.0.28.7 # stream to a remote analyser +./start.sh --pcap=session.pcap # also record decoded events to PCAP +./start.sh --debug # full decoder + sigrok output (all + # annotation rows + libsigrok -l 4); + # by default only decoded APDUs and + # decoder warnings/errors are shown +``` + +On Windows, `start.bat` takes the same core options (space form; the +`--opt=value` form also works) — see the Windows install notes above. + +### Wiring + +The recommended tap is the short cable with external pull resistors (see +*The tap in practice* below): 10 kΩ to GND on VCC (pulls low when off) and +47 kΩ to VCC on DATA (faster rise to high). Its pin mapping is **fixed and +known in advance** — see the "Pin mapping" table below — and is exactly what +`start.sh` defaults to (`D5`=CLK, `D0`=I/O, `D4`=RST, `D2`=VCC). No wiring +auto-detection is needed; the pins never move. + +> **GND first.** Plug GND first and verify it manually (continuity meter +> or known-good contact) — a missing or loose ground masquerades as every +> other fault at once: floating lines, phantom start bits, all-zero frames. + +### Pin mapping + +The FX2 clone channels are assigned via `-P iso7816:clk=N:data=N:rst=N:vcc=N`. +The recommended short-cable tap (external pull resistors) uses fixed pins that +are exactly `start.sh`'s defaults; `--clk`/`--data`/`--rst`/`--vcc` remap them +if you wire differently: + +| FX2 channel | SIM contact | Signal | +|-------------|-------------|--------| +| D0 | C7 | I/O | +| D2 | C1 | VCC (digital level only!) | +| D4 | C2 | RST | +| D5 | C3 | CLK | +| GND | C5 | GND | + +FX2 input threshold is TTL-ish (~1.4V): 1.8V-class cards may read unreliably; +3V/5V classes are fine. + +**Samplerate and 8-bit mode (important):** the FX2's nominal 24 MHz is only +available when sampling in 8-bit mode, i.e. when **only channels D0–D7 are +enabled**. Enabling the 9th channel (A0/analog on CWAV AX clones) or any +analog input forces 16-bit collection, which libsigrok caps at 12 MHz. +`start.sh`/`start.bat` therefore pass `-C D0,D1,D2,D3,D4,D5,D6,D7` +explicitly and default to **16 MHz** (comfortably under the 24 MHz USB +bandwidth ceiling; ~3.3 samples per 4.8 MHz clock cycle). `setup.sh`/ +`setup.bat` probe and report your hardware's actual maximum under the +same restriction. + +### Clock modes + +- `native` (default) — live captures. The decoder follows the PPS speed + switch and re-arms on RST, so warm resets and post-PPS traffic decode + correctly. +- `detect` — for offline experiments or captures without PPS. It does not + follow the PPS switch, so post-PPS traffic can be misread. +- `sample_as_clock` — experimental upstream mode; not recommended for SIM + captures. + +### Troubleshooting live capture + +**The capture stops early (especially on Windows).** A common cause is the +wrong USB driver. The Saleae Logic driver works only with Saleae Logic +software; sigrok needs the **WinUSB** driver. Install it with **Zadig** +(bundled with the sigrok-cli installer) and repeat the assignment after the +device re-enumerates with the firmware's VID/PID. See the sigrok documentation: + +- https://sigrok.org/wiki/Windows#Drivers +- https://sigrok.org/wiki/Fx2lafw + +**Device not found / no signal.** Check the WinUSB driver (Windows), the +fx2lafw firmware, the wiring and GND (see Wiring), and try another USB port or +a known-good cable. Cheap USB cables and hubs are common causes of stalls. + +**The capture ends by itself (`rc=0`).** The FX2 is at its USB bandwidth limit +at high samplerates. Lower `--samplerate`, avoid hubs, and close other USB +traffic. `start.sh` automatically restarts the capture on `rc=0` (default 20 +restarts, 2 s apart; `--no-loop`, `--max-restarts=N`, `--restart-delay=S`). +With `--pcap=FILE`, each restart writes `FILE..`. + +`start.sh` runs until Ctrl+C; keystrokes do not stop it (the "press any key" +prompt is disabled). Useful options: + +```bash +./start.sh --pcap=s.pcap --log=s.log # record events and the rc= verdict +./start.sh ... --samplerate=24M # more timing headroom if needed +./start.sh ... --klog # also record the kernel journal +./start.sh ... --debug # full decoder + sigrok output +``` + +- `--log` records the session-end `rc=` line. +- The decoder logs `SIGNAL INTEGRITY WARNING` when ≥ 8 of the last 64 frames + fail parity. +- Desynced packets are kept and flagged `GSMTAP_FLAG_BAD_FCS` in the GSMTAP + header `res` byte — visible in Wireshark as a BAD-FCS warning. + +### Raw sigrok-cli + +Equivalent commands without the wrapper scripts: + +```bash +# Minimal: CLK+I/O only, live stream to localhost:4729 +sigrok-cli -d fx2lafw --config samplerate=12M --continuous \ + -P iso7816:clk=D0:data=D1:clock_option=detect -A iso7816 + +# Full wiring: CLK + I/O + RST + VCC with line event tracking +sigrok-cli -d fx2lafw --config samplerate=12M --continuous \ + -P iso7816:clk=D5:data=D0:rst=D4:vcc=D2:clock_option=native:rst_detect=true:vcc_detect=true \ + -A iso7816 + +# Stream to a remote analyser / disable streaming / write PCAP file +... -P iso7816:...:gsmtap_host=10.0.28.7 ... +... -P iso7816:...:gsmtap_enable=false ... +... -P iso7816:...:pcap_file=trace.pcap ... + +# Classic upstream mode: binary PCAP to stdout +sigrok-cli -i capture.sr -P iso7816:clk=2:data=0 -B iso7816=pcap > out.pcap +``` + ## The tap in practice ![Components](resources/components.jpg) @@ -47,23 +303,23 @@ this decoder's `pcap_file=` option). ![Short cable pull resistors](resources/short_cable_pull_resistors.jpg) *Short cable with external pull resistors — 10 kΩ to GND on VCC (pulls low when off), 47 kΩ to VCC on DATA (faster rise to high)* -## What was added on top of upstream +## Features | Feature | Description | |---------|-------------| | Live GSMTAP stream | Every decoded event is sent as a GSMTAP-SIM UDP packet (default on, mimics simtrace2-sniff) | -| Correct sub_types | ATR=0x01 and PPS=0x02 now tagged properly in PCAP output (upstream hardcoded everything to APDU=0x00) | +| Correct sub_types | ATR=0x01 and PPS=0x02 are tagged properly in PCAP output | | ATR/PPS in PCAP | ATR and combined PPS request+response are emitted as PCAP packets | | RST tracking (optional) | `rst_detect=true`: emits reset assert/deassert events (sub_type 0x10) | | VCC tracking (optional) | `vcc_detect=true`: emits power on/off events (sub_type 0x11) | | Direct PCAP file | `pcap_file=` writes PCAP without shell redirection | -| Start-bit deglitch | Deglitch in the start-bit detector (2 samples at 16 MHz, scaled from the sample rate since v1.9.7) eliminates sub-ETU LOW glitches from FX2LP pull-up artifacts, preventing byte misalignment on fast phone traces | -| Mid-session ETU lock | The DATA-edge ETU estimator rejects guard-only (all-zero) and single-spacing bursts and invalidates a rate that fails parity, so a capture at a non-default F/D locks safely | -| ATR / resync guards | A DATA-state `0x3B`/`0x3F` is an ATR candidate only before the first APDU; parity-dirty or bare (TS+T0) frames are ignored, and `resync_idle` really waits for the idle level | -| Inverse convention | TS=0x3F ATRs follow ISO 7816-3 7.1: inverted data, msb first, start bit still LOW from an idle-HIGH line | -| T=1 blocks | NAD/PCB/LEN/INF/LRC decode with M-bit chaining; the I-block INF is emitted as the APDU, R/S blocks are not; a truncated capture ends cleanly | -| Parity flag | A packet containing a parity-error byte is emitted with the GSMTAP BAD_FCS flag (not just an annotation) | -| Rate-aware thresholds | Start-bit deglitch, guard floors and the ETU glitch floor scale from the capture sample rate instead of assuming 16 MHz | +| Start-bit deglitch | Suppresses sub-ETU LOW glitches (2 samples at 16 MHz, scaled to the samplerate) | +| Mid-session ETU lock | Recovers the ETU from DATA for captures without a usable CLK; a rate that fails parity is re-measured | +| ATR / resync guards | Validates the ATR, ignores mis-framed ATR candidates, and re-aligns after a desync | +| Inverse convention | Supports direct (TS=0x3B) and inverse (TS=0x3F) cards | +| T=1 blocks | Decodes NAD/PCB/LEN/INF/LRC with M-bit chaining; the I-block INF is emitted as the APDU | +| Parity flag | Packets containing a parity-error byte are flagged `GSMTAP_FLAG_BAD_FCS` | +| Rate-aware thresholds | Deglitch, guard and ETU floors scale with the capture samplerate | ## Decoder options @@ -117,344 +373,6 @@ This carriage is this decoder's own extension (upstream simtrace2-sniff never sets `res`); the flag semantics mirror simtrace2's per-message USB data flags and are not part of the libosmocore spec. -## Usage - -Quick start (after installing — release download or source checkout; see -Installation below): - -```bash -./setup.sh # check sigrok-cli, register decoder symlink -./start.sh # capture + GSMTAP stream to 127.0.0.1:4729 -``` - -On Windows the same two steps are `setup.bat` then `start.bat` (see -Installation below). - -`start.sh` defaults: pins D5=CLK, D0=I/O, D4=RST, D2=VCC, 16 MHz samplerate. -Override via args: - -```bash -./start.sh --clk=D1 --data=D6 # different wiring -./start.sh --no-rst --no-vcc # CLK+I/O only -./start.sh --host=10.0.28.7 # stream to a remote analyser -./start.sh --pcap=session.pcap # also record decoded events to PCAP -./start.sh --debug # full decoder + sigrok output (all - # annotation rows + libsigrok -l 4); - # by default only decoded APDUs and - # decoder warnings/errors are shown -``` - -### Wiring - -The recommended tap is the short cable with external pull resistors (see -the photos above): 10 kΩ to GND on VCC (pulls low when off) and 47 kΩ to -VCC on DATA (faster rise to high). Its pin mapping is **fixed and known -in advance** — see the "Pin mapping" table below — and is exactly what -`start.sh` defaults to (`D5`=CLK, `D0`=I/O, `D4`=RST, `D2`=VCC). No -wiring auto-detection is needed; the pins never move. - -> **GND first.** Plug GND first and verify it manually (continuity meter -> or known-good contact) — a missing or loose ground masquerades as every -> other fault at once: floating lines, phantom start bits, all-zero frames. - -### Robustness against noisy signals - -Live captures can glitch (a phantom start bit during power-up used to -shift the whole ATR parse off-by-one). The decoder now: - -- validates the ATR's TS byte (`0x3B`/`0x3F` per TS 102 221 §5.2.2) and - resyncs on the next real falling edge if it is bogus; -- never lets a decode exception kill the capture — errors are logged, - annotated, and the state machine resyncs (end-of-stream still exits - cleanly); -- decodes T=1 blocks (NAD/PCB/LEN/INF/LRC) and bounds the M-bit chain so garbage - cannot loop forever. - -After an accepted PPS the decoder **follows the speed switch**: in -native CLK mode `clock_skip` becomes F/D CLK cycles per bit (e.g. -512/16 = 32), matching both sides' new UART rate. Live capture -confirmed that keeping 372 after PPS aliases all subsequent traffic. - -A **warm reset** (the reader re-asserts RST every ~1.6 s) makes the card -answer with a fresh ATR at the default 372 cycles/bit. The decoder -**re-arms the ATR hunt on RST deassert**: state back to `FIND START`, -native skip reset to 372, hunt count cleared — so the re-ATR parses as -an ATR instead of being mis-read as TPDU traffic at the PPS-negotiated -rate. A **half-ETU start-bit guard** (edge reader) additionally rejects the phantom -`0x00` an idle glitch can insert before that ATR. Requires -`rst_detect=true` (the `rst` channel assigned); without it a mid-session -reset is still mis-read. - -### Troubleshooting live capture - -`start.sh` runs a single `--continuous` capture until you press **Ctrl+C** -(`rc=130`). stdin is detached from sigrok-cli, so pressing keys/Enter in -the terminal does **not** stop it (sigrok's "press any key to stop -acquisition" prompt is disabled) — that keypress was previously -mis-read as a "premature abort", but there was never a device fault. - -Most of the early "noise" seen in captures (parity errors, mis-framed -garbage, a bouncing VCC line) was a badly-decoded state machine, not the -hardware: re-seating the tap did nothing, while the decoder rewrite fixed -it completely (warm-reset re-arm, half-ETU start-bit guard, 10 ms VCC -debounce, T=0 exchange reassembly). A clean capture now decodes to zero -garbage — see the `vs_reader.py` validation below. - -If a capture *does* end on its own (`rc=0`), the device genuinely stopped -streaming; the FX2's USB bandwidth ceiling at sustained high sample rates -is the usual suspect. - -```bash -./start.sh --pcap=s.pcap --log=s.log # also record decoded events, log rc= -./start.sh ... --samplerate=24M # more timing headroom if needed -./start.sh ... --klog # also record kernel journal -./start.sh ... --debug # full output: all annotation rows - # + libsigrok internals at -l 4 - # (default: APDUs + warnings only) -``` - -`start.sh` captures a continuous stream at the configured rate (default 16 -MHz) until Ctrl+C (`rc=130`). A healthy capture never ends by itself; if the -FX2 drops the USB transfer mid-session (a flaky device, `rc=0` "device -stopped streaming"), the capture auto-restarts so the session is not lost — -it re-launches on every `rc=0` until you press Ctrl+C or hit -`--max-restarts=N` (default 20; `0` = unlimited), with a `--restart-delay=S` -gap (default 2 s). When restarting with `--pcap=FILE`, each session's capture -is written to `FILE..` so a restart never overwrites the previous one, -and the repetitive `sr_session_stop: session was NULL` teardown line is -filtered from stderr. - -- `--no-loop` disables auto-restart (single capture only). -- `--loop` forces auto-restart on (this is the default). -- `--max-restarts=N` caps restarts (default 20; `0` = unlimited). -- `--restart-delay=S` seconds to wait between restarts (default 2). -- `--log` captures the `rc=` verdict line for the session end. -- The decoder logs `SIGNAL INTEGRITY WARNING` when >= 8 of the last - 64 frames fail parity. -- Desynced TPDUs (mis-framed exchanges) are kept but flagged with - `GSMTAP_FLAG_BAD_FCS` in the GSMTAP header `res` byte — visible in - Wireshark as a BAD-FCS warning. -- A T=0 header with a structurally invalid INS (ISO 7816-4 §5.1.2: - `0x00` or `0x6x`/`0x9x`) is almost always a one-byte shift from - a stray leading byte (e.g. a leftover SW2 read after a PACKETEND). - Instead of silently dropping the whole 5-byte window (which let the next - byte become a bogus CLA and swallow the remaining dialog into one CONCAT - packet), the decoder drops only the leading byte and re-frames the rest, - recovering the real command. Every consumed-but-unemitted byte is - explicitly logged (`discarded byte 0x…: reason`); idle 0x00/0xFF discards - are rate-limited, non-idle discards always produce a decoder annotation. -- A card may finish a command with SW1 SW2 at the first procedure byte - (ISO 7816-3 §10.3.3), including a case-2 command with P3 > 0: the SW is - framed as the status word, not read as command data. A response - **shorter than Le** is split at the status word and the packet is - flagged `BAD_FCS` (the following exchanges stay intact), and `P3=0` - (Le=256) response data is kept. - -Performance: in native CLK mode the decoder calibrates samples per CLK -edge once from the ATR's first frame, then advances bit timing with -single sample-skip waits instead of one wait per CLK edge. The PPS speed -switch is followed via `clock_skip = F/D`; there is no post-PPS or -parity-triggered recalibration. - -### Mode comparison on FX2 hardware (A/B result) - -- `native` decoded real traffic (ATR, PPS switch, 100+ valid APDUs in a - 12 s window); the one persistent artifact was the VCC sense line - "bouncing" — the ~1 kHz ringing the 10 ms debounce now suppresses. -- `detect` never produced a usable session on this rig: it missed the - PPS speed switch entirely (no PPS handling fired), aliasing all - post-PPS traffic; a second attempt caught a dead I/O line. - -`native` stays the default. Use `--clock=detect` only for offline -experiments without PPS. A run full of all-zero frames means the tap -lost contact with a line. - -Parity is **even** per TS 102 221 ("an even number of bits set to '1' -including the parity bit"); frames failing the check are flagged as -`CHKSUM ERROR` but still decoded. - -Equivalent raw sigrok-cli commands: - -```bash -# Minimal: CLK+I/O only, live stream to localhost:4729 -sigrok-cli -d fx2lafw --config samplerate=12M --continuous \ - -P iso7816:clk=D0:data=D1:clock_option=detect -A iso7816 - -# Full wiring: CLK + I/O + RST + VCC with line event tracking -sigrok-cli -d fx2lafw --config samplerate=12M --continuous \ - -P iso7816:clk=D5:data=D0:rst=D4:vcc=D2:clock_option=native:rst_detect=true:vcc_detect=true \ - -A iso7816 - -# Stream to a remote analyser / disable streaming / write PCAP file -... -P iso7816:...:gsmtap_host=10.0.28.7 ... -... -P iso7816:...:gsmtap_enable=false ... -... -P iso7816:...:pcap_file=trace.pcap ... - -# Classic upstream mode: binary PCAP to stdout -sigrok-cli -i capture.sr -P iso7816:clk=2:data=0 -B iso7816=pcap > out.pcap -``` - -### Pin mapping - -The FX2 clone channels are assigned via `-P iso7816:clk=N:data=N:rst=N:vcc=N`. -The recommended short-cable tap (external pull resistors) uses fixed pins that -are exactly `start.sh`'s defaults; `--clk`/`--data`/`--rst`/`--vcc` remap them -if you wire differently: - -| FX2 channel | SIM contact | Signal | -|-------------|-------------|--------| -| D0 | C7 | I/O | -| D2 | C1 | VCC (digital level only!) | -| D4 | C2 | RST | -| D5 | C3 | CLK | -| GND | C5 | GND | - -FX2 input threshold is TTL-ish (~1.4V): 1.8V-class cards may read unreliably; -3V/5V classes are fine. - -**Samplerate and 8-bit mode (important):** the FX2's nominal 24 MHz is only -available when sampling in 8-bit mode, i.e. when **only channels D0–D7 are -enabled**. Enabling the 9th channel (A0/analog on CWAV AX clones) or any -analog input forces 16-bit collection, which libsigrok caps at 12 MHz. -`start.sh`/`start.bat` therefore pass `-C D0,D1,D2,D3,D4,D5,D6,D7` -explicitly and default to **16 MHz** (comfortably under the 24 MHz USB -bandwidth ceiling; ~3.3 samples per 4.8 MHz clock cycle). `setup.sh`/ -`setup.bat` probe and report your hardware's actual maximum under the -same restriction. - -## Installation - -Both ways install the same decoder — pick one: - -- **Download (recommended)** — a release archive. Nothing to clone and no git - history: extract it, run `setup`, run `start`. Best if you only want to - capture. -- **Source checkout** — a `git clone`. The same runtime plus the development - material: `tests/` and the trace/baseline tools (`tools/capture_baseline.sh`, - `tools/compare_baseline.sh`, `tools/vs_reader.py`). The example traces - (`examples/`) are gitignored and stay local in either case. The release - archives intentionally do not contain `tests/`, the dev tools or - `examples/`. - -### Download (recommended) - -Grab the latest archive from -[Releases](https://github.com/anttro/sigrok_iso7816_stream/releases/latest): - -- `sigrok_iso7816_stream-.tar.gz` — Linux -- `sigrok_iso7816_stream-.zip` — Windows - -Each release also publishes `SHA256SUMS`, which lists **both** archives; keep -it next to the file you downloaded and verify: - -```bash -sha256sum -c --ignore-missing SHA256SUMS # GNU coreutils (Linux) -``` - -On Windows run `certutil -hashfile sigrok_iso7816_stream-.zip SHA256` -and compare the output with the `.zip` line in `SHA256SUMS`. - -#### Linux (download) - -```bash -tar xzf sigrok_iso7816_stream-.tar.gz -cd sigrok_iso7816_stream- -./setup.sh -./start.sh -``` - -`setup.sh` verifies sigrok-cli and the FX2 firmware package -(`sigrok-firmware-fx2lafw`) are installed, symlinks the project directory into -`~/.local/share/libsigrokdecode/decoders/iso7816` (user-local decoders shadow -system-wide ones), and probes the connected device for its maximum supported -samplerate. - -#### Windows (download) - -Prerequisites: - -1. **sigrok-cli** Windows installer (0.7.2 x86_64) from - [sigrok.org/wiki/Downloads](https://sigrok.org/wiki/Downloads) — the tested - release. Nightly Windows installers are also published on that page; they - may change the sigrok-cli syntax or the decoder API, so the 0.7.2 - release installer remains the supported version. - If sigrok-cli fails to start with error `0xc0150002`, install the - [Visual C++ 2010 Redistributable](https://www.microsoft.com/en-us/download/details.aspx?id=26999) - (`msvcr100.dll` is required by the bundled Python runtime). -2. fx2lafw firmware ships bundled with the installer — no separate download. - -Driver setup (FX2 dongles need WinUSB, the vendor driver won't work): - -- Run **Zadig**, which ships *inside* the sigrok-cli installation directory - (also reachable from the Start menu). Select the FX2 device in its dropdown - and install the **WinUSB** driver. -- After firmware upload the device re-enumerates with a different VID/PID — - if it still isn't found, run Zadig a **second time** for the re-enumerated - entry. -- Windows binds drivers per USB port when no serial number is present: - moving the dongle to another port may require repeating Zadig. - -Then extract the release `.zip` (right-click → Extract All in Explorer) and -run, inside the extracted folder: - -```bat -setup.bat -start.bat -``` - -`setup.bat` verifies sigrok-cli and bundled firmware, registers this project's -decoder via a junction into `%LOCALAPPDATA%\libsigrokdecode\decoders\iso7816` -(confirmed by `sigrok-cli -L` listing `iso7816`), and probes the device's -accepted samplerates. The release zip ships the batch files with CRLF line -endings, so no conversion is needed. `start.bat --help` lists its options -(the core subset of `start.sh`: channels, samplerate, clock, host/port, pcap, -protocol, debug). - -### Linux (source checkout) - -```bash -git clone git@github.com:anttro/sigrok_iso7816_stream.git -cd sigrok_iso7816_stream -./setup.sh -``` - -A fresh clone needs the same `./setup.sh` checks and symlink as above: it -verifies sigrok-cli and the FX2 firmware package, symlinks the project -directory into `~/.local/share/libsigrokdecode/decoders/iso7816` and probes -the device's maximum samplerate. - -### Windows (source checkout) - -The Windows prerequisites (sigrok-cli + the Visual C++ 2010 Redistributable, -the bundled fx2lafw firmware, and the Zadig/WinUSB driver setup) are the same -as in [Windows (download)](#windows-download) above. - -```bat -git clone git@github.com:anttro/sigrok_iso7816_stream.git -cd sigrok_iso7816_stream -setup.bat -``` - -`setup.bat` performs the same checks and junction registration as above. -`start.bat` supports the core option subset (channels, samplerate, clock, -host/port, pcap, protocol, debug; `start.sh` has the full set) — the space -form is the primary one, and `--clk=CH` also works: - -```bat -start.bat --clk D1 --data D6 -start.bat --help -``` - -Capture works the same as on Linux: - -```bat -start.bat rem capture + GSMTAP stream -``` - -Note: batch files need CRLF line endings; the repo enforces this via -`.gitattributes`, so a fresh clone on Windows is already correct (the release -zip ships the same CRLF files). - ## RST/VCC detection notes and limitations - Events are detected **asynchronously before the first ATR** (power-on / @@ -465,13 +383,9 @@ zip ships the same CRLF files). - VCC is digital-only: the decoder sees powered/not-powered, never the voltage class (1.8/3/5V). - **RST and VCC use level-stability hysteresis at 10 ms** (samplerate-scaled): - a new level is reported only once it has been continuously stable for ≥ 10 ms - — either because it persists that long, or because it ends after being stable - that long. This makes power-up and power-down *symmetric*: a VCC sense line - that **rings on the rising edge** (noisy/floating tap) no longer loses its - "VCC on" event — it fires once the line settles HIGH, instead of being eaten - by edge debounce. RST uses the same scheme, so a brief RST glitch no longer - triggers a phantom warm-reset re-arm. + a new level is reported only once it has been continuously stable for ≥ 10 ms. + This makes power-up and power-down symmetric and suppresses ringing and + short glitches. - **VCC events are generally unreliable — prefer not to track VCC.** A floating or unconnected VCC sense pin reads HIGH at all times (logic-high with no load), so the decoder sees "powered" constantly and emits spurious power events on @@ -482,23 +396,14 @@ zip ships the same CRLF files). - Unassigned optional channels are ignored even if `rst_detect`/`vcc_detect` is enabled (guarded via `has_channel()`). -## Testing +## Development and testing -Verified against the upstream example captures: - -```bash -# ATR+PPS+54 APDUs from the test_8 reader capture (~19s decode) -# GSMTAP stream verified with tshark (ATR/APDU dissected natively), -# custom 0x10/0x11 events verified with a UDP listener, and end-to-end -# into the SIMtrace Analyser server (POST /api/capture/start → decode → stop). -``` - -A synthetic VCD generator covering RST/VCC edge cases lives in the project -notes (`projects/SIGROK_ISO7816.md` in the parent workspace). +The decoder is validated against example captures with `tools/vs_reader.py`. +Trace fixtures are kept locally and are not part of the repository. ### Validation against the reader SDK (`tools/vs_reader.py`) -On a controlled rig (PCSC reader driven by software) the reference APDU log +On a controlled rig (PC/SC reader driven by software) the reference APDU log from the reader SDK can be diffed against the decoded PCAP: ```bash @@ -511,32 +416,12 @@ python3 tools/vs_reader.py .log out.pcap `vs_reader.py` aligns each reader-log exchange to the capture APDUs (byte-exact LCS match) and classifies the leftovers as proactive/CAT (unseen by the reader SDK), pre-capture/dropped, or garbage. -The mid-session capture whose warm resets previously produced 4 garbage -events — with the re-arm + start-bit guard it decodes to **0 garbage** -(`RESULT: OK - capture fully explained`). - -test_7 (4 ATR resets fragmenting the session) now captures all 37/37 reader -exchanges (up from 10/37 before the deglitch fix). Samsung phone traces with -16 CLK/ETU (F=512/D=32) now de-concatenate to 924 individual T=0 exchanges -(previously merged into 52 oversized APDUs). - -Replayable trace fixtures (kept locally, outside the repo) cover -controlled-rig reader sessions (with their reader-SDK ground-truth logs), -phone captures with gated CLK, and **cold-boot captures** that start -*before* power-up (VCC/RST low at t=0). The four Samsung fixtures are -cold boots taken with a new short cable (30 mm wires, external pull -resistors GND→VCC and VCC→DATA), named channels `DATA/VCC/RST/CLK` on bits -0/2/4/5; the `sim2` variants are cropped to the power-on window. ### Cold-boot captures (capture starts before power-up) -When the capture starts pre-power-up, the decoder must arm the ATR -hunt because RST is still low at sample 0: it primes the initial -VCC/RST levels on the first step (instead of defaulting them to deasserted), -and on an RST-low-at-start it enters `FIND START` with a cleared ETU, so the -pre-ATR power-up DATA transitions cannot lock a bogus bit rate. It then -decodes the full ATR (`3b9f96801fc78031e073fe2117574a3382033339001e`) with -0 garbage: +When the capture starts before power-up, RST is still low at sample 0. Use +`rst_detect=true` and `protocol=T=0`; the decoder arms the ATR hunt on the +initial RST level and decodes the full ATR. Example: ```bash sigrok-cli -i .sr \ @@ -544,48 +429,16 @@ sigrok-cli -i .sr \ -A iso7816 ``` -An RST deassert that lands while an ATR parse is already in progress no longer -re-arms the hunt mid-read — it logs `RST deasserted (hunt/ATR already in -progress)` and leaves the in-flight ATR alone (test_8/test_7 CHKSUM 18→0). - ### Capture scenarios: reader (constant CLK) and phone (Clock Stop Mode) -The decoder handles the two physically different SIM sniffing setups: - - **Reader / constant-CLK capture** — the reader drives a steady CLK for the - whole session. In mid-session mode the capture - decodes to **0 garbage** (`RESULT: OK`) against the reader-SDK - ground truth (`tools/vs_reader.py .log out.pcap`). - Warm-reset reader captures use the synthetic-T=0-ATR fallback. - -- **Phone / stopped-CLK capture** — the phone gates or stops CLK between - transfers (Clock Stop Mode), so the ETU is not the 372-clock default and - cannot be inferred from CLK. Run with `protocol=T=0`; the decoder recovers the ETU from the DATA line via edge - counting, locks it, and decodes with the drift-immune edge-list bit reader. - T=0 case 3/4 commands (e.g. `80 12`/`80 14` STK envelope) are consolidated - into a single command→response APDU. A 2-sample start-bit deglitch eliminates - sub-ETU LOW glitches caused by FX2LP internal pull-up artifacts, preventing - byte misalignment on fast phone traces. - -### Proven data rates and ETUs - -All traces decoded at **16 MHz sample rate**, 0 garbage, RESULT: OK. -Since v1.5.0 every example trace also reports **0 CONCAT** (the invalid-INS -re-frame eliminated the last multi-exchange swallow family on -4gmodem/A55_sim2/S21p_sim2). - -| Trace | CLK mode | ETU (samples) | CLK/ETU | Convention | Notes | -|-------|----------|---------------|---------|------------|-------| -| test_8 | constant | ~43 | 372 (standard) | Direct | PC/SC reader, ATR+PPS+APDUs | -| test_7 | constant | ~43 | 372 (standard) | Direct | PC/SC reader, warm resets | -| xiaomi | gated/stopped | ~53 | recovered from DATA | Direct | Phone, mid-session | -| samsung | gated/stopped | ~72 | 16 (F=512/D=32) | Direct | Phone, non-standard F/D, STK menu | -| alcor_reader | constant | ~53 | 16 (F=512/D=32) | Direct | PC/SC reader, CLK 4.0 MHz at ATR -> 4.8 MHz after PPS | - -The decoder auto-detects the ETU from the trace and selects the appropriate -bit reader (CLK-sync for constant CLK, edge-list for gated/stopped CLK). -No manual configuration is needed beyond `clock_option=native` and -`protocol=T=0` for phone captures. + whole session. Validate it against the reader SDK with + `tools/vs_reader.py .log out.pcap`. +- **Phone / gated or stopped-CLK capture** — the phone gates or stops CLK + between transfers (Clock Stop Mode), so the ETU cannot be derived from CLK. + Run with `protocol=T=0`; the decoder recovers the ETU from the DATA line and + decodes with the edge-list reader. T=0 case 3/4 commands (e.g. `80 12`/`80 14` + STK envelopes) are consolidated into one command→response APDU. Recommended invocations: @@ -602,6 +455,26 @@ sigrok-cli -i .sr \ -A iso7816 ``` +### Data rates and ETUs + +Reference values observed on the example captures at a 16 MHz samplerate: + +| Trace | CLK mode | ETU (samples) | CLK/ETU | Convention | Notes | +|-------|----------|---------------|---------|------------|-------| +| test_8 | constant | ~43 | 372 (standard) | Direct | PC/SC reader, ATR+PPS+APDUs | +| test_7 | constant | ~43 | 372 (standard) | Direct | PC/SC reader, warm resets | +| xiaomi | gated/stopped | ~53 | recovered from DATA | Direct | Phone, mid-session | +| samsung | gated/stopped | ~72 | 16 (F=512/D=32) | Direct | Phone, non-standard F/D, STK menu | +| alcor_reader | constant | ~53 | 16 (F=512/D=32) | Direct | PC/SC reader, CLK 4.0 MHz at ATR -> 4.8 MHz after PPS | + +The decoder auto-detects the ETU and selects the bit reader (CLK-sync for +constant CLK, edge-list for gated/stopped CLK). No manual configuration is +needed beyond `clock_option=native` and `protocol=T=0` for phone captures. + +Parity is **even** per TS 102 221 ("an even number of bits set to '1' +including the parity bit"); frames failing the check are flagged as +`CHKSUM ERROR` but still decoded. + ## License GPL-2.0+, same as upstream. diff --git a/README_RUS.md b/README_RUS.md index 2dfd56a..b43c632 100644 --- a/README_RUS.md +++ b/README_RUS.md @@ -21,6 +21,272 @@ SIM-карта ⇄ ридер (пассивный съём с контактов GSMTAP pcap-файлы (включая PCAP, который этот декодер пишет через опцию `pcap_file=`). +## Установка и запуск + +Оба способа ставят один и тот же декодер — выберите один: + +- **Скачать (рекомендуется)** — архив релиза. Не нужно ничего клонировать и + нет истории git: распакуйте, запустите `setup`, затем `start`. Лучший + вариант, если нужен только съём. +- **Из исходников** — `git clone`. Тот же рантайм плюс материал для + разработки: `tests/` и инструменты трасс и базовой линии + (`tools/capture_baseline.sh`, `tools/compare_baseline.sh`, + `tools/vs_reader.py`). Трассы примеров (`examples/`) исключены из git и + остаются локальными. В архивах релиза нет `tests/`, dev-инструментов и + `examples/`. + +### Скачать (рекомендуется) + +Скачайте последний архив со страницы +[Releases](https://github.com/anttro/sigrok_iso7816_stream/releases/latest): + +- `sigrok_iso7816_stream-.tar.gz` — Linux +- `sigrok_iso7816_stream-.zip` — Windows + +К каждому релизу прилагается `SHA256SUMS` — в нём **оба** архива. +Положите файл рядом со скачанным архивом и проверьте: + +```bash +sha256sum -c --ignore-missing SHA256SUMS # GNU coreutils (Linux) +``` + +В Windows выполните `certutil -hashfile sigrok_iso7816_stream-.zip SHA256` +и сравните вывод со строкой `.zip` в `SHA256SUMS`. + +#### Linux (скачать) + +```bash +tar xzf sigrok_iso7816_stream-.tar.gz +cd sigrok_iso7816_stream- +./setup.sh +./start.sh +``` + +`setup.sh` проверяет, что установлены sigrok-cli и пакет прошивки FX2 +(`sigrok-firmware-fx2lafw`), создаёт симлинк каталога проекта в +`~/.local/share/libsigrokdecode/decoders/iso7816` (пользовательские +декодеры перекрывают системные) и опрашивает подключённое устройство на +предмет максимальной поддерживаемой частоты дискретизации. + +#### Windows (скачать) + +Предварительные требования: + +1. **sigrok-cli** — установщик для Windows (0.7.2 x86_64) с + [sigrok.org/wiki/Downloads](https://sigrok.org/wiki/Downloads) — + протестированная версия. На этой же странице публикуются ночные сборки + для Windows; они могут менять синтаксис sigrok-cli или API декодеров, + поэтому поддерживаемой остаётся версия из релизного установщика 0.7.2. + Если sigrok-cli не запускается с ошибкой `0xc0150002`, установите + [Visual C++ 2010 Redistributable](https://www.microsoft.com/en-us/download/details.aspx?id=26999) + (`msvcr100.dll` требуется встроенному Python-рантайму). +2. Прошивка fx2lafw поставляется вместе с установщиком — отдельно скачивать не нужно. + +Настройка драйвера (донглам FX2 нужен WinUSB, вендорский драйвер не подойдёт): + +- Запустите **Zadig**, который лежит *внутри* каталога установки sigrok-cli + (также доступен из меню «Пуск»). Выберите устройство FX2 в выпадающем + списке и установите драйвер **WinUSB**. +- После загрузки прошивки устройство переподключается с другим VID/PID — + если оно всё ещё не находится, запустите Zadig **второй раз** для + переподключившегося устройства. +- Windows привязывает драйверы к USB-порту, когда нет серийного номера: + перенос донгла в другой порт может потребовать повторить Zadig. + +Затем распакуйте архив `.zip` (в Проводнике: правой кнопкой → «Извлечь все») +и запустите в распакованном каталоге: + +```bat +setup.bat +start.bat +``` + +`setup.bat` проверяет sigrok-cli и встроенную прошивку, регистрирует декодер +этого проекта через junction в +`%LOCALAPPDATA%\libsigrokdecode\decoders\iso7816` (подтверждается тем, что +`sigrok-cli -L` показывает `iso7816`), и опрашивает устройство на предмет +поддерживаемых частот дискретизации. В zip-архиве релиза bat-файлы уже с +переводами строк CRLF, поэтому преобразование не требуется. +`start.bat --help` перечисляет его опции (основное подмножество `start.sh`: +каналы, частота дискретизации, clock, host/port, pcap, protocol, debug). + +### Из исходников + +#### Linux (из исходников) + +```bash +git clone git@github.com:anttro/sigrok_iso7816_stream.git +cd sigrok_iso7816_stream +./setup.sh +./start.sh +``` + +`setup.sh` выполняет те же проверки и создаёт тот же симлинк, что и выше. + +#### Windows (из исходников) + +Предварительные требования Windows (sigrok-cli и Visual C++ 2010 +Redistributable, встроенная прошивка fx2lafw и настройка драйвера +Zadig/WinUSB) — те же, что в разделе +[Windows (скачать)](#windows-скачать) выше. + +```bat +git clone git@github.com:anttro/sigrok_iso7816_stream.git +cd sigrok_iso7816_stream +setup.bat +start.bat +``` + +`setup.bat` выполняет те же проверки и регистрацию junction, что и выше. +`start.bat` поддерживает основное подмножество опций; основной формат — с +пробелом, `--clk=CH` тоже работает (`start.bat --help` перечисляет опции): + +```bat +start.bat --clk D1 --data D6 +``` + +Примечание: bat-файлы требуют переводов строк CRLF; репозиторий следит за +этим через `.gitattributes`, поэтому свежий клон в Windows уже корректен +(zip-архив релиза содержит те же файлы с CRLF). + +## Использование + +`start.sh` пишет непрерывный поток на частоте 16 МГц до Ctrl+C (`rc=130`) и +стримит GSMTAP на 127.0.0.1:4729. Умолчания: выводы D5=CLK, D0=I/O, +D4=RST, D2=VCC. Переопределяются аргументами: + +```bash +./start.sh --clk=D1 --data=D6 # другое подключение +./start.sh --no-rst --no-vcc # только CLK+I/O +./start.sh --host=10.0.28.7 # стримить на удалённый анализатор +./start.sh --pcap=session.pcap # также записать декодированные события в PCAP +./start.sh --debug # полный вывод декодера и sigrok (все + # строки аннотаций + libsigrok -l 4); + # по умолчанию показываются только + # декодированные APDU и предупреждения/ошибки +``` + +В Windows `start.bat` принимает то же основное подмножество опций (форма с +пробелом; форма `--opt=value` тоже работает) — см. заметки по установке +Windows выше. + +### Подключение + +Рекомендуемый способ съёма — короткий кабель с внешними подтягивающими +резисторами (см. раздел «Съём на практике» ниже): 10 кОм к GND на VCC +(тянет вниз без питания) и 47 кОм к VCC на DATA (быстрее фронт вверх). +Его распиновка **фиксирована и известна заранее** — см. таблицу +«Распиновка» ниже — и в точности совпадает с умолчаниями `start.sh` +(`D5`=CLK, `D0`=I/O, `D4`=RST, `D2`=VCC). Автодетект подключения не нужен; +выводы не меняются. + +> **Сначала GND.** Сначала подключите GND и проверьте его вручную +> (мультиметром или заведомо исправным контактом) — отсутствующий или +> плохой контакт земли маскируется под все остальные неисправности сразу: +> плавающие линии, фантомные стартовые биты, кадры из одних нулей. + +### Распиновка + +Каналы клона FX2 назначаются через `-P iso7816:clk=N:data=N:rst=N:vcc=N`. +Рекомендуемый съём коротким кабелем (с внешними подтягивающими резисторами) +использует фиксированные выводы, которые в точности совпадают с умолчаниями +`start.sh`; `--clk`/`--data`/`--rst`/`--vcc` переназначают их, если вы +подключили иначе: + +| Канал FX2 | Контакт SIM | Сигнал | +|-------------|-------------|--------| +| D0 | C7 | I/O | +| D2 | C1 | VCC (только цифровой уровень!) | +| D4 | C2 | RST | +| D5 | C3 | CLK | +| GND | C5 | GND | + +Входной порог FX2 близок к TTL (~1.4 В): карты класса 1.8 В могут читаться +нестабильно; классы 3 В/5 В — нормально. + +**Частота дискретизации и 8-битный режим (важно):** номинальные 24 МГц FX2 +доступны только при дискретизации в 8-битном режиме, т.е. когда **включены +только каналы D0–D7**. Включение 9-го канала (A0/аналоговый на клонах CWAV +AX) или любого аналогового входа переводит сбор в 16-битный, который +libsigrok ограничивает 12 МГц. Поэтому `start.sh`/`start.bat` явно +передают `-C D0,D1,D2,D3,D4,D5,D6,D7` и по умолчанию используют **16 МГц** +(с комфортным запасом под потолком USB 24 МГц; ~3.3 отсчёта на такт CLK +4.8 МГц). `setup.sh`/`setup.bat` проверяют и сообщают фактический максимум +вашего железа при том же ограничении. + +### Режимы CLK + +- `native` (по умолчанию) — живые записи. Декодер отслеживает переключение + скорости по PPS и заново взводится по RST, поэтому тёплые сбросы и трафик + после PPS разбираются корректно. +- `detect` — для офлайн-экспериментов или записей без PPS. Он не отслеживает + переключение по PPS, поэтому трафик после PPS может читаться неверно. +- `sample_as_clock` — экспериментальный режим upstream; для съёма SIM не + рекомендуется. + +### Решение проблем при живой записи + +**Запись обрывается рано (особенно в Windows).** Частая причина — +неподходящий драйвер USB. Драйвер Saleae Logic работает только с Saleae +Logic software; sigrok нужен драйвер **WinUSB**. Установите его через +**Zadig** (входит в установщик sigrok-cli) и повторите назначение после +переподключения устройства с VID/PID прошивки. Подробности в документации +sigrok: + +- https://sigrok.org/wiki/Windows#Drivers +- https://sigrok.org/wiki/Fx2lafw + +**Устройство не найдено / нет сигнала.** Проверьте драйвер WinUSB (Windows), +прошивку fx2lafw, подключение и GND (см. «Подключение»), попробуйте другой +USB-порт и заведомо исправный кабель. Дешёвые USB-кабели и хабы — частая +причина остановок. + +**Запись завершается сама (`rc=0`).** FX2 упирается в потолок пропускной +способности USB на высокой частоте дискретизации. Снизьте `--samplerate`, +избегайте хабов, закройте другой USB-трафик. `start.sh` автоматически +перезапускает запись при `rc=0` (по умолчанию 20 перезапусков с паузой 2 с; +`--no-loop`, `--max-restarts=N`, `--restart-delay=S`). При `--pcap=FILE` +каждый перезапуск пишет `FILE..`. + +`start.sh` работает до Ctrl+C; нажатия клавиш его не останавливают +(приглашение «нажмите любую клавишу» отключено). Полезные опции: + +```bash +./start.sh --pcap=s.pcap --log=s.log # записать события и вердикт rc= +./start.sh ... --samplerate=24M # больше запаса по таймингу при необходимости +./start.sh ... --klog # также записать журнал ядра +./start.sh ... --debug # полный вывод декодера и sigrok +``` + +- `--log` сохраняет строку вердикта `rc=` в конце сессии. +- Декодер пишет `SIGNAL INTEGRITY WARNING`, когда ≥ 8 из последних 64 кадров + не проходят проверку чётности. +- Десинхронизированные пакеты сохраняются с флагом `GSMTAP_FLAG_BAD_FCS` в + байте `res` заголовка GSMTAP — видно в Wireshark как предупреждение BAD-FCS. + +### Сырые команды sigrok-cli + +Эквивалентные команды без скриптов-обёрток: + +```bash +# Минимум: только CLK+I/O, живой поток на localhost:4729 +sigrok-cli -d fx2lafw --config samplerate=12M --continuous \ + -P iso7816:clk=D0:data=D1:clock_option=detect -A iso7816 + +# Полное подключение: CLK + I/O + RST + VCC с отслеживанием событий линий +sigrok-cli -d fx2lafw --config samplerate=12M --continuous \ + -P iso7816:clk=D5:data=D0:rst=D4:vcc=D2:clock_option=native:rst_detect=true:vcc_detect=true \ + -A iso7816 + +# Поток на удалённый анализатор / отключить стриминг / писать PCAP-файл +... -P iso7816:...:gsmtap_host=10.0.28.7 ... +... -P iso7816:...:gsmtap_enable=false ... +... -P iso7816:...:pcap_file=trace.pcap ... + +# Классический режим upstream: бинарный PCAP в stdout +sigrok-cli -i capture.sr -P iso7816:clk=2:data=0 -B iso7816=pcap > out.pcap +``` + ## Съём на практике ![Компоненты](resources/components.jpg) @@ -50,23 +316,23 @@ GSMTAP pcap-файлы (включая PCAP, который этот декод ![Подтягивающие резисторы](resources/short_cable_pull_resistors.jpg) *Короткий кабель с внешними подтягивающими резисторами — 10 кОм к GND на VCC (тянет вниз, когда питания нет), 47 кОм к VCC на DATA (быстрее фронт вверх)* -## Что добавлено поверх upstream +## Возможности | Возможность | Описание | |---------|-------------| | Живой поток GSMTAP | Каждое декодированное событие отправляется как GSMTAP-SIM UDP-пакет (включено по умолчанию, повторяет поведение simtrace2-sniff) | -| Правильные sub_types | ATR=0x01 и PPS=0x02 теперь корректно помечаются в PCAP (в upstream всё писалось как APDU=0x00) | +| Правильные sub_types | ATR=0x01 и PPS=0x02 корректно помечаются в PCAP | | ATR/PPS в PCAP | ATR и объединённые запрос+ответ PPS выводятся как PCAP-пакеты | | Отслеживание RST (опционально) | `rst_detect=true`: события assert/deassert сброса (sub_type 0x10) | | Отслеживание VCC (опционально) | `vcc_detect=true`: события включения/выключения питания (sub_type 0x11) | | PCAP сразу в файл | `pcap_file=` пишет PCAP без перенаправления вывода оболочки | -| Деглитч стартового бита | Деглитч в детекторе стартового бита (2 отсчёта при 16 МГц, с v1.9.7 масштабируется от частоты дискретизации) убирает LOW-глитчи короче ETU от артефактов подтяжки FX2LP и предотвращает смещение байтов на быстрых телефонных трассах | -| Захват ETU в середине сессии | Оценщик ETU по фронтам DATA отбрасывает пачки только со сторожевым интервалом (нулевые данные) и одиночные интервалы, а также сбрасывает скорость, не прошедшую проверку чётности, поэтому трасса с нестандартным F/D захватывается надёжно | -| Защита ATR / ресинхронизации | `0x3B`/`0x3F` в состоянии DATA считается кандидатом в ATR только до первого APDU; кадры с ошибкой чётности или голый TS+T0 игнорируются, а `resync_idle` действительно ждёт уровень простоя | -| Инверсная конвенция | ATR с TS=0x3F разбирается по ISO 7816-3 7.1: инверсные данные, msb первым, стартовый бит по-прежнему LOW при простое линии HIGH | -| Блоки T=1 | Разбор NAD/PCB/LEN/INF/LRC с цепочкой по биту M; INF I-блока выдаётся как APDU, R/S-блоки не выдаются; обрезанная запись завершается чисто | -| Флаг чётности | Пакет с байтом с ошибкой чётности выдаётся с флагом GSMTAP BAD_FCS (не только аннотацией) | -| Пороги от частоты | Деглитч стартового бита, пороги защиты и порог глитча ETU масштабируются от частоты дискретизации, а не считаются от 16 МГц | +| Деглитч стартового бита | Подавляет LOW-глитчи короче ETU (2 отсчёта при 16 МГц, масштабируется от частоты дискретизации) | +| Захват ETU в середине сессии | Восстанавливает ETU по линии DATA, когда CLK непригоден; скорость, не прошедшая проверку чётности, измеряется заново | +| Защита ATR / ресинхронизации | Проверяет ATR, игнорирует неверно кадрированные кандидаты и выравнивается после десинхронизации | +| Инверсная конвенция | Поддерживает прямую (TS=0x3B) и инверсную (TS=0x3F) карты | +| Блоки T=1 | Разбирает NAD/PCB/LEN/INF/LRC с цепочкой по биту M; INF I-блока выдаётся как APDU | +| Флаг чётности | Пакеты с ошибкой чётности помечаются `GSMTAP_FLAG_BAD_FCS` | +| Пороги от частоты | Пороги деглитча, защиты и ETU масштабируются от частоты дискретизации | ## Опции декодера @@ -121,354 +387,6 @@ uint32 в герцах (полезная нагрузка 7 байт). Пока никогда не заполняет `res`); семантика флагов повторяет флаги данных (data flags) USB-протокола simtrace2 и не является частью спецификации libosmocore. -## Использование - -Быстрый старт (после установки — скачанный архив или клон репозитория; -см. «Установка» ниже): - -```bash -./setup.sh # проверить sigrok-cli, зарегистрировать симлинк декодера -./start.sh # запись + поток GSMTAP на 127.0.0.1:4729 -``` - -В Windows те же два шага — `setup.bat`, затем `start.bat` (см. «Установка» -ниже). - -Умолчания `start.sh`: выводы D5=CLK, D0=I/O, D4=RST, D2=VCC, частота -дискретизации 16 МГц. Переопределяются аргументами: - -```bash -./start.sh --clk=D1 --data=D6 # другое подключение -./start.sh --no-rst --no-vcc # только CLK+I/O -./start.sh --host=10.0.28.7 # стримить на удалённый анализатор -./start.sh --pcap=session.pcap # также записать декодированные события в PCAP -./start.sh --debug # полный вывод декодера и sigrok (все - # строки аннотаций + libsigrok -l 4); - # по умолчанию показываются только - # декодированные APDU и предупреждения/ошибки -``` - -### Подключение - -Рекомендуемый способ съёма — короткий кабель с внешними подтягивающими -резисторами (см. фото выше): 10 кОм к GND на VCC (тянет вниз без питания) -и 47 кОм к VCC на DATA (быстрее фронт вверх). Его распиновка **фиксирована -и известна заранее** — см. таблицу «Распиновка» ниже — и в точности -совпадает с умолчаниями `start.sh` (`D5`=CLK, `D0`=I/O, `D4`=RST, -`D2`=VCC). Автодетект подключения не нужен; выводы не меняются. - -> **Сначала GND.** Сначала подключите GND и проверьте его вручную -> (мультиметром или заведомо исправным контактом) — отсутствующий или -> плохой контакт земли маскируется под все остальные неисправности сразу: -> плавающие линии, фантомные стартовые биты, кадры из одних нулей. - -### Устойчивость к шумным сигналам - -Живые записи могут глитчить (фантомный стартовый бит при включении питания -раньше сдвигал весь разбор ATR на единицу). Теперь декодер: - -- проверяет байт TS в ATR (`0x3B`/`0x3F` по TS 102 221 §5.2.2) и - ресинхронизируется на следующем настоящем спаде, если он неверен; -- никогда не даёт исключению при декодировании убить запись — ошибки - логируются, аннотируются, а конечный автомат ресинхронизируется - (конец потока по-прежнему завершается чисто); -- разбирает блоки T=1 (NAD/PCB/LEN/INF/LRC) и ограничивает цепочку по биту M, - чтобы мусор не мог зациклиться навсегда. - -После принятого PPS декодер **следует переключению скорости**: в режиме -native CLK `clock_skip` становится равным F/D тактов CLK на бит (например, -512/16 = 32), что соответствует новой скорости UART у обеих сторон. Живая -запись подтвердила, что сохранение 372 после PPS алиасит весь последующий -трафик. - -**Тёплый сброс** (ридер заново подаёт RST примерно каждые ~1.6 с) заставляет -карту ответить свежим ATR на стандартных 372 тактах/бит. Декодер -**заново взводит охоту за ATR по deassert RST**: состояние возвращается в -`FIND START`, native-пропуск сбрасывается в 372, счётчик охоты очищается — -поэтому повторный ATR разбирается как ATR, а не ошибочно читается как -TPDU-трафик на скорости, согласованной PPS. **Защита стартового бита в -0.5 ETU** (edge-ридер) дополнительно отбрасывает фантомный `0x00`, который глитч на -холостом ходу может вставить перед этим ATR. Требуется `rst_detect=true` -(назначенный канал `rst`); без него сброс в середине сессии всё равно -будет прочитан неверно. - -### Решение проблем при живой записи - -`start.sh` запускает одну `--continuous` запись, пока вы не нажмёте -**Ctrl+C** (`rc=130`). stdin отвязан от sigrok-cli, поэтому нажатия -клавиш/Enter в терминале **не** останавливают запись (приглашение sigrok -«нажмите любую клавишу для остановки» отключено) — раньше это нажатие -ошибочно трактовалось как «преждевременный обрыв», хотя никакой -неисправности устройства не было. - -Большая часть раннего «шума» в записях (ошибки чётности, мусор из-за -неверного кадрирования, дребезг линии VCC) была следствием плохо -декодированного конечного автомата, а не железа: переподключение съёма -ничего не давало, а переписанный декодер полностью это вылечил (re-arm по -тёплому сбросу, защита стартового бита 0.5 ETU, антидребезг VCC 10 мс, -сборка обмена T=0). Чистая запись теперь декодируется с нулём мусора — -см. проверку `vs_reader.py` ниже. - -Если запись *всё-таки* завершается сама (`rc=0`), устройство действительно -перестало стримить; обычный подозреваемый — потолок пропускной способности -USB у FX2 при длительной высокой частоте дискретизации. - -```bash -./start.sh --pcap=s.pcap --log=s.log # также записать события и лог rc= -./start.sh ... --samplerate=24M # больше запаса по таймингу при необходимости -./start.sh ... --klog # также записать журнал ядра -./start.sh ... --debug # полный вывод: все строки аннотаций - # + внутренности libsigrok на -l 4 - # (по умолчанию: только APDU + предупреждения) -``` - -`start.sh` пишет непрерывный поток на настроенной частоте (по умолчанию -16 МГц) до Ctrl+C (`rc=130`). Здоровая запись никогда не завершается -сама; если FX2 роняет USB-передачу в середине сессии (нестабильное -устройство, `rc=0` «device stopped streaming»), запись автоматически -перезапускается, чтобы не потерять сессию — она перезапускается при каждом -`rc=0`, пока вы не нажмёте Ctrl+C или не сработает `--max-restarts=N` -(по умолчанию 20; `0` = без ограничения), с паузой `--restart-delay=S` -(по умолчанию 2 с). При перезапуске с `--pcap=FILE` запись каждой сессии -пишется в `FILE..`, поэтому перезапуск никогда не перезаписывает -предыдущую, а повторяющаяся строка завершения -`sr_session_stop: session was NULL` фильтруется из stderr. - -- `--no-loop` отключает авто-перезапуск (только одна запись). -- `--loop` принудительно включает авто-перезапуск (это поведение по умолчанию). -- `--max-restarts=N` ограничивает число перезапусков (по умолчанию 20; `0` = без ограничения). -- `--restart-delay=S` — секунды ожидания между перезапусками (по умолчанию 2). -- `--log` сохраняет строку вердикта `rc=` для завершения сессии. -- Декодер пишет `SIGNAL INTEGRITY WARNING`, когда ≥ 8 из последних - 64 кадров не проходят проверку чётности. -- Десинхронизированные TPDU (обмены с ошибкой кадрирования) сохраняются, - но помечаются `GSMTAP_FLAG_BAD_FCS` в байте `res` заголовка GSMTAP — - видно в Wireshark как предупреждение BAD-FCS. -- Заголовок T=0 со структурно некорректным INS (ISO 7816-4 §5.1.2: - `0x00` или `0x6x`/`0x9x`) почти всегда сдвинут на - один байт из-за лишнего ведущего байта (например, дочитанного остатка - SW2 после PACKETEND). Вместо молчаливого отбрасывания всего 5-байтового - окна (из-за чего следующий байт становился фиктивным CLA и проглатывал - остаток диалога в один CONCAT-пакет) декодер отбрасывает только ведущий - байт и перекадрирует остальные, восстанавливая настоящую команду. - Каждый потреблённый, но не выведенный байт явно логируется - (`discarded byte 0x…: reason`); отбрасывания холостых 0x00/0xFF - ограничены по частоте, отбрасывания не-холостых байтов всегда дают - аннотацию декодера. -- Карта может завершить команду словами SW1 SW2 на первом процедурном - байте (ISO 7816-3 §10.3.3), в том числе для case-2 команды с P3 > 0: - SW оформляется как статусное слово, а не читается как данные. Ответ - **короче Le** разделяется по статусному слову и пакет помечается - `BAD_FCS` (следующие обмены сохраняются); данные ответа при `P3=0` - (Le=256) сохраняются. - -Производительность: в режиме native CLK декодер один раз калибрует число -отсчётов на фронт CLK по первому кадру ATR, а затем продвигает битовую -синхронизацию одиночными пропусками отсчётов вместо ожидания на каждый -фронт CLK. Переключение скорости по PPS отслеживается через -`clock_skip = F/D`; никакой перекалибровки после PPS или по чётности нет. - -### Сравнение режимов на железе FX2 (результат A/B) - -- `native` декодировал реальный трафик (ATR, переключение PPS, 100+ валидных - APDU за 12-секундное окно); единственным устойчивым артефактом был - «дребезг» линии VCC — звон ~1 кГц, который теперь подавляет антидребезг 10 мс. -- `detect` ни разу не дал пригодной сессии на этом стенде: он полностью - пропускал переключение скорости по PPS (обработка PPS не срабатывала) и - алиасил весь трафик после PPS; вторая попытка поймала мёртвую линию I/O. - -`native` остаётся режимом по умолчанию. Используйте `--clock=detect` -только для офлайн-экспериментов без PPS. Запись, целиком состоящая из -нулевых кадров, означает, что съём потерял контакт с линией. - -Чётность — **чётная** по TS 102 221 («чётное число битов, установленных в -'1', включая бит чётности»); кадры, не прошедшие проверку, помечаются -`CHKSUM ERROR`, но всё равно декодируются. - -Эквивалентные «сырые» команды sigrok-cli: - -```bash -# Минимум: только CLK+I/O, живой поток на localhost:4729 -sigrok-cli -d fx2lafw --config samplerate=12M --continuous \ - -P iso7816:clk=D0:data=D1:clock_option=detect -A iso7816 - -# Полное подключение: CLK + I/O + RST + VCC с отслеживанием событий линий -sigrok-cli -d fx2lafw --config samplerate=12M --continuous \ - -P iso7816:clk=D5:data=D0:rst=D4:vcc=D2:clock_option=native:rst_detect=true:vcc_detect=true \ - -A iso7816 - -# Поток на удалённый анализатор / отключить стриминг / писать PCAP-файл -... -P iso7816:...:gsmtap_host=10.0.28.7 ... -... -P iso7816:...:gsmtap_enable=false ... -... -P iso7816:...:pcap_file=trace.pcap ... - -# Классический режим upstream: бинарный PCAP в stdout -sigrok-cli -i capture.sr -P iso7816:clk=2:data=0 -B iso7816=pcap > out.pcap -``` - -### Распиновка - -Каналы клона FX2 назначаются через `-P iso7816:clk=N:data=N:rst=N:vcc=N`. -Рекомендуемый съём коротким кабелем (с внешними подтягивающими резисторами) -использует фиксированные выводы, которые в точности совпадают с умолчаниями -`start.sh`; `--clk`/`--data`/`--rst`/`--vcc` переназначают их, если вы -подключили иначе: - -| Канал FX2 | Контакт SIM | Сигнал | -|-------------|-------------|--------| -| D0 | C7 | I/O | -| D2 | C1 | VCC (только цифровой уровень!) | -| D4 | C2 | RST | -| D5 | C3 | CLK | -| GND | C5 | GND | - -Входной порог FX2 близок к TTL (~1.4 В): карты класса 1.8 В могут читаться -нестабильно; классы 3 В/5 В — нормально. - -**Частота дискретизации и 8-битный режим (важно):** номинальные 24 МГц FX2 -доступны только при дискретизации в 8-битном режиме, т.е. когда **включены -только каналы D0–D7**. Включение 9-го канала (A0/аналоговый на клонах CWAV -AX) или любого аналогового входа переводит сбор в 16-битный, который -libsigrok ограничивает 12 МГц. Поэтому `start.sh`/`start.bat` явно -передают `-C D0,D1,D2,D3,D4,D5,D6,D7` и по умолчанию используют **16 МГц** -(с комфортным запасом под потолком USB 24 МГц; ~3.3 отсчёта на такт CLK -4.8 МГц). `setup.sh`/`setup.bat` проверяют и сообщают фактический максимум -вашего железа при том же ограничении. - -## Установка - -Оба способа ставят один и тот же декодер — выберите один: - -- **Скачать (рекомендуется)** — архив релиза. Не нужно ничего клонировать и - нет истории git: распакуйте, запустите `setup`, затем `start`. Лучший - вариант, если нужен только съём. -- **Из исходников** — `git clone`. Тот же рантайм плюс материал для - разработки: `tests/` и инструменты трасс и базовой линии - (`tools/capture_baseline.sh`, `tools/compare_baseline.sh`, - `tools/vs_reader.py`). Трассы примеров (`examples/`) исключены из git и в - любом случае остаются локальными. В архивах релиза намеренно нет `tests/`, - dev-инструментов и `examples/`. - -### Скачать (рекомендуется) - -Скачайте последний архив со страницы -[Releases](https://github.com/anttro/sigrok_iso7816_stream/releases/latest): - -- `sigrok_iso7816_stream-.tar.gz` — Linux -- `sigrok_iso7816_stream-.zip` — Windows - -К каждому релизу прилагается `SHA256SUMS` — в нём **оба** архива. -Положите файл рядом со скачанным архивом и проверьте: - -```bash -sha256sum -c --ignore-missing SHA256SUMS # GNU coreutils (Linux) -``` - -В Windows выполните `certutil -hashfile sigrok_iso7816_stream-.zip SHA256` -и сравните вывод со строкой `.zip` в `SHA256SUMS`. - -#### Linux (скачать) - -```bash -tar xzf sigrok_iso7816_stream-.tar.gz -cd sigrok_iso7816_stream- -./setup.sh -./start.sh -``` - -`setup.sh` проверяет, что установлены sigrok-cli и пакет прошивки FX2 -(`sigrok-firmware-fx2lafw`), создаёт симлинк каталога проекта в -`~/.local/share/libsigrokdecode/decoders/iso7816` (пользовательские -декодеры перекрывают системные) и опрашивает подключённое устройство на -предмет максимальной поддерживаемой частоты дискретизации. - -#### Windows (скачать) - -Предварительные требования: - -1. **sigrok-cli** — установщик для Windows (0.7.2 x86_64) с - [sigrok.org/wiki/Downloads](https://sigrok.org/wiki/Downloads) — - протестированная версия. На этой же странице публикуются ночные сборки - для Windows; они могут менять синтаксис sigrok-cli или API декодеров, - поэтому поддерживаемой остаётся версия из релизного установщика 0.7.2. Если sigrok-cli не запускается с ошибкой `0xc0150002`, установите - [Visual C++ 2010 Redistributable](https://www.microsoft.com/en-us/download/details.aspx?id=26999) - (`msvcr100.dll` требуется встроенному Python-рантайму). -2. Прошивка fx2lafw поставляется вместе с установщиком — отдельно скачивать не нужно. - -Настройка драйвера (донглам FX2 нужен WinUSB, вендорский драйвер не подойдёт): - -- Запустите **Zadig**, который лежит *внутри* каталога установки sigrok-cli - (также доступен из меню «Пуск»). Выберите устройство FX2 в выпадающем - списке и установите драйвер **WinUSB**. -- После загрузки прошивки устройство переподключается с другим VID/PID — - если оно всё ещё не находится, запустите Zadig **второй раз** для - переподключившегося устройства. -- Windows привязывает драйверы к USB-порту, когда нет серийного номера: - перенос донгла в другой порт может потребовать повторить Zadig. - -Затем распакуйте архив `.zip` (в Проводнике: правой кнопкой → «Извлечь все») -и запустите в распакованном каталоге: - -```bat -setup.bat -start.bat -``` - -`setup.bat` проверяет sigrok-cli и встроенную прошивку, регистрирует декодер -этого проекта через junction в -`%LOCALAPPDATA%\libsigrokdecode\decoders\iso7816` (подтверждается тем, что -`sigrok-cli -L` показывает `iso7816`), и опрашивает устройство на предмет -поддерживаемых частот дискретизации. В zip-архиве релиза bat-файлы уже с -переводами строк CRLF, поэтому преобразование не требуется. -`start.bat --help` перечисляет его опции (основное подмножество `start.sh`: -каналы, частота дискретизации, clock, host/port, pcap, protocol, debug). - -### Linux (из исходников) - -```bash -git clone git@github.com:anttro/sigrok_iso7816_stream.git -cd sigrok_iso7816_stream -./setup.sh -``` - -Свежему клону нужны те же проверки и симлинк `./setup.sh`, что и выше: он -проверяет sigrok-cli и пакет прошивки FX2, создаёт симлинк каталога проекта -в `~/.local/share/libsigrokdecode/decoders/iso7816` и опрашивает устройство -на предмет максимальной частоты дискретизации. - -### Windows (из исходников) - -Предварительные требования Windows (sigrok-cli и Visual C++ 2010 -Redistributable, встроенная прошивка fx2lafw и настройка драйвера -Zadig/WinUSB) — те же, что в разделе -[Windows (скачать)](#windows-скачать) выше. - -```bat -git clone git@github.com:anttro/sigrok_iso7816_stream.git -cd sigrok_iso7816_stream -setup.bat -``` - -`setup.bat` выполняет те же проверки и регистрацию junction, что и выше. -`start.bat` поддерживает основное подмножество опций (каналы, частота -дискретизации, clock, host/port, pcap, protocol, debug; полный набор — в -`start.sh`) — основной формат с пробелом, а `--clk=CH` тоже работает: - -```bat -start.bat --clk D1 --data D6 -start.bat --help -``` - -Запись работает так же, как в Linux: - -```bat -start.bat rem запись + поток GSMTAP -``` - -Примечание: bat-файлы требуют переводов строк CRLF; репозиторий следит за -этим через `.gitattributes`, поэтому свежий клон в Windows уже корректен -(zip-архив релиза содержит те же файлы с CRLF). - ## Заметки и ограничения по детектированию RST/VCC - События детектируются **асинхронно до первого ATR** (включение питания / @@ -479,16 +397,11 @@ start.bat rem запись + поток GSMTAP пакета могут быть пропущены. - VCC — только цифровой: декодер видит «питание есть/нет», но никогда не класс напряжения (1.8/3/5 В). -- **RST и VCC используют гистерезис стабильности уровня в 10 мс** +- **RST и VCC используют гистерезис стабильности уровня 10 мс** (масштабируется от частоты дискретизации): новый уровень сообщается - только после того, как он непрерывно стабилен ≥ 10 мс — либо потому, что - он держится так долго, либо потому, что он закончился, продержавшись - столько. Это делает включение и выключение питания *симметричными*: - линия VCC, которая **звенит на фронте** (шумный/плавающий съём), больше - не теряет событие «VCC on» — оно срабатывает, как только линия - устанавливается в HIGH, вместо того чтобы быть съеденным дребезгом - фронта. RST использует ту же схему, поэтому короткий глитч RST больше - не вызывает фантомный re-arm по тёплому сбросу. + только после того, как он непрерывно стабилен ≥ 10 мс. Это делает + включение и выключение питания *симметричными* и подавляет звон и + короткие глитчи. - **События VCC в целом ненадёжны — лучше не отслеживать VCC.** Плавающий или неподключённый пин съёма VCC всегда читается как HIGH (логическая единица без нагрузки), поэтому декодер постоянно видит «питание подано» @@ -501,20 +414,10 @@ start.bat rem запись + поток GSMTAP - Неназначенные опциональные каналы игнорируются, даже если `rst_detect`/`vcc_detect` включены (защита через `has_channel()`). -## Тестирование +## Разработка и тестирование -Проверено на примерах записей из upstream: - -```bash -# ATR+PPS+54 APDU из записи ридера test_8 (~19 с декодирования) -# Поток GSMTAP проверен через tshark (ATR/APDU разбираются нативно), -# кастомные события 0x10/0x11 — через UDP-слушатель, и сквозным путём -# в сервер SIMtrace Analyser (POST /api/capture/start → decode → stop). -``` - -Синтетический генератор VCD, покрывающий краевые случаи RST/VCC, живёт в -заметках проекта (`projects/SIGROK_ISO7816.md` в родительском рабочем -пространстве). +Декодер проверяется на примерах записей с помощью `tools/vs_reader.py`. +Фикстуры трасс хранятся локально и не входят в репозиторий. ### Проверка по SDK ридера (`tools/vs_reader.py`) @@ -531,33 +434,12 @@ python3 tools/vs_reader.py .log out.pcap `vs_reader.py` выравнивает каждый обмен из журнала ридера с APDU из записи (побайтовое LCS-совпадение) и классифицирует остатки как proactive/CAT (невидимые для SDK ридера), pre-capture/потерянные или мусор. -Запись, начатая в середине сессии, тёплые сбросы которой раньше давали -4 мусорных события, с re-arm и защитой стартового бита декодируется в -**0 мусора** (`RESULT: OK - capture fully explained`). - -test_7 (4 сброса ATR, фрагментирующих сессию) теперь захватывает все 37/37 -обменов ридера (было 10/37 до исправления деглитча). Телефонные трассы -Samsung с 16 CLK/ETU (F=512/D=32) теперь разбираются на 924 отдельных -обмена T=0 (раньше сливались в 52 APDU завышенного размера). - -Воспроизводимые фикстуры трасс (хранятся локально, вне репозитория) -покрывают сессии ридера с контролируемого стенда (с эталонными журналами -SDK ридера), телефонные записи с гейтированным CLK и **записи холодного -старта**, начинающиеся *до* включения питания (VCC/RST низкие при t=0). -Четыре фикстуры Samsung — холодные старты, снятые новым коротким кабелем -(провода 30 мм, внешние подтягивающие резисторы GND→VCC и VCC→DATA), с -каналами `DATA/VCC/RST/CLK` на битах 0/2/4/5; варианты `sim2` обрезаны до -окна включения питания. ### Записи холодного старта (запись начинается до включения питания) -Когда запись начинается до включения питания, декодер должен взвести охоту -за ATR, потому что RST всё ещё низкий на отсчёте 0: он инициализирует -начальные уровни VCC/RST на первом шаге (вместо того чтобы по умолчанию -считать их снятыми) и при низком RST на старте входит в `FIND START` с -очищенным ETU, поэтому переходы DATA при включении питания до ATR не могут -зафиксировать фиктивную битовую скорость. Затем он декодирует полный ATR -(`3b9f96801fc78031e073fe2117574a3382033339001e`) с 0 мусора: +Когда запись начинается до включения питания, RST всё ещё низкий на +отсчёте 0. Используйте `rst_detect=true` и `protocol=T=0`; декодер взводит +охоту за ATR по начальному уровню RST и разбирает полный ATR. Пример: ```bash sigrok-cli -i .sr \ @@ -565,52 +447,17 @@ sigrok-cli -i .sr \ -A iso7816 ``` -Снятие RST (deassert), которое приходит, пока разбор ATR уже идёт, больше не -перевзводит охоту посреди чтения — оно логирует `RST deasserted (hunt/ATR -already in progress)` и не трогает разбираемый ATR (test_8/test_7 -CHKSUM 18→0). - ### Сценарии записи: ридер (постоянный CLK) и телефон (Clock Stop Mode) -Декодер обрабатывает две физически разные схемы съёма SIM: - - **Запись ридера / постоянный CLK** — ридер ведёт ровный CLK всю сессию. - В режиме mid-session запись декодируется в **0 мусора** - (`RESULT: OK`) относительно эталона из SDK ридера - (`tools/vs_reader.py .log out.pcap`). - Записи ридера с тёплыми сбросами используют fallback с синтетическим - T=0-ATR. - -- **Запись телефона / остановленный CLK** — телефон гейтирует или - останавливает CLK между передачами (Clock Stop Mode), поэтому ETU не - равен стандартным 372 тактам и не может быть выведен из CLK. Запускайте - с `protocol=T=0`; декодер восстанавливает ETU из линии DATA подсчётом - фронтов, фиксирует его и декодирует устойчивым к дрейфу edge-list - читателем битов. Команды T=0 case 3/4 (например, `80 12`/`80 14` - STK envelope) объединяются в один APDU команда→ответ. Деглитч стартового - бита в 2 отсчёта убирает LOW-глитчи короче ETU, вызванные артефактами - внутренней подтяжки FX2LP, и предотвращает смещение байтов на быстрых - телефонных трассах. - -### Проверенные скорости данных и ETU - -Все трассы декодированы на **частоте дискретизации 16 МГц**, 0 мусора, -RESULT: OK. Начиная с v1.5.0 каждая трасса из набора примеров также -сообщает **0 CONCAT** (перекадрирование по некорректному INS устранило -последнее семейство проглатывания нескольких обменов на -4gmodem/A55_sim2/S21p_sim2). - -| Трасса | Режим CLK | ETU (отсчёты) | CLK/ETU | Конвенция | Примечания | -|-------|----------|---------------|---------|------------|-------| -| test_8 | постоянный | ~43 | 372 (стандарт) | Direct | PC/SC ридер, ATR+PPS+APDU | -| test_7 | постоянный | ~43 | 372 (стандарт) | Direct | PC/SC ридер, тёплые сбросы | -| xiaomi | гейтированный/остановленный | ~53 | восстановлен из DATA | Direct | Телефон, середина сессии | -| samsung | гейтированный/остановленный | ~72 | 16 (F=512/D=32) | Direct | Телефон, нестандартный F/D, меню STK | - -Декодер автоопределяет ETU по трассе и выбирает подходящий читатель битов -(CLK-синхронный для постоянного CLK, edge-list для гейтированного/ -остановленного CLK). Никакой ручной настройки не требуется, кроме -`clock_option=native` и `protocol=T=0` для телефонных записей. + Проверяйте её по SDK ридера через + `tools/vs_reader.py .log out.pcap`. +- **Запись телефона / гейтированный или остановленный CLK** — телефон + гейтирует или останавливает CLK между передачами (Clock Stop Mode), + поэтому ETU нельзя вывести из CLK. Запускайте с `protocol=T=0`; декодер + восстанавливает ETU из линии DATA и декодирует edge-list читателем. + Команды T=0 case 3/4 (например, `80 12`/`80 14` STK envelope) объединяются + в один APDU команда→ответ. Рекомендуемые вызовы: @@ -627,6 +474,28 @@ sigrok-cli -i .sr \ -A iso7816 ``` +### Скорости данных и ETU + +Справочные значения, наблюдавшиеся на примерах записей при частоте +дискретизации 16 МГц: + +| Трасса | Режим CLK | ETU (отсчёты) | CLK/ETU | Конвенция | Примечания | +|-------|----------|---------------|---------|------------|-------| +| test_8 | постоянный | ~43 | 372 (стандарт) | Direct | PC/SC ридер, ATR+PPS+APDU | +| test_7 | постоянный | ~43 | 372 (стандарт) | Direct | PC/SC ридер, тёплые сбросы | +| xiaomi | гейтированный/остановленный | ~53 | восстановлен из DATA | Direct | Телефон, середина сессии | +| samsung | гейтированный/остановленный | ~72 | 16 (F=512/D=32) | Direct | Телефон, нестандартный F/D, меню STK | +| alcor_reader | постоянный | ~53 | 16 (F=512/D=32) | Direct | PC/SC ридер, CLK 4.0 МГц на ATR -> 4.8 МГц после PPS | + +Декодер автоопределяет ETU и выбирает подходящий читатель битов +(CLK-синхронный для постоянного CLK, edge-list для гейтированного/ +остановленного CLK). Никакой ручной настройки не требуется, кроме +`clock_option=native` и `protocol=T=0` для телефонных записей. + +Чётность — **чётная** по TS 102 221 («чётное число битов, установленных в +'1', включая бит чётности»); кадры, не прошедшие проверку, помечаются +`CHKSUM ERROR`, но всё равно декодируются. + ## Лицензия GPL-2.0+, как и upstream.