Files
swaits e81cb9dc20
CI / lint (push) Canceled after 0s
CI / test (3.10) (push) Canceled after 0s
CI / test (3.11) (push) Canceled after 0s
CI / test (3.12) (push) Canceled after 0s
CI / test (3.13) (push) Canceled after 0s
CI / publish (push) Canceled after 0s
chore: release 1.0.0
2026-04-22 09:56:05 -06:00

88 lines
3.8 KiB
Markdown
Raw Permalink 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 — 2026-04-22
### Breaking
- **Upgraded to the DongLoRa Protocol v2 wire format.** The 0.x line spoke the legacy
v0.1 protocol with hardcoded tag constants (`TAG_OK=4`, `TAG_ERROR=5`,
`CMD_TAG_SET_CONFIG=2`, …) that don't exist in v1.0. This release is
wire-incompatible with 0.x clients and firmware.
- **Pins `donglora>=1.0.0`** and uses its `donglora.frame` /
`donglora.events` / `donglora.commands` modules as the wire-level
backbone. No more in-package reimplementation of the wire protocol.
- **Structural rewrite** mirroring the Rust sibling
[`donglora-mux`](https://crates.io/crates/donglora-mux) one-to-one:
`donglora_mux/{daemon,intercept,session,tagmap}.py` replace the single
601-line `__init__.py`.
### Added
- **`TagMapper`** — per-command device-tag allocator. Enables concurrent
out-of-order command/response correlation for multi-client setups
(the v0.1-era single-oneshot-response slot is gone).
- **Full `§13.2` multi-client `SET_CONFIG` semantics** — tracks the
`(client_id, modulation)` lock owner. Cross-client calls synthesize:
- `OK(APPLIED / MINE, params)` when the caller owns the lock
(forwarded to dongle).
- `OK(ALREADY_MATCHED / OTHER, current)` when another client holds
the lock and the requested params byte-match.
- `OK(LOCKED_MISMATCH / OTHER, current)` when they differ; `current`
echoes the lock owner's actual modulation.
- Lock auto-releases when the owning client disconnects.
- **TX loopback fan-out (`§13.4`)** — on `TX_DONE(TRANSMITTED)` the mux
synthesizes an `RX` frame with `origin = LOCAL_LOOPBACK` and sends it
to every connected client except the transmitter.
- **Async `ERR(EFRAME)` fan-out** — if the dongle emits async framing
errors (tag 0), they're broadcast to all clients rather than swallowed.
- **Per-client TX cache** on `ClientSession` so the loopback fan-out
doesn't need the sender to re-buffer the payload.
- **Socket and serial file locking** (`fcntl.flock`) to prevent multiple
mux instances from fighting over the same dongle or socket path.
- **500 ms keepalive** matching `PROTOCOL.md §3.4` (2× margin on the
1 s inactivity timer). Replaces the 5 s cadence from 0.x.
- **Clean ^C / SIGTERM shutdown** — per-client handler tasks are tracked
and cancelled on shutdown, so blocked `reader.read()` calls no longer
pin the event loop open.
### Removed
- Every v0.1 wire constant and the inline `cobs` + raw `serial.Serial`
frame codec.
- The single `pending_response: asyncio.Future` slot (fundamentally
incompatible with v1.0's per-tag concurrency).
### Test coverage
- 28 tests (up from 11):
- `test_tagmap.py` (6) — tag allocator behaviour.
- `test_intercept.py` (13) — every branch of the `decide()` matrix,
including the `ALREADY_MATCHED` / `LOCKED_MISMATCH` synthesis paths.
- `test_multiclient.py` (9) — asyncio-driven daemon dispatch tests:
concurrent tag routing, `SET_CONFIG` lock installation, TX loopback
to peer clients, lock release on disconnect, unsolicited-frame drop.
## 0.2.0 — 2026-04-08
### Features
- **PyPI-ready metadata** — full classifiers, URLs, keywords, readme. Publishable
as `donglora-mux`.
- **Interception test suite** — 11 tests ported from the Rust mux covering
SetConfig locking, StartRx/StopRx reference counting, and passthrough
behaviour.
- **GitHub Actions CI** — ruff lint + format, pytest on Python 3.10–3.13, PyPI
publish on tag.
- **Strict ruff linting** — E, W, F, I, UP, B, C4, ARG, SIM, RUF rules.
### Fixes
- Fixed broken dependency path (`../../clients/python` → `../client-py`).
- Fixed dependency name (`donglora-python` → `donglora`).
- Applied `contextlib.suppress` where ruff/SIM105 flagged try-except-pass.
- Collapsed nested `if` per ruff/SIM102.
## 0.1.0 — 2026-04-06
Initial release.