Fix pcap timestamp wrap, ATR-hunt EOF crash, start.bat protocol; tighten launchers + vs_reader
- pd.py ts_from_samplenum: drop c_uint32 truncation + dead sampleOverflowCount (pcap timestamps wrapped backwards past ~4.5 min at 16 MHz). - pd.py handle_atr: guard None reads at EOF (was TypeError (None & 0x80) on a capture truncated mid-ATR-hunt). - start.bat: add --protocol (+ :protocol=T=0 default) to match start.sh's mid-session decode; correct the 'flag-for-flag' header comment. - start.sh: reject --rst/--vcc assigned to the same pin (was unchecked). - setup.bat: set DEVICE_MSG on blocked/skipped probe so the trailing 'unknown' message is suppressed. - vs_reader.py: RESULT now fails on CONCAT / payload mismatch / suspicious CLA, not just GARBAGE (OK text unchanged; clean traces stay identical).
This commit is contained in:
1 parent
9d00827837
commit
e6ff3a2e14
5 files changed
+46
-12
No files matched your search
@@ -20,7 +20,6 @@ import struct
|
||||
import sys
|
||||
import time
|
||||
import codecs
|
||||
import ctypes
|
||||
import traceback
|
||||
from collections import deque
|
||||
|
||||
@@ -450,7 +449,6 @@ class Decoder(srd.Decoder):
|
||||
# card was already in reset" indistinguishable from a live session.
|
||||
self._primed = False
|
||||
self.lastSamplePositive = True
|
||||
self.sampleOverflowCount = 0
|
||||
# Rolling parity-error monitor: warns when the wire degrades
|
||||
# (e.g. GSM TX bursts coupling into the probe wiring).
|
||||
self.parity_hist = deque(maxlen=64)
|
||||
@@ -755,9 +753,12 @@ class Decoder(srd.Decoder):
|
||||
self.wrote_pcap_header = True
|
||||
|
||||
def ts_from_samplenum(self, sample):
|
||||
x = ctypes.c_uint32(sample).value;
|
||||
ovrflow = ctypes.c_uint32(int(self.sampleOverflowCount * 0xFFFFFFFF * self.secs_per_sample)).value
|
||||
ts = float(x) * self.secs_per_sample + ovrflow + self._pcap_base_time
|
||||
# Use the full sample number. The previous c_uint32 truncation (plus
|
||||
# an overflow counter that was never incremented) made pcap timestamps
|
||||
# wrap and go backwards once a capture passed 2^32 samples (~4.5 min
|
||||
# at 16 MHz). float64 holds sample numbers well past 2^53, so the
|
||||
# whole sample domain is representable.
|
||||
ts = float(sample) * self.secs_per_sample + self._pcap_base_time
|
||||
return (int(ts), int((ts % 1.0) * 1e6))
|
||||
|
||||
def signal_quality(self, err):
|
||||
@@ -1556,6 +1557,10 @@ class Decoder(srd.Decoder):
|
||||
self.put(atr_start, self.samplenum, self.out_ann,
|
||||
[Ann.ANN_WARN, ["Invalid TS byte 0x{byte:02x} - skipped".format(byte=byte)]])
|
||||
byte = self.read_byte()
|
||||
if byte is None:
|
||||
# End of capture mid-hunt: stop cleanly instead of raising
|
||||
# TypeError (None & 0x80) in the next loop iteration.
|
||||
return
|
||||
atr_start = self.ss
|
||||
ts_attempts += 1
|
||||
if (byte not in (0x3b, 0x3f)):
|
||||
@@ -1599,6 +1604,8 @@ class Decoder(srd.Decoder):
|
||||
ts=byte, conv="inverse" if self._inverse_convention else "direct"))
|
||||
|
||||
t0 = self.read_byte()
|
||||
if t0 is None:
|
||||
return
|
||||
self.ATR.append(t0)
|
||||
# Lock ETU from the first two ATR bytes (TS + T0). The ATR is sent
|
||||
# at the default ETU, so its edge spacings are the authoritative
|
||||
|
||||
@@ -106,10 +106,12 @@ for %%r in (1M 2M 4M 8M 12M 16M 20M 24M) do (
|
||||
-P "iso7816:clk=D0:data=D1" >"%TEMP%\iso7816-probe.txt" 2>&1
|
||||
type "%TEMP%\iso7816-probe.txt" | findstr /c:"Unable to claim" >nul && (
|
||||
echo blocked - another program holds the device
|
||||
set "DEVICE_MSG=1"
|
||||
goto :probedone
|
||||
)
|
||||
type "%TEMP%\iso7816-probe.txt" | findstr /c:"Failed to open" /c:"No devices found" >nul && (
|
||||
echo skipped - no FX2 device connected
|
||||
set "DEVICE_MSG=1"
|
||||
goto :probedone
|
||||
)
|
||||
type "%TEMP%\iso7816-probe.txt" | findstr /r /c:"invalid argument" /c:"Unable to sample" /c:"Could not start" >nul || set MAX_RATE=%%r
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
@echo off
|
||||
rem sigrok_iso7816_stream launcher (Windows): capture ISO 7816 and stream
|
||||
rem GSMTAP to :4729. Flag-for-flag equivalent of start.sh.
|
||||
rem GSMTAP to :4729. Mirrors the core start.sh flags (channel/samplerate/
|
||||
rem clock/gsmtap/pcap/protocol/debug); start.sh has the full flag set.
|
||||
|
||||
setlocal EnableExtensions EnableDelayedExpansion
|
||||
|
||||
@@ -15,6 +16,7 @@ set "PORT=4729"
|
||||
set "PCAP="
|
||||
set "DEBUG="
|
||||
set "ANNOT=iso7816=apdus,iso7816=warnings"
|
||||
set "PROTOCOL=T=0"
|
||||
|
||||
:argloop
|
||||
if "%~1"=="" goto :argsdone
|
||||
@@ -28,6 +30,7 @@ if /i "%~1"=="--host" ( set "HOST=%~2" & shift & shift & goto :arg
|
||||
if /i "%~1"=="--port" ( set "PORT=%~2" & shift & shift & goto :argloop )
|
||||
if /i "%~1"=="--pcap" ( set "PCAP=%~2" & shift & shift & goto :argloop )
|
||||
if /i "%~1"=="--debug" ( set "DEBUG=1" & set "ANNOT=iso7816" & shift & goto :argloop )
|
||||
if /i "%~1"=="--protocol" ( set "PROTOCOL=%~2" & shift & shift & goto :argloop )
|
||||
if /i "%~1"=="--no-rst" ( set "RST=" & shift & goto :argloop )
|
||||
if /i "%~1"=="--no-vcc" ( set "VCC=" & shift & goto :argloop )
|
||||
if /i "%~1"=="-h" ( goto :usage )
|
||||
@@ -49,6 +52,7 @@ echo --pcap=FILE Also write decoded events to FILE (no spaces in path)
|
||||
echo --debug Full decoder + sigrok output (all annotation rows + -l 4).
|
||||
echo
|
||||
echo By default only decoded APDUs and decoder warnings/errors are shown.
|
||||
echo --protocol=MODE T=0 (default), T=1, or auto (mid-session decode)
|
||||
echo --no-rst Disable RST tracking
|
||||
echo --no-vcc Disable VCC tracking
|
||||
echo.
|
||||
@@ -82,11 +86,17 @@ exit /b 1
|
||||
|
||||
:found
|
||||
|
||||
rem Normalize --protocol to the decoder's accepted form (T=0 / T=1 / auto).
|
||||
if /i "%PROTOCOL%"=="T0" set "PROTOCOL=T=0"
|
||||
if /i "%PROTOCOL%"=="T1" set "PROTOCOL=T=1"
|
||||
if /i "%PROTOCOL%"=="AUTO" set "PROTOCOL=auto"
|
||||
|
||||
set "OPTS=clk=%CLK%:data=%DATA%:clock_option=%CLOCK%"
|
||||
set "OPTS=%OPTS%:gsmtap_host=%HOST%:gsmtap_port=%PORT%"
|
||||
if defined RST set "OPTS=%OPTS%:rst=%RST%:rst_detect=true"
|
||||
if defined VCC set "OPTS=%OPTS%:vcc=%VCC%:vcc_detect=true"
|
||||
if defined PCAP set "OPTS=%OPTS%:pcap_file=%PCAP%"
|
||||
set "OPTS=%OPTS%:protocol=%PROTOCOL%"
|
||||
|
||||
set "CMDLINE=sigrok-cli -d fx2lafw --config samplerate=%SAMPLERATE% --continuous -C D0,D1,D2,D3,D4,D5,D6,D7"
|
||||
if defined DEBUG set "CMDLINE=%CMDLINE% -l 4"
|
||||
|
||||
@@ -189,6 +189,7 @@ check_dup clk "${CLK}" rst "${RST}"
|
||||
check_dup clk "${CLK}" vcc "${VCC}"
|
||||
check_dup data "${DATA}" rst "${RST}"
|
||||
check_dup data "${DATA}" vcc "${VCC}"
|
||||
check_dup rst "${RST}" vcc "${VCC}"
|
||||
|
||||
echo "Channels: clk=${CLK} data=${DATA}${RST:+ rst=${RST}}${VCC:+ vcc=${VCC}}"
|
||||
|
||||
|
||||
+20
-6
@@ -380,12 +380,26 @@ def main():
|
||||
print('\nWARNING: capture contains 0 APDUs but reader log has %d exchange(s).'
|
||||
% len(reader))
|
||||
|
||||
ok = (len(pcap_garbage) == 0 and not no_apdu_failure)
|
||||
print('\nRESULT: %s' % ('OK - capture fully explained (reader + CAT + valid retries)'
|
||||
if ok else
|
||||
'UNCLEAN - %d mis-framed capture APDU(s)%s'
|
||||
% (len(pcap_garbage),
|
||||
', 0 capture APDUs' if no_apdu_failure else '')))
|
||||
ok = (len(pcap_garbage) == 0
|
||||
and len(concat_indices) == 0
|
||||
and len(payload_mismatches) == 0
|
||||
and len(suspicious_cla) == 0
|
||||
and not no_apdu_failure)
|
||||
if ok:
|
||||
print('\nRESULT: OK - capture fully explained (reader + CAT + valid retries)')
|
||||
else:
|
||||
problems = []
|
||||
if pcap_garbage:
|
||||
problems.append('%d garbage APDU(s)' % len(pcap_garbage))
|
||||
if concat_indices:
|
||||
problems.append('%d CONCAT packet(s)' % len(concat_indices))
|
||||
if payload_mismatches:
|
||||
problems.append('%d payload mismatch(es)' % len(payload_mismatches))
|
||||
if suspicious_cla:
|
||||
problems.append('%d suspicious CLA' % len(suspicious_cla))
|
||||
if no_apdu_failure:
|
||||
problems.append('0 capture APDUs')
|
||||
print('\nRESULT: UNCLEAN - %s' % ', '.join(problems))
|
||||
sys.exit(0 if ok else 1)
|
||||
|
||||
|
||||
|
||||
Reference in new issue
Block a user