Files
client-rs/CHANGELOG.md
T
swaits 6937ad47ba 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.
2026-04-22 09:45:38 -06:00

114 lines
5.1 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Changelog
## 1.0.0-alpha.1 — 2026-04-21
### Breaking
- **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
### Fixed
- **`connect()` no longer falls through from mux to USB serial.** If a mux
socket file exists, `connect(None, timeout)` and `try_connect(timeout)` now
commit to the mux and return an error if the mux is unreachable — instead of
silently bypassing it and grabbing the USB port directly. This prevents a
race condition where a client could steal the serial port from the mux during
reconnect. Callers with explicit `port = Some(...)` are unaffected.
## 0.2.0 — 2026-04-07
### Features
- **Ping-on-connect validation** — all connect functions automatically ping the
device after connecting and reject non-DongLoRa devices within 200ms. No more
accidentally talking LoRa protocol to an Arduino.
- **`try_connect(timeout)`** — non-blocking alternative to `connect()`. Returns
an error immediately if no DongLoRa device is found instead of blocking
indefinitely.
- **USB-UART bridge chip fallback** — `find_port()` now detects boards using
CP2102, CH9102, CH340, or FT232R bridge chips (validated via ping).
- **Payload size validation** — `transmit()` rejects payloads exceeding 256
bytes with a clear error before hitting the wire.
- **`ErrorCode` implements `std::error::Error`** — usable in error chains.
### Breaking changes
- Wire-level tag constants (`CMD_TAG_*`, `RESP_TAG_*`, `ERROR_INVALID_CONFIG`)
removed from the top-level re-exports. Access them via
`donglora_client::protocol::*` if needed.
- `connect()` and friends now validate the device on connect. Code that
previously connected to non-DongLoRa serial devices will now get an error.
### Fixes
- Fixed repository URL in crate metadata.
- `drain_rx` no longer swallows the original error if timeout restore also fails.
- Removed dead `firmware/PROTOCOL.md` reference from docs.
## 0.1.0 — 2026-04-06
Initial release.
### Features
- High-level `Client<T>` with send/recv and command helpers (ping, set_config,
start_rx, stop_rx, transmit, get_config, get_mac, display_on, display_off)
- COBS wire framing via `ucobs` (matches firmware implementation)
- Auto-detection connection: TCP mux, Unix socket mux, direct USB serial
- Bounded RX packet buffering (256 packets, FIFO eviction)
- `FrameReader` accumulator for streaming byte sources
- USB device discovery by VID:PID with blocking wait
### Resilience
- Cross-platform timeout handling: `TimedOut` (Windows) and `WouldBlock`
(Linux/macOS) both treated as clean timeouts in `read_frame`
- `EINTR`/`Interrupted` signals retried automatically in `read_frame`
- `drain_rx` always restores the original timeout, even on I/O errors
- TCP mux connections use `connect_timeout` (bounded by caller's timeout)
- Mux sockets set both read and write timeouts
- `SerialTransport` tracks timeout accurately for save/restore
- Unexpected unsolicited frames logged via `tracing::warn` instead of silently
discarded