Files
sigrok_iso7816_stream/tools/capture_baseline.sh
T
catarrh 3bf5cee222 v1.9.2: PPS CLK upshift + exact CLK-edge projection (new reader fixture)
- handle_pps(): flag the first post-PPS character; _read_byte_clk() re-measures
  the CLK period there and accounts the measurement's 16 edges.  The Alcor
  reader upclocks 4.0 -> 4.8 MHz at PPS (FI/DI still 512/32), so the ATR
  measurement was stale: 64 vs 53.33 samples/ETU, no post-PPS APDU framed.
- _wait_clk_rising(): project to the n-th edge (skip to target - half a
  period, take one edge) instead of "skip n-2 cycles + 2 edges", which lost
  ~1 edge per call on fractional periods and slid the samples ~0.5 ETU early
  by the parity bit.  xiaomi 7698 -> 2, 4gmodem 7218 -> 0, S21p_sim2 394 -> 0
  CHKSUM lines (previously misread as dirty-wire noise).
- CONCAT gate: EMBEDDED_CLA excludes the structural 0x4x/0x5x classes (payload
  false hit on the Alcor secured packet); mirrored in tools/vs_reader.py and
  covered by a new vector in tests/test_gsmtap.py.
- tools/capture_baseline.sh: add the alcor_reader_sample fixture; baseline
  regenerated (APDU counts and RESULT: OK unchanged everywhere, 0 CONCAT).
- 75/75 unit tests.  README/AGENTS updated.
2026-09-27 23:52:40 +03:00

121 lines
6.7 KiB
Bash
Executable File

#!/bin/bash
# Capture baseline measurements for all traces in mid-session mode.
# Usage: ./tools/capture_baseline.sh > tests/baseline.txt
# Compare with: diff tests/baseline.txt <(./tools/capture_baseline.sh)
set -e
cd "$(dirname "$0")/.."
# Clear stale bytecode cache — prevents false results from old code.
find . -name "__pycache__" -type d -exec rm -rf {} + 2>/dev/null || true
find . -name "*.pyc" -delete 2>/dev/null || true
run_test() {
local label="$1"
shift
echo "=== $label ==="
# Run decoder, capture stderr too
local output
output=$("$@" 2>&1) || true
# Extract key metrics
echo "$output" | grep -E "iso7816 decoder v|etu recovered|ENDATR|CHKSUM ERROR|INVALID Procedure|desynced APDU|CONCAT APDU|warm reset|Invalid TS|No valid TS|RST low at start|RST deasserted|expecting cold-boot" | head -20
# CHKSUM errors are a key degradation signal.
chksum_count=$(echo "$output" | grep -c "CHKSUM ERROR" || true)
echo "CHKSUM ERROR count: $chksum_count"
# CONCAT: packets with embedded exchanges (mis-frame swallowed several
# real exchanges into one "valid" APDU). Must stay 0 for clean traces.
# grep the log form (with ':'), not the annotation text, so each packet
# is counted once.
concat_count=$(echo "$output" | grep -c "CONCAT APDU:" || true)
echo "CONCAT APDU count: $concat_count"
# Check for vs_reader results if pcap exists
if [ -f /tmp/out.pcap ]; then
local reader_log=""
case "$label" in
test_8*) reader_log="examples/test_8_reader.log" ;;
test_7*) reader_log="examples/test_7_reader.log" ;;
esac
if [ -n "$reader_log" ] && [ -f "$reader_log" ]; then
python3 tools/vs_reader.py "$reader_log" /tmp/out.pcap 2>&1 || true
else
# No ground-truth reader log; run pcap-only analysis to surface
# BAD_FCS / suspicious CLA / payload issues.
python3 tools/vs_reader.py --pcap-only /tmp/out.pcap 2>&1 || true
fi
fi
echo ""
}
# Signal diagnostic: extract key metrics from .sr trace
signal_diag() {
local sr_file="$1"
local clk="$2"
local data="$3"
local rst_opt=""
local vcc_opt=""
[ -n "$4" ] && rst_opt="--rst $4"
[ -n "$5" ] && vcc_opt="--vcc $5"
python3 tools/signal_diagnostic.py "$sr_file" --clk "$clk" --data "$data" $rst_opt $vcc_opt 2>&1 \
| grep -E 'Frequency|Period|Rising|Transitions|First activity|stable|noisy' | head -10
}
echo "=== Baseline captured $(date -Iseconds) ==="
echo ""
# test_8
run_test "test_8" sigrok-cli -i examples/test_8_raw16.sr -P iso7816:clk=CLK:data=DATA:rst=RST:vcc=VCC:clock_option=native:rst_detect=true:gsmtap_enable=false:pcap_file=/tmp/out.pcap -A iso7816
# test_7
run_test "test_7" sigrok-cli -i examples/test_7_raw16.sr -P iso7816:clk=CLK:data=DATA:rst=RST:vcc=VCC:clock_option=native:rst_detect=true:gsmtap_enable=false:pcap_file=/tmp/out.pcap -A iso7816
# xiaomi_phone_sample
run_test "xiaomi_phone_sample" timeout 30 sigrok-cli -i examples/xiaomi_phone_sample.sr -P iso7816:clk=CLK:data=DATA:rst=RST:clock_option=native:protocol=T=0:gsmtap_enable=false:pcap_file=/tmp/out.pcap -A iso7816
# xiaomi_mi_a1_coldboot_sample — capture starts BEFORE power-up (VCC low at t=0).
# Regression fixture: must arm the ATR hunt when RST is still low at start
# and start decoding the ATR once the card wakes up.
run_test "xiaomi_mi_a1_coldboot" timeout 300 sigrok-cli -i examples/xiaomi_mi_a1_coldboot_sample.sr -P iso7816:clk=CLK:data=DATA:rst=RST:vcc=VCC:clock_option=native:protocol=T=0:rst_detect=true:vcc_detect=true:gsmtap_enable=false:pcap_file=/tmp/out.pcap -A iso7816
# 4gmodem_coldboot_sample — same pre-power-up capture shape, modem SIM.
run_test "4gmodem_coldboot" timeout 300 sigrok-cli -i examples/4gmodem_coldboot_sample.sr -P iso7816:clk=CLK:data=DATA:rst=RST:vcc=VCC:clock_option=native:protocol=T=0:rst_detect=true:vcc_detect=true:gsmtap_enable=false:pcap_file=/tmp/out.pcap -A iso7816
# alcor_reader_sample — PC/SC reader (Alcor). Regression fixture for the PPS
# clock upshift: CLK is 4.0 MHz at the ATR but 4.8 MHz after PPS (FI/DI
# 512/32 -> 16 CLK/bit = 3.333 samples/CLK at 16 MHz), so the samples-per-clock
# measured at the ATR goes stale; the first post-PPS character must re-measure
# it or no post-PPS APDU frames.
run_test "alcor_reader_sample" timeout 300 sigrok-cli -i examples/alcor_reader_sample.sr -P iso7816:clk=CLK:data=DATA:rst=RST:vcc=VCC:clock_option=native:rst_detect=true:gsmtap_enable=false:pcap_file=/tmp/out.pcap -A iso7816
# samsung_A55_coldboot_new_cable — Samsung A55 with the 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.
run_test "samsung_A55_coldboot_new_cable" timeout 300 sigrok-cli -i examples/samsung_A55_coldboot_new_cable.sr -P iso7816:clk=CLK:data=DATA:rst=RST:vcc=VCC:clock_option=native:protocol=T=0:rst_detect=true:vcc_detect=true:gsmtap_enable=false:pcap_file=/tmp/out.pcap -A iso7816
# samsung_A55_coldboot_new_cable_sim2 — A55 SIM slot 2, same cable; trace
# cropped to the power-on window (~21 s of pre-power idle removed).
run_test "samsung_A55_coldboot_new_cable_sim2" timeout 300 sigrok-cli -i examples/samsung_A55_coldboot_new_cable_sim2.sr -P iso7816:clk=CLK:data=DATA:rst=RST:vcc=VCC:clock_option=native:protocol=T=0:rst_detect=true:vcc_detect=true:gsmtap_enable=false:pcap_file=/tmp/out.pcap -A iso7816
# samsung_S21p_coldboot_new_cable — Samsung S21+ with the new short cable.
run_test "samsung_S21p_coldboot_new_cable" timeout 300 sigrok-cli -i examples/samsung_S21p_coldboot_new_cable.sr -P iso7816:clk=CLK:data=DATA:rst=RST:vcc=VCC:clock_option=native:protocol=T=0:rst_detect=true:vcc_detect=true:gsmtap_enable=false:pcap_file=/tmp/out.pcap -A iso7816
# samsung_S21p_coldboot_new_cable_sim2 — S21+ SIM slot 2, same cable; trace
# cropped to the power-on window (~17 s of pre-power idle removed).
run_test "samsung_S21p_coldboot_new_cable_sim2" timeout 300 sigrok-cli -i examples/samsung_S21p_coldboot_new_cable_sim2.sr -P iso7816:clk=CLK:data=DATA:rst=RST:vcc=VCC:clock_option=native:protocol=T=0:rst_detect=true:vcc_detect=true:gsmtap_enable=false:pcap_file=/tmp/out.pcap -A iso7816
# signal diagnostics
echo "=== signal diagnostics ==="
echo "--- test_8 ---"
signal_diag examples/test_8_raw16.sr CLK DATA RST VCC
echo "--- test_7 ---"
signal_diag examples/test_7_raw16.sr CLK DATA RST VCC
echo "--- xiaomi_phone_sample ---"
signal_diag examples/xiaomi_phone_sample.sr CLK DATA RST
echo "--- samsung_A55_coldboot_new_cable ---"
signal_diag examples/samsung_A55_coldboot_new_cable.sr CLK DATA RST VCC
echo "--- samsung_S21p_coldboot_new_cable ---"
signal_diag examples/samsung_S21p_coldboot_new_cable.sr CLK DATA RST VCC
# unit tests
echo "=== unit tests ==="
python3 tests/test_gsmtap.py -v 2>&1