mirror of
https://github.com/liquidraver/ZephCore.git
synced 2026-10-14 10:37:16 +00:00
DESIGN.md is the reconciled high-level design after the 2026-09 restructure: system context, roles, build-time composition, layers and dependency rules (with the known exceptions), threading and event loop, end-to-end flows, cross-cutting concerns and the upstream alignment policy. docs/adr/ holds the nine decision records (ESP32 boot layout, S3 native USB, overlay precedence, BLE privacy, Zephyr main pin, SX126x duty cycle and RX-busy gating, adaptive contention window, storage backend, WiFi companion boards). ARCHITECTURE.md stays the detailed component reference and links both. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
1.9 KiB
1.9 KiB
ADR 0007 — Adaptive contention window instead of Arduino's static tx/rx delays
Status: accepted (recorded 2026-09-25; ZephCore-only)
Context
Replaces Arduino's static txdelay/rxdelay with three mechanisms:
- EMA-based flood delay factor: scales flood TX retransmit jitter adaptively based on local contention
history. Jitter is double-capped:
min(2000ms, 6·airtime)for repeaters — the airtime-scaled ceiling keeps SF7/narrow-BW configs from wasting time in oversized windows, while the absolute cap bounds per-hop latency in dense areas. Ring buffer holds 24 concurrent tracked retransmits (sized for ~50-neighbor hilltops). - Per-dupe reactive backoff: each heard duplicate of a pending TX packet delays transmission by
backoff_multiplier * airtimefrom NOW. Capped atmin(2000ms, 12·airtime)total reactive extension per packet. After the cap, CAD handles channel-busy detection like Arduino. - Initial-flood jitter (companion-only): companions don't forward floods (when
client_repeat=0) and use a fixed20..150mswindow for originated TX — small enough to feel responsive, large enough to avoid lockstep collisions with nearby repeaters. Passive flood tracking is disabled in that mode (no EMA warming needed). Whenclient_repeat=1, the EMA is warmed naturally via the forwarding path andgetRetransmitDelay()falls back to the same adaptive math as repeaters. - Direct packets: use minimal fixed jitter only (no adaptive scaling).
Decision
set backoff.multiplier X controls per-dupe delay (default 0.2; 0.0 disables reactive backoff). The old CLI
commands (txdelay, rxdelay, direct.txdelay) are accepted for prefs compatibility but ignored; get txdelay
shows the adaptive state.
Consequences
A divergence from upstream by design (memory acw-reactive-backoff); ports touching Mesh/Dispatcher timing
must keep it.