# Changelog ## [2.0.1] - 2026-04-25 ### Fixed - **TUI quit no longer hangs on a misleading "updating DHT" screen.** The 2.0.0 migration to `iroh-gossip-rendezvous` removed the synchronous mainline-DHT publish that the old `Gossip::shutdown()` performed (rendezvous entries age out instead), but the TUI flow was unchanged: pressing `q` drew an "updating DHT…" overlay, awaited `swarm.shutdown()`, and only then restored the terminal — so the user sat on the stale message for as long as `endpoint.close()` took to flush in-flight connections. Restore the terminal the moment `q` is pressed, drop the overlay, and cap the graceful-shutdown wait at 2 s so a slow endpoint close can't stall the process. ## [2.0.0] - 2026-04-23 ### Breaking - **Partition-healing / DHT-rendezvous extracted to its own crate.** The 700+ lines of gossip-partition-healing logic in `src/gossip.rs` are now the `iroh-gossip-rendezvous` crate on crates.io (pinned here at `^0.1`). Any downstream code that reached into `bridge::gossip::*` for partition types needs to import from `iroh_gossip_rendezvous::*` instead. The normative protocol spec moved with the code — `dht-partition-healing.md` at the bridge root is now a pointer to the new crate's `PROTOCOL.md`. - **`iroh` and `iroh-gossip` bumped 0.97 → 0.98** (major; carries iroh's own breaking changes through to any bridge consumers that import from those crates transitively). ### Changed - Direct deps `mainline`, `sha2`, `zeroize` removed — all now reachable transitively via `iroh-gossip-rendezvous`. Closure is smaller and the rendezvous concern lives in exactly one place. - `donglora-client` version spec loosened `"1.0.0"` → `"1"`. Patch and minor releases of the client propagate on the next `cargo build` / `cargo install` without a bridge re-publish; already-released `donglora-client 1.0.1` (CH340K USB bridge support) is picked up automatically. ## [1.0.1] - 2026-04-22 ### Security - Bump both pinned `rand` versions past [RUSTSEC-2026-0097][adv] (`rand` is unsound with a custom `log::Log` impl that calls `rand::rng()` at trace/warn level and hits the 64 KB reseed path): - `rand 0.9.2` → `0.9.4` (fix `>= 0.9.3`). - `rand 0.8.5` → `0.8.6` (fix `>= 0.8.6`). The advisory is only reachable under a very narrow set of conditions (custom logger invoking `rand::rng()` during a reseed while emitting trace-level logs, or warn-level with a failed `getrandom`). We are not known to do that, but shipping the upgrade is the right call. [adv]: https://rustsec.org/advisories/RUSTSEC-2026-0097 ## [1.0.0] - 2026-04-22 ### Breaking - **Upgraded to `donglora-client` 1.0.0-alpha.1 (DongLoRa Protocol v2 wire protocol).** Wire-incompatible with 0.x firmware. Connect/config/TX/RX all go through the new async `Dongle` API. - **Radio loop is now a tokio task**, not a dedicated `std::thread`. Everything is async end-to-end. - **`[radio]` config schema changes:** - `tx_power` renamed to `tx_power_dbm` and is now a plain `i8` (no `"max"` keyword — v1.0 exposes a concrete dBm range via `GET_INFO`). - `cad` field removed — CAD is a per-TX flag in v1.0, not a config property. The `[tx]` section's `skip_cad` (default false) controls it. - Default `sync_word` changed `0x3444` → `0x1424` to match the `SX126x` register encoding of `MeshCore`'s private sync byte (`RADIOLIB_SX126X_SYNC_WORD_PRIVATE`). ### Added - **TX retry with backoff (new `[tx]` config section).** Every TX now runs through `Dongle::tx_with_retry`, which retries `TX_DONE(CHANNEL_BUSY)` and `ERR(EBUSY)` per spec `PROTOCOL.md §6.10` / §C.5.5. Defaults: 3 attempts, randomized 20–100 ms backoff, doubling up to 500 ms cap, 5 s per-attempt timeout. Configurable via `[tx]` keys `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 `↻` marker in yellow and an `N/M` attempt counter. Terminal TX failures render in red with `✗`. Post-retry success shows the final attempt count (`OK 2/3`). - **Stats: `tx_retries` and `tx_failures` counters.** Lifetime totals, surfaced in the `StatsSnapshot`. - **Measured airtime** from `TX_DONE` is now reported instead of a theoretical estimate, feeding the rate limiter with the real on-air duration. ### Removed - The explicit 2-second liveness ping loop in the radio thread. The `Dongle` now runs a 500 ms keepalive task internally, matching spec §3.4's 1 s inactivity window with 2× margin. ## [0.3.1] - 2026-04-07 ### Fixed - **Sticky mux reconnect.** Once the bridge connects via mux, all subsequent reconnects use mux-only mode (`connect_mux_auto`). Previously, each reconnect re-ran the full mux→USB fallback chain, which could steal the serial port from the mux during a brief disconnect. ## [0.3.0] - 2026-04-07 ### Changed - Upgraded to `donglora-client` 0.2: all connections now auto-validate via ping-on-connect, rejecting non-DongLoRa serial devices within 200ms. - Simplified connection logic — removed manual mux/serial fallback and manual ping; `donglora_client::connect()` handles the full fallback chain and validation internally. - Config negotiation detects mux vs serial via transport type instead of string comparison. ### Fixed - Repository and homepage URLs now point to `github.com/donglora/bridge` (was `swaits/donglora-bridge`). - README links updated to `donglora` GitHub org. ## [0.2.2] - 2026-04-06 ### Fixed - TUI now fits in 80-column terminals (was 86). ## [0.2.1] - 2026-04-06 ### Fixed - CI: removed stale sibling-clone step, added `libudev-dev` dependency, upgraded `actions/checkout` to v5 (Node.js 24). ## [0.2.0] - 2026-04-06 ### Added - Auto-detect connection mode: when no `port` is configured, the bridge now tries the mux daemon first and falls back to direct USB serial (`find_port()`) if the mux is unavailable. Previously it would retry the mux forever. ### Changed - Config negotiation on direct serial connections now pushes `SetConfig` with the desired radio config when it differs from the dongle's current config. On mux connections, the existing behavior (accept the mux's config) is unchanged. ## [0.1.0] - 2026-04-06 Initial release.