2 Commits
Author SHA1 Message Date
Cort BuffingtonandClaude Opus 4.8 ad4e0ed13a reporting: mirror dashboard normalization to dmrlink3 (Step 3)
Ports hblink3's dashboard-reporting overhaul to dmrlink3's IPSC path so the
two converge (plan: ~/development/dashboard-reporting-normalization.md):

- Granular peer events: a centralized reconciliation sweep in both the master
  and peer maintenance loops (report_maintenance) diffs currently-connected
  peers vs the last-reported set and emits send_peer connected/disconnected
  deltas only on change -- the dashboard reflects membership immediately
  instead of waiting for the periodic full push. (The single master link-state,
  in PEER mode, continues to ride the snapshot.)

- Demote the full push: reporting_loop now calls periodic_push, which re-pushes
  the full config+bridge snapshot only every REPORT_RESYNC_SECONDS (60s) as a
  reconciliation safety net and sends a tiny {'type':'ping'} heartbeat on the
  other ticks. Idle feed stops re-serializing full state every REPORT_INTERVAL.

- Ping-loss quality metric (PING_LOSS): detects a peer/master that STAYS
  CONNECTED but loses keepalives (lossy link -> choppy audio). One uniform
  gap-inference path serves both roles -- MASTER mode observes peers'
  MASTER_ALIVE_REQs, PEER mode observes the master's/peers' *_ALIVE_REPLYs to
  our requests. IPSC's cadence is known (ALIVE_TIMER) so no self-calibration is
  needed (unlike hblink3). A gap beyond the keepalive-timeout horizon is treated
  as a session lapse (reconnect), not loss. Sliding window pruned to
  PING_LOSS_WINDOW minutes; dashboard flags the row gold at >= PING_LOSS_WARN%.

Config: PING_LOSS_WINDOW / PING_LOSS_WARN added to GLOBAL (optional, defaults).
Dashboard: backend applies peer deltas + ignores the ping heartbeat; frontend
renders "N% ping loss" and golds the radio id. Tests: TestPeerEvents +
TestPingLoss (73 pass). Verified live over real sockets (peer delta fired,
heartbeat/resync split confirmed, PING_LOSS climbed to 30% under a lossy peer)
and deployed to the live dmrlink3 services clean.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-12 10:00:33 -05:00
Cort BuffingtonandClaude Sonnet 4.6 b41e3f13b6 Add test suite: 49 unit tests for IPSC protocol and bridge routing
tests/helpers.py       — MockDatagramTransport, config factories, GV packet builder
tests/test_protocol.py — registration, de-reg, keepalive, peer-list unicast,
                         timeslot detection (the TS_CALL_MSK bug fix), unknown opcodes
tests/test_bridge.py   — forwarding, packet rewriting (peer-id, TGID, TS, burst-type),
                         per-TS call_start tracking, Talker Alias seq_id churn immunity,
                         contention handling (hangtime, TRUNKS bypass)
tests/fake_ipsc_peer.py — standalone asyncio tool for live integration testing;
                         registers with dmrlink3, sends keepalives, supports --auto-call

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-26 13:53:54 -05:00