feat!: Protocol v2 client rewrite with Dongle/Session model

The full 1.0 client surface, matching the protocol v2 wire definitions from donglora-protocol 1.0.0.

* Public API is now async. The blocking Client<T: Transport> is replaced by Dongle (from donglora_client::connect / connect_with / ConnectOptions).

* src/client.rs and src/codec.rs are removed in favor of src/dongle.rs (high-level surface), src/session.rs (per-client tag/slot state), src/retry.rs (RetryPolicy + tx_with_retry), src/errors.rs (thiserror-based ClientError / ClientResult). src/protocol.rs is replaced by direct donglora-protocol imports.

* Transport is now tokio-serial for USB and tokio::net::{UnixStream, TcpStream} for mux, replacing the blocking serial + shim model.

* Dongle::tx_with_retry(data, &RetryPolicy) implements PROTOCOL.md §6.10 randomized backoff for CHANNEL_BUSY / EBUSY, returning a TxOutcome with per-attempt trace.

* Background keepalive task pings every 500 ms on host idle, tracking the 1 s inactivity timeout from §3.4 with 2x margin. Disable via ConnectOptions::keepalive(false).

* Auto-recovery from ERR(ENOTCONFIGURED): the Dongle caches the last SET_CONFIG and silently re-applies on session drop, retrying once.

* Error taxonomy switches from anyhow to thiserror. Transport-level conditions (Timeout, TransportClosed, ReaderExited, BadFrame) are first-class.

* Examples rewritten for the async API: examples/ping.rs, examples/tx.rs, examples/rx.rs all target the MeshCore US preset (910.525 MHz / BW 62.5 / SF 7 / CR 4/5 / sync 0x1424 / 20 dBm). examples/common/mod.rs holds the shared helper.

* tests/vectors.rs gains protocol-level roundtrip coverage anchored to the published donglora-protocol 1.0.0 types.
This commit is contained in:
swaits committed 2026-04-22 09:45:38 -06:00
1 parent 055fc76b87
commit 6937ad47ba
19 files changed
+2897 -1605

No files matched your search

+42 -6
View File
@@ -1,13 +1,49 @@
# Changelog
## Unreleased
## 1.0.0-alpha.1 — 2026-04-21
### Fixed
### Breaking
- Once a mux connection succeeds, all future `connect()` calls in the same
process only try the mux. `connect()` blocks waiting for the socket to
reappear; `try_connect()` returns an error so callers can retry with backoff.
Prevents clients from stealing the serial port during mux restarts.
- **Migrated to the DongLoRa Protocol v2 wire format.** All message
types, tag correlation, and framing now follow `PROTOCOL.md` v1.0. This is a
wire-incompatible break with 0.x clients and firmware. `donglora-client` now
depends on `donglora-protocol` for the normative type definitions.
- **Full tokio-async rewrite.** Public API is `async`; the blocking
`Client<T: Transport>` is gone. Replace with `Dongle` from
`donglora_client::connect()` (or the new `ConnectOptions` builder +
`connect_with`). Serial I/O is now `tokio-serial`; mux connections are
`tokio::net::UnixStream` / `tokio::net::TcpStream`.
- **`thiserror`-based error taxonomy.** `anyhow::Result` on public APIs
is replaced by `donglora_client::ClientResult<T> = Result<T, ClientError>`.
Variants mirror the Python client's `DongloraError` hierarchy plus
transport-level conditions (`Timeout`, `TransportClosed`, `ReaderExited`,
`BadFrame`).
### Added
- **`Dongle::tx_with_retry(data, &RetryPolicy)`** — randomized backoff +
exponential retry for `TX_DONE(CHANNEL_BUSY)` and `ERR(EBUSY)`, per spec
§6.10. Returns a [`TxOutcome`] capturing every per-attempt result so callers
(the bridge TUI especially) can display retry state.
- **Auto-recovery from `ERR(ENOTCONFIGURED)`.** `Dongle` caches the applied
config from the most recent `SET_CONFIG` and silently re-applies it + retries
once when the firmware's inactivity timer expires mid-session.
- **Background keepalive task.** Spawned at connect time, pings the device
every 500 ms when the host has been idle, tracking the 1 s inactivity window
from spec §3.4 with 2× safety margin. Disable via
`ConnectOptions::keepalive(false)`.
- **Rich `RxPayload` metadata.** Bridge-relevant fields (`rssi_tenths_dbm`,
`snr_tenths_db`, `freq_err_hz`, `timestamp_us`, `crc_valid`,
`packets_dropped`, `origin`) are surfaced directly from the wire.
- **New examples:** `cargo run --example tx` / `--example rx` alongside the
existing `ping`, all using the MeshCore US preset
(910.525 MHz / BW 62.5 / SF 7 / CR 4/5 / sync 0x1424 / 20 dBm).
### Removed
- The `Client<T>`, `Response`, `RadioConfig`, `Bandwidth`, and `TX_POWER_MAX`
types. `Modulation` / `LoRaConfig` / `LoRaBandwidth` (re-exported from
`donglora-protocol`) replace them.
## 0.2.1 — 2026-04-07