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.
Reload GLOBAL, REPORTS, ALIASES and SYSTEMS without full restart:
add/remove UDP listeners (OBP, GENERATOR expansion), update bind
addresses, preserve PEERS/STATS and active streams on unchanged ports.
Inject Talker Alias on HBP bridge/repeat via standalone DMRA packets
and embedded LC in forwarded DMRD voice (FLCO 4–7) for MMDVMHost/
DMRGateway. UTF-8 encoding (format 2) and LC/TA superframe alternation
for the full stream; clear embed state on VTERM.
When LOGGER.ENABLED is false, setup_logging attaches only a NullHandler
so legacy configs without the key keep current behavior. Document the
option in EN/ES configuration guides and example YAML templates.
Use a flat OBP STATUS dict like legacy routerOBP, iterate it in
stream_trimmer_loop, stop HBP STATUS[stream_id] writes, cap BCSQ log
dedup with a bounded deque, and sweep stale voice-announcement entries.
Add reopen_file_handlers() and register SIGUSR2 after logging setup in
main and parrot. Document create/postrotate/kill -USR2 in monitoring
guide (EN/ES). SIGUSR2 only reopens file handlers; does not reload YAML.
Skip options_config_for_system when static TS/timer fingerprint matches the last
successful RPTO apply to avoid log spam and redundant work.
Document why make_single_bridge must not rebuild 9990–9999 when the bridge
already exists: it drops the ECHO ACTIVE row and breaks the parrot path.
When BRIDGES[tg] existed without TS1/TS2 rows for a MASTER, make_static_tg
only updated existing rows and that hotspot never received traffic. Append
inactive legs like make_stat_bridge / legacy UA re-add.