Wi-Fi CSI chain selection: 8-chain health and missing-chain audit
By Wu Jun · Updated 2026-11-02 · Wi-Fi CSI, chain selection, GL-MT6000, MT7986, data quality · 6 min read
A reported 2 Tx x 4 Rx capture is often described as eight CSI chains. That does not mean the receiver behaves like eight equal, independent sensors. Chains may be missing, groups may be incomplete, and amplitude or temporal variability may differ. A parser that assumes eight valid records per group can silently mix missing data, duplicate chains or unintended fallbacks into an experiment.
This audit asks a narrow question using two public GL-MT6000 captures, a 10-minute primary capture and a 60-second comparison: are all eight tx/rx chains equally present, can RSSI/SNR select one, and can amplitude or temporal variance prove which chain is best? Both captures, the analysis script, CSVs, SVG figure and checksums are public [1] [2].
1. Results
| Check | Measured |
|---|---|
| Closed measurement groups | 7,609 |
| Groups with all eight tx/rx records | 6,714, or 88.238% |
Groups with only the four tx0 chains |
895, or 11.762% |
| Groups with complete 256-subcarrier, non-zero-I/Q records | 7,608 |
| Groups where RSSI is identical across all chains | 7,609 / 7,609 |
| Groups where SNR is identical across all chains | 7,609 / 7,609 |
| Per-chain temporal coefficient of variation | 0.104 to 0.623 |
Three conclusions follow:
- Eight-chain mode does not mean every measurement has eight chains. About 11.8% of closed groups contain only four.
- RSSI/SNR cannot rank individual chains in this capture. Both fields are identical across chains inside every group and describe the shared reception context.
- Low amplitude or low variance does not prove a better chain. Without a noise-only baseline, known motion and task ground truth, a quiet chain may be stable, insensitive or heavily attenuated.
- A chain ranking does not carry across sessions. The 60-second capture contains eight chains in all 347 groups, but its amplitude ranking is negatively correlated with the 10-minute capture; both the strongest-amplitude and lowest-CV chain change.
2. Presence and temporal variability
The left panel below shows each chain's presence across 7,609 closed groups. The right panel plots median group mean amplitude against temporal coefficient of variation. It is a diagnostic view, not a "best chain" leaderboard.
Figure 1: Chain presence and temporal variability. Colour distinguishes always-present and intermittent chains. The figure does not claim that a low-variance chain is the physically best one.
| Chain | Group presence | Median mean amplitude | Temporal CV |
|---|---|---|---|
tx0/rx0 |
7,609 | 945.632 | 0.149077 |
tx0/rx1 |
7,609 | 1,346.556 | 0.104246 |
tx0/rx2 |
7,609 | 1,000.199 | 0.191578 |
tx0/rx3 |
7,609 | 716.449 | 0.273735 |
tx1/rx0 |
6,714 | 313.300 | 0.622773 |
tx1/rx1 |
6,714 | 502.511 | 0.396518 |
tx1/rx2 |
6,714 | 1,147.028 | 0.172088 |
tx1/rx3 |
6,714 | 1,099.939 | 0.143339 |
tx0/rx1 has the lowest temporal CV and tx1/rx0 the highest, a difference of roughly six times.
That is not evidence that one is six times better. Motion can raise variance, while nulls and small
denominators can inflate CV. Amplitude also depends on automatic gain control, the RF path and the
firmware's CSI extraction.
3. A second session rejects a fixed "best chain"
The project also publishes a 60-second de-identified demo capture with SHA-256
41c35d9d23e5c03ddd34ae97617e772fecdb55e8545156181828b060605a87a6. The same script gives:
| Metric | 10-minute capture | 60-second capture |
|---|---|---|
| Closed groups | 7,609 | 347 |
| Eight-chain groups | 6,714 | 347 |
| Four-chain groups | 895 | 0 |
| Highest median mean amplitude | tx0/rx1 |
tx1/rx1 |
| Lowest temporal CV | tx0/rx1 |
tx0/rx0 |
| Cross-capture amplitude correlation | -0.415472 | |
| Cross-capture CV correlation | -0.225449 |
This is not a small rank change. tx1/rx0 moves from amplitude rank 8 in the 10-minute capture
to rank 2 in the 60-second capture. Median RSSI also changes from -31 dBm to -39 dBm. Two captures
from the same router and home are enough to reject a permanent "best chain" rule.
A more defensible workflow is:
- run a short independent calibration for every deployment or new session;
- store chain completeness, RSSI/SNR context, amplitude distribution and temporal CV as session metadata;
- apply a fixed-chain choice only within its calibration session and revalidate it on a new session;
- choose a chain by downstream task metrics, not amplitude or CV alone.
4. Reproduction
The analysis uses only Python's standard library and NumPy. It does not require SciPy or Matplotlib.
- Walk the outer container:
<float64 ts><uint16 len><payload>. - Read the 24-byte CSI header and preserve
tx,rx,rssi,snr,subcarrier_countandchain_info. - Close a measurement group only when bit 15 of
chain_infois set. - Accept only 256-subcarrier pairs with non-zero I/Q.
- Compute
sqrt(I^2 + Q^2)per subcarrier, then the mean across the record. - Compute temporal CV as
standard deviation / meanof group mean amplitude for each chain. - Save presence, amplitude distribution and temporal variability per tx/rx pair.
Run:
python3 analyze_csi_chain_health.py csi-10m.anon.bin \
--summary summary.json \
--csv chain_metrics.csv \
--img csi-chain-health.svg
Downloads:
- Analysis script
- Chain metrics CSV
- Cross-session comparison CSV
- Machine-readable summary
- README and limits
- SHA-256 checksums
The source capture SHA-256 is 527466ceb8b5f835e55ff348f02808736b947db39e7baac1f34e375de146a440.
5. A chain gate that does not silently change identity
A practical system should use an explicit gate rather than a hidden fixed chain:
for each closed group:
verify expected chain records are unique
reject incomplete 256-subcarrier records
preserve raw chain IDs
compute per-chain health metrics on a calibration window
if task requires a fixed chain:
select it from calibration, not from the test window
else:
expose chain-specific features and missingness
if no chain passes the gate:
return unavailable
The calibration and test windows must remain separate. Selecting the most stable-looking chain on the test capture and then reporting accuracy on that same capture leaks information. Use empty-room, still-person or known-motion sessions for calibration, then evaluate on unseen sessions.
Keeping only complete eight-chain groups would discard 895 of 7,609 closed groups in this capture.
Do not silently fill a missing tx1 chain with tx0/rx0. Either label eight-chain and four-chain
groups explicitly or expose chain missingness as a downstream feature.
6. Why RSSI/SNR did not help
In this capture, RSSI and SNR are identical across all chains within each closed group. They can describe the overall reception context but cannot answer which of the eight chains is cleaner. That need not hold for every vendor or firmware, so a replicator must verify field semantics rather than assume each row contains a per-chain RSSI.
The same caution applies to selecting a chain from CSV columns that look correlated. First establish whether the field changes with chain identity; then discuss statistical selection.
7. What these captures cannot prove
- It cannot prove that
tx0/rx1is the physically or experimentally best chain. - It cannot treat temporal CV as a noise floor without a controlled empty-room baseline.
- It cannot map
tx0/tx1orrx0torx3directly to physical antenna positions. - It cannot transfer this device's ordering to another firmware, room, client or new session.
- It cannot establish respiration, fall, occupancy or identity accuracy.
A useful chain-selection result must report completeness, missingness patterns, calibration, cross-session stability and downstream task metrics. Without that evidence, the defensible conclusion is "the chains are not equivalent and need explicit gating", not "chain X is best".
8. Next measurements
The next study needs three repeatable conditions: a noise-only empty-room baseline, a known sinusoidal or mechanical control, and human sessions across postures and distances. Hold channel, bandwidth, client, offered load and firmware fixed, and retain raw chain identity. Only then can chain selection become a measured experimental decision rather than a heuristic.
References and data sources
Every external claim carries a source and an evidence grade (grading scheme). Grade E marks first-party, reproducible measurements from this project.
- Grade E · first-party measurement
This project's 10-minute raw capture (57,293 records / 600.0 s, SHA-256 00373f83…95e2)
Router CSI Lab · 2026
okwujun.pw/en/datasets/ · verified: Reassembled chunks verified byte-identical (2026-10-11) · The local raw master has SHA-256 00373f83…95e2; the public de-identified derivative has SHA-256 527466ce…a440. They must not be confused. - Grade E · first-party measurement
Router CSI Toolkit — capture/analysis/watchdog scripts (MIT, public repository)
Router CSI Lab · 2026
github.com/jjjwu/router-csi-toolkit · verified: GitHub API verified the public repository, capture-quality preflight, successful CI and the v0.1.3 release on 2026-11-02; the archive SHA-256 is 59f144c0…adea7 · The public repository includes a dependency-free capture preflight; the browser checker uses the same container definition and evidence boundaries. - Grade A · standard/review
WiFi Sensing with Channel State Information: A Survey
W. Ma, W. Zhou, X. Wang · ACM Computing Surveys · 2019
doi:10.1145/3310194 · citations 857 · verified: CrossRef API, 2026-10-11 · The field's most-cited CSI sensing survey (857 citations, verified via CrossRef). - Grade B · peer-reviewed
Tool release: gathering 802.11n traces with channel state information
D. Halperin, W. Hu, A. Sheth, D. Wetherall · ACM SIGCOMM Computer Communication Review · 2011
doi:10.1145/1925861.1925870 · citations 1713 · verified: CrossRef API, 2026-10-11 · The formal paper for the Intel 5300 CSI Tool (1713 citations) — the widely reproduced starting point for CSI capture. - Grade C · official docs
openwrt/mt76 — mac80211 driver for MediaTek Wi-Fi chipsets
OpenWrt project / MediaTek
github.com/openwrt/mt76 · verified: GitHub API 2026-10-11 (stars 890, last push 2026-10-08) · Upstream of the open-source mt76 driver used here; the CSI patch is applied on top of this codebase.