v1.5.0: invalid-INS one-byte re-frame + explicit discard logging
Residual CONCAT mis-frames (4gmodem/A55_sim2/S21p_sim2) traced to a silent 5-byte drop at an invalid-INS T=0 header (0x0f 00 a4 08 04). Drop only the stray leading byte and re-frame the remaining four via _replay so the real command (00 a4 08 04 02 2f 00 -> 61 1c) is recovered. - _note_discard()/_consume_first(): every consumed-but-unemitted byte is now logged; idle 0x00/0xFF discards are rate-limited, real data always gets an ANN_WARN annotation. - All read-until-SW loops log skipped non-SW bytes. - All traces: CONCAT 0; BAD_FCS/GARBAGE 0; test_8/test_7 RESULT OK; 47/47 unit tests; baseline byte-identical. History rewritten to a single root commit so no example trace is stored in the repo (fixtures are local-only, gitignored). README keeps only generic <trace>.sr placeholders; AGENTS.md retains the fixture names.
This commit is contained in:
commit
d3715c9385
34 files changed
+7855
No files matched your search
Executable
+113
@@ -0,0 +1,113 @@
|
||||
#!/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
|
||||
|
||||
# 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
|
||||
Reference in new issue
Block a user