Overlay Talker Alias in repeated DMRD bursts so WPSD/MMDVMHost can display
aliases on RX, buffer TA from OBP voice, and inject the template at VHEAD
when the source sends no TA.
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.