feat!: bridge on DongLoRa Protocol v2 and async client

The 1.0 bridge running on the async Dongle API from donglora-client 1.0.0 and the Protocol v2 wire format.

* Radio loop is now a tokio task, not a dedicated std::thread. Everything is async end to end.

* [radio] config schema: tx_power renamed to tx_power_dbm (plain i8, no "max" keyword), cad field removed (CAD is a per-TX flag in v1.0), default sync_word changed 0x3444 to 0x1424 to match the SX126x register encoding of MeshCore private sync byte.

* TX retry with backoff (new [tx] config section). Every TX runs through Dongle::tx_with_retry, retrying TX_DONE(CHANNEL_BUSY) and ERR(EBUSY) per PROTOCOL.md §6.10 / §C.5.5. Defaults: 3 attempts, 20-100 ms randomized backoff, doubling to 500 ms cap, 5 s per-attempt timeout. Configurable via max_attempts, backoff_min_ms, backoff_max_ms, backoff_cap_ms, backoff_multiplier, per_attempt_timeout_secs.

* TUI packet log shows retry state: in-flight retries render with a cycle marker in yellow and an N/M attempt counter, terminal TX failures render in red, post-retry success shows final attempt count.

* Stats gain tx_retries and tx_failures counters surfaced in StatsSnapshot.

* Measured airtime from TX_DONE replaces the theoretical estimate, feeding the rate limiter with the real on-air duration.

* The explicit 2 s liveness ping loop is gone. The Dongle runs a 500 ms internal keepalive, matching spec §3.4 inactivity window with 2x margin.
This commit is contained in:
swaits committed 2026-04-22 09:48:01 -06:00
1 parent 030280791e
commit 0b9775c310
11 files changed
+1010 -669

No files matched your search

Generated
+63 -35
View File
@@ -906,7 +906,7 @@ dependencies = [
[[package]]
name = "donglora-bridge"
version = "0.3.1"
version = "1.0.0-alpha.1"
dependencies = [
"anyhow",
"blake3",
@@ -938,13 +938,22 @@ dependencies = [
[[package]]
name = "donglora-client"
version = "0.2.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "343d750fe1e5dad94d4b31e6dbbb05214b39e66f3c94a2ff2a29b0031ffd2826"
version = "1.0.0-alpha.1"
dependencies = [
"anyhow",
"serialport",
"donglora-protocol",
"rand 0.9.2",
"thiserror 2.0.18",
"tokio",
"tokio-serial",
"tokio-stream",
"tracing",
]
[[package]]
name = "donglora-protocol"
version = "0.1.0"
dependencies = [
"heapless 0.9.2",
"ucobs",
]
@@ -1398,6 +1407,15 @@ dependencies = [
"byteorder",
]
[[package]]
name = "hash32"
version = "0.3.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "47d60b12902ba28e2730cd37e95b8c9223af2808df9e902d4df49588d1470606"
dependencies = [
"byteorder",
]
[[package]]
name = "hashbrown"
version = "0.15.5"
@@ -1425,13 +1443,23 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "cdc6457c0eb62c71aac4bc17216026d8410337c4126773b9c5daba343f17964f"
dependencies = [
"atomic-polyfill",
"hash32",
"hash32 0.2.1",
"rustc_version",
"serde",
"spin 0.9.8",
"stable_deref_trait",
]
[[package]]
name = "heapless"
version = "0.9.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2af2455f757db2b292a9b1768c4b70186d443bcb3b316252d6b540aec1cd89ed"
dependencies = [
"hash32 0.3.1",
"stable_deref_trait",
]
[[package]]
name = "heck"
version = "0.5.0"
@@ -2190,26 +2218,6 @@ dependencies = [
"libc",
]
[[package]]
name = "libudev"
version = "0.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "78b324152da65df7bb95acfcaab55e3097ceaab02fb19b228a9eb74d55f135e0"
dependencies = [
"libc",
"libudev-sys",
]
[[package]]
name = "libudev-sys"
version = "0.1.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3c8469b4a23b962c1396b9b451dda50ef5b283e8dd309d69033475fa9b334324"
dependencies = [
"libc",
"pkg-config",
]
[[package]]
name = "line-clipping"
version = "0.3.7"
@@ -2375,6 +2383,19 @@ dependencies = [
"windows-sys 0.61.2",
]
[[package]]
name = "mio-serial"
version = "5.0.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "029e1f407e261176a983a6599c084efd322d9301028055c87174beac71397ba3"
dependencies = [
"log",
"mio",
"nix 0.29.0",
"serialport",
"winapi",
]
[[package]]
name = "moka"
version = "0.12.15"
@@ -3038,12 +3059,6 @@ dependencies = [
"spki",
]
[[package]]
name = "pkg-config"
version = "0.3.32"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7edddbd0b52d732b21ad9a5fab5c704c14cd949e5e9a1ec5929a24fded1b904c"
[[package]]
name = "plist"
version = "1.8.0"
@@ -3126,7 +3141,7 @@ dependencies = [
"cobs",
"embedded-io 0.4.0",
"embedded-io 0.6.1",
"heapless",
"heapless 0.7.17",
"postcard-derive",
"serde",
]
@@ -3775,7 +3790,6 @@ dependencies = [
"core-foundation",
"core-foundation-sys",
"io-kit-sys",
"libudev",
"mach2",
"nix 0.26.4",
"scopeguard",
@@ -4284,6 +4298,20 @@ dependencies = [
"tokio",
]
[[package]]
name = "tokio-serial"
version = "5.4.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "aa1d5427f11ba7c5e6384521cfd76f2d64572ff29f3f4f7aa0f496282923fdc8"
dependencies = [
"cfg-if",
"futures",
"log",
"mio-serial",
"serialport",
"tokio",
]
[[package]]
name = "tokio-stream"
version = "0.1.18"