From 4f4123b5c15232777c0ae2dabfe20cb3ee3ccabc Mon Sep 17 00:00:00 2001 From: Joseph <162703152+josephnef@users.noreply.github.com> Date: Sun, 7 Jun 2026 22:00:59 +0300 Subject: [PATCH] Surface RX seq_num + TSF low on MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Both fields are already on the RX descriptor: `seq_num` is parsed at FrameParser.cpp:98, `tsfl` was one commented-out line at line 129. The FEC layer (#86 / #87) and any latency-measurement consumer want both visible; this is the data the chip already gives us. * src/FrameParser.h — add `uint32_t tsfl` to rx_pkt_attrib alongside the existing seq_num. * src/FrameParser.cpp — uncomment the TSFL parser: - /* pattrib.tsfl=(byte)GET_RX_STATUS_DESC_TSFL_8812(pdesc); */ + pattrib.tsfl = GET_RX_STATUS_DESC_TSFL_8812(pdesc); Drop the bogus `(byte)` cast — the macro reads all 32 bits of pdesc+20 as a u32, not a byte (verified against rtl8812a_recv.h). * demo/main.cpp — extend the printf with `seq=%u tsfl=%u`. Optional fields; PR #84's regex pattern in stream_rx.py / tun_p2p.py / corruption_analysis.py already tolerates the new fields via the same pass-through approach used for rssi/evm/snr (no Python-side change required to keep working). What this enables (out of scope for this PR — just data surfacing) * FEC RX side can dedup by chip-side seq before feeding the codec, so air-level retransmissions stop double-counting at the codec. * One-way latency measurement by diffing TSF against the host clock at TX time — a building block for the F5 TX-RPT goodput numbers and for any adaptive `--fec-overhead` loop. Verification * `cmake --build build -j` clean. * Default behaviour: lines now carry seq + tsfl fields; existing Python consumers (regexes are tolerant) keep working. tests/regress.py 4-cell matrix byte-identical. Co-Authored-By: Claude Opus 4.7 --- demo/main.cpp | 10 ++++++++-- src/FrameParser.cpp | 8 ++++++-- src/FrameParser.h | 6 ++++++ 3 files changed, 20 insertions(+), 4 deletions(-) diff --git a/demo/main.cpp b/demo/main.cpp index 1aa014f..1e65e2b 100644 --- a/demo/main.cpp +++ b/demo/main.cpp @@ -107,14 +107,20 @@ static void packetProcessor(const Packet &packet) { * source as the Tier-2 diagnostics — so a consumer like * corruption_analysis.py can correlate BER with link quality on a * per-frame basis instead of relying on aggregated statistics. */ + /* seq + tsfl: chip-side sequence number (12-bit u16) and TSF low + * (full 32-bit u32). Consumers can dedup by seq and measure + * one-way latency by diffing TSF against the host clock. Optional + * fields — pre-#84 regex consumers tolerate them via the same + * pass-through pattern. */ printf("rate=%u len=%zu crc_err=%u icv_err=%u " - "rssi=%d,%d evm=%d,%d snr=%d,%d body=", + "rssi=%d,%d evm=%d,%d snr=%d,%d seq=%u tsfl=%u body=", packet.RxAtrib.data_rate, packet.Data.size(), packet.RxAtrib.crc_err ? 1u : 0u, packet.RxAtrib.icv_err ? 1u : 0u, packet.RxAtrib.rssi[0], packet.RxAtrib.rssi[1], packet.RxAtrib.evm[0], packet.RxAtrib.evm[1], - packet.RxAtrib.snr[0], packet.RxAtrib.snr[1]); + packet.RxAtrib.snr[0], packet.RxAtrib.snr[1], + packet.RxAtrib.seq_num, packet.RxAtrib.tsfl); for (size_t i = 24; i < packet.Data.size(); ++i) printf("%02x", packet.Data[i]); printf("\n"); diff --git a/src/FrameParser.cpp b/src/FrameParser.cpp index 5a162ed..d4120e5 100644 --- a/src/FrameParser.cpp +++ b/src/FrameParser.cpp @@ -125,8 +125,12 @@ static rx_pkt_attrib rtl8812_query_rx_desc_status(uint8_t *pdesc) { * tools/precoder/seed_probe.py is the reliable path. */ pattrib.scrambler = (uint8_t)LE_BITS_TO_4BYTE(pdesc + 16, 9, 7); - /* Offset 20 */ - /* pattrib.tsfl=(byte)GET_RX_STATUS_DESC_TSFL_8812(pdesc); */ + /* Offset 20 — chip-side TSF low (32 bits). Surfaced via RxAtrib.tsfl + * for downstream latency measurement and dup-detection (see + * demo/main.cpp's line). The macro reads bits 0..31 + * of pdesc+20 (full 4-byte u32), not a byte — the original commented + * `(byte)` cast in master was a copy-paste from another field. */ + pattrib.tsfl = GET_RX_STATUS_DESC_TSFL_8812(pdesc); return pattrib; } diff --git a/src/FrameParser.h b/src/FrameParser.h index 280ad0a..f74f3c7 100644 --- a/src/FrameParser.h +++ b/src/FrameParser.h @@ -285,6 +285,12 @@ struct rx_pkt_attrib encrypt algorith */ bool crc_err; bool icv_err; + /* TSF low (4 bytes at RX-descriptor offset 20) — chip-side timestamp + * for the frame. With the seq_num just above it, a downstream layer + * can drop duplicates by seq and measure one-way latency by diffing + * the chip's TSF against its own wall clock. Populated by + * FrameParser; surfaced through demo/main.cpp's . */ + uint32_t tsfl; uint8_t data_rate; uint8_t bw; uint8_t stbc;