A block read repeats one 32 bit word, so every offset yields a rotation and more
than one can pass the structural checks. A T5577 in direct/nrz carried both
00080040, the word on the tag, and 00080001, its ror19 - both master key 0,
reserved 0, RF/32, direct. test() answers with the first hit from a fixed floor,
so which one detect reported was scan order rather than evidence.
No structural check separates them: every bit of block 0 is a real field, and
the three the scan skips are otp, fast write and inverse data, all settable. The
tag can, though - maxblock has to account for what regular read mode cycles
through. So measure the broadcast period and keep the rotation that agrees,
reusing the constraint printConfiguration already applies to the psk2/psk3
pre-images. Costs one acquisition, and only when the reading is ambiguous.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
The emitted bit is the running phase, so a shift accepted before the tag answers
toggles curPhase once too often and the rest of the word comes back complemented.
pskFindFirstPhaseShift judged its first measured length, but waveStart starts as
wherever the caller began looking - that length is part of a wave, not a wave,
and any gap beating fc was taken as a shift. Baseline on the first peak instead.
pskRawDemod_ext separately trusted a shift under one bit period in; the clock is
known by then, so look again from a bit period in.
Both are needed - dropping either leaves one of the tags measured inverting on
most reads.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
aggregate_bits sized each run of like waves in bits and then forced a zero to
one. That is right mid-stream, where a run rounding to nothing would drop a bit
the tag did send. On the leading run it is wrong: a single subcarrier wave is
about fchigh samples against a bit period of clk, so it rounds to no bits and
was made into one anyway - a bit the tag never sent, shifting every bit after it
and dragging startIdx back by most of a bit period.
Skip a leading run that rounds to nothing and let the next transition be first.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
The samples before the first level change were counted as bits, and where no
edge arrives inside ten clocks the long-run flush fired first and invented ten
of them out of the quiet lead-in. The count sat on a rounding boundary, so one
sample of jitter in that edge added or dropped a leading bit and rotated the
rest of the word - while startIdx, derived from the same count, held i % clk and
could name no sample.
A level change can only fall on a bit boundary, so start there and report it.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
GetT55xxBlockData extracted every block at config.offset, a bit index into a
demod buffer cached by the last detect - a different capture. Demodulators do
not all start on the same bit, so a later read could return a rotation of the
block with nothing marking it as wrong: psk1 by four or five bits, fsk2a and
nrz by one, manchester and biphase never.
Record the boundary where it is stable instead. Every demodulator reports the
graph sample its first bit sits on, and turn_read_lf_on(137 * 8) makes the
firmware open each read acquisition at the same point, so the word boundary
lands on the same sample every time. Convert back per demodulation.
Block 0 re-anchors from its known value, and a write is now verified by the
value being anywhere in the repeating stream rather than at one cached offset -
which also fixes correct writes reporting as validation failures. A block 0
verify re-detects on a mismatch, not only on a decode failure: the pre-write
config can decode the post-write signal into garbage rather than failing.
Also fixes a -1 password sentinel truncated to 32 bits by a ternary, which made
that detect report a password that was never supplied.
Measured on a T5577 across psk1, fsk2a and direct/nrz: three consecutive dumps
agree field for field, against a baseline where psk1 corrupted 22 of 24.
Co-Authored-By: Claude Opus 5 (1M context)
Send a synchronous zero-length packet after CDC responses whose length is
an exact multiple of the endpoint packet size, preventing oversized host
reads from remaining pending.
# Updates
1. Updated `MEGACASH` vendor name from `Bank Mega` to `PT Bank Mega Tbk` *which is the vendor's full name*.
-r&y.
Signed-off-by: ry4000 <154689120+ry4000@users.noreply.github.com>
# Updates
1. Updated `Fermax` AID to reflect the parent company's name/country and DESFire PACS product.
Signed-off-by: ry4000 <154689120+ry4000@users.noreply.github.com>
# Updates
1. Changed `type` from `e-amusement` to `arcade` for:
- Bandai Namco Passport
- Konami e-amusement pass
- Sega Aime
- Taito NESiCA
2. Updated `description` to include the full name and `(AIC)` annotation to note that this information only applies to the Amusement IC Card variants as opposed to MFC/ICODE SLI/MFC/MFU, respectively.
-r&y.
Signed-off-by: ry4000 <154689120+ry4000@users.noreply.github.com>