From 4400c0bc76203adb9a4c874e1708b80ce26cb41e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rodrigo=20P=C3=A9rez?= Date: Sun, 15 Mar 2026 00:12:47 -0300 Subject: [PATCH] fix: bridge 9990 routing for parrot (ECHO) Expand _make_echo_bridges to add MASTER entries with ON activation triggers, matching legacy make_bridges behavior. Add missing in-band signalling call in MASTER datagram handler so voice terminators activate bridge entries for subsequent transmissions. --- .../twisted_adapters/udp_hbp.py | 8 +++++++ src/adn_server/main.py | 23 +++++++++++++++---- 2 files changed, 26 insertions(+), 5 deletions(-) diff --git a/src/adn_server/infrastructure/twisted_adapters/udp_hbp.py b/src/adn_server/infrastructure/twisted_adapters/udp_hbp.py index c1386ce..f0b80a3 100644 --- a/src/adn_server/infrastructure/twisted_adapters/udp_hbp.py +++ b/src/adn_server/infrastructure/twisted_adapters/udp_hbp.py @@ -468,6 +468,14 @@ class HBPProtocol(DatagramProtocol): self._system, _peer_id, _rf_src, _dst_id, _seq, _slot, _call_type, _frame_type, _dtype_vseq, _stream_id, _data, ) + if ( + _frame_type == HBPF_DATA_SYNC + and _dtype_vseq == HBPF_SLT_VTERM + and _slot in self.STATUS + and self.STATUS[_slot].get("RX_TYPE") != HBPF_SLT_VTERM + and self._on_in_band_signalling + ): + self._on_in_band_signalling(self._system, _slot, _dst_id, pkt_time) if _slot in self.STATUS: self.STATUS[_slot]["RX_PEER"] = _peer_id self.STATUS[_slot]["RX_SEQ"] = _seq diff --git a/src/adn_server/main.py b/src/adn_server/main.py index c9caf47..5046671 100644 --- a/src/adn_server/main.py +++ b/src/adn_server/main.py @@ -74,16 +74,17 @@ class ReportSenderAdapter(ReportSender): self._factory.send_bridge_event(event) -def _make_echo_bridges() -> dict: - """Initial BRIDGES for ECHO peer (legacy make_bridges 9990).""" +def _make_echo_bridges(config: dict) -> dict: + """Initial BRIDGES for ECHO peer (legacy make_bridges 9990 + MASTER expansion).""" now = time.time() timeout_sec = 2 * 60 - return { + tgid_b = bytes_3(9990) + bridges: dict = { "9990": [ { "SYSTEM": "ECHO", "TS": 2, - "TGID": bytes_3(9990), + "TGID": tgid_b, "ACTIVE": True, "TIMEOUT": timeout_sec, "TO_TYPE": "NONE", @@ -94,6 +95,18 @@ def _make_echo_bridges() -> dict: } ] } + systems_cfg = config.get("SYSTEMS", {}) + for _system, sys_cfg in systems_cfg.items(): + if sys_cfg.get("MODE") != "MASTER": + continue + _tmout = float(sys_cfg.get("DEFAULT_UA_TIMER", 10)) + ts1 = any(e["SYSTEM"] == _system and e["TS"] == 1 for e in bridges["9990"]) + ts2 = any(e["SYSTEM"] == _system and e["TS"] == 2 for e in bridges["9990"]) + if not ts1: + bridges["9990"].append({"SYSTEM": _system, "TS": 1, "TGID": tgid_b, "ACTIVE": False, "TIMEOUT": _tmout * 60, "TO_TYPE": "ON", "OFF": [], "ON": [tgid_b], "RESET": [], "TIMER": now}) + if not ts2: + bridges["9990"].append({"SYSTEM": _system, "TS": 2, "TGID": tgid_b, "ACTIVE": False, "TIMEOUT": _tmout * 60, "TO_TYPE": "ON", "OFF": [], "ON": [tgid_b], "RESET": [], "TIMER": now}) + return bridges def _looping_errback(logger: logging.Logger, failure): @@ -156,7 +169,7 @@ def main() -> None: bridge_router = InMemoryBridgeRouter() systems_cfg = config.get("SYSTEMS", {}) if "ECHO" in systems_cfg and systems_cfg.get("ECHO", {}).get("MODE") == "PEER": - bridge_router.set_bridges(_make_echo_bridges()) + bridge_router.set_bridges(_make_echo_bridges(config)) else: bridge_router.set_bridges({})