Research: WiFi AP selection algorithm — cross-platform findings + roadmap for price/bandwidth-aware steering
I maintainer di solito rispondono entro 1 giorno
Nessuno ha ancora preso questa issue.
Valutazione
- Difficoltà
- 5/5
- Tempo stimato
- Più di una settimana
- Idoneità per principianti
- 25/100
- Tipo di issue
- Funzionalità
- Chiarezza
- Abbastanza chiara
- Stato di attività
- Tranquilla
- Stack tecnologico
- go
- Ambito
- networking
Direzione di ricerca
Start by reading PR #235 for the existing vendor IE discovery and scoring implementation, then review #241 for the identity dependency. The issue lays out four roadmap phases but names no implementation files or tests; first clarify which phase is intended. Done would mean an agreed scope and implementation for that phase, respecting its listed dependencies.
Scritto dal modello di indicizzazione a partire dal testo della issue.
Descrizione
Background
PR #235 implements vendor IE-based AP identification and a scoring algorithm that helps TollGate routers prefer nearby TollGate APs over regular APs. During review, the initial score boost (+200) was flagged as potentially too aggressive.
We conducted a cross-platform analysis of how every major OS and enterprise WiFi system handles AP switching based on signal strength. This issue documents those findings and lays out a roadmap for evolving the scoring algorithm toward price/bandwidth-aware AP selection.
Cross-Platform WiFi Roaming Research
Platform Thresholds
| Platform | Roam Trigger | Candidate Hysteresis | Source |
|---|---|---|---|
| macOS (Apple silicon + Intel) | -75 dBm | 12 dB stronger | Apple Platform Deployment |
| iOS / iPadOS / visionOS | -70 dBm | 8 dB (active) / 12 dB (idle) | Same |
| Android (AOSP ThroughputScorer) | Entry: -80/-77 dBm; Sufficient: -73/-70 dBm | Band award: +40 (10% of max score) | AOSP Wi-Fi Network Selection |
| Windows | Not published (driver-controlled) | 5-level "Roaming Aggressiveness" | Microsoft Learn |
| wpa_supplicant (OpenWrt) | None (picks strongest) | 5 dBm tolerance for rate tie-break | wpa_supplicant scan.c |
Enterprise AP-Side Steering
| Vendor | Steering Trigger | Hysteresis | Method |
|---|---|---|---|
| Cisco 9800 | RSSI + data rate thresholds | Default 6 dB | 802.11v BTM + force disassociate |
| Aruba ClientMatch | Continuous RSSI monitoring | Delta: 5-10 dB; Sticky SNR: 18 dB | 802.11v BTM -> deauth fallback |
| UniFi | -65 dBm (5GHz), -70 dBm (6GHz) | N/A | BSS transition frames |
Key Insight
Every real-world system uses 6-12 dB hysteresis. The largest network-type preference in any open-source codebase is Android band award at +40 (~10% of max score). Our original +200 boost was 17-40x larger than any production WiFi steering system.
Immediate Fix (done in #235)
// Before:
if ni.IsTollGate { score += 200 }
// After (calibrated from research):
if ni.IsTollGate && ni.Signal > -75 { score += 15 }
Also reduced SSID prefix boost from +100 to +10 (easily spoofed, weak identifier).
Roadmap: Price/Bandwidth-Aware AP Selection
Phase 1: TollGate Identification and Memory
Maintain a local registry of discovered TollGates keyed by Nostr npub (stable, cryptographically verifiable) with secondary MAC/SSID:
TollGateRegistry entry:
identity:
npub: <nostr public key from vendor IE>
mac: <BSSID>
ssid: <broadcast SSID>
first_seen: <timestamp>
last_seen: <timestamp>
signal_history: [{timestamp, rssi, channel, band}, ...]
Storage: JSON at /etc/tollgate/known_tollgates.json, loaded at startup, updated on scan, persisted periodically.
Phase 2: Active Speed Testing
Signal strength correlates poorly with throughput. Probe candidate TollGates before committing:
SpeedTest record:
tollgate_npub: <npub>
rssi: <dBm at test time>
channel: <channel>
band: <2.4/5/6 GHz>
latency_ms: <ping to gateway IP>
throughput_mbps: <small file download timed>
price_per_step: <sat, from vendor IE>
step_size: <bytes or ms>
Approach: HTTP probe to backend /health endpoint on port 2121 (reachable pre-auth on NDS allow list). Append results to /etc/tollgate/speed_history.jsonl.
Phase 3: Advertised Price and Bandwidth
Extend vendor IE TLV structure with additional fields so TollGates can publish their terms:
Vendor IE TLV extensions:
Type 0x03: Price per step (uint32 satoshis)
Type 0x04: Step unit (enum: bytes/milliseconds)
Type 0x05: Step size (uint32)
Type 0x06: Advertised speed (uint32 Mbps, optional)
Constraint: Total IE body must stay 255 bytes (802.11 limit). Price/unit/size = 9 bytes, easily fits.
Scoring formula evolution:
score := ni.Signal
if ni.IsTollGate && ni.Signal > -75 {
score += 15 // base preference
if ni.PricePerStep < cheapestKnown { score += 20 }
if hist := registry.Lookup(ni.Npub); hist != nil {
score += min(hist.LastThroughputMbps / 5, 20)
}
}
This lets a TollGate decide: "TollGate A at -60 dBm costs 2 sat/MB at 50 Mbps; TollGate B at -55 dBm costs 5 sat/MB at unknown speed. Pick A."
Phase 4: Learning and Adaptation
Use speed history to build per-TollGate reliability models:
- Rolling average throughput at various RSSI levels
- Price accuracy (advertised vs actual)
- Uptime percentage
- Channel congestion by time of day
Weight historical measured performance higher than advertised specs (like Android ThroughputScorer uses predicted throughput as dominant factor).
Dependencies
| Phase | Requires | Status |
|---|---|---|
| 1 (registry) | Vendor IE (#235), NIP-06 identity (#241) | #235 ready, #241 in review |
| 2 (speed test) | HTTP probe to /health | Backend serves port 2121 |
| 3 (advertised data) | Vendor IE TLV extension | Protocol spec change needed |
| 4 (learning) | Speed history accumulation | Depends on Phases 2-3 |
Related
- #235 — Vendor IE discovery + scoring
- #241 — Unified identity (NIP-06 npub derivation)
- #271 — cdk-go evaluation
- Lingua principale
- Go
- Stelle
- 12
- Fork
- 14
- Merge medio
- 3g 20h
- PR unite (30g)
- 261
Preparare l'ambiente
- Nessun Dockerfile né file Docker Compose
- Nessun modello di pull request
- Leggi la guida per i contributori
Come iniziare
- Leggi tutta la issue e poi la guida ai contributi del progetto.
- Commenta sulla issue per dire che te ne occupi tu — evita che due persone facciano lo stesso lavoro.
- Fai un fork del repository e lavora su un branch.
- Apri una pull request che faccia riferimento al numero della issue.
Altre issue di OpenTollGate/tollgate-module-basic-go
-
Difficoltà 1/5 Meno di un'ora Idoneità per principianti 85/100
OpenTollGate/tollgate-module-basic-go#1159 ·
I maintainer di solito rispondono entro 1 giorno
-
Degraded-mode hygiene follow-ups: dead walletNotInitializedError() + main.go's startup log still over-promises mint recoveryForse già presa Una pull request collegata a questa issue è aperta o già unita. Aperta
Difficoltà 2/5 1-3 ore Idoneità per principianti 72/100
OpenTollGate/tollgate-module-basic-go#1135 · 1 commento ·
I maintainer di solito rispondono entro 1 giorno
-
setup_uhttpd_portal hardcodes the GUEST portal docroot to the TollGate path — the brand token cannot select a re-brand guest portalForse già presa Una pull request collegata a questa issue è aperta o già unita. Aperta
Difficoltà 2/5 1-3 ore Idoneità per principianti 72/100
OpenTollGate/tollgate-module-basic-go#1122 ·
I maintainer di solito rispondono entro 1 giorno
-
changelog: dependency-security sweep missing from [Unreleased] [Amperstrand fork #105 review debt]Aperta
Difficoltà 1/5 Meno di un'ora Idoneità per principianti 72/100
OpenTollGate/tollgate-module-basic-go#1055 · 1 commento ·
I maintainer di solito rispondono entro 1 giorno
-
Difficoltà 2/5 1-3 ore Idoneità per principianti 78/100
OpenTollGate/tollgate-module-basic-go#1027 · 1 commento ·
I maintainer di solito rispondono entro 1 giorno
Tutte le issue di OpenTollGate/tollgate-module-basic-go
Issue simili
-
Difficoltà 2/5 1-3 ore Idoneità per principianti 62/100
router-for-me/CLIProxyAPI#7209 ·
I maintainer di solito rispondono entro 1 giorno
-
Difficoltà 2/5 1-3 ore Idoneità per principianti 62/100
Azure/azure-storage-azcopy#3674 ·
I maintainer di solito rispondono entro 1 giorno
-
date_time, url_encode, html_escape, to_unix_time, contains_all and contains_any panic when called without argumentsForse già presa @antcybersec l’ha presa oggi. Aperta
Difficoltà 2/5 1-3 ore Idoneità per principianti 78/100
projectdiscovery/dsl#372 ·
I maintainer di solito rispondono entro 1 giorno
-
blocked-needs-validation
Difficoltà 2/5 1-3 ore Idoneità per principianti 62/100
projectcapsule/capsule#2265 ·
I maintainer di solito rispondono entro 1 giorno
-
Remove "Model catalog refresh unavailable" warning from OpenRouter agent runsForse già presa @superplanehq-integration l’ha presa oggi. Apertasuperplane
Difficoltà 2/5 1-3 ore Idoneità per principianti 75/100
superplanehq/superplane#9164 ·
I maintainer di solito rispondono entro 1 giorno