feat(radio): adaptive LBT — scale CAD retries to current LoRa config

The CAD pre-TX loop previously ran up to 10 retries with a fixed 10 ms
sleep — roughly one max-length packet only at SF7/BW500. At SF10/BW125
the 100 ms total was ~4% of one packet; at SF12/BW125 LBT was a no-op.

Now the per-retry sleep is sized to one time-on-air of an assumed-peer
80-byte packet under the active config, cached on RadioContext and
recomputed on every SET_CONFIG. Retries scale as
clamp(floor(BUDGET/T)+1, 1, 10) with BUDGET=2.5 s, so fast configs
still get up to 10 retries while SF11/12 degrade to single-CAD-and-bail
(logged at config-apply). Sleeps are jittered ±20% per iteration to
decorrelate simultaneously-backing-off contenders.

The ToA math, CR→{1..4} mapping, retry-count derivation, and jitter
helper live in a pure src/lbt.rs module so they're host-testable via
DONGLORA_HOST_TEST=1 cargo test (13 tests).

Validated on-device: 20 iterations of the AI Bot test flow that
previously saw ~2 ChannelBusy errors now see zero at the same SF/BW.
This commit is contained in:
swaits committed 2026-04-25 20:15:44 -06:00
1 parent 23ddc15557
commit d262abe853
6 files changed
+370 -21

No files matched your search

Generated
+5
View File
@@ -1733,6 +1733,7 @@ dependencies = [
[[package]]
name = "lora-modulation"
version = "0.1.5"
source = "git+https://github.com/swaits/lora-rs.git?branch=fix%2Fsx126x-busy-race#f9ebb303a7029cbc3f19f0760ae164946000b152"
dependencies = [
"defmt 0.3.100",
]
@@ -1740,6 +1741,7 @@ dependencies = [
[[package]]
name = "lora-phy"
version = "3.0.2-alpha"
source = "git+https://github.com/swaits/lora-rs.git?branch=fix%2Fsx126x-busy-race#f9ebb303a7029cbc3f19f0760ae164946000b152"
dependencies = [
"defmt 0.3.100",
"document-features",
@@ -1753,6 +1755,7 @@ dependencies = [
[[package]]
name = "lorawan"
version = "0.9.1"
source = "git+https://github.com/swaits/lora-rs.git?branch=fix%2Fsx126x-busy-race#f9ebb303a7029cbc3f19f0760ae164946000b152"
dependencies = [
"aes",
"cmac",
@@ -1764,6 +1767,7 @@ dependencies = [
[[package]]
name = "lorawan-device"
version = "0.12.2"
source = "git+https://github.com/swaits/lora-rs.git?branch=fix%2Fsx126x-busy-race#f9ebb303a7029cbc3f19f0760ae164946000b152"
dependencies = [
"defmt 0.3.100",
"document-features",
@@ -1778,6 +1782,7 @@ dependencies = [
[[package]]
name = "lorawan-macros"
version = "0.1.0"
source = "git+https://github.com/swaits/lora-rs.git?branch=fix%2Fsx126x-busy-race#f9ebb303a7029cbc3f19f0760ae164946000b152"
dependencies = [
"proc-macro2",
"quote",