Match bridge_tables_with_active_source and to_target forward selection on
subscription rows; add parity tests vs legacy BRIDGES scan including OBP dedup.
Add opt-in REPORTS.MQTT with retained shared state and live voice_event
topics, topology static TG in v2 payloads, dashboard_state builder, and
SIGHUP reload.
Decouple bridge events from TCP send via a reactor-drained queue (50ms, 2048
events). Export peer connected_at in topology so monitor timers survive refresh.
SessionReplayer replays golden fixtures through DeterministicScenario;
add HBP group voice session, behavior tests, and dev CAPTURE scaffold.
Set pytest pythonpath so bare `pytest` finds tests.* imports.
Move Talker Alias / embedded LC and BRIDGES table lifecycle into
application/bridge/; BridgeUseCases remains the public facade with
dmrd_received and unit/private paths only.
Move shared TG/OBP helpers and legacy timer loops (rule_timer, trimmers,
bridge_reset, bridge_debug) into application/bridge/; BridgeUseCases keeps
the public facade via BridgeTimerMixin.
Introduce RuntimeContextHolder with ConfigProxy so main wiring keeps a stable
config view while SIGHUP reload builds a deep copy, applies reload_server_config,
then swaps the pointer only on success.
Inject ReportingUseCases into BridgeUseCases and centralize BRDG_EVENT
emission through _send_bridge_event; use reporting use cases for periodic
CONFIG/BRIDGE snapshots in main.
Stop renumbering DMRD sequence to 1..255 on replay; duplicate seq values
after ~15–30s caused MMDVMHost to drop voice while TX continued. Match
legacy playback.py (stream ID rewrite only).
Add TALKER_ALIAS_TEXT_FORMAT: single or comma-separated encodings for
embedded LC (e.g. utf8,iso8 for Motorola and Hytera). Example template
defaults to both formats; runtime default remains utf8 when omitted.
Extract corrected encode_emblc and TA embedded-LC wiring from domain into
infrastructure adapters. Inject DmrEmbeddedLcEncoder and TalkerAliasEmblcEncoder
from main.py so application layers stay free of infrastructure imports. Use the
fixed encoder for bridge group LC and pkt_gen as well as Talker Alias overlay.
- both: passthrough when source sends TA (DMRA or embedded voice), inject
template otherwise; OBP sources inject immediately at VHEAD
- Always rewrite destination group embedded LC on bridge forward (legacy
parity; fixes OBP TG mismatch packet loss introduced by TA branch)
- Fix dmr_utils3 encode_emblc index bug for lossless injected TA text
- Log decoded TA from voice; strict MMDVM DMRA wire layout
- chore: ruff per-file E402 ignore for main/parrot entrypoints
Popping STATUS[stream_id] on BCSQ (and forward-leg END,TX) destroyed live
stream state mid-call, causing repeated *CALL START* churn, a BCSQ storm and
GROUP_HANGTIME ping-pong on HBP masters that left receivers (MMDVMHost) with
only the voice header before the watchdog expired. Legacy hblink only records
_bcsq[tgid] and skips the quenched target; the stream entry survives until the
trimmer removes it by age. Emit a one-shot monitor END,TX and keep STATUS.
Clear stale OpenBridge TX chips in the monitor when BCSQ quenches a forward
leg or the source stream goes idle, using the same BRDG_EVENT format as legacy.
Two report paths passed eight format arguments into seven placeholders, so duration was silently dropped. Remove unused get_bridges() call in bridge_reset_loop.
Run routerHBP group controls before bridge scans, pass UDP receive time
into dmrd_received for rate/timeout parity with legacy, and set RX_START
on new HBP streams in the router. Talker Alias behaviour is unchanged.
Add idle (5s) and max (180s) recording timers, synthetic VTERM when the
hotspot ends without terminator, and non-blocking reactor playback.
Handle hotspot re-key mid-PTT without a second VHEAD and renumber playback
seq so bridge ingress does not drop frames. Restore prohibited static bridge
legs (TG 9990 ECHO) after bridge reset and options refresh.
Align OpenBridge group voice with bridge_master.routerOBP: use the legacy
RATE DROP formula, run loop control only from the second packet onward, and
send BCSQ once on loop loser instead of periodic retransmits.
Notify report clients immediately after SIGHUP reload, emit END events when
removing systems, and keep OPTIONS/TS1_STATIC/TS2_STATIC when merging YAML.