Files

10784 lines
406 KiB
Python

#!/usr/bin/env python3
import argparse
import base64
import hashlib
import json
import math
import os
import selectors
from collections import deque
import queue
import secrets
import shutil
import socket
import sys
import threading
import time
import traceback
import urllib.parse
import uuid
from typing import IO, Any, Callable, Dict, List, Optional, Set, Tuple
import RNS
APP_NAMESPACE = "qortal-hub"
PRESENCE_ASPECT = "presence"
PRESENCE_VERSION = "v1"
IDENTITY_FILENAME = "presence-bridge.identity"
_state_lock = threading.RLock()
_reticulum = None
_identity = None
_destination = None
_announce_handler = None
_known_peers: Dict[str, Any] = {}
_candidate_peers: Dict[str, Dict[str, Any]] = {}
_verified_overlay_peers: Dict[str, Dict[str, Any]] = {}
_overlay_peer_failures: Dict[str, Dict[str, Any]] = {}
# Outbound peers we chose for our presence overlay fanout.
_active_overlay_neighbors: Dict[str, float] = {}
# Inbound peers that chose us. They are included in publish fanout too, but
# have their own cap so inbound reciprocity is not blocked by outbound fill.
_inbound_overlay_neighbors: Dict[str, float] = {}
# Per-peer metadata: last_seen_inbound, last_send_ok, last_request_path_at, ts_seed_until (epoch seconds).
_peer_lifecycle: Dict[str, Dict[str, Any]] = {}
# Recent presence senders (destination hash hex, lowercased) for recall retries on publish.
_recent_presence_senders: "deque[str]" = deque(maxlen=128)
_last_presence_wire: Optional[bytes] = None
_last_transport_state: Optional[Dict[str, Any]] = None
_transport_monitor_thread: Optional[threading.Thread] = None
_rns_callback_scheduler_monitor_thread: Optional[threading.Thread] = None
_MAX_ENCRYPTED_WIRE_BYTES = int(getattr(RNS.Packet, "ENCRYPTED_MDU", RNS.Packet.MDU))
# Grep logs for this string to confirm the rebuilt script is running (sync with GC_RETICULUM_WIRE_BUILD_MARKER in group-call-wire-reticulum.ts).
PRESENCE_BRIDGE_BUILD = "wire394-reticulum-binary-audio-v1"
# Peer cache: must match TS base58 in electron/src/presence.ts (Qortal alphabet).
_BASE58_ALPHABET = "123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz"
_BASE58_MAP = {c: i for i, c in enumerate(_BASE58_ALPHABET)}
# Lifecycle / path nudge (see reticulum presence plan).
_PEER_STALE_SECONDS = 4 * 3600
_PEER_TS_SEED_LEASE_SECONDS = 300
_MAX_KNOWN_PEERS = 256
_REQUEST_PATH_COOLDOWN_SECONDS = 30.0
_MAX_PATH_NUDGES_PER_PUBLISH = 8
_NO_VERIFIED_PEERS_ANNOUNCE_COOLDOWN_SECONDS = 2 * 60
# Extra RNS announce while verified overlay peer count is below this (same cooldown as legacy "no peers" path).
_MIN_VERIFIED_OVERLAY_PEERS_BEFORE_SKIP_EXTRA_ANNOUNCE = 3
_KR_MISMATCH_LOGGED: set[str] = set()
_OVERLAY_MAX_OUTBOUND_NEIGHBORS = 12
_OVERLAY_MAX_INBOUND_NEIGHBORS = 8
_OVERLAY_BOOTSTRAP_MAX_OUTBOUND_NEIGHBORS = _OVERLAY_MAX_OUTBOUND_NEIGHBORS
_OVERLAY_MIN_HEALTHY_FANOUT = 8
_OVERLAY_NEIGHBOR_GRACE_SECONDS = 90.0
_CANDIDATE_PROOF_WINDOW_SECONDS = 90.0
_CANDIDATE_FAILURE_LIMIT = 2
_OVERLAY_DEFAULT_HOPS = 4
_OVERLAY_LINK_PATH_REQUEST_COOLDOWN_SECONDS = 5.0
_OVERLAY_LINK_PATH_AWAIT_SECONDS = 0.35
_OVERLAY_LINK_FAILURE_SUPPRESS_LIMIT = 2
_OVERLAY_LINK_FAILURE_SUPPRESS_SECONDS = 3 * 60.0
_OVERLAY_LINK_TIMEOUT_RECENT_ACTIVITY_GRACE_SECONDS = 30.0
_OVERLAY_MAX_TOTAL_LINKS = _OVERLAY_MAX_OUTBOUND_NEIGHBORS + _OVERLAY_MAX_INBOUND_NEIGHBORS + 4
_OVERLAY_UNESTABLISHED_LINK_TIMEOUT_SECONDS = 15.0
_OVERLAY_PENDING_UNESTABLISHED_LIMIT = 4
_PRESENCE_BRIDGE_VERBOSE_LOGS = (
os.environ.get("QORTAL_PRESENCE_BRIDGE_VERBOSE_LOGS", "").strip().lower()
in ("1", "true", "yes", "on")
)
# Presence heartbeats are expected every 25s and TS expires sessions after 95s.
# Keep overlay links a little longer than that, but do not trust a link forever
# when no inbound Qortal overlay traffic arrives after the remote app exits.
_OVERLAY_LINK_RX_IDLE_TIMEOUT_SECONDS = 95.0
_CALL_RELAY_DEDUP_TTL_SECONDS = 90.0
_CALL_RELAY_DEDUP_MAX = 4096
_call_relay_dedup: Dict[str, float] = {}
_call_relay_dedup_last_log_at: float = 0.0
_call_relay_dedup_suppressed_since_log: int = 0
_QCHAT_FILE_LINK_OPEN_PATH_AWAIT_SECONDS = 8.0
_QCHAT_FILE_LINK_MAX_OPEN_ATTEMPTS = 4
_QCHAT_FILE_LINK_RETRY_DELAY_SECONDS = 2.0
# Inbound RNS.Link: classify overlay vs audio by first JSON packet; if none, default to overlay.
_INBOUND_LINK_CLASSIFY_TIMEOUT_SEC = 5.0
_pending_inbound_classify_link_ids: Set[int] = set()
_inbound_classify_timers: Dict[int, threading.Timer] = {}
# RNS Destination.announce: once after authenticated local presence activity
# (PRESENCE_ANNOUNCE, or PRESENCE_HEARTBEAT after bridge recovery), then every
# RNS_ANNOUNCE_INTERVAL_SEC while session active; cancel on PRESENCE_OFFLINE / stop.
RNS_ANNOUNCE_INTERVAL_SEC = 15 * 60
_rns_auth_announced: bool = False
_rns_periodic_announce_timer: Optional[threading.Timer] = None
_last_no_verified_peers_announce_at: float = 0.0
def qortal_base58_decode(s: str) -> bytes:
"""Decode Qortal Base58 (same algorithm as presence.ts base58Decode)."""
if not isinstance(s, str) or not s:
raise ValueError("empty")
bytes_acc = [0]
for ch in s:
if ch not in _BASE58_MAP:
raise ValueError(f"invalid Base58 char: {ch!r}")
carry = _BASE58_MAP[ch]
for j in range(len(bytes_acc)):
carry += bytes_acc[j] * 58
bytes_acc[j] = carry & 0xFF
carry >>= 8
while carry > 0:
bytes_acc.append(carry & 0xFF)
carry >>= 8
# Leading '1's → leading zero bytes (after decode loop, before reverse)
idx = 0
while idx < len(s) and s[idx] == "1":
bytes_acc.append(0)
idx += 1
return bytes(bytes_acc[::-1])
def _normalize_json_numbers(obj: Any) -> Any:
"""Match Node JSON.stringify: whole-number floats become ints (no '.0' suffix)."""
if isinstance(obj, float):
if obj.is_integer():
return int(obj)
return obj
if isinstance(obj, dict):
return {k: _normalize_json_numbers(v) for k, v in obj.items()}
if isinstance(obj, list):
return [_normalize_json_numbers(v) for v in obj]
return obj
def _call_wire_json_bytes(out: Dict[str, Any]) -> bytes:
"""Compact UTF-8 JSON aligned with Electron wire size checks in group-call-wire-reticulum.ts."""
return json.dumps(
out,
separators=(",", ":"),
ensure_ascii=False,
allow_nan=False,
).encode("utf-8")
_GROUP_AUDIO_WIRE_TYPE = "GCA"
_GROUP_AUDIO_HEARTBEAT_WIRE_TYPE = "GAC"
_GROUP_AUDIO_BINARY_MAGIC = b"QGAU"
_GROUP_AUDIO_BINARY_VERSION = 1
_GROUP_AUDIO_BINARY_HEADER_BYTES = 9
_audio_links_by_id: Dict[str, Dict[str, Any]] = {}
_audio_link_ids_by_object: Dict[int, str] = {}
_outgoing_audio_link_id_by_peer_hash: Dict[str, str] = {}
_active_audio_link_id_by_peer_hash: Dict[str, str] = {}
_audio_link_desired_by_peer_hash: Dict[str, Dict[str, Any]] = {}
_overlay_links_by_id: Dict[str, Dict[str, Any]] = {}
_overlay_link_ids_by_object: Dict[int, str] = {}
_active_overlay_link_id_by_peer_hash: Dict[str, str] = {}
_qchat_file_links_by_id: Dict[str, Dict[str, Any]] = {}
_qchat_file_link_ids_by_object: Dict[int, str] = {}
_outgoing_qchat_file_link_id_by_peer_hash: Dict[str, str] = {}
_incoming_unified_peer_hash_by_object: Dict[int, str] = {}
_qchat_file_accepts_by_peer: Dict[str, Dict[str, Any]] = {}
_qchat_file_pending_sends_by_transfer: Dict[str, Dict[str, Any]] = {}
_QCHAT_FILE_PROGRESS_MIN_INTERVAL_SECONDS = 0.5
_QCHAT_FILE_PROGRESS_MIN_DELTA = 0.005
_QCHAT_FILE_CHUNK_SIZE = (1024 * 1024) - 1
_QCHAT_FILE_PARALLEL_LINKS = 1
_QCHAT_FILE_SUCCESS_LINK_CLOSE_GRACE_SECONDS = 15.0
_QCHAT_FILE_CHUNK_ACK_TIMEOUT_SECONDS = 90.0
_TRANSPORT_MONITOR_INTERVAL_SECONDS = 5.0
_OVERLAY_PENDING_PACKET_LIMIT = 24
# Binary audio IPC (fd 3 parent→child, fd 4 child→parent). Must match electron/src/reticulum-audio-ipc.ts.
# Diagnostics: grep logs for "target=reticulum-audio-ipc" (fd open, parse, drops, first bytes).
_AUDIO_IPC_LOG = "target=reticulum-audio-ipc"
AUDIO_MAGIC = b"QAUD"
AUDIO_VERSION = 2
AUDIO_HEADER_BYTES = 9
AUDIO_MAX_BODY = 65536
AUDIO_MAX_FRAMES = 32
AUDIO_MAX_PAYLOAD = 8192
AUDIO_MAX_LINK_ID_LEN = 36
AUDIO_MAX_ROOM_ID_LEN = 255
AUDIO_MAX_HASH_LEN = 128
_CMD_QUEUE_MAX = 256
_AUDIO_DECODED_QUEUE_MAX = 96
_JSON_RESP_OUT_QUEUE_MAX = 512
_JSON_EVENT_OUT_QUEUE_MAX = 2048
_AUDIO_BINARY_OUT_QUEUE_MAX = 128
_AUDIO_BATCH_STALE_SECONDS = 0.75
_AUDIO_OUTBOUND_DEADLINE_SECONDS = 0.32
_AUDIO_DATA_PLANE_STALE_MS = 160
_AUDIO_DATA_PLANE_MAX_ROUTES = 128
_AUDIO_MIN_BATCHES_PER_EXECUTOR_PASS = 2
_AUDIO_MAX_BATCHES_PER_EXECUTOR_PASS = 16
_AUDIO_BACKLOG_BATCH_STEP = 2
_AUDIO_BACKLOG_CMD_TIMEOUT_SECONDS = 0.005
_AUDIO_QUEUE_STATE_MIN_INTERVAL_SECONDS = 0.5
_BRIDGE_PRESSURE_LOG_INTERVAL_SECONDS = 5.0
_BRIDGE_PRESSURE_RNS_GAP_THRESHOLD_MS = 1000.0
_PRESENCE_PRESSURE_LOG_INTERVAL_SECONDS = 10.0
_CALLBACK_SLOW_LOG_THRESHOLD_MS = 100.0
_CALLBACK_SLOW_LOG_MIN_INTERVAL_SECONDS = 5.0
_PACKET_PATH_IDLE_REQUEST_COOLDOWN_SECONDS = 5.0
_PACKET_PATH_ACTIVE_REQUEST_COOLDOWN_SECONDS = 0.75
_PACKET_PATH_FRESH_SECONDS = 3.0
_PACKET_PATH_RECENT_FAILURE_SECONDS = 2.0
_PACKET_PATH_AWAIT_SECONDS = 0.12
_PACKET_PATH_IDLE_AWAIT_SECONDS = 0.02
_AUDIO_LINK_OPEN_PATH_AWAIT_SECONDS = 2.0
_AUDIO_LINK_ESTABLISH_TIMEOUT_SECONDS = 12.0
_AUDIO_LINK_MAX_ESTABLISH_ATTEMPTS = 4
_AUDIO_LINK_RETRY_MIN_SECONDS = 1.0
_AUDIO_LINK_RETRY_MAX_SECONDS = 20.0
_PACKET_PATH_WARMING_TIMEOUTS_BEFORE_FAILING = 2
_PACKET_PATH_INBOUND_FRESH_SECONDS = 3.0
_PACKET_PATH_POLL_INTERVAL_SECONDS = 0.01
_SCHEDULER_AUDIO_SHARDS = 4
_SCHEDULER_SLOW_TASK_LOG_THRESHOLD_MS = 80.0
_SCHEDULER_QUEUE_MAX_BY_LANE: Dict[str, int] = {
"control-send": 256,
"link-management": 128,
"path-management": 128,
"file-transfer": 64,
}
for _audio_shard in range(_SCHEDULER_AUDIO_SHARDS):
_SCHEDULER_QUEUE_MAX_BY_LANE[f"audio-send-{_audio_shard}"] = 64
_shutdown = threading.Event()
_json_resp_queue: "queue.Queue[Optional[Dict[str, Any]]]" = queue.Queue(
maxsize=_JSON_RESP_OUT_QUEUE_MAX
)
_json_event_queue: "queue.Queue[Optional[Dict[str, Any]]]" = queue.Queue(
maxsize=_JSON_EVENT_OUT_QUEUE_MAX
)
_audio_binary_out_queue: "queue.Queue[Optional[bytes]]" = queue.Queue(
maxsize=_AUDIO_BINARY_OUT_QUEUE_MAX
)
_cmd_queue_bounded: "queue.Queue[Optional[Dict[str, Any]]]" = queue.Queue(
maxsize=_CMD_QUEUE_MAX
)
_audio_decoded_queue: "queue.Queue[Optional[list]]" = queue.Queue(
maxsize=_AUDIO_DECODED_QUEUE_MAX
)
_scheduler_queues: Dict[str, "queue.Queue[Optional[Tuple[float, str, Callable[..., Any], tuple, dict]]]"] = {}
_scheduler_threads: list[threading.Thread] = []
_scheduler_stats: Dict[str, Dict[str, Any]] = {}
_rns_wake_read_fd: Optional[int] = None
_rns_wake_write_fd: Optional[int] = None
if os.name != "nt":
try:
_rns_wake_read_fd, _rns_wake_write_fd = os.pipe()
os.set_blocking(_rns_wake_read_fd, False)
os.set_blocking(_rns_wake_write_fd, False)
except OSError:
_rns_wake_read_fd = None
_rns_wake_write_fd = None
_audio_in_fd: Optional[int] = None
_audio_drops_ingress = 0
_audio_drops_json_out = 0
_audio_drops_binary_out = 0
_audio_stale_drops = 0
_audio_packet_send_failures = 0
_audio_packet_path_requests = 0
_audio_packet_path_resolutions = 0
_audio_packet_path_timeouts = 0
_audio_packet_fresh_sends = 0
_audio_packet_stale_sends = 0
_audio_packet_unknown_sends = 0
_audio_deadline_drops = 0
_audio_decoded_queue_evict_oldest = 0
_audio_decoded_queue_drop_newest = 0
_audio_fd3_decoded_age_ms_max = 0.0
_audio_decoded_queue_dwell_ms_max = 0.0
_audio_rns_send_duration_ms_max = 0.0
_audio_packet_path_check_ms_max = 0.0
_audio_executor_loop_gap_ms_max = 0.0
_audio_executor_gap_while_queued_ms_max = 0.0
_audio_executor_audio_pass_ms_max = 0.0
_audio_process_batch_ms_max = 0.0
_audio_process_batch_frames_max = 0
_audio_rns_send_slow_count = 0
_audio_executor_stall_count = 0
_audio_executor_command_ms_max = 0.0
_audio_executor_command_while_queued_ms_max = 0.0
_audio_executor_command_slow_count = 0
_audio_rns_callback_scheduler_gap_ms_max = 0.0
_audio_rns_callback_scheduler_gap_ms_window = 0.0
_audio_rns_callback_scheduler_gap_over_100_count = 0
_audio_rns_callback_scheduler_gap_over_250_count = 0
_audio_rns_callback_scheduler_gap_over_500_count = 0
_audio_rns_callback_scheduler_gap_over_1000_count = 0
_audio_rns_raw_inbound_gap_ms_max = 0.0
_audio_rns_raw_inbound_gap_ms_window = 0.0
_audio_rns_raw_inbound_gap_over_80_count = 0
_audio_rns_raw_inbound_gap_over_160_count = 0
_audio_rns_raw_inbound_gap_over_320_count = 0
_audio_rns_raw_inbound_gap_over_640_count = 0
_audio_rns_raw_inbound_gap_over_1000_count = 0
_audio_rns_raw_inbound_to_link_receive_ms_max = 0.0
_audio_rns_raw_inbound_to_link_receive_over_80_count = 0
_audio_rns_raw_inbound_to_link_receive_over_160_count = 0
_audio_rns_raw_inbound_to_link_receive_over_320_count = 0
_audio_rns_raw_inbound_to_link_receive_over_640_count = 0
_audio_rns_raw_inbound_to_link_receive_over_1000_count = 0
_audio_rns_raw_inbound_to_link_receive_samples = 0
_audio_rns_raw_inbound_interface_last = ""
_audio_rns_raw_inbound_interface_worst = ""
_audio_rns_shared_frame_gap_ms_max = 0.0
_audio_rns_shared_frame_gap_ms_window = 0.0
_audio_rns_shared_frame_gap_over_80_count = 0
_audio_rns_shared_frame_gap_over_160_count = 0
_audio_rns_shared_frame_gap_over_320_count = 0
_audio_rns_shared_frame_gap_over_640_count = 0
_audio_rns_shared_frame_gap_over_1000_count = 0
_audio_rns_shared_frame_to_transport_inbound_ms_max = 0.0
_audio_rns_shared_frame_to_transport_inbound_over_80_count = 0
_audio_rns_shared_frame_to_transport_inbound_over_160_count = 0
_audio_rns_shared_frame_to_transport_inbound_over_320_count = 0
_audio_rns_shared_frame_to_transport_inbound_over_640_count = 0
_audio_rns_shared_frame_to_transport_inbound_over_1000_count = 0
_audio_rns_shared_frame_to_transport_inbound_samples = 0
_audio_rns_shared_frame_interface_last = ""
_audio_rns_shared_frame_interface_worst = ""
_audio_media_route_stats: Dict[str, Dict[str, Any]] = {}
_audio_link_receive_probe_by_packet_id: Dict[int, Dict[str, Any]] = {}
_audio_rns_raw_inbound_probe_by_packet_hash: Dict[bytes, Dict[str, Any]] = {}
_audio_rns_raw_inbound_last_wall_ms_by_destination_hash: Dict[str, int] = {}
_audio_rns_shared_frame_probe_by_packet_hash: Dict[bytes, Dict[str, Any]] = {}
_audio_rns_shared_frame_last_wall_ms_by_destination_hash: Dict[str, int] = {}
_rns_link_receive_probe_installed = False
_rns_transport_inbound_probe_installed = False
_rns_shared_frame_probe_installed = False
_rns_shared_rpc_failure_guard_installed = False
_rns_shared_rpc_failure_last_log_by_method: Dict[str, float] = {}
_rns_link_receive_probe_context = threading.local()
_AUDIO_MEDIA_ROUTE_STATS_MAX = 64
_AUDIO_LINK_RECEIVE_PROBE_MAX = 2048
_AUDIO_RNS_RAW_INBOUND_PROBE_MAX = 4096
_AUDIO_RNS_SHARED_FRAME_PROBE_MAX = 4096
_AUDIO_ROUTE_GAP_BUCKETS_MS = (80, 160, 320, 640, 1000)
_AUDIO_RNS_CALLBACK_SCHEDULER_MONITOR_INTERVAL_SECONDS = 0.05
_AUDIO_SLOW_RNS_SEND_LOG_THRESHOLD_MS = 40.0
_AUDIO_TIMING_DELAY_LOG_THRESHOLD_MS = 80.0
_AUDIO_TIMING_GAP_LOG_THRESHOLD_MS = 320.0
_AUDIO_TIMING_LOG_THROTTLE_SECONDS = 2.0
_AUDIO_PATH_PRESSURE_LOG_INTERVAL_MS = 5000
_AUDIO_EXECUTOR_STALL_LOG_THRESHOLD_MS = 120.0
_AUDIO_PROCESS_BATCH_LOG_THRESHOLD_MS = 80.0
_AUDIO_EXECUTOR_COMMAND_LOG_THRESHOLD_MS = 80.0
_audio_queue_state_last_emit = 0.0
_audio_queue_state_dirty = False
_bridge_pressure_last_log_at = 0.0
_rns_interface_pressure_last_log_at = 0.0
_RNS_INTERFACE_PRESSURE_LOG_INTERVAL_SECONDS = 15.0
_presence_pressure_window_started_at = time.monotonic()
_presence_pressure_counts: Dict[str, int] = {}
_callback_slow_last_log_by_name: Dict[str, float] = {}
_audio_timing_anomaly_log_last_by_key: Dict[str, float] = {}
_audio_fd3_parse_last_wall_ms_by_route: Dict[str, int] = {}
# One-shot narrowing logs (grep target=reticulum-audio-ipc stage=…)
_audio_ipc_fd3_first_batch_ok_logged = False
_audio_ipc_rns_first_send_ok_logged = False
_audio_ipc_fd4_first_chunk_logged = False
_audio_data_plane_lock = threading.RLock()
_audio_data_plane_server_thread: Optional[threading.Thread] = None
_audio_data_plane_socket: Optional[socket.socket] = None
_audio_data_plane_endpoint = ""
_audio_data_plane_token = ""
_audio_data_plane_routes_by_address: Dict[str, Dict[str, Any]] = {}
_audio_data_plane_clients: Dict[int, socket.socket] = {}
_call_media_path_state: Dict[str, Dict[str, Any]] = {}
# Compact group-call control on call aspect (see electron/src/group-call-wire-reticulum.ts).
_GROUP_CALL_WIRE_TYPES = frozenset(
{
"GA",
"GAC",
"GJ",
"GL",
"GH",
"GK",
"GK0",
"GK1",
"GQ",
"GQ0",
"GQ1",
"GT",
"GT0",
"GT1",
"GR",
"GR0",
"GR1",
"GO",
"GO0",
"GO1",
"GE",
"GE0",
"GE1",
"GF",
"GI",
"GX",
}
)
_AUDIO_LINK_WIRE_TYPES = frozenset(
{_GROUP_AUDIO_HEARTBEAT_WIRE_TYPE}
)
def _queue_json_event_line(frame: Dict[str, Any]) -> None:
global _audio_drops_json_out
try:
_json_event_queue.put_nowait(frame)
except queue.Full:
_audio_drops_json_out += 1
_mark_audio_queue_state_dirty()
if _audio_drops_json_out % 200 == 1:
log(
f"[presence_bridge] json_event_queue full drops={_audio_drops_json_out}"
)
def _queue_json_resp_line(frame: Dict[str, Any]) -> None:
while not _shutdown.is_set():
try:
_json_resp_queue.put(frame, timeout=0.05)
return
except queue.Full:
continue
def emit(frame: Dict[str, Any]) -> None:
_queue_json_event_line(frame)
def emit_resp(req_id: str, ok: bool, payload: Optional[Dict[str, Any]] = None, error: Optional[str] = None) -> None:
frame: Dict[str, Any] = {"type": "resp", "id": req_id, "ok": ok}
if payload is not None:
frame["payload"] = payload
if error is not None:
frame["error"] = error
_queue_json_resp_line(frame)
def emit_event(event: str, payload: Optional[Dict[str, Any]] = None) -> None:
frame: Dict[str, Any] = {"type": "event", "event": event}
if payload is not None:
frame["payload"] = payload
_queue_json_event_line(frame)
def _log_clock_time() -> str:
return time.strftime("%H:%M:%S", time.localtime())
def _mark_audio_queue_state_dirty() -> None:
global _audio_queue_state_dirty
_audio_queue_state_dirty = True
def _scheduler_stats_for_lane(lane: str) -> Dict[str, Any]:
stats = _scheduler_stats.get(lane)
if stats is not None:
return stats
stats = {
"lane": lane,
"queueMax": int(_SCHEDULER_QUEUE_MAX_BY_LANE.get(lane) or 0),
"queueDepth": 0,
"queueDepthHighWater": 0,
"droppedTasks": 0,
"completedTasks": 0,
"enqueuedTasks": 0,
"dwellMsMax": 0.0,
"busyMsMax": 0.0,
"slowTaskCount": 0,
"lastTask": "",
}
_scheduler_stats[lane] = stats
return stats
def _logical_scheduler_lane(lane: str) -> str:
if lane.startswith("audio-send-"):
return "audio-send"
return lane
def _scheduler_diagnostics() -> list:
with _state_lock:
out = []
for lane in sorted(_scheduler_stats.keys()):
stats = dict(_scheduler_stats_for_lane(lane))
q = _scheduler_queues.get(lane)
stats["queueDepth"] = q.qsize() if q is not None else int(stats.get("queueDepth") or 0)
stats["logicalLane"] = _logical_scheduler_lane(lane)
out.append(stats)
return out
def _format_bridge_pressure_counts(counts: Dict[str, int]) -> str:
if not counts:
return "none"
return ",".join(f"{key}:{value}" for key, value in sorted(counts.items()))
def _maybe_log_bridge_pressure(now: Optional[float] = None, force: bool = False) -> None:
global _bridge_pressure_last_log_at
global _audio_rns_callback_scheduler_gap_ms_window
global _audio_rns_raw_inbound_gap_ms_window
global _audio_rns_shared_frame_gap_ms_window
if now is None:
now = time.monotonic()
if not force and now - _bridge_pressure_last_log_at < _BRIDGE_PRESSURE_LOG_INTERVAL_SECONDS:
return
cmd_q = _cmd_queue_bounded.qsize()
resp_q = _json_resp_queue.qsize()
event_q = _json_event_queue.qsize()
lane_depths: Dict[str, int] = {}
slow_counts: Dict[str, int] = {}
with _state_lock:
lanes = set(_SCHEDULER_QUEUE_MAX_BY_LANE.keys()) | set(_scheduler_queues.keys()) | set(_scheduler_stats.keys())
for lane in lanes:
q = _scheduler_queues.get(lane)
lane_depths[lane] = q.qsize() if q is not None else 0
stats = _scheduler_stats.get(lane)
slow_count = int(stats.get("slowTaskCount") or 0) if stats is not None else 0
if slow_count > 0:
slow_counts[lane] = slow_count
overlay_links = len(_overlay_links_by_id)
audio_links = len(_audio_links_by_id)
file_links = len(_qchat_file_links_by_id)
rns_scheduler_gap_ms_max = float(_audio_rns_callback_scheduler_gap_ms_max or 0.0)
rns_raw_gap_ms_max = float(_audio_rns_raw_inbound_gap_ms_max or 0.0)
rns_shared_gap_ms_max = float(_audio_rns_shared_frame_gap_ms_max or 0.0)
rns_gap_ms_max = max(rns_scheduler_gap_ms_max, rns_raw_gap_ms_max, rns_shared_gap_ms_max)
rns_scheduler_gap_ms_window = float(_audio_rns_callback_scheduler_gap_ms_window or 0.0)
rns_raw_gap_ms_window = float(_audio_rns_raw_inbound_gap_ms_window or 0.0)
rns_shared_gap_ms_window = float(_audio_rns_shared_frame_gap_ms_window or 0.0)
rns_gap_ms_window = max(
rns_scheduler_gap_ms_window,
rns_raw_gap_ms_window,
rns_shared_gap_ms_window,
)
rns_gap_pressure = (
rns_gap_ms_window >= _BRIDGE_PRESSURE_RNS_GAP_THRESHOLD_MS
)
has_pressure = (
cmd_q > 0
or resp_q > 0
or event_q > 0
or any(depth > 0 for depth in lane_depths.values())
or file_links > 0
or rns_gap_pressure
)
if not force and not has_pressure:
return
_bridge_pressure_last_log_at = now
lanes_text = _format_bridge_pressure_counts(lane_depths)
slow_text = _format_bridge_pressure_counts(slow_counts)
log(
"[presence_bridge] bridge_pressure "
f"cmd_q={cmd_q} resp_q={resp_q} event_q={event_q} "
f"lanes={lanes_text} "
f"links=overlay:{overlay_links},audio:{audio_links},file:{file_links} "
f"scheduler_slow={slow_text} rns_gap_ms_window={int(rns_gap_ms_window)} "
f"rns_gap_ms_max={int(rns_gap_ms_max)} "
f"rns_gap_window_parts=scheduler:{int(rns_scheduler_gap_ms_window)},"
f"raw:{int(rns_raw_gap_ms_window)},shared:{int(rns_shared_gap_ms_window)} "
f"rns_gap_max_parts=scheduler:{int(rns_scheduler_gap_ms_max)},"
f"raw:{int(rns_raw_gap_ms_max)},shared:{int(rns_shared_gap_ms_max)}"
)
if rns_gap_ms_window >= _BRIDGE_PRESSURE_RNS_GAP_THRESHOLD_MS:
_maybe_log_rns_interface_pressure(
rns_gap_ms_window,
reason="bridge_pressure",
now=now,
)
_audio_rns_callback_scheduler_gap_ms_window = 0.0
_audio_rns_raw_inbound_gap_ms_window = 0.0
_audio_rns_shared_frame_gap_ms_window = 0.0
def _note_presence_pressure(kind: str, message_type: str = "") -> None:
global _presence_pressure_window_started_at, _presence_pressure_counts
try:
now = time.monotonic()
snapshot: Optional[Dict[str, int]] = None
elapsed = 0.0
with _state_lock:
key = str(kind or "").strip()
if key:
_presence_pressure_counts[key] = int(_presence_pressure_counts.get(key) or 0) + 1
type_key = str(message_type or "").strip()
if type_key:
safe_type = "".join(ch if ch.isalnum() or ch in ("_", "-") else "_" for ch in type_key)
_presence_pressure_counts[f"type:{safe_type}"] = int(
_presence_pressure_counts.get(f"type:{safe_type}") or 0
) + 1
elapsed = max(0.0, now - _presence_pressure_window_started_at)
if elapsed < _PRESENCE_PRESSURE_LOG_INTERVAL_SECONDS:
return
if _presence_pressure_counts:
snapshot = dict(_presence_pressure_counts)
_presence_pressure_counts = {}
_presence_pressure_window_started_at = now
overlay_links = len(_overlay_links_by_id)
audio_links = len(_audio_links_by_id)
file_links = len(_qchat_file_links_by_id)
known_peers = len(_known_peers)
verified_peers = len(_verified_overlay_peers)
candidates = len(_candidate_peers)
outbound_neighbors = len(_active_overlay_neighbors)
inbound_neighbors = len(_inbound_overlay_neighbors)
if not snapshot:
return
def count(name: str) -> int:
return int(snapshot.get(name) or 0)
source_total = count("source:hub") + count("source:overlay") + count("source:qchat_file")
presence_total = (
count("type:PRESENCE_ANNOUNCE")
+ count("type:PRESENCE_HEARTBEAT")
+ count("type:PRESENCE_OFFLINE")
)
decoded_total = presence_total + count("decoded:call") + count("decoded:group_call")
log(
"[presence_bridge] presence_pressure "
f"window_s={int(elapsed)} inbound={source_total} decoded={decoded_total} "
f"sources=hub:{count('source:hub')},overlay:{count('source:overlay')},qchat_file:{count('source:qchat_file')} "
f"presence=total:{presence_total},announce:{count('type:PRESENCE_ANNOUNCE')},"
f"heartbeat:{count('type:PRESENCE_HEARTBEAT')},offline:{count('type:PRESENCE_OFFLINE')} "
f"calls=dm:{count('decoded:call')},group:{count('decoded:group_call')} "
f"links=overlay:{overlay_links},audio:{audio_links},file:{file_links} "
f"peers=known:{known_peers},verified:{verified_peers},candidates:{candidates},"
f"outbound:{outbound_neighbors},inbound:{inbound_neighbors}"
)
except Exception:
return
def _callback_payload_label(raw: Any) -> str:
try:
if not isinstance(raw, (bytes, bytearray)):
return ""
data = bytes(raw)
if not data:
return ""
stripped = data.lstrip()
if stripped.startswith(b"{"):
try:
decoded = json.loads(data.decode("utf-8"))
if isinstance(decoded, dict):
label = decoded.get("t") or decoded.get("type")
return str(label or "")[:80]
except Exception:
return "json_decode_failed"
if _decode_group_audio_wire(data) is not None:
return "group_audio"
return "binary"
except Exception:
return ""
def _note_callback_duration(name: str, started_at: float, raw: Any = None) -> None:
try:
duration_ms = (time.monotonic() - started_at) * 1000.0
if duration_ms < _CALLBACK_SLOW_LOG_THRESHOLD_MS:
return
now = time.monotonic()
last_at = float(_callback_slow_last_log_by_name.get(name) or 0.0)
if now - last_at < _CALLBACK_SLOW_LOG_MIN_INTERVAL_SECONDS:
return
_callback_slow_last_log_by_name[name] = now
label = _callback_payload_label(raw)
log(
"[presence_bridge] callback_slow "
f"name={name} duration_ms={duration_ms:.1f}"
f"{(' type=' + label) if label else ''}"
)
except Exception:
return
def _note_scheduler_enqueue(lane: str) -> None:
with _state_lock:
stats = _scheduler_stats_for_lane(lane)
q = _scheduler_queues.get(lane)
depth = q.qsize() if q is not None else 0
stats["queueDepth"] = depth
stats["queueDepthHighWater"] = max(int(stats.get("queueDepthHighWater") or 0), depth)
stats["enqueuedTasks"] = int(stats.get("enqueuedTasks") or 0) + 1
_mark_audio_queue_state_dirty()
def _note_scheduler_drop(lane: str) -> None:
with _state_lock:
stats = _scheduler_stats_for_lane(lane)
stats["droppedTasks"] = int(stats.get("droppedTasks") or 0) + 1
_mark_audio_queue_state_dirty()
def _note_scheduler_complete(lane: str, name: str, queued_at: float, started_at: float) -> None:
duration_ms = max(0.0, (time.monotonic() - started_at) * 1000.0)
dwell_ms = max(0.0, (started_at - queued_at) * 1000.0)
with _state_lock:
stats = _scheduler_stats_for_lane(lane)
q = _scheduler_queues.get(lane)
stats["queueDepth"] = q.qsize() if q is not None else int(stats.get("queueDepth") or 0)
stats["completedTasks"] = int(stats.get("completedTasks") or 0) + 1
stats["dwellMsMax"] = max(float(stats.get("dwellMsMax") or 0.0), dwell_ms)
stats["busyMsMax"] = max(float(stats.get("busyMsMax") or 0.0), duration_ms)
stats["lastTask"] = str(name or "")[:80]
if duration_ms >= _SCHEDULER_SLOW_TASK_LOG_THRESHOLD_MS:
stats["slowTaskCount"] = int(stats.get("slowTaskCount") or 0) + 1
_mark_audio_queue_state_dirty()
if duration_ms >= _SCHEDULER_SLOW_TASK_LOG_THRESHOLD_MS:
log(
f"[presence_bridge] {_AUDIO_IPC_LOG} stage=scheduler-task-slow "
f"lane={lane} task={str(name or '')[:80]!r} duration_ms={duration_ms:.3f} "
f"dwell_ms={dwell_ms:.3f}"
)
def _enqueue_scheduler_task(
lane: str,
name: str,
fn: Callable[..., Any],
*args: Any,
drop_oldest: bool = False,
**kwargs: Any,
) -> bool:
q = _scheduler_queues.get(lane)
if q is None:
try:
fn(*args, **kwargs)
return True
except Exception as exc:
emit_event(
"error",
{
"code": "scheduler_direct_task_failed",
"message": str(exc),
"detail": traceback.format_exc(limit=3),
"lane": lane,
"task": name,
},
)
return False
item = (time.monotonic(), name, fn, args, kwargs)
try:
q.put_nowait(item)
_note_scheduler_enqueue(lane)
return True
except queue.Full:
if not drop_oldest:
_note_scheduler_drop(lane)
return False
try:
q.get_nowait()
_note_scheduler_drop(lane)
except queue.Empty:
pass
try:
q.put_nowait(item)
_note_scheduler_enqueue(lane)
return True
except queue.Full:
_note_scheduler_drop(lane)
return False
def _scheduler_worker_loop(lane: str) -> None:
q = _scheduler_queues[lane]
while not _shutdown.is_set():
item = q.get()
if item is None:
return
queued_at, name, fn, args, kwargs = item
started_at = time.monotonic()
try:
fn(*args, **kwargs)
except Exception as exc:
emit_event(
"error",
{
"code": "scheduler_task_failed",
"message": str(exc),
"detail": traceback.format_exc(limit=3),
"lane": lane,
"task": name,
},
)
finally:
_note_scheduler_complete(lane, name, queued_at, started_at)
_emit_audio_queue_state()
def _start_scheduler_workers() -> None:
if _scheduler_threads:
return
for lane, maxsize in _SCHEDULER_QUEUE_MAX_BY_LANE.items():
_scheduler_queues[lane] = queue.Queue(maxsize=max(1, int(maxsize)))
_scheduler_stats_for_lane(lane)
worker_count = 1
for worker_index in range(worker_count):
thread = threading.Thread(
target=_scheduler_worker_loop,
args=(lane,),
name=f"reticulum-{lane}-{worker_index}",
daemon=True,
)
thread.start()
_scheduler_threads.append(thread)
log(
"[presence_bridge] target=reticulum-scheduler started "
f"lanes={','.join(sorted(_SCHEDULER_QUEUE_MAX_BY_LANE.keys()))}"
)
def _stop_scheduler_workers() -> None:
for q in list(_scheduler_queues.values()):
try:
q.put_nowait(None)
except queue.Full:
try:
q.get_nowait()
q.put_nowait(None)
except Exception:
pass
for thread in list(_scheduler_threads):
thread.join(timeout=5.0)
def _audio_route_stats_key(
transport: str,
route_key: str,
peer_presence_hash: str = "",
peer_destination_hash: str = "",
) -> str:
if str(transport or "").strip().lower() == "link":
return f"{transport}:{route_key}"
peer_key = str(peer_presence_hash or peer_destination_hash or "").strip().lower()
return f"{transport}:{route_key}:{peer_key}"
def _get_audio_route_stats(
transport: str,
route_key: str,
peer_presence_hash: str = "",
peer_destination_hash: str = "",
incoming: Optional[bool] = None,
) -> Dict[str, Any]:
key = _audio_route_stats_key(
transport, route_key, peer_presence_hash, peer_destination_hash
)
stats = _audio_media_route_stats.get(key)
if stats is None:
if len(_audio_media_route_stats) >= _AUDIO_MEDIA_ROUTE_STATS_MAX:
oldest_key = min(
_audio_media_route_stats,
key=lambda k: float(_audio_media_route_stats[k].get("lastActivityAtMs") or 0),
)
_audio_media_route_stats.pop(oldest_key, None)
stats = {
"transport": transport,
"routeKey": route_key,
"linkId": route_key if transport == "link" else "",
"peerPresenceHash": str(peer_presence_hash or ""),
"peerDestinationHash": str(peer_destination_hash or ""),
"incoming": incoming is True,
"sentFrames": 0,
"sentBytes": 0,
"sendFailures": 0,
"receivedFrames": 0,
"receivedBytes": 0,
"fd4EnqueuedFrames": 0,
"fd4EnqueueFailures": 0,
"lastSendAtMs": 0,
"lastSendFailureAtMs": 0,
"lastReceiveAtMs": 0,
"lastFd4EnqueueAtMs": 0,
"lastActivityAtMs": 0,
"lastRoomId": "",
"pressureWindowStartedAtMs": 0,
"pressureWindowFrames": 0,
"pressureWindowBytes": 0,
"pressureWindowReceiveGapMsMax": 0,
"pressureWindowFd4DelayMsMax": 0,
"sendGapMsMax": 0,
"receiveGapMsMax": 0,
"sendGapOver80Count": 0,
"sendGapOver160Count": 0,
"sendGapOver320Count": 0,
"sendGapOver640Count": 0,
"sendGapOver1000Count": 0,
"receiveGapOver80Count": 0,
"receiveGapOver160Count": 0,
"receiveGapOver320Count": 0,
"receiveGapOver640Count": 0,
"receiveGapOver1000Count": 0,
"linkReceiveGapMsMax": 0,
"linkReceiveGapOver80Count": 0,
"linkReceiveGapOver160Count": 0,
"linkReceiveGapOver320Count": 0,
"linkReceiveGapOver640Count": 0,
"linkReceiveGapOver1000Count": 0,
"linkReceiveToCallbackDispatchMsMax": 0,
"linkCallbackDispatchToStartMsMax": 0,
"linkReceiveToCallbackStartMsMax": 0,
"linkCallbackDispatchToStartOver80Count": 0,
"linkCallbackDispatchToStartOver160Count": 0,
"linkCallbackDispatchToStartOver320Count": 0,
"linkCallbackDispatchToStartOver640Count": 0,
"linkCallbackDispatchToStartOver1000Count": 0,
"rnsRawInboundGapMsMax": 0,
"rnsRawInboundGapOver80Count": 0,
"rnsRawInboundGapOver160Count": 0,
"rnsRawInboundGapOver320Count": 0,
"rnsRawInboundGapOver640Count": 0,
"rnsRawInboundGapOver1000Count": 0,
"rnsRawInboundToLinkReceiveMsMax": 0,
"rnsRawInboundToLinkReceiveOver80Count": 0,
"rnsRawInboundToLinkReceiveOver160Count": 0,
"rnsRawInboundToLinkReceiveOver320Count": 0,
"rnsRawInboundToLinkReceiveOver640Count": 0,
"rnsRawInboundToLinkReceiveOver1000Count": 0,
"rnsRawInboundInterfaceLast": "",
"rnsRawInboundInterfaceWorst": "",
"rnsSharedFrameGapMsMax": 0,
"rnsSharedFrameGapOver80Count": 0,
"rnsSharedFrameGapOver160Count": 0,
"rnsSharedFrameGapOver320Count": 0,
"rnsSharedFrameGapOver640Count": 0,
"rnsSharedFrameGapOver1000Count": 0,
"rnsSharedFrameToTransportInboundMsMax": 0,
"rnsSharedFrameToTransportInboundOver80Count": 0,
"rnsSharedFrameToTransportInboundOver160Count": 0,
"rnsSharedFrameToTransportInboundOver320Count": 0,
"rnsSharedFrameToTransportInboundOver640Count": 0,
"rnsSharedFrameToTransportInboundOver1000Count": 0,
"rnsSharedFrameInterfaceLast": "",
"rnsSharedFrameInterfaceWorst": "",
"preRnsSendAgeMsMax": 0,
"rnsSendDurationMsMax": 0,
"receiveToFd4EnqueueMsMax": 0,
}
_audio_media_route_stats[key] = stats
if peer_presence_hash:
stats["peerPresenceHash"] = str(peer_presence_hash)
if peer_destination_hash:
stats["peerDestinationHash"] = str(peer_destination_hash)
if incoming is not None:
stats["incoming"] = incoming is True
return stats
def _note_audio_route_gap(
stats: Dict[str, Any],
*,
previous_key: str,
max_key: str,
bucket_prefix: str,
now_ms: int,
) -> None:
previous_ms = int(stats.get(previous_key) or 0)
if previous_ms <= 0:
return
gap_ms = max(0, now_ms - previous_ms)
if gap_ms > int(stats.get(max_key) or 0):
stats[max_key] = gap_ms
for bucket_ms in _AUDIO_ROUTE_GAP_BUCKETS_MS:
if gap_ms >= bucket_ms:
key = f"{bucket_prefix}GapOver{bucket_ms}Count"
stats[key] = int(stats.get(key) or 0) + 1
def _note_audio_route_bucketed_duration(
stats: Dict[str, Any],
*,
duration_ms: float,
max_key: str,
bucket_prefix: Optional[str] = None,
) -> None:
duration = max(0.0, float(duration_ms or 0.0))
if duration > float(stats.get(max_key) or 0):
stats[max_key] = duration
if not bucket_prefix:
return
for bucket_ms in _AUDIO_ROUTE_GAP_BUCKETS_MS:
if duration >= bucket_ms:
key = f"{bucket_prefix}Over{bucket_ms}Count"
stats[key] = int(stats.get(key) or 0) + 1
def _maybe_log_audio_path_pressure(
stats: Dict[str, Any],
*,
transport: str,
route_key: str,
room_id: str,
peer_presence_hash: str,
peer_destination_hash: str,
now_ms: int,
) -> None:
window_started_at_ms = int(stats.get("pressureWindowStartedAtMs") or 0)
if window_started_at_ms <= 0:
stats["pressureWindowStartedAtMs"] = now_ms
return
elapsed_ms = max(0, now_ms - window_started_at_ms)
if elapsed_ms < _AUDIO_PATH_PRESSURE_LOG_INTERVAL_MS:
return
frames = int(stats.get("pressureWindowFrames") or 0)
if frames <= 0:
stats["pressureWindowStartedAtMs"] = now_ms
return
bytes_count = int(stats.get("pressureWindowBytes") or 0)
receive_gap_ms = int(stats.get("pressureWindowReceiveGapMsMax") or 0)
fd4_delay_ms = int(stats.get("pressureWindowFd4DelayMsMax") or 0)
log(
f"[presence_bridge] audio_path_pressure side=python_rx "
f"window_ms={elapsed_ms} room={room_id or 'n/a'} transport={transport} "
f"route={_short_route(route_key)} link={_short_route(route_key) if transport == 'link' else 'n/a'} "
f"peer={_short_route(peer_presence_hash)} dest={_short_route(peer_destination_hash)} "
f"packets={frames} bytes={bytes_count} rx_gap_ms={receive_gap_ms} "
f"fd4_enqueue_delay_ms={fd4_delay_ms} fd4_enqueued={int(stats.get('fd4EnqueuedFrames') or 0)} "
f"fd4_failures={int(stats.get('fd4EnqueueFailures') or 0)}"
)
stats["pressureWindowStartedAtMs"] = now_ms
stats["pressureWindowFrames"] = 0
stats["pressureWindowBytes"] = 0
stats["pressureWindowReceiveGapMsMax"] = 0
stats["pressureWindowFd4DelayMsMax"] = 0
def _interface_label(interface: Any) -> str:
if interface is None:
return ""
try:
value = getattr(interface, "name", None)
if value is None:
value = str(interface)
return str(value or "")[:160]
except Exception:
return ""
def _short_route(value: Any, limit: int = 16) -> str:
text = str(value or "").strip()
return text[:limit] if text else "n/a"
_GC_LINK_CONTROL_MAGIC = b"QGCCTL1\x00"
def _inspect_gcall_audio_payload(payload: Any) -> tuple[str, str]:
if not isinstance(payload, (bytes, bytearray)):
return "media", ""
data = bytes(payload)
if len(data) <= len(_GC_LINK_CONTROL_MAGIC) or not data.startswith(
_GC_LINK_CONTROL_MAGIC
):
return "media", ""
try:
parsed = json.loads(data[len(_GC_LINK_CONTROL_MAGIC) :].decode("utf-8"))
control_type = (
str(parsed.get("type") or "") if isinstance(parsed, dict) else ""
)
except Exception:
control_type = ""
return "control", control_type
def _log_audio_timing_anomaly(stage: str, route_key: str, detail: str) -> None:
"""Throttled timeline logs for narrowing Reticulum audio gaps."""
key = f"{stage}:{route_key}"
now = time.monotonic()
last = float(_audio_timing_anomaly_log_last_by_key.get(key) or 0.0)
if now - last < _AUDIO_TIMING_LOG_THROTTLE_SECONDS:
return
_audio_timing_anomaly_log_last_by_key[key] = now
if len(_audio_timing_anomaly_log_last_by_key) > 512:
for old_key in list(_audio_timing_anomaly_log_last_by_key.keys())[:128]:
_audio_timing_anomaly_log_last_by_key.pop(old_key, None)
log(f"[presence_bridge] {_AUDIO_IPC_LOG} stage={stage} {detail}")
def _log_audio_data_plane(stage: str, detail: str = "") -> None:
suffix = f" {detail}" if detail else ""
log(f"[presence_bridge] target=gcall-audio-data-plane stage={stage}{suffix}")
def _ws_accept_key(key: str) -> str:
digest = hashlib.sha1(
(key + "258EAFA5-E914-47DA-95CA-C5AB0DC85B11").encode("ascii")
).digest()
return base64.b64encode(digest).decode("ascii")
def _ws_send_json(conn: socket.socket, payload: Dict[str, Any]) -> bool:
try:
data = json.dumps(payload, separators=(",", ":")).encode("utf-8")
header = bytearray([0x81])
if len(data) < 126:
header.append(len(data))
elif len(data) < 65536:
header.extend([126, (len(data) >> 8) & 0xFF, len(data) & 0xFF])
else:
header.extend([127])
header.extend(len(data).to_bytes(8, "big"))
conn.sendall(bytes(header) + data)
return True
except Exception as exc:
_log_audio_data_plane("ws-send-failed", f"err={str(exc)[:160]}")
return False
def _ws_read_frame(conn: socket.socket) -> Optional[Tuple[int, bytes]]:
header = conn.recv(2)
if len(header) < 2:
return None
opcode = header[0] & 0x0F
masked = (header[1] & 0x80) != 0
length = header[1] & 0x7F
if length == 126:
ext = conn.recv(2)
if len(ext) < 2:
return None
length = int.from_bytes(ext, "big")
elif length == 127:
ext = conn.recv(8)
if len(ext) < 8:
return None
length = int.from_bytes(ext, "big")
if length > 262144:
raise ValueError("websocket frame too large")
mask = b""
if masked:
mask = conn.recv(4)
if len(mask) < 4:
return None
data = b""
while len(data) < length:
chunk = conn.recv(length - len(data))
if not chunk:
return None
data += chunk
if masked:
data = bytes(b ^ mask[i % 4] for i, b in enumerate(data))
return opcode, data
def _audio_data_plane_route_for_address(address: str) -> Optional[Dict[str, Any]]:
key = str(address or "").strip()
if not key:
return None
with _audio_data_plane_lock:
route = _audio_data_plane_routes_by_address.get(key)
if isinstance(route, dict):
return dict(route)
return None
def _audio_data_plane_enqueue_frame(message: Dict[str, Any]) -> Tuple[bool, str]:
if _destination is None:
return False, "bridge_not_started"
room_id = str(message.get("roomId") or "").strip()
if not room_id:
return False, "missing_room"
target = str(message.get("targetAddress") or "").strip()
route = _audio_data_plane_route_for_address(target)
if route is None:
return False, "route_missing"
encoded = message.get("data")
if not isinstance(encoded, str) or not encoded:
return False, "missing_payload"
try:
raw = base64.b64decode(encoded, validate=True)
except Exception:
return False, "bad_payload_base64"
if len(raw) <= 0 or len(raw) > AUDIO_MAX_PAYLOAD:
return False, "bad_payload_size"
now_ms = _now_wall_ms()
source_ms = message.get("rendererSendAtWallMs")
if isinstance(source_ms, (int, float)) and source_ms > 0:
age_ms = max(0, now_ms - int(source_ms))
if age_ms > _AUDIO_DATA_PLANE_STALE_MS:
return False, f"stale:{age_ms}"
transport = "packet" if route.get("transport") == "packet" else "link"
link_id = str(route.get("linkId") or "")
peer_presence_hash = str(route.get("peerPresenceHash") or "").strip().lower()
peer_destination_hash = str(route.get("peerDestinationHash") or "").strip().lower()
if transport == "link" and not link_id:
return False, "route_link_missing"
if transport == "packet" and not peer_presence_hash:
return False, "route_peer_missing"
ok = _put_audio_decoded_batch_keep_newest(
[
(
link_id if transport == "link" else "",
room_id,
peer_presence_hash,
peer_destination_hash,
int(source_ms) if isinstance(source_ms, (int, float)) and source_ms > 0 else now_ms,
raw,
)
]
)
if not ok:
return False, "decoded_queue_full"
return True, "queued"
def _handle_audio_data_plane_message(conn: socket.socket, message: Dict[str, Any]) -> None:
kind = message.get("type")
if kind == "hello":
_ws_send_json(conn, {"type": "hello-ok", "atMs": _now_wall_ms()})
return
if kind != "audio":
_ws_send_json(conn, {"type": "error", "reason": "unknown_type"})
return
targets = message.get("targets")
if not isinstance(targets, list) or not targets:
_ws_send_json(conn, {"type": "audio-result", "ok": False, "reason": "missing_targets"})
return
queued = 0
failures: list = []
for target in targets[:_AUDIO_DATA_PLANE_MAX_ROUTES]:
if not isinstance(target, str) or not target.strip():
continue
per_target = dict(message)
per_target["targetAddress"] = target
ok, reason = _audio_data_plane_enqueue_frame(per_target)
if ok:
queued += 1
else:
failures.append({"targetAddress": target, "reason": reason})
if reason.startswith("stale:"):
_log_audio_data_plane(
"stale-outbound-drop",
f"room={str(message.get('roomId') or '')[:80]} target={target[:16]} reason={reason}",
)
_ws_send_json(
conn,
{
"type": "audio-result",
"ok": queued > 0,
"queued": queued,
"failures": failures[:8],
"atMs": _now_wall_ms(),
},
)
def _audio_data_plane_client_loop(conn: socket.socket, addr: Any) -> None:
client_id = id(conn)
try:
request = b""
while b"\r\n\r\n" not in request and len(request) < 8192:
chunk = conn.recv(1024)
if not chunk:
return
request += chunk
header_text = request.decode("iso-8859-1", errors="replace")
first_line = header_text.split("\r\n", 1)[0]
parts = first_line.split(" ")
path = parts[1] if len(parts) >= 2 else "/"
query = urllib.parse.parse_qs(urllib.parse.urlparse(path).query)
token = (query.get("token") or [""])[0]
with _audio_data_plane_lock:
expected = _audio_data_plane_token
if not expected or not secrets.compare_digest(str(token), expected):
conn.sendall(b"HTTP/1.1 401 Unauthorized\r\nConnection: close\r\n\r\n")
_log_audio_data_plane("auth-rejected", f"addr={addr}")
return
headers: Dict[str, str] = {}
for line in header_text.split("\r\n")[1:]:
if ":" in line:
k, v = line.split(":", 1)
headers[k.strip().lower()] = v.strip()
sec_key = headers.get("sec-websocket-key", "")
if not sec_key:
conn.sendall(b"HTTP/1.1 400 Bad Request\r\nConnection: close\r\n\r\n")
return
response = (
"HTTP/1.1 101 Switching Protocols\r\n"
"Upgrade: websocket\r\n"
"Connection: Upgrade\r\n"
f"Sec-WebSocket-Accept: {_ws_accept_key(sec_key)}\r\n\r\n"
)
conn.sendall(response.encode("ascii"))
with _audio_data_plane_lock:
_audio_data_plane_clients[client_id] = conn
_log_audio_data_plane("connection-open", f"addr={addr}")
conn.settimeout(None)
_ws_send_json(conn, {"type": "ready", "atMs": _now_wall_ms()})
while not _shutdown.is_set():
frame = _ws_read_frame(conn)
if frame is None:
break
opcode, data = frame
if opcode == 0x8:
break
if opcode == 0x9:
conn.sendall(b"\x8a\x00")
continue
if opcode != 0x1:
continue
try:
parsed = json.loads(data.decode("utf-8"))
except Exception:
_ws_send_json(conn, {"type": "error", "reason": "bad_json"})
continue
if isinstance(parsed, dict):
if parsed.get("type") == "ping":
_ws_send_json(
conn,
{
"type": "pong",
"atMs": _now_wall_ms(),
"echoAtMs": parsed.get("atMs"),
},
)
continue
_handle_audio_data_plane_message(conn, parsed)
except Exception as exc:
_log_audio_data_plane("connection-error", f"addr={addr} err={str(exc)[:160]}")
finally:
with _audio_data_plane_lock:
_audio_data_plane_clients.pop(client_id, None)
try:
conn.close()
except Exception:
pass
_log_audio_data_plane("connection-closed", f"addr={addr}")
def _audio_data_plane_accept_loop(sock: socket.socket) -> None:
while not _shutdown.is_set():
try:
conn, addr = sock.accept()
conn.settimeout(5.0)
threading.Thread(
target=_audio_data_plane_client_loop,
args=(conn, addr),
name="gcall-audio-data-plane-client",
daemon=True,
).start()
except OSError:
break
except Exception as exc:
_log_audio_data_plane("accept-failed", f"err={str(exc)[:160]}")
def _ensure_audio_data_plane_server() -> Tuple[bool, Dict[str, Any], str]:
global _audio_data_plane_server_thread, _audio_data_plane_socket
global _audio_data_plane_endpoint, _audio_data_plane_token
with _audio_data_plane_lock:
if _audio_data_plane_endpoint and _audio_data_plane_token:
return True, {
"endpoint": _audio_data_plane_endpoint,
"token": _audio_data_plane_token,
"version": 2,
}, ""
try:
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
sock.bind(("127.0.0.1", 0))
sock.listen(16)
host, port = sock.getsockname()
_audio_data_plane_socket = sock
_audio_data_plane_token = secrets.token_urlsafe(32)
_audio_data_plane_endpoint = f"ws://{host}:{port}/gcall-audio"
_audio_data_plane_server_thread = threading.Thread(
target=_audio_data_plane_accept_loop,
args=(sock,),
name="gcall-audio-data-plane",
daemon=True,
)
_audio_data_plane_server_thread.start()
_log_audio_data_plane("listen-ok", f"endpoint={_audio_data_plane_endpoint}")
return True, {
"endpoint": _audio_data_plane_endpoint,
"token": _audio_data_plane_token,
"version": 2,
}, ""
except Exception as exc:
_log_audio_data_plane("listen-failed", f"err={str(exc)[:160]}")
return False, {}, str(exc)
def _configure_audio_data_plane_routes(routes: Any) -> int:
next_routes: Dict[str, Dict[str, Any]] = {}
if isinstance(routes, list):
for raw in routes[:_AUDIO_DATA_PLANE_MAX_ROUTES]:
if not isinstance(raw, dict):
continue
address = str(raw.get("address") or "").strip()
if not address:
continue
transport = "packet" if raw.get("transport") == "packet" else "link"
next_routes[address] = {
"address": address,
"transport": transport,
"linkId": str(raw.get("linkId") or ""),
"peerPresenceHash": str(raw.get("peerPresenceHash") or "").strip().lower(),
"peerDestinationHash": str(raw.get("peerDestinationHash") or "").strip().lower(),
}
with _audio_data_plane_lock:
_audio_data_plane_routes_by_address.clear()
_audio_data_plane_routes_by_address.update(next_routes)
_log_audio_data_plane("routes-configured", f"routes={len(next_routes)}")
return len(next_routes)
def _increment_raw_gap_buckets(gap_ms: float) -> None:
global _audio_rns_raw_inbound_gap_over_80_count
global _audio_rns_raw_inbound_gap_over_160_count
global _audio_rns_raw_inbound_gap_over_320_count
global _audio_rns_raw_inbound_gap_over_640_count
global _audio_rns_raw_inbound_gap_over_1000_count
if gap_ms >= 80:
_audio_rns_raw_inbound_gap_over_80_count += 1
if gap_ms >= 160:
_audio_rns_raw_inbound_gap_over_160_count += 1
if gap_ms >= 320:
_audio_rns_raw_inbound_gap_over_320_count += 1
if gap_ms >= 640:
_audio_rns_raw_inbound_gap_over_640_count += 1
if gap_ms >= 1000:
_audio_rns_raw_inbound_gap_over_1000_count += 1
def _increment_raw_to_link_buckets(duration_ms: float) -> None:
global _audio_rns_raw_inbound_to_link_receive_over_80_count
global _audio_rns_raw_inbound_to_link_receive_over_160_count
global _audio_rns_raw_inbound_to_link_receive_over_320_count
global _audio_rns_raw_inbound_to_link_receive_over_640_count
global _audio_rns_raw_inbound_to_link_receive_over_1000_count
if duration_ms >= 80:
_audio_rns_raw_inbound_to_link_receive_over_80_count += 1
if duration_ms >= 160:
_audio_rns_raw_inbound_to_link_receive_over_160_count += 1
if duration_ms >= 320:
_audio_rns_raw_inbound_to_link_receive_over_320_count += 1
if duration_ms >= 640:
_audio_rns_raw_inbound_to_link_receive_over_640_count += 1
if duration_ms >= 1000:
_audio_rns_raw_inbound_to_link_receive_over_1000_count += 1
def _increment_shared_frame_gap_buckets(gap_ms: float) -> None:
global _audio_rns_shared_frame_gap_over_80_count
global _audio_rns_shared_frame_gap_over_160_count
global _audio_rns_shared_frame_gap_over_320_count
global _audio_rns_shared_frame_gap_over_640_count
global _audio_rns_shared_frame_gap_over_1000_count
if gap_ms >= 80:
_audio_rns_shared_frame_gap_over_80_count += 1
if gap_ms >= 160:
_audio_rns_shared_frame_gap_over_160_count += 1
if gap_ms >= 320:
_audio_rns_shared_frame_gap_over_320_count += 1
if gap_ms >= 640:
_audio_rns_shared_frame_gap_over_640_count += 1
if gap_ms >= 1000:
_audio_rns_shared_frame_gap_over_1000_count += 1
def _increment_shared_to_transport_buckets(duration_ms: float) -> None:
global _audio_rns_shared_frame_to_transport_inbound_over_80_count
global _audio_rns_shared_frame_to_transport_inbound_over_160_count
global _audio_rns_shared_frame_to_transport_inbound_over_320_count
global _audio_rns_shared_frame_to_transport_inbound_over_640_count
global _audio_rns_shared_frame_to_transport_inbound_over_1000_count
if duration_ms >= 80:
_audio_rns_shared_frame_to_transport_inbound_over_80_count += 1
if duration_ms >= 160:
_audio_rns_shared_frame_to_transport_inbound_over_160_count += 1
if duration_ms >= 320:
_audio_rns_shared_frame_to_transport_inbound_over_320_count += 1
if duration_ms >= 640:
_audio_rns_shared_frame_to_transport_inbound_over_640_count += 1
if duration_ms >= 1000:
_audio_rns_shared_frame_to_transport_inbound_over_1000_count += 1
def _prune_rns_shared_frame_probe_cache() -> None:
if len(_audio_rns_shared_frame_probe_by_packet_hash) <= _AUDIO_RNS_SHARED_FRAME_PROBE_MAX:
return
overflow = len(_audio_rns_shared_frame_probe_by_packet_hash) - _AUDIO_RNS_SHARED_FRAME_PROBE_MAX
for packet_hash in list(_audio_rns_shared_frame_probe_by_packet_hash.keys())[: max(1, overflow)]:
_audio_rns_shared_frame_probe_by_packet_hash.pop(packet_hash, None)
def _prune_rns_raw_inbound_probe_cache() -> None:
if len(_audio_rns_raw_inbound_probe_by_packet_hash) <= _AUDIO_RNS_RAW_INBOUND_PROBE_MAX:
return
overflow = len(_audio_rns_raw_inbound_probe_by_packet_hash) - _AUDIO_RNS_RAW_INBOUND_PROBE_MAX
for packet_hash in list(_audio_rns_raw_inbound_probe_by_packet_hash.keys())[: max(1, overflow)]:
_audio_rns_raw_inbound_probe_by_packet_hash.pop(packet_hash, None)
def _record_rns_shared_frame_probe(raw: Any, interface: Any) -> None:
global _audio_rns_shared_frame_gap_ms_max, _audio_rns_shared_frame_interface_last
global _audio_rns_shared_frame_interface_worst
global _audio_rns_shared_frame_gap_ms_window
if not isinstance(raw, (bytes, bytearray)) or len(raw) < 4:
return
try:
packet = RNS.Packet(None, bytes(raw), create_receipt=False)
if not packet.unpack():
return
if (
getattr(packet, "packet_type", None) != getattr(RNS.Packet, "DATA", object())
or getattr(packet, "destination_type", None) != getattr(RNS.Destination, "LINK", object())
):
return
packet_hash = getattr(packet, "packet_hash", None)
destination_hash = getattr(packet, "destination_hash", None)
if not isinstance(packet_hash, (bytes, bytearray)):
return
destination_hex = bytes(destination_hash or b"").hex()
if not destination_hex:
return
now_mono = time.monotonic()
now_wall_ms = _now_wall_ms()
interface_name = _interface_label(interface)
with _state_lock:
previous_ms = int(_audio_rns_shared_frame_last_wall_ms_by_destination_hash.get(destination_hex) or 0)
frame_gap_ms = 0
if previous_ms > 0:
frame_gap_ms = max(0, now_wall_ms - previous_ms)
if frame_gap_ms > _audio_rns_shared_frame_gap_ms_max:
_audio_rns_shared_frame_gap_ms_max = float(frame_gap_ms)
_audio_rns_shared_frame_interface_worst = interface_name
if frame_gap_ms > _audio_rns_shared_frame_gap_ms_window:
_audio_rns_shared_frame_gap_ms_window = float(frame_gap_ms)
_increment_shared_frame_gap_buckets(float(frame_gap_ms))
if frame_gap_ms >= _AUDIO_TIMING_GAP_LOG_THRESHOLD_MS:
_log_audio_timing_anomaly(
"rns-shared-frame-gap",
destination_hex,
f"destination={_short_route(destination_hex)} gap_ms={frame_gap_ms} "
f"interface={interface_name or 'n/a'} packet={_short_route(bytes(packet_hash).hex())}",
)
_audio_rns_shared_frame_last_wall_ms_by_destination_hash[destination_hex] = now_wall_ms
_audio_rns_shared_frame_interface_last = interface_name
_audio_rns_shared_frame_probe_by_packet_hash[bytes(packet_hash)] = {
"monotonic": now_mono,
"wallMs": now_wall_ms,
"destinationHash": destination_hex,
"interface": interface_name,
"frameGapMs": frame_gap_ms,
}
_prune_rns_shared_frame_probe_cache()
_mark_audio_queue_state_dirty()
except Exception:
return
def _record_rns_raw_inbound_probe(raw: Any, interface: Any) -> None:
global _audio_rns_raw_inbound_gap_ms_max, _audio_rns_raw_inbound_interface_last
global _audio_rns_raw_inbound_interface_worst
global _audio_rns_raw_inbound_gap_ms_window
global _audio_rns_shared_frame_to_transport_inbound_ms_max
global _audio_rns_shared_frame_to_transport_inbound_samples
global _audio_rns_shared_frame_interface_last, _audio_rns_shared_frame_interface_worst
if not isinstance(raw, (bytes, bytearray)) or len(raw) < 4:
return
try:
packet = RNS.Packet(None, bytes(raw), create_receipt=False)
if not packet.unpack():
return
if (
getattr(packet, "packet_type", None) != getattr(RNS.Packet, "DATA", object())
or getattr(packet, "destination_type", None) != getattr(RNS.Destination, "LINK", object())
):
return
packet_hash = getattr(packet, "packet_hash", None)
destination_hash = getattr(packet, "destination_hash", None)
if not isinstance(packet_hash, (bytes, bytearray)):
return
destination_hex = bytes(destination_hash or b"").hex()
if not destination_hex:
return
now_mono = time.monotonic()
now_wall_ms = _now_wall_ms()
interface_name = _interface_label(interface)
shared_probe = None
with _state_lock:
shared_probe = _audio_rns_shared_frame_probe_by_packet_hash.pop(bytes(packet_hash), None)
shared_to_transport_ms = 0.0
shared_frame_gap_ms = 0.0
shared_interface_name = ""
if shared_probe is not None:
shared_mono = float(shared_probe.get("monotonic") or 0.0)
shared_to_transport_ms = (
max(0.0, (now_mono - shared_mono) * 1000.0)
if shared_mono > 0
else 0.0
)
shared_frame_gap_ms = max(0.0, float(shared_probe.get("frameGapMs") or 0.0))
shared_interface_name = str(shared_probe.get("interface") or interface_name)
_audio_rns_shared_frame_to_transport_inbound_samples += 1
_audio_rns_shared_frame_interface_last = shared_interface_name
if shared_to_transport_ms > _audio_rns_shared_frame_to_transport_inbound_ms_max:
_audio_rns_shared_frame_to_transport_inbound_ms_max = shared_to_transport_ms
_audio_rns_shared_frame_interface_worst = shared_interface_name
_increment_shared_to_transport_buckets(shared_to_transport_ms)
if shared_to_transport_ms >= _AUDIO_TIMING_DELAY_LOG_THRESHOLD_MS:
_log_audio_timing_anomaly(
"rns-shared-to-transport-delay",
destination_hex,
f"destination={_short_route(destination_hex)} "
f"delay_ms={shared_to_transport_ms:.3f} "
f"shared_gap_ms={shared_frame_gap_ms:.3f} "
f"interface={shared_interface_name or interface_name or 'n/a'} "
f"packet={_short_route(bytes(packet_hash).hex())}",
)
previous_ms = int(_audio_rns_raw_inbound_last_wall_ms_by_destination_hash.get(destination_hex) or 0)
raw_gap_ms = 0
if previous_ms > 0:
raw_gap_ms = max(0, now_wall_ms - previous_ms)
if raw_gap_ms > _audio_rns_raw_inbound_gap_ms_max:
_audio_rns_raw_inbound_gap_ms_max = float(raw_gap_ms)
_audio_rns_raw_inbound_interface_worst = interface_name
if raw_gap_ms > _audio_rns_raw_inbound_gap_ms_window:
_audio_rns_raw_inbound_gap_ms_window = float(raw_gap_ms)
_increment_raw_gap_buckets(float(raw_gap_ms))
if raw_gap_ms >= _AUDIO_TIMING_GAP_LOG_THRESHOLD_MS:
_log_audio_timing_anomaly(
"rns-raw-inbound-gap",
destination_hex,
f"destination={_short_route(destination_hex)} gap_ms={raw_gap_ms} "
f"interface={interface_name or 'n/a'} packet={_short_route(bytes(packet_hash).hex())}",
)
_audio_rns_raw_inbound_last_wall_ms_by_destination_hash[destination_hex] = now_wall_ms
_audio_rns_raw_inbound_interface_last = interface_name
_audio_rns_raw_inbound_probe_by_packet_hash[bytes(packet_hash)] = {
"monotonic": now_mono,
"wallMs": now_wall_ms,
"destinationHash": destination_hex,
"interface": interface_name,
"rawGapMs": raw_gap_ms,
"sharedFrameGapMs": shared_frame_gap_ms,
"sharedFrameToTransportInboundMs": shared_to_transport_ms,
"sharedFrameInterface": shared_interface_name,
}
_prune_rns_raw_inbound_probe_cache()
_mark_audio_queue_state_dirty()
except Exception:
return
def _get_audio_route_stats_for_link_id(
link_id: str,
*,
incoming: Optional[bool] = None,
) -> Optional[Dict[str, Any]]:
if not link_id:
return None
state = get_audio_link_state(link_id)
if state is None:
return None
return _get_audio_route_stats(
"link",
link_id,
str(state.get("peerPresenceHash") or ""),
str(state.get("peerDestinationHash") or ""),
state.get("incoming") is True if incoming is None else incoming,
)
def _prune_audio_link_receive_probe_cache() -> None:
if len(_audio_link_receive_probe_by_packet_id) <= _AUDIO_LINK_RECEIVE_PROBE_MAX:
return
overflow = len(_audio_link_receive_probe_by_packet_id) - _AUDIO_LINK_RECEIVE_PROBE_MAX
for packet_id in list(_audio_link_receive_probe_by_packet_id.keys())[: max(1, overflow)]:
_audio_link_receive_probe_by_packet_id.pop(packet_id, None)
def _qortal_link_receive_probe(
stage: str,
link: Any,
packet: Any,
monotonic_at: float,
wall_at: float,
) -> None:
"""Runtime RNS.Link.receive probe to split delivery vs callback dispatch."""
global _audio_rns_raw_inbound_to_link_receive_ms_max
global _audio_rns_raw_inbound_to_link_receive_samples
global _audio_rns_raw_inbound_interface_last, _audio_rns_raw_inbound_interface_worst
if link is None or packet is None:
return
link_id = get_audio_link_id(link)
if not link_id:
return
packet_id = id(packet)
now_wall_ms = int(max(0.0, float(wall_at or time.time())) * 1000.0)
now_mono = float(monotonic_at or time.monotonic())
stats = _get_audio_route_stats_for_link_id(link_id)
if stats is None:
return
if stage == "receive_enter":
raw_probe = None
packet_hash = getattr(packet, "packet_hash", None)
if isinstance(packet_hash, (bytes, bytearray)):
with _state_lock:
raw_probe = _audio_rns_raw_inbound_probe_by_packet_hash.pop(bytes(packet_hash), None)
if raw_probe is not None:
raw_mono = float(raw_probe.get("monotonic") or 0.0)
raw_to_link_ms = max(0.0, (now_mono - raw_mono) * 1000.0) if raw_mono > 0 else 0.0
interface_name = str(raw_probe.get("interface") or "")
raw_gap_ms = max(0.0, float(raw_probe.get("rawGapMs") or 0.0))
shared_frame_gap_ms = max(0.0, float(raw_probe.get("sharedFrameGapMs") or 0.0))
shared_to_transport_ms = max(
0.0, float(raw_probe.get("sharedFrameToTransportInboundMs") or 0.0)
)
shared_interface_name = str(raw_probe.get("sharedFrameInterface") or interface_name)
if raw_to_link_ms > float(stats.get("rnsRawInboundToLinkReceiveMsMax") or 0):
stats["rnsRawInboundToLinkReceiveMsMax"] = raw_to_link_ms
stats["rnsRawInboundInterfaceWorst"] = interface_name
stats["rnsRawInboundInterfaceLast"] = interface_name
if raw_to_link_ms >= _AUDIO_TIMING_DELAY_LOG_THRESHOLD_MS:
_log_audio_timing_anomaly(
"rns-raw-to-link-delay",
link_id,
f"link={_short_route(link_id)} delay_ms={raw_to_link_ms:.3f} "
f"raw_gap_ms={raw_gap_ms:.3f} shared_gap_ms={shared_frame_gap_ms:.3f} "
f"shared_to_transport_ms={shared_to_transport_ms:.3f} "
f"interface={interface_name or 'n/a'}",
)
_note_audio_route_bucketed_duration(
stats,
duration_ms=raw_to_link_ms,
max_key="rnsRawInboundToLinkReceiveMsMax",
bucket_prefix="rnsRawInboundToLinkReceive",
)
if raw_gap_ms > float(stats.get("rnsRawInboundGapMsMax") or 0):
stats["rnsRawInboundGapMsMax"] = raw_gap_ms
for bucket_ms in _AUDIO_ROUTE_GAP_BUCKETS_MS:
if raw_gap_ms >= bucket_ms:
key = f"rnsRawInboundGapOver{bucket_ms}Count"
stats[key] = int(stats.get(key) or 0) + 1
if shared_frame_gap_ms > float(stats.get("rnsSharedFrameGapMsMax") or 0):
stats["rnsSharedFrameGapMsMax"] = shared_frame_gap_ms
for bucket_ms in _AUDIO_ROUTE_GAP_BUCKETS_MS:
if shared_frame_gap_ms >= bucket_ms:
key = f"rnsSharedFrameGapOver{bucket_ms}Count"
stats[key] = int(stats.get(key) or 0) + 1
if shared_to_transport_ms > float(
stats.get("rnsSharedFrameToTransportInboundMsMax") or 0
):
stats["rnsSharedFrameInterfaceWorst"] = shared_interface_name
stats["rnsSharedFrameInterfaceLast"] = shared_interface_name
_note_audio_route_bucketed_duration(
stats,
duration_ms=shared_to_transport_ms,
max_key="rnsSharedFrameToTransportInboundMsMax",
bucket_prefix="rnsSharedFrameToTransportInbound",
)
with _state_lock:
_audio_rns_raw_inbound_to_link_receive_samples += 1
_audio_rns_raw_inbound_interface_last = interface_name
if raw_to_link_ms > _audio_rns_raw_inbound_to_link_receive_ms_max:
_audio_rns_raw_inbound_to_link_receive_ms_max = raw_to_link_ms
_audio_rns_raw_inbound_interface_worst = interface_name
_increment_raw_to_link_buckets(raw_to_link_ms)
previous_link_receive_ms = int(stats.get("lastLinkReceiveEnterAtMs") or 0)
if previous_link_receive_ms > 0:
link_receive_gap_ms = max(0, now_wall_ms - previous_link_receive_ms)
if link_receive_gap_ms >= _AUDIO_TIMING_GAP_LOG_THRESHOLD_MS:
_log_audio_timing_anomaly(
"rns-link-receive-gap",
link_id,
f"link={_short_route(link_id)} gap_ms={link_receive_gap_ms} "
f"peer={_short_route(stats.get('peerPresenceHash'))} "
f"dest={_short_route(stats.get('peerDestinationHash'))}",
)
_note_audio_route_gap(
stats,
previous_key="lastLinkReceiveEnterAtMs",
max_key="linkReceiveGapMsMax",
bucket_prefix="linkReceive",
now_ms=now_wall_ms,
)
stats["lastLinkReceiveEnterAtMs"] = now_wall_ms
stats["lastActivityAtMs"] = max(int(stats.get("lastActivityAtMs") or 0), now_wall_ms)
_audio_link_receive_probe_by_packet_id[packet_id] = {
"linkId": link_id,
"receiveEnterMonotonic": now_mono,
"receiveEnterAtMs": now_wall_ms,
"callbackDispatchMonotonic": 0.0,
"callbackDispatchAtMs": 0,
}
_prune_audio_link_receive_probe_cache()
_mark_audio_queue_state_dirty()
return
if stage == "callback_dispatch":
probe = _audio_link_receive_probe_by_packet_id.get(packet_id)
if probe is None:
probe = {
"linkId": link_id,
"receiveEnterMonotonic": 0.0,
"receiveEnterAtMs": 0,
}
_audio_link_receive_probe_by_packet_id[packet_id] = probe
_prune_audio_link_receive_probe_cache()
enter_mono = float(probe.get("receiveEnterMonotonic") or 0.0)
if enter_mono > 0:
dispatch_delay_ms = (now_mono - enter_mono) * 1000.0
if dispatch_delay_ms >= _AUDIO_TIMING_DELAY_LOG_THRESHOLD_MS:
_log_audio_timing_anomaly(
"rns-link-callback-dispatch-delay",
link_id,
f"link={_short_route(link_id)} delay_ms={dispatch_delay_ms:.3f} "
f"peer={_short_route(stats.get('peerPresenceHash'))} "
f"dest={_short_route(stats.get('peerDestinationHash'))}",
)
_note_audio_route_bucketed_duration(
stats,
duration_ms=dispatch_delay_ms,
max_key="linkReceiveToCallbackDispatchMsMax",
)
probe["callbackDispatchMonotonic"] = now_mono
probe["callbackDispatchAtMs"] = now_wall_ms
_mark_audio_queue_state_dirty()
return
if stage == "callback_start":
probe = _audio_link_receive_probe_by_packet_id.pop(packet_id, None)
if probe is None:
return
dispatch_mono = float(probe.get("callbackDispatchMonotonic") or 0.0)
enter_mono = float(probe.get("receiveEnterMonotonic") or 0.0)
if dispatch_mono > 0:
_note_audio_route_bucketed_duration(
stats,
duration_ms=(now_mono - dispatch_mono) * 1000.0,
max_key="linkCallbackDispatchToStartMsMax",
bucket_prefix="linkCallbackDispatchToStart",
)
if enter_mono > 0:
_note_audio_route_bucketed_duration(
stats,
duration_ms=(now_mono - enter_mono) * 1000.0,
max_key="linkReceiveToCallbackStartMsMax",
)
_mark_audio_queue_state_dirty()
setattr(RNS, "_qortal_link_receive_probe", _qortal_link_receive_probe)
def install_rns_link_receive_probe() -> None:
"""Track RNS.Link.receive timing without replacing global threading primitives."""
global _rns_link_receive_probe_installed
if _rns_link_receive_probe_installed:
return
original_receive = getattr(RNS.Link, "receive", None)
if not callable(original_receive):
return
def probed_receive(self, packet):
try:
if (
getattr(packet, "packet_type", None) == getattr(RNS.Packet, "DATA", object())
and getattr(packet, "context", None) == getattr(RNS.Packet, "NONE", object())
):
_qortal_link_receive_probe(
"receive_enter",
self,
packet,
time.monotonic(),
time.time(),
)
except Exception:
pass
return original_receive(self, packet)
setattr(RNS.Link, "receive", probed_receive)
_rns_link_receive_probe_installed = True
def install_rns_shared_frame_probe() -> None:
"""Track shared-instance frame arrival before it enters RNS.Transport."""
global _rns_shared_frame_probe_installed
if _rns_shared_frame_probe_installed:
return
try:
from RNS.Interfaces.LocalInterface import LocalClientInterface
except Exception:
return
original_process_incoming = getattr(LocalClientInterface, "process_incoming", None)
if not callable(original_process_incoming):
return
def probed_process_incoming(self, data):
try:
if getattr(self, "is_connected_to_shared_instance", False):
_record_rns_shared_frame_probe(data, self)
except Exception:
pass
return original_process_incoming(self, data)
setattr(LocalClientInterface, "process_incoming", probed_process_incoming)
_rns_shared_frame_probe_installed = True
def install_rns_transport_inbound_probe() -> None:
"""Track when raw link packets enter RNS.Transport before Link.receive routing."""
global _rns_transport_inbound_probe_installed
if _rns_transport_inbound_probe_installed:
return
original_inbound = getattr(RNS.Transport, "inbound", None)
if not callable(original_inbound):
return
def probed_inbound(raw, interface=None):
try:
_record_rns_raw_inbound_probe(raw, interface)
except Exception:
pass
return original_inbound(raw, interface)
setattr(RNS.Transport, "inbound", staticmethod(probed_inbound))
_rns_transport_inbound_probe_installed = True
def install_rns_shared_rpc_failure_guard() -> None:
"""Keep shared-instance helper RPC failures from aborting inbound frames."""
global _rns_shared_rpc_failure_guard_installed
if _rns_shared_rpc_failure_guard_installed:
return
reticulum_cls = getattr(RNS, "Reticulum", None)
if reticulum_cls is None:
return
rpc_failure_types = (ConnectionResetError, BrokenPipeError, EOFError, OSError)
safe_return_factories = {
"_used_destination_data": lambda: False,
"_retain_destination_data": lambda: False,
"_unretain_destination_data": lambda: False,
"_retain_identity": lambda: False,
"get_blackholed_identities": list,
"is_blackholed": lambda: False,
}
def make_guard(method_name: str, original):
def guarded(self, *args, **kwargs):
if not getattr(self, "is_connected_to_shared_instance", False):
return original(self, *args, **kwargs)
try:
return original(self, *args, **kwargs)
except rpc_failure_types as exc:
now = time.monotonic()
last = _rns_shared_rpc_failure_last_log_by_method.get(method_name, 0.0)
if now - last >= 30.0:
_rns_shared_rpc_failure_last_log_by_method[method_name] = now
log(
"[presence_bridge] target=reticulum-shared-rpc "
f"method={method_name} action=ignored_nonfatal "
f"return={safe_return_factories[method_name]()!r} "
f"err={type(exc).__name__}: {exc}"
)
return safe_return_factories[method_name]()
return guarded
installed_any = False
for method_name in safe_return_factories:
original = getattr(reticulum_cls, method_name, None)
if callable(original):
setattr(reticulum_cls, method_name, make_guard(method_name, original))
installed_any = True
_rns_shared_rpc_failure_guard_installed = installed_any
def _now_wall_ms() -> int:
return int(time.time() * 1000)
def _note_audio_route_send(
transport: str,
route_key: str,
room_id: str,
peer_presence_hash: str = "",
peer_destination_hash: str = "",
byte_count: int = 0,
ok: bool = True,
incoming: Optional[bool] = None,
source_received_at_wall_ms: Optional[int] = None,
send_duration_ms: Optional[float] = None,
) -> None:
with _state_lock:
stats = _get_audio_route_stats(
transport, route_key, peer_presence_hash, peer_destination_hash, incoming
)
now_ms = _now_wall_ms()
stats["lastRoomId"] = str(room_id or "")
stats["lastActivityAtMs"] = now_ms
if ok:
previous_send_ms = int(stats.get("lastSendAtMs") or 0)
if previous_send_ms > 0:
send_gap_ms = max(0, now_ms - previous_send_ms)
if send_gap_ms >= _AUDIO_TIMING_GAP_LOG_THRESHOLD_MS:
_log_audio_timing_anomaly(
"rns-audio-send-gap",
f"{transport}:{route_key}",
f"transport={transport} route={_short_route(route_key)} "
f"room={room_id or 'n/a'} gap_ms={send_gap_ms} "
f"peer={_short_route(peer_presence_hash)} dest={_short_route(peer_destination_hash)}",
)
_note_audio_route_gap(
stats,
previous_key="lastSendAtMs",
max_key="sendGapMsMax",
bucket_prefix="send",
now_ms=now_ms,
)
stats["sentFrames"] = int(stats.get("sentFrames") or 0) + 1
stats["sentBytes"] = int(stats.get("sentBytes") or 0) + max(0, int(byte_count or 0))
stats["lastSendAtMs"] = now_ms
if isinstance(source_received_at_wall_ms, int) and source_received_at_wall_ms > 0:
age_ms = max(0, now_ms - source_received_at_wall_ms)
if age_ms > int(stats.get("preRnsSendAgeMsMax") or 0):
stats["preRnsSendAgeMsMax"] = age_ms
if age_ms >= _AUDIO_TIMING_DELAY_LOG_THRESHOLD_MS:
_log_audio_timing_anomaly(
"rns-audio-pre-send-age",
f"{transport}:{route_key}",
f"transport={transport} route={_short_route(route_key)} "
f"room={room_id or 'n/a'} age_ms={age_ms} "
f"bytes={max(0, int(byte_count or 0))} "
f"peer={_short_route(peer_presence_hash)} dest={_short_route(peer_destination_hash)}",
)
if isinstance(send_duration_ms, (int, float)):
duration_ms = max(0.0, float(send_duration_ms))
if duration_ms > float(stats.get("rnsSendDurationMsMax") or 0):
stats["rnsSendDurationMsMax"] = duration_ms
if duration_ms >= _AUDIO_TIMING_DELAY_LOG_THRESHOLD_MS:
_log_audio_timing_anomaly(
"rns-audio-send-duration",
f"{transport}:{route_key}",
f"transport={transport} route={_short_route(route_key)} "
f"room={room_id or 'n/a'} duration_ms={duration_ms:.3f} "
f"bytes={max(0, int(byte_count or 0))} "
f"peer={_short_route(peer_presence_hash)} dest={_short_route(peer_destination_hash)}",
)
else:
stats["sendFailures"] = int(stats.get("sendFailures") or 0) + 1
stats["lastSendFailureAtMs"] = now_ms
_mark_audio_queue_state_dirty()
def _note_audio_route_receive(
transport: str,
route_key: str,
room_id: str,
peer_presence_hash: str = "",
peer_destination_hash: str = "",
byte_count: int = 0,
fd4_enqueued: Optional[bool] = None,
incoming: Optional[bool] = None,
received_at_wall_ms: Optional[int] = None,
fd4_enqueued_at_wall_ms: Optional[int] = None,
) -> None:
with _state_lock:
stats = _get_audio_route_stats(
transport, route_key, peer_presence_hash, peer_destination_hash, incoming
)
now_ms = (
received_at_wall_ms
if isinstance(received_at_wall_ms, int) and received_at_wall_ms > 0
else _now_wall_ms()
)
previous_receive_ms = int(stats.get("lastReceiveAtMs") or 0)
receive_gap_ms = 0
if previous_receive_ms > 0:
receive_gap_ms = max(0, now_ms - previous_receive_ms)
if receive_gap_ms >= _AUDIO_TIMING_GAP_LOG_THRESHOLD_MS:
_log_audio_timing_anomaly(
"rns-audio-callback-gap",
f"{transport}:{route_key}",
f"transport={transport} route={_short_route(route_key)} "
f"room={room_id or 'n/a'} gap_ms={receive_gap_ms} "
f"bytes={max(0, int(byte_count or 0))} "
f"peer={_short_route(peer_presence_hash)} dest={_short_route(peer_destination_hash)}",
)
_note_audio_route_gap(
stats,
previous_key="lastReceiveAtMs",
max_key="receiveGapMsMax",
bucket_prefix="receive",
now_ms=now_ms,
)
stats["receivedFrames"] = int(stats.get("receivedFrames") or 0) + 1
stats["receivedBytes"] = int(stats.get("receivedBytes") or 0) + max(0, int(byte_count or 0))
stats["pressureWindowFrames"] = int(stats.get("pressureWindowFrames") or 0) + 1
stats["pressureWindowBytes"] = int(stats.get("pressureWindowBytes") or 0) + max(0, int(byte_count or 0))
if receive_gap_ms > int(stats.get("pressureWindowReceiveGapMsMax") or 0):
stats["pressureWindowReceiveGapMsMax"] = receive_gap_ms
stats["lastReceiveAtMs"] = now_ms
stats["lastActivityAtMs"] = now_ms
stats["lastRoomId"] = str(room_id or "")
if fd4_enqueued is True:
stats["fd4EnqueuedFrames"] = int(stats.get("fd4EnqueuedFrames") or 0) + 1
fd4_ms = (
fd4_enqueued_at_wall_ms
if isinstance(fd4_enqueued_at_wall_ms, int) and fd4_enqueued_at_wall_ms > 0
else _now_wall_ms()
)
stats["lastFd4EnqueueAtMs"] = fd4_ms
enqueue_delay_ms = max(0, fd4_ms - now_ms)
if enqueue_delay_ms > int(stats.get("receiveToFd4EnqueueMsMax") or 0):
stats["receiveToFd4EnqueueMsMax"] = enqueue_delay_ms
if enqueue_delay_ms > int(stats.get("pressureWindowFd4DelayMsMax") or 0):
stats["pressureWindowFd4DelayMsMax"] = enqueue_delay_ms
if enqueue_delay_ms >= _AUDIO_TIMING_DELAY_LOG_THRESHOLD_MS:
_log_audio_timing_anomaly(
"rns-audio-fd4-enqueue-delay",
f"{transport}:{route_key}",
f"transport={transport} route={_short_route(route_key)} "
f"room={room_id or 'n/a'} delay_ms={enqueue_delay_ms} "
f"bytes={max(0, int(byte_count or 0))} "
f"peer={_short_route(peer_presence_hash)} dest={_short_route(peer_destination_hash)}",
)
elif fd4_enqueued is False:
stats["fd4EnqueueFailures"] = int(stats.get("fd4EnqueueFailures") or 0) + 1
_maybe_log_audio_path_pressure(
stats,
transport=transport,
route_key=route_key,
room_id=room_id,
peer_presence_hash=peer_presence_hash,
peer_destination_hash=peer_destination_hash,
now_ms=now_ms,
)
_mark_audio_queue_state_dirty()
def _audio_media_route_diagnostics() -> list:
with _state_lock:
routes = sorted(
_audio_media_route_stats.values(),
key=lambda item: int(item.get("lastActivityAtMs") or 0),
reverse=True,
)
return [dict(route) for route in routes[:16]]
def _clear_audio_media_route_diagnostics(room_id: str = "") -> int:
normalized_room_id = str(room_id or "").strip()
with _state_lock:
if not normalized_room_id:
cleared = len(_audio_media_route_stats)
_audio_media_route_stats.clear()
return cleared
keys = [
key
for key, stats in _audio_media_route_stats.items()
if str(stats.get("lastRoomId") or "") == normalized_room_id
]
for key in keys:
_audio_media_route_stats.pop(key, None)
return len(keys)
def _notify_rns_work_available() -> None:
if _rns_wake_write_fd is None:
return
try:
os.write(_rns_wake_write_fd, b"\x01")
except BlockingIOError:
pass
except OSError:
pass
def _drain_rns_wake_pipe() -> None:
if _rns_wake_read_fd is None:
return
while True:
try:
chunk = os.read(_rns_wake_read_fd, 1024)
except BlockingIOError:
return
except OSError:
return
if not chunk:
return
def _decoded_queue_oldest_age_ms(now: float) -> float:
with _audio_decoded_queue.mutex:
queued = _audio_decoded_queue.queue[0] if _audio_decoded_queue.queue else None
if not queued:
return 0.0
queued_at, _batch = queued
if not isinstance(queued_at, (int, float)):
return 0.0
return max(0.0, (now - queued_at) * 1000.0)
def _binary_out_queue_oldest_age_ms(now: float) -> float:
with _audio_binary_out_queue.mutex:
queued = _audio_binary_out_queue.queue[0] if _audio_binary_out_queue.queue else None
if not queued:
return 0.0
if not isinstance(queued, tuple) or len(queued) < 2:
return 0.0
queued_at = queued[0]
if not isinstance(queued_at, (int, float)):
return 0.0
return max(0.0, (now - queued_at) * 1000.0)
def _emit_audio_queue_state(force: bool = False) -> None:
global _audio_queue_state_dirty, _audio_queue_state_last_emit
now = time.monotonic()
if not force and not _audio_queue_state_dirty:
return
if not force and now - _audio_queue_state_last_emit < _AUDIO_QUEUE_STATE_MIN_INTERVAL_SECONDS:
return
_audio_queue_state_last_emit = now
_audio_queue_state_dirty = False
emit_event(
"group_audio_queue_state",
{
"decodedQueueDepth": _audio_decoded_queue.qsize(),
"decodedQueueOldestAgeMs": _decoded_queue_oldest_age_ms(now),
"decodedQueueMax": _AUDIO_DECODED_QUEUE_MAX,
"decodedQueueDrops": _audio_drops_ingress,
"binaryOutQueueDepth": _audio_binary_out_queue.qsize(),
"binaryOutQueueOldestAgeMs": _binary_out_queue_oldest_age_ms(now),
"binaryOutQueueMax": _AUDIO_BINARY_OUT_QUEUE_MAX,
"binaryOutQueueDrops": _audio_drops_binary_out,
"jsonOutQueueDrops": _audio_drops_json_out,
"staleDrops": _audio_stale_drops,
"packetSendFailures": _audio_packet_send_failures,
"packetPathRequests": _audio_packet_path_requests,
"packetPathResolutions": _audio_packet_path_resolutions,
"packetPathTimeouts": _audio_packet_path_timeouts,
"packetFreshSends": _audio_packet_fresh_sends,
"packetStaleSends": _audio_packet_stale_sends,
"packetUnknownSends": _audio_packet_unknown_sends,
"deadlineDropCount": _audio_deadline_drops,
"decodedQueueEvictOldestCount": _audio_decoded_queue_evict_oldest,
"decodedQueueDropNewestCount": _audio_decoded_queue_drop_newest,
"fd3DecodedAgeMsMax": _audio_fd3_decoded_age_ms_max,
"decodedQueueDwellMsMax": _audio_decoded_queue_dwell_ms_max,
"rnsSendDurationMsMax": _audio_rns_send_duration_ms_max,
"packetPathCheckMsMax": _audio_packet_path_check_ms_max,
"executorLoopGapMsMax": _audio_executor_loop_gap_ms_max,
"executorGapWhileQueuedMsMax": _audio_executor_gap_while_queued_ms_max,
"executorAudioPassMsMax": _audio_executor_audio_pass_ms_max,
"processBatchMsMax": _audio_process_batch_ms_max,
"processBatchFramesMax": _audio_process_batch_frames_max,
"rnsSendSlowCount": _audio_rns_send_slow_count,
"executorStallCount": _audio_executor_stall_count,
"executorCommandMsMax": _audio_executor_command_ms_max,
"executorCommandWhileQueuedMsMax": _audio_executor_command_while_queued_ms_max,
"executorCommandSlowCount": _audio_executor_command_slow_count,
"rnsCallbackSchedulerGapMsWindow": _audio_rns_callback_scheduler_gap_ms_window,
"rnsCallbackSchedulerGapMsMax": _audio_rns_callback_scheduler_gap_ms_max,
"rnsCallbackSchedulerGapOver100Count": _audio_rns_callback_scheduler_gap_over_100_count,
"rnsCallbackSchedulerGapOver250Count": _audio_rns_callback_scheduler_gap_over_250_count,
"rnsCallbackSchedulerGapOver500Count": _audio_rns_callback_scheduler_gap_over_500_count,
"rnsCallbackSchedulerGapOver1000Count": _audio_rns_callback_scheduler_gap_over_1000_count,
"rnsRawInboundGapMsWindow": _audio_rns_raw_inbound_gap_ms_window,
"rnsRawInboundGapMsMax": _audio_rns_raw_inbound_gap_ms_max,
"rnsRawInboundGapOver80Count": _audio_rns_raw_inbound_gap_over_80_count,
"rnsRawInboundGapOver160Count": _audio_rns_raw_inbound_gap_over_160_count,
"rnsRawInboundGapOver320Count": _audio_rns_raw_inbound_gap_over_320_count,
"rnsRawInboundGapOver640Count": _audio_rns_raw_inbound_gap_over_640_count,
"rnsRawInboundGapOver1000Count": _audio_rns_raw_inbound_gap_over_1000_count,
"rnsRawInboundToLinkReceiveMsMax": _audio_rns_raw_inbound_to_link_receive_ms_max,
"rnsRawInboundToLinkReceiveOver80Count": _audio_rns_raw_inbound_to_link_receive_over_80_count,
"rnsRawInboundToLinkReceiveOver160Count": _audio_rns_raw_inbound_to_link_receive_over_160_count,
"rnsRawInboundToLinkReceiveOver320Count": _audio_rns_raw_inbound_to_link_receive_over_320_count,
"rnsRawInboundToLinkReceiveOver640Count": _audio_rns_raw_inbound_to_link_receive_over_640_count,
"rnsRawInboundToLinkReceiveOver1000Count": _audio_rns_raw_inbound_to_link_receive_over_1000_count,
"rnsRawInboundToLinkReceiveSamples": _audio_rns_raw_inbound_to_link_receive_samples,
"rnsRawInboundInterfaceLast": _audio_rns_raw_inbound_interface_last,
"rnsRawInboundInterfaceWorst": _audio_rns_raw_inbound_interface_worst,
"rnsSharedFrameGapMsWindow": _audio_rns_shared_frame_gap_ms_window,
"rnsSharedFrameGapMsMax": _audio_rns_shared_frame_gap_ms_max,
"rnsSharedFrameGapOver80Count": _audio_rns_shared_frame_gap_over_80_count,
"rnsSharedFrameGapOver160Count": _audio_rns_shared_frame_gap_over_160_count,
"rnsSharedFrameGapOver320Count": _audio_rns_shared_frame_gap_over_320_count,
"rnsSharedFrameGapOver640Count": _audio_rns_shared_frame_gap_over_640_count,
"rnsSharedFrameGapOver1000Count": _audio_rns_shared_frame_gap_over_1000_count,
"rnsSharedFrameToTransportInboundMsMax": _audio_rns_shared_frame_to_transport_inbound_ms_max,
"rnsSharedFrameToTransportInboundOver80Count": _audio_rns_shared_frame_to_transport_inbound_over_80_count,
"rnsSharedFrameToTransportInboundOver160Count": _audio_rns_shared_frame_to_transport_inbound_over_160_count,
"rnsSharedFrameToTransportInboundOver320Count": _audio_rns_shared_frame_to_transport_inbound_over_320_count,
"rnsSharedFrameToTransportInboundOver640Count": _audio_rns_shared_frame_to_transport_inbound_over_640_count,
"rnsSharedFrameToTransportInboundOver1000Count": _audio_rns_shared_frame_to_transport_inbound_over_1000_count,
"rnsSharedFrameToTransportInboundSamples": _audio_rns_shared_frame_to_transport_inbound_samples,
"rnsSharedFrameInterfaceLast": _audio_rns_shared_frame_interface_last,
"rnsSharedFrameInterfaceWorst": _audio_rns_shared_frame_interface_worst,
"schedulerDiagnostics": _scheduler_diagnostics(),
"mediaRouteDiagnostics": _audio_media_route_diagnostics(),
},
)
_maybe_log_bridge_pressure(now)
def _emit_binary_audio(chunk: bytes) -> bool:
global _audio_drops_binary_out, _audio_ipc_fd4_first_chunk_logged
try:
_audio_binary_out_queue.put_nowait((time.monotonic(), chunk))
_mark_audio_queue_state_dirty()
if not _audio_ipc_fd4_first_chunk_logged:
_audio_ipc_fd4_first_chunk_logged = True
log(
f"[presence_bridge] {_AUDIO_IPC_LOG} stage=fd4-first-chunk-enqueued-to-parent "
f"len={len(chunk)}"
)
return True
except queue.Full:
_audio_drops_binary_out += 1
_mark_audio_queue_state_dirty()
if _audio_drops_binary_out % 100 == 1:
log(
f"[presence_bridge] {_AUDIO_IPC_LOG} fd4=binary-out-queue-full drops={_audio_drops_binary_out}"
)
return False
def _read_exact(f: IO[bytes], n: int) -> bytes:
buf = b""
while len(buf) < n:
chunk = f.read(n - len(buf))
if not chunk:
raise EOFError()
buf += chunk
return buf
def _write_all_binary(f: IO[bytes], data: bytes) -> None:
"""Pipe writes may be partial; must loop until all bytes are sent."""
off = 0
mem = memoryview(data)
while off < len(data):
n = f.write(mem[off:])
if n is None:
f.flush()
continue
if not isinstance(n, int) or n <= 0:
raise OSError("fd4 write returned no progress")
off += n
f.flush()
def _parse_audio_batch_body(body: bytes) -> list:
if len(body) < 2:
raise ValueError("body too short")
n = int.from_bytes(body[0:2], "big")
if n == 0 or n > AUDIO_MAX_FRAMES:
raise ValueError("bad frame count")
o = 2
out: list = []
for _ in range(n):
if o >= len(body):
raise ValueError("truncated")
ll = body[o]
o += 1
if ll > AUDIO_MAX_LINK_ID_LEN or o + ll > len(body):
raise ValueError("bad link id")
link_id = body[o : o + ll].decode("utf-8")
o += ll
if o >= len(body):
raise ValueError("truncated")
rl = body[o]
o += 1
if rl > AUDIO_MAX_ROOM_ID_LEN or o + rl > len(body):
raise ValueError("bad room id")
room_id = body[o : o + rl].decode("utf-8")
o += rl
if o >= len(body):
raise ValueError("truncated")
pl = body[o]
o += 1
if pl > AUDIO_MAX_HASH_LEN or o + pl > len(body):
raise ValueError("bad pph")
peer_presence_hash = body[o : o + pl].decode("utf-8")
o += pl
if o >= len(body):
raise ValueError("truncated")
cl = body[o]
o += 1
if cl > AUDIO_MAX_HASH_LEN or o + cl > len(body):
raise ValueError("bad pch")
peer_call_hash = body[o : o + cl].decode("utf-8")
o += cl
if o + 2 > len(body):
raise ValueError("truncated plen")
plen = int.from_bytes(body[o : o + 2], "big")
o += 2
if o + 8 > len(body):
raise ValueError("truncated received_at")
received_at_wall_ms = int.from_bytes(body[o : o + 8], "big")
o += 8
if plen > AUDIO_MAX_PAYLOAD or o + plen > len(body):
raise ValueError("bad payload")
raw = bytes(body[o : o + plen])
o += plen
out.append(
(
link_id,
room_id,
peer_presence_hash,
peer_call_hash,
received_at_wall_ms,
raw,
)
)
if o != len(body):
raise ValueError("leftover")
return out
def _encode_audio_batch_binary(
frames: list,
) -> bytes:
"""frames: list of (link_id, room_id, peer_presence_hash, peer_call_hash, received_at_wall_ms, raw: bytes)"""
n = len(frames)
if n == 0 or n > AUDIO_MAX_FRAMES:
raise ValueError("bad frame count")
body = bytearray()
body.extend(n.to_bytes(2, "big"))
for link_id, room_id, pph, pch, received_at_wall_ms, raw in frames:
lid = link_id.encode("utf-8")
rid = room_id.encode("utf-8")
pb = pph.encode("utf-8")
cb = pch.encode("utf-8")
if (
len(lid) > AUDIO_MAX_LINK_ID_LEN
or len(rid) > AUDIO_MAX_ROOM_ID_LEN
or len(pb) > AUDIO_MAX_HASH_LEN
or len(cb) > AUDIO_MAX_HASH_LEN
or len(raw) > AUDIO_MAX_PAYLOAD
):
raise ValueError("field too large")
body.append(len(lid))
body.extend(lid)
body.append(len(rid))
body.extend(rid)
body.append(len(pb))
body.extend(pb)
body.append(len(cb))
body.extend(cb)
body.extend(len(raw).to_bytes(2, "big"))
body.extend(int(max(0, int(received_at_wall_ms))).to_bytes(8, "big"))
body.extend(raw)
body_bytes = bytes(body)
if len(body_bytes) > AUDIO_MAX_BODY:
raise ValueError("body too large")
header = bytearray()
header.extend(AUDIO_MAGIC)
header.append(AUDIO_VERSION)
header.extend(len(body_bytes).to_bytes(4, "big"))
return bytes(header) + body_bytes
def _filter_outbound_audio_deadline(
frames: list, now_wall_ms: Optional[int] = None
) -> tuple[list, int]:
"""Drop parent→child audio frames that already missed the live send deadline."""
if not frames:
return frames, 0
now_ms = (
now_wall_ms if isinstance(now_wall_ms, int) else int(time.time() * 1000)
)
deadline_ms = int(_AUDIO_OUTBOUND_DEADLINE_SECONDS * 1000)
fresh: list = []
dropped = 0
for frame in frames:
try:
received_at_wall_ms = int(frame[4])
except Exception:
received_at_wall_ms = 0
if received_at_wall_ms > 0 and now_ms - received_at_wall_ms > deadline_ms:
dropped += 1
continue
fresh.append(frame)
return fresh, dropped
def _note_fd3_decoded_age(frames: list) -> None:
global _audio_fd3_decoded_age_ms_max
if not frames:
return
now_ms = int(time.time() * 1000)
max_age = 0.0
max_frame: Optional[tuple] = None
for frame in frames:
try:
received_at_wall_ms = int(frame[4])
except Exception:
received_at_wall_ms = 0
if received_at_wall_ms > 0:
age_ms = float(max(0, now_ms - received_at_wall_ms))
if age_ms > max_age:
max_age = age_ms
max_frame = frame
if max_age > _audio_fd3_decoded_age_ms_max:
_audio_fd3_decoded_age_ms_max = max_age
_mark_audio_queue_state_dirty()
if max_age >= _AUDIO_TIMING_DELAY_LOG_THRESHOLD_MS and max_frame is not None:
try:
route_key = str(max_frame[0] or max_frame[2] or "")
room_id = str(max_frame[1] or "")
peer_presence_hash = str(max_frame[2] or "")
peer_destination_hash = str(max_frame[3] or "")
byte_count = len(max_frame[5]) if len(max_frame) > 5 else 0
except Exception:
route_key = "unknown"
room_id = ""
peer_presence_hash = ""
peer_destination_hash = ""
byte_count = 0
_log_audio_timing_anomaly(
"rns-audio-fd3-decoded-age",
f"fd3:{route_key}",
f"route={_short_route(route_key)} room={room_id or 'n/a'} "
f"age_ms={max_age:.0f} bytes={max(0, int(byte_count or 0))} "
f"peer={_short_route(peer_presence_hash)} dest={_short_route(peer_destination_hash)}",
)
def _note_decoded_queue_dwell_ms(dwell_ms: float) -> None:
global _audio_decoded_queue_dwell_ms_max
if dwell_ms > _audio_decoded_queue_dwell_ms_max:
_audio_decoded_queue_dwell_ms_max = dwell_ms
_mark_audio_queue_state_dirty()
if dwell_ms >= _AUDIO_TIMING_DELAY_LOG_THRESHOLD_MS:
_log_audio_timing_anomaly(
"rns-audio-decoded-queue-dwell",
"decoded-queue",
f"dwell_ms={dwell_ms:.0f}",
)
def _note_rns_send_duration(start_monotonic: float) -> float:
global _audio_rns_send_duration_ms_max, _audio_rns_send_slow_count
duration_ms = max(0.0, (time.monotonic() - start_monotonic) * 1000.0)
if duration_ms > _audio_rns_send_duration_ms_max:
_audio_rns_send_duration_ms_max = duration_ms
_mark_audio_queue_state_dirty()
if duration_ms >= _AUDIO_SLOW_RNS_SEND_LOG_THRESHOLD_MS:
_audio_rns_send_slow_count += 1
_mark_audio_queue_state_dirty()
log(
f"[presence_bridge] {_AUDIO_IPC_LOG} stage=rns-send-slow "
f"duration_ms={duration_ms:.3f} threshold_ms={_AUDIO_SLOW_RNS_SEND_LOG_THRESHOLD_MS:.1f}"
)
return duration_ms
def _note_packet_path_check_duration(start_monotonic: float) -> None:
global _audio_packet_path_check_ms_max
duration_ms = max(0.0, (time.monotonic() - start_monotonic) * 1000.0)
if duration_ms > _audio_packet_path_check_ms_max:
_audio_packet_path_check_ms_max = duration_ms
_mark_audio_queue_state_dirty()
def _note_executor_loop_gap(
previous_loop_at: Optional[float],
now: float,
queued_before_gap: int,
) -> None:
global _audio_executor_loop_gap_ms_max, _audio_executor_gap_while_queued_ms_max
global _audio_executor_stall_count
if previous_loop_at is None:
return
gap_ms = max(0.0, (now - previous_loop_at) * 1000.0)
if gap_ms > _audio_executor_loop_gap_ms_max:
_audio_executor_loop_gap_ms_max = gap_ms
_mark_audio_queue_state_dirty()
if queued_before_gap > 0 and gap_ms > _audio_executor_gap_while_queued_ms_max:
_audio_executor_gap_while_queued_ms_max = gap_ms
_mark_audio_queue_state_dirty()
if queued_before_gap > 0 and gap_ms >= _AUDIO_EXECUTOR_STALL_LOG_THRESHOLD_MS:
_audio_executor_stall_count += 1
_mark_audio_queue_state_dirty()
log(
f"[presence_bridge] {_AUDIO_IPC_LOG} stage=rns-executor-stall "
f"gap_ms={gap_ms:.3f} queued_before_gap={queued_before_gap} "
f"threshold_ms={_AUDIO_EXECUTOR_STALL_LOG_THRESHOLD_MS:.1f}"
)
def _note_executor_audio_pass_duration(start_monotonic: float, batches: int) -> None:
global _audio_executor_audio_pass_ms_max
if batches <= 0:
return
duration_ms = max(0.0, (time.monotonic() - start_monotonic) * 1000.0)
if duration_ms > _audio_executor_audio_pass_ms_max:
_audio_executor_audio_pass_ms_max = duration_ms
_mark_audio_queue_state_dirty()
def _note_process_audio_batch_duration(start_monotonic: float, frame_count: int) -> None:
global _audio_process_batch_ms_max, _audio_process_batch_frames_max
duration_ms = max(0.0, (time.monotonic() - start_monotonic) * 1000.0)
if duration_ms > _audio_process_batch_ms_max:
_audio_process_batch_ms_max = duration_ms
_mark_audio_queue_state_dirty()
if frame_count > _audio_process_batch_frames_max:
_audio_process_batch_frames_max = frame_count
_mark_audio_queue_state_dirty()
if duration_ms >= _AUDIO_PROCESS_BATCH_LOG_THRESHOLD_MS:
log(
f"[presence_bridge] {_AUDIO_IPC_LOG} stage=process-audio-batch-slow "
f"duration_ms={duration_ms:.3f} frames={frame_count} "
f"threshold_ms={_AUDIO_PROCESS_BATCH_LOG_THRESHOLD_MS:.1f}"
)
def _note_executor_command_duration(
start_monotonic: float,
action: Any,
audio_queued_at_start: int,
) -> None:
global _audio_executor_command_ms_max, _audio_executor_command_while_queued_ms_max
global _audio_executor_command_slow_count
duration_ms = max(0.0, (time.monotonic() - start_monotonic) * 1000.0)
if duration_ms > _audio_executor_command_ms_max:
_audio_executor_command_ms_max = duration_ms
_mark_audio_queue_state_dirty()
if audio_queued_at_start > 0 and duration_ms > _audio_executor_command_while_queued_ms_max:
_audio_executor_command_while_queued_ms_max = duration_ms
_mark_audio_queue_state_dirty()
if duration_ms >= _AUDIO_EXECUTOR_COMMAND_LOG_THRESHOLD_MS:
_audio_executor_command_slow_count += 1
_mark_audio_queue_state_dirty()
log(
f"[presence_bridge] {_AUDIO_IPC_LOG} stage=rns-executor-command-slow "
f"duration_ms={duration_ms:.3f} action={str(action)[:80]!r} "
f"audio_queued_at_start={audio_queued_at_start} "
f"threshold_ms={_AUDIO_EXECUTOR_COMMAND_LOG_THRESHOLD_MS:.1f}"
)
def _put_audio_decoded_batch_keep_newest(frames: list) -> bool:
"""Admit fresh outbound audio by evicting the oldest decoded batch under pressure."""
global _audio_drops_ingress, _audio_decoded_queue_evict_oldest
global _audio_decoded_queue_drop_newest
queued = (time.monotonic(), frames)
try:
_audio_decoded_queue.put_nowait(queued)
_mark_audio_queue_state_dirty()
_notify_rns_work_available()
return True
except queue.Full:
pass
evicted_oldest = False
try:
dropped = _audio_decoded_queue.get_nowait()
if dropped is not None:
evicted_oldest = True
_audio_drops_ingress += 1
_audio_decoded_queue_evict_oldest += 1
except queue.Empty:
pass
try:
_audio_decoded_queue.put_nowait(queued)
_mark_audio_queue_state_dirty()
_notify_rns_work_available()
if evicted_oldest and _audio_drops_ingress % 100 == 1:
log(
f"[presence_bridge] {_AUDIO_IPC_LOG} fd3=decoded-queue-full "
f"evicted_oldest drops={_audio_drops_ingress}"
)
return True
except queue.Full:
_audio_drops_ingress += 1
_audio_decoded_queue_drop_newest += 1
_mark_audio_queue_state_dirty()
if _audio_drops_ingress % 100 == 1:
log(
f"[presence_bridge] {_AUDIO_IPC_LOG} fd3=decoded-queue-full "
f"drop_newest drops={_audio_drops_ingress}"
)
return False
def _process_audio_batch(frames: list) -> None:
"""frames: list of (link_id, room_id, peer_presence_hash, peer_call_hash, received_at_wall_ms, raw_opus_bytes)"""
global _audio_ipc_rns_first_send_ok_logged, _audio_packet_send_failures
global _audio_packet_fresh_sends, _audio_packet_stale_sends, _audio_packet_unknown_sends
process_start = time.monotonic()
for link_id, room_id, peer_presence_hash, peer_call_hash, _received_at_wall_ms, raw in frames:
if link_id:
peer_key_hint = str(peer_presence_hash or peer_call_hash or "").strip().lower()
snapshot = _snapshot_audio_link_for_send(link_id, peer_key_hint)
send_link_id = str(snapshot.get("linkId") or link_id) if snapshot is not None else link_id
if snapshot is None:
emit_event(
"group_audio_send_failed",
{
"linkId": link_id,
"peerPresenceHash": peer_key_hint,
"reason": "unknown_link_id",
"code": "unknown_link_id",
"transport": "link",
},
)
continue
if snapshot.get("ready") is not True:
emit_event(
"group_audio_send_failed",
{
"linkId": send_link_id,
"peerPresenceHash": str(snapshot.get("peerPresenceHash") or ""),
"reason": str(snapshot.get("reason") or "audio_link_not_ready"),
"code": str(snapshot.get("reason") or "audio_link_not_ready"),
"transport": "link",
},
)
continue
link = snapshot.get("link")
if link is None:
emit_event(
"group_audio_send_failed",
{
"linkId": send_link_id,
"peerPresenceHash": str(snapshot.get("peerPresenceHash") or ""),
"reason": "unknown_link_id",
"code": "unknown_link_id",
"transport": "link",
},
)
continue
try:
wire_bytes = make_group_audio_wire(room_id, raw)
max_wire_bytes = _MAX_ENCRYPTED_WIRE_BYTES
try:
link_mdu = link.get_mdu()
if isinstance(link_mdu, int) and link_mdu > 0:
max_wire_bytes = link_mdu
except Exception:
pass
if len(wire_bytes) > max_wire_bytes:
emit_event(
"group_audio_send_failed",
{
"linkId": send_link_id,
"peerPresenceHash": str(snapshot.get("peerPresenceHash") or ""),
"reason": "audio_payload_too_large",
"code": "audio_payload_too_large",
"transport": "link",
},
)
continue
send_lock = snapshot.get("sendLock")
generation = int(snapshot.get("generation") or 0)
if send_lock is None:
send_lock = threading.RLock()
with send_lock:
if not _audio_link_generation_matches(send_link_id, generation):
emit_event(
"group_audio_send_failed",
{
"linkId": send_link_id,
"peerPresenceHash": str(snapshot.get("peerPresenceHash") or ""),
"reason": "audio_link_generation_changed",
"code": "audio_link_generation_changed",
"transport": "link",
},
)
continue
packet = RNS.Packet(link, wire_bytes, create_receipt=False)
send_start = time.monotonic()
result = packet.send()
send_duration_ms = _note_rns_send_duration(send_start)
if result is False:
_audio_packet_send_failures += 1
_note_audio_route_send(
"link",
send_link_id,
room_id,
str(snapshot.get("peerPresenceHash") or ""),
str(snapshot.get("peerDestinationHash") or ""),
len(wire_bytes),
ok=False,
incoming=snapshot.get("incoming") is True,
source_received_at_wall_ms=_received_at_wall_ms,
send_duration_ms=send_duration_ms,
)
_mark_audio_queue_state_dirty()
emit_event(
"group_audio_send_failed",
{
"linkId": send_link_id,
"peerPresenceHash": str(snapshot.get("peerPresenceHash") or ""),
"reason": "packet_send_false",
"code": "packet_send_false",
"transport": "link",
},
)
else:
with _state_lock:
current_state = _audio_links_by_id.get(send_link_id)
if current_state is not None:
now_send = time.time()
current_state["last_send_ok_at"] = now_send
current_state["last_activity_at"] = now_send
_note_audio_route_send(
"link",
send_link_id,
room_id,
str(snapshot.get("peerPresenceHash") or ""),
str(snapshot.get("peerDestinationHash") or ""),
len(wire_bytes),
ok=True,
incoming=snapshot.get("incoming") is True,
source_received_at_wall_ms=_received_at_wall_ms,
send_duration_ms=send_duration_ms,
)
if not _audio_ipc_rns_first_send_ok_logged:
_audio_ipc_rns_first_send_ok_logged = True
log(
f"[presence_bridge] {_AUDIO_IPC_LOG} stage=rns-first-packet-send-ok "
f"link_prefix={send_link_id[:8] if len(send_link_id) >= 8 else send_link_id} bytes_wire={len(wire_bytes)}"
)
continue
except Exception as exc:
_audio_packet_send_failures += 1
_note_audio_route_send(
"link",
send_link_id,
room_id,
str(snapshot.get("peerPresenceHash") or ""),
str(snapshot.get("peerDestinationHash") or ""),
0,
ok=False,
incoming=snapshot.get("incoming") is True,
)
_mark_audio_queue_state_dirty()
emit_event(
"group_audio_send_failed",
{
"linkId": send_link_id,
"peerPresenceHash": str(snapshot.get("peerPresenceHash") or ""),
"reason": "exception",
"code": "exception",
"error": str(exc),
"transport": "link",
},
)
continue
peer_hash = str(peer_presence_hash or "").strip().lower()
if not peer_hash:
emit_event(
"group_audio_send_failed",
{
"reason": "unknown_peer_presence_hash",
"code": "unknown_peer_presence_hash",
"transport": "packet",
},
)
continue
peer_identity = _get_group_audio_peer_identity(peer_hash)
if peer_identity is None:
emit_event(
"group_audio_send_failed",
{
"peerPresenceHash": peer_hash,
"reason": "unknown_peer_presence_hash",
"code": "unknown_peer_presence_hash",
"transport": "packet",
},
)
continue
try:
outbound = build_outbound_destination(peer_identity)
destination_hash = outbound.hash
path_check_start = time.monotonic()
path_state, path_ready = _ensure_call_media_path(
peer_hash,
destination_hash,
active_call=True,
allow_wait=False,
reason="audio_send",
)
_note_packet_path_check_duration(path_check_start)
if path_state == "fresh":
_audio_packet_fresh_sends += 1
elif path_state in ("stale", "warming"):
_audio_packet_stale_sends += 1
else:
_audio_packet_unknown_sends += 1
_mark_audio_queue_state_dirty()
if not path_ready:
emit_event(
"group_audio_send_failed",
{
"peerPresenceHash": peer_hash,
"reason": "path_request_timeout",
"code": "path_request_timeout",
"pathState": path_state,
"transport": "packet",
},
)
continue
wire_bytes = make_group_audio_wire(room_id, raw)
if len(wire_bytes) > _MAX_ENCRYPTED_WIRE_BYTES:
emit_event(
"group_audio_send_failed",
{
"peerPresenceHash": peer_hash,
"reason": "audio_payload_too_large",
"code": "audio_payload_too_large",
"transport": "packet",
},
)
continue
packet = RNS.Packet(outbound, wire_bytes, create_receipt=False)
send_start = time.monotonic()
result = packet.send()
send_duration_ms = _note_rns_send_duration(send_start)
if result is False:
_audio_packet_send_failures += 1
_note_audio_route_send(
"packet",
str(peer_hash),
room_id,
str(peer_hash),
str(peer_call_hash or destination_hash_hex(destination_hash)),
len(wire_bytes),
ok=False,
source_received_at_wall_ms=_received_at_wall_ms,
send_duration_ms=send_duration_ms,
)
_note_call_media_send_result(peer_hash, False)
_mark_audio_queue_state_dirty()
emit_event(
"group_audio_send_failed",
{
"peerPresenceHash": peer_hash,
"reason": "packet_send_false",
"code": "packet_send_false",
"transport": "packet",
},
)
continue
_note_audio_route_send(
"packet",
str(peer_hash),
room_id,
str(peer_hash),
str(peer_call_hash or destination_hash_hex(destination_hash)),
len(wire_bytes),
ok=True,
source_received_at_wall_ms=_received_at_wall_ms,
send_duration_ms=send_duration_ms,
)
_note_call_media_send_result(peer_hash, True)
if not _audio_ipc_rns_first_send_ok_logged:
_audio_ipc_rns_first_send_ok_logged = True
target = str(peer_call_hash or destination_hash_hex(destination_hash))
log(
f"[presence_bridge] {_AUDIO_IPC_LOG} stage=rns-first-packet-send-ok "
f"packet_peer={target[:16]} bytes_wire={len(wire_bytes)}"
)
except Exception as exc:
_audio_packet_send_failures += 1
_note_audio_route_send(
"packet",
str(peer_hash),
room_id,
str(peer_hash),
str(peer_call_hash or ""),
0,
ok=False,
)
_note_call_media_send_result(peer_hash, False)
_mark_audio_queue_state_dirty()
emit_event(
"group_audio_send_failed",
{
"peerPresenceHash": peer_hash,
"reason": "exception",
"code": "exception",
"error": str(exc),
"transport": "packet",
},
)
_note_process_audio_batch_duration(process_start, len(frames))
def _stdout_writer_loop() -> None:
resp_closed = False
event_closed = False
while True:
if not resp_closed:
try:
frame = _json_resp_queue.get_nowait()
except queue.Empty:
frame = None
else:
if frame is None:
resp_closed = True
else:
sys.stdout.write(json.dumps(frame, separators=(",", ":")) + "\n")
sys.stdout.flush()
continue
if resp_closed and event_closed:
break
if not resp_closed:
try:
frame = _json_resp_queue.get(timeout=0.01)
except queue.Empty:
frame = None
else:
if frame is None:
resp_closed = True
else:
sys.stdout.write(json.dumps(frame, separators=(",", ":")) + "\n")
sys.stdout.flush()
continue
if event_closed:
continue
try:
frame = _json_event_queue.get(timeout=0.05)
except queue.Empty:
continue
if frame is None:
event_closed = True
continue
sys.stdout.write(json.dumps(frame, separators=(",", ":")) + "\n")
sys.stdout.flush()
def _audio_binary_out_writer_loop() -> None:
try:
outf = open(4, "wb", buffering=0)
except OSError as exc:
log(f"[presence_bridge] {_AUDIO_IPC_LOG} fd4=open-failed child→parent-binary-disabled err={exc}")
return
log(
f"[presence_bridge] {_AUDIO_IPC_LOG} fd4=egress-ready child→parent-binary (inbound audio to Electron)"
)
while True:
queued = _audio_binary_out_queue.get()
if queued is None:
break
try:
_queued_at, chunk = queued
_write_all_binary(outf, chunk)
except BrokenPipeError:
break
except Exception as exc:
log(f"[presence_bridge] {_AUDIO_IPC_LOG} fd4=write-error err={exc}")
def _open_audio_input_fd_for_audio_reader() -> Optional[int]:
global _audio_in_fd
try:
os.set_blocking(3, False)
except OSError as exc:
log(f"[presence_bridge] {_AUDIO_IPC_LOG} fd3=open-failed parent→child-binary-disabled err={exc}")
return None
_audio_in_fd = 3
log(
f"[presence_bridge] {_AUDIO_IPC_LOG} fd3=ingress-ready parent→child-binary "
f"(outbound audio from Electron, dedicated-reader)"
)
return _audio_in_fd
def _audio_input_buffer_has_complete_batch(buffer: bytearray) -> bool:
if len(buffer) < AUDIO_HEADER_BYTES:
return False
if bytes(buffer[0:4]) != AUDIO_MAGIC:
return True
body_len = int.from_bytes(buffer[5:9], "big")
return len(buffer) >= AUDIO_HEADER_BYTES + body_len
def _read_audio_input_available(fd: int, buffer: bytearray) -> bool:
while True:
try:
chunk = os.read(fd, 65536)
except BlockingIOError:
return True
except OSError as exc:
log(f"[presence_bridge] {_AUDIO_IPC_LOG} fd3=read-error err={exc}")
return False
if not chunk:
return False
buffer.extend(chunk)
def _process_audio_input_frames(frames: list, queued_at: float) -> bool:
global _audio_stale_drops, _audio_deadline_drops, _audio_ipc_fd3_first_batch_ok_logged
global _audio_fd3_parse_last_wall_ms_by_route
batch_age = max(0.0, time.monotonic() - queued_at)
now_wall_ms = int(time.time() * 1000)
for frame in frames:
try:
route_key = str(frame[0] or frame[2] or "")
room_id = str(frame[1] or "")
peer_presence_hash = str(frame[2] or "")
peer_destination_hash = str(frame[3] or "")
payload = frame[5] if len(frame) > 5 else b""
byte_count = (
len(payload) if isinstance(payload, (bytes, bytearray)) else 0
)
frame_kind, control_type = _inspect_gcall_audio_payload(payload)
except Exception:
route_key = "unknown"
room_id = ""
peer_presence_hash = ""
peer_destination_hash = ""
byte_count = 0
frame_kind = "media"
control_type = ""
previous_parse_ms = int(
_audio_fd3_parse_last_wall_ms_by_route.get(route_key) or 0
)
if previous_parse_ms > 0:
parse_gap_ms = max(0, now_wall_ms - previous_parse_ms)
if parse_gap_ms >= _AUDIO_TIMING_GAP_LOG_THRESHOLD_MS:
stage = (
"rns-control-fd3-parse-gap"
if frame_kind == "control"
else "rns-audio-fd3-parse-gap"
)
_log_audio_timing_anomaly(
stage,
f"fd3:{route_key}",
f"route={_short_route(route_key)} room={room_id or 'n/a'} "
f"gap_ms={parse_gap_ms} bytes={max(0, int(byte_count or 0))} "
f"frame_kind={frame_kind}"
f"{(' control_type=' + control_type) if control_type else ''} "
f"peer={_short_route(peer_presence_hash)} dest={_short_route(peer_destination_hash)}",
)
_audio_fd3_parse_last_wall_ms_by_route[route_key] = now_wall_ms
_note_fd3_decoded_age(frames)
frames, deadline_drops = _filter_outbound_audio_deadline(frames)
if deadline_drops > 0:
_audio_deadline_drops += deadline_drops
_audio_stale_drops += deadline_drops
_mark_audio_queue_state_dirty()
_emit_audio_queue_state()
if not frames:
return False
if not _audio_ipc_fd3_first_batch_ok_logged:
_audio_ipc_fd3_first_batch_ok_logged = True
nframes = len(frames) if isinstance(frames, list) else 0
log(
f"[presence_bridge] {_AUDIO_IPC_LOG} stage=fd3-first-batch-from-parent-parsed "
f"frames={nframes} mode=dedicated-reader"
)
if batch_age > _AUDIO_BATCH_STALE_SECONDS:
_audio_stale_drops += len(frames)
_mark_audio_queue_state_dirty()
return False
return _put_audio_decoded_batch_keep_newest(frames)
def _drain_audio_input_buffer(buffer: bytearray, batch_budget: int) -> tuple[bool, int]:
drained_audio = False
drained_batches = 0
while drained_batches < batch_budget and len(buffer) >= AUDIO_HEADER_BYTES:
if bytes(buffer[0:4]) != AUDIO_MAGIC:
del buffer[0:1]
log(f"[presence_bridge] {_AUDIO_IPC_LOG} fd3=bad-magic")
continue
if buffer[4] != AUDIO_VERSION:
got_version = buffer[4]
del buffer[:AUDIO_HEADER_BYTES]
log(f"[presence_bridge] {_AUDIO_IPC_LOG} fd3=bad-version got={got_version}")
continue
body_len = int.from_bytes(buffer[5:9], "big")
if body_len > AUDIO_MAX_BODY or body_len < 2:
del buffer[:AUDIO_HEADER_BYTES]
log(f"[presence_bridge] {_AUDIO_IPC_LOG} fd3=bad-body_len len={body_len}")
continue
frame_len = AUDIO_HEADER_BYTES + body_len
if len(buffer) < frame_len:
break
queued_at = time.monotonic()
body = bytes(buffer[AUDIO_HEADER_BYTES:frame_len])
del buffer[:frame_len]
try:
frames = _parse_audio_batch_body(body)
except ValueError as exc:
log(f"[presence_bridge] {_AUDIO_IPC_LOG} fd3=parse-batch-failed err={exc}")
continue
_process_audio_input_frames(frames, queued_at)
drained_audio = True
drained_batches += 1
if drained_audio:
_mark_audio_queue_state_dirty()
_emit_audio_queue_state()
return drained_audio, drained_batches
def _audio_fd3_reader_loop() -> None:
audio_input_buffer = bytearray()
audio_fd = _open_audio_input_fd_for_audio_reader()
if audio_fd is None:
return
selector = None
selector_enabled = False
if os.name == "nt":
log(f"[presence_bridge] {_AUDIO_IPC_LOG} stage=fd3-reader-selector-skipped platform=windows")
else:
selector = selectors.DefaultSelector()
try:
selector.register(audio_fd, selectors.EVENT_READ, "audio")
selector_enabled = True
except Exception as exc:
log(f"[presence_bridge] {_AUDIO_IPC_LOG} stage=fd3-reader-selector-setup-failed err={exc}")
try:
selector.close()
except Exception:
pass
selector = None
selector_enabled = False
log(f"[presence_bridge] {_AUDIO_IPC_LOG} stage=fd3-reader-thread-started")
try:
while not _shutdown.is_set():
if _audio_input_buffer_has_complete_batch(audio_input_buffer):
_drain_audio_input_buffer(audio_input_buffer, _AUDIO_MAX_BATCHES_PER_EXECUTOR_PASS)
continue
if selector_enabled:
try:
assert selector is not None
events = selector.select(timeout=0.05)
except Exception as exc:
log(f"[presence_bridge] {_AUDIO_IPC_LOG} stage=fd3-reader-selector-error err={exc}")
selector_enabled = False
try:
if selector is not None:
selector.close()
except Exception:
pass
selector = None
events = []
for _key, _mask in events:
if not _read_audio_input_available(audio_fd, audio_input_buffer):
log(f"[presence_bridge] {_AUDIO_IPC_LOG} fd3=closed")
return
else:
if not _read_audio_input_available(audio_fd, audio_input_buffer):
log(f"[presence_bridge] {_AUDIO_IPC_LOG} fd3=closed")
return
if not _audio_input_buffer_has_complete_batch(audio_input_buffer):
time.sleep(0.005)
if _audio_input_buffer_has_complete_batch(audio_input_buffer):
_drain_audio_input_buffer(audio_input_buffer, _AUDIO_MAX_BATCHES_PER_EXECUTOR_PASS)
else:
_emit_audio_queue_state()
finally:
if selector is not None:
try:
selector.close()
except Exception:
pass
def _audio_frame_route_key(frame: Any) -> str:
try:
link_id, _room_id, peer_presence_hash, peer_call_hash, *_rest = frame
except Exception:
return "unknown"
link_key = str(link_id or "").strip()
if link_key:
return f"link:{link_key}"
peer_key = str(peer_presence_hash or peer_call_hash or "").strip().lower()
return f"packet:{peer_key or 'unknown'}"
def _audio_scheduler_lane_for_route(route_key: str) -> str:
digest = hashlib.blake2s(str(route_key or "unknown").encode("utf-8"), digest_size=2).digest()
shard = int.from_bytes(digest, "big") % max(1, _SCHEDULER_AUDIO_SHARDS)
return f"audio-send-{shard}"
def _enqueue_audio_send_batch(route_key: str, batch: list) -> bool:
if not batch:
return False
lane = _audio_scheduler_lane_for_route(route_key)
return _enqueue_scheduler_task(
lane,
f"audio-send:{route_key}",
_process_audio_batch,
batch,
drop_oldest=True,
)
def _drain_audio_executor_pass(batch_budget: int) -> tuple[bool, int]:
global _audio_stale_drops, _audio_deadline_drops
global _audio_drops_ingress, _audio_decoded_queue_drop_newest
drained_audio = False
drained_batches = 0
audio_pass_start = time.monotonic()
try:
while drained_batches < batch_budget:
queued = _audio_decoded_queue.get_nowait()
if queued is None:
break
queued_at, batch = queued
batch_age = time.monotonic() - queued_at
_note_decoded_queue_dwell_ms(batch_age * 1000.0)
if batch_age > _AUDIO_BATCH_STALE_SECONDS:
_audio_stale_drops += len(batch)
_mark_audio_queue_state_dirty()
else:
batch, deadline_drops = _filter_outbound_audio_deadline(batch)
if deadline_drops > 0:
_audio_deadline_drops += deadline_drops
_audio_stale_drops += deadline_drops
_mark_audio_queue_state_dirty()
if batch:
by_route: Dict[str, list] = {}
for frame in batch:
route_key = _audio_frame_route_key(frame)
by_route.setdefault(route_key, []).append(frame)
for route_key, route_batch in by_route.items():
if not _enqueue_audio_send_batch(route_key, route_batch):
_audio_drops_ingress += len(route_batch)
_audio_decoded_queue_drop_newest += len(route_batch)
_mark_audio_queue_state_dirty()
drained_audio = True
drained_batches += 1
except queue.Empty:
pass
_note_executor_audio_pass_duration(audio_pass_start, drained_batches)
if drained_audio:
_mark_audio_queue_state_dirty()
_emit_audio_queue_state()
return drained_audio, drained_batches
def _handle_rns_command_message(
message: Optional[Dict[str, Any]],
audio_queued_at_start_override: Optional[int] = None,
) -> bool:
if message is None:
try:
while True:
queued = _audio_decoded_queue.get_nowait()
if queued is None:
continue
_, batch = queued
_process_audio_batch(batch)
except queue.Empty:
pass
_emit_audio_queue_state(force=True)
return False
action = message.get("action") if isinstance(message, dict) else None
lane = _scheduler_lane_for_command(action)
ok = _enqueue_scheduler_task(lane, f"cmd:{action or 'unknown'}", handle_command, message)
if not ok:
req_id = str(message.get("id") or "") if isinstance(message, dict) else ""
if req_id:
emit_resp(
req_id,
False,
payload={"code": "scheduler_queue_full", "lane": lane},
error=f"Reticulum scheduler lane is full: {lane}",
)
else:
emit_event(
"error",
{
"code": "scheduler_queue_full",
"message": f"Reticulum scheduler lane is full: {lane}",
"action": str(action or ""),
},
)
_emit_audio_queue_state()
return True
def _scheduler_lane_for_command(action: Any) -> str:
action_name = str(action or "")
if action_name in {"clear_group_audio_diagnostics"}:
return "control-send"
if action_name in {
"open_group_audio_link",
"close_group_audio_link",
"reset_group_audio_peer_state",
"overlay_sync_state",
}:
return "link-management"
if action_name in {"warm_group_audio_path"}:
return "path-management"
if action_name in {
"accept_qchat_file_resource",
"send_qchat_file_resource",
"authorize_qchat_file_resource",
"reject_qchat_file_resource",
}:
return "file-transfer"
return "control-send"
def _rns_executor_loop() -> None:
last_loop_at: Optional[float] = None
queued_before_gap = 0
next_lane = "audio"
selector = selectors.DefaultSelector()
selector_enabled = False
try:
if _rns_wake_read_fd is not None:
selector.register(_rns_wake_read_fd, selectors.EVENT_READ, "wake")
selector_enabled = bool(selector.get_map())
except Exception as exc:
log(f"[presence_bridge] {_AUDIO_IPC_LOG} stage=rns-owner-selector-setup-failed err={exc}")
try:
selector.close()
except Exception:
pass
selector_enabled = False
while True:
loop_start = time.monotonic()
_note_executor_loop_gap(last_loop_at, loop_start, queued_before_gap)
last_loop_at = loop_start
audio_ready = not _audio_decoded_queue.empty()
cmd_ready = not _cmd_queue_bounded.empty()
if not audio_ready and not cmd_ready:
if _shutdown.is_set():
return
queued_before_gap = 0
_emit_audio_queue_state()
_maybe_log_bridge_pressure()
if selector_enabled:
try:
events = selector.select(timeout=0.05)
except Exception as exc:
log(f"[presence_bridge] {_AUDIO_IPC_LOG} stage=rns-owner-selector-error err={exc}")
events = []
for key, _mask in events:
if key.data == "wake":
_drain_rns_wake_pipe()
else:
try:
message = _cmd_queue_bounded.get(timeout=0.01)
except queue.Empty:
time.sleep(0.002)
continue
if not _handle_rns_command_message(message, 0):
return
next_lane = "audio"
queued_before_gap = _audio_decoded_queue.qsize()
continue
if audio_ready and (not cmd_ready or next_lane == "audio"):
decoded_backlog = _audio_decoded_queue.qsize()
if cmd_ready:
batch_budget = _AUDIO_MIN_BATCHES_PER_EXECUTOR_PASS
else:
batch_budget = min(
_AUDIO_MAX_BATCHES_PER_EXECUTOR_PASS,
_AUDIO_MIN_BATCHES_PER_EXECUTOR_PASS
+ max(0, decoded_backlog // _AUDIO_BACKLOG_BATCH_STEP),
)
_drain_audio_executor_pass(batch_budget)
next_lane = "cmd"
queued_before_gap = _audio_decoded_queue.qsize()
continue
if cmd_ready:
try:
message = _cmd_queue_bounded.get_nowait()
except queue.Empty:
queued_before_gap = _audio_decoded_queue.qsize()
continue
audio_queued_at_start = _audio_decoded_queue.qsize()
if not _handle_rns_command_message(message, audio_queued_at_start):
return
next_lane = "audio"
queued_before_gap = _audio_decoded_queue.qsize()
continue
def log(message: str) -> None:
print(message, file=sys.stderr, flush=True)
def verbose_presence_log(message: str) -> None:
if _PRESENCE_BRIDGE_VERBOSE_LOGS:
log(message)
def as_bool(value: Any) -> bool:
if isinstance(value, bool):
return value
if isinstance(value, (int, float)):
return value != 0
return False
def _compact_interface_value(value: Any) -> str:
if isinstance(value, bool):
return "yes" if value else "no"
if isinstance(value, (int, float)):
if isinstance(value, float):
return f"{value:.3f}".rstrip("0").rstrip(".")
return str(value)
return str(value or "").replace(",", "_").replace(" ", "_")[:80]
def _compact_interface_detail(item: Dict[str, Any]) -> str:
name = str(item.get("name") or item.get("short_name") or item.get("ifac_name") or "")
interface_type = str(item.get("type") or item.get("ifac_type") or "")
online = as_bool(item.get("status"))
parts = [
f"name={name.replace(',', '_')[:80] or 'unknown'}",
f"type={interface_type.replace(',', '_')[:48] or 'unknown'}",
f"online={'yes' if online else 'no'}",
]
wanted_keys = (
"rxb",
"txb",
"rxs",
"txs",
"rx",
"tx",
"rx_bytes",
"tx_bytes",
"rx_bitrate",
"tx_bitrate",
"bitrate",
"clients",
"peers",
"held_announces",
"announces",
)
for key in wanted_keys:
if key in item:
parts.append(f"{key}={_compact_interface_value(item.get(key))}")
return "{" + ";".join(parts) + "}"
def _collect_rns_interface_pressure_summary(max_interfaces: int = 12) -> str:
if _reticulum is None:
return "reticulum=not-started"
try:
stats = _reticulum.get_interface_stats() or {}
except Exception as exc:
return f"error={str(exc).replace(' ', '_')[:120]}"
interfaces = stats.get("interfaces")
if not isinstance(interfaces, list):
interfaces = []
details = [
_compact_interface_detail(item)
for item in interfaces[:max_interfaces]
if isinstance(item, dict)
]
omitted = max(0, len(interfaces) - len(details))
top_parts = [
f"transport={'on' if 'transport_id' in stats else 'off'}",
f"interfaces={len(interfaces)}",
]
for key in ("transport_id", "rss", "ifac_size", "path_table_size", "link_count"):
if key in stats:
top_parts.append(f"{key}={_compact_interface_value(stats.get(key))}")
if omitted > 0:
top_parts.append(f"omitted={omitted}")
return " ".join(top_parts) + " details=" + "|".join(details)
def _maybe_log_rns_interface_pressure(
gap_ms: float,
*,
reason: str,
now: Optional[float] = None,
) -> None:
global _rns_interface_pressure_last_log_at
if gap_ms < _BRIDGE_PRESSURE_RNS_GAP_THRESHOLD_MS:
return
if now is None:
now = time.monotonic()
if now - _rns_interface_pressure_last_log_at < _RNS_INTERFACE_PRESSURE_LOG_INTERVAL_SECONDS:
return
_rns_interface_pressure_last_log_at = now
log(
"[presence_bridge] rns_interface_pressure "
f"reason={reason} gap_ms={int(gap_ms)} "
f"{_collect_rns_interface_pressure_summary()}"
)
def _is_qortal_mesh_listen_name(name: str) -> bool:
"""Match managed-config section title; RNS may use a short or long display name."""
n = (name or "").strip()
if n == "Qortal Hub Mesh Listen":
return True
return "Qortal Hub Mesh Listen" in n
def _is_mesh_listen_inbound_backbone_client(item: Dict[str, Any]) -> bool:
"""
Inbound peers attached to mesh listen appear as BackboneClientInterface with
"Client on Qortal Hub Mesh Listen" in the name. Those are not bootstrap hubs.
Outbound Backbone hubs (e.g. phantom.mobilefabrik.com) use the same type.
"""
if str(item.get("type") or "") != "BackboneClientInterface":
return False
n = str(item.get("name") or item.get("short_name") or "")
return "Client on Qortal Hub Mesh Listen" in n
def summarize_transport_state(payload: Dict[str, Any]) -> str:
return (
f"{payload.get('reachability')} "
f"hubs={payload.get('onlineHubInterfaces', 0)}/{payload.get('configuredHubInterfaces', 0)} "
f"remote_hubs={payload.get('onlineRemoteHubInterfaces', 0)}/{payload.get('configuredRemoteHubInterfaces', 0)} "
f"transport={'on' if payload.get('transportEnabled') else 'off'}"
)
def collect_transport_state() -> Dict[str, Any]:
if _reticulum is None:
return {
"reachability": "unknown",
"transportEnabled": False,
"configuredHubInterfaces": 0,
"onlineHubInterfaces": 0,
"configuredRemoteHubInterfaces": 0,
"onlineRemoteHubInterfaces": 0,
"hubSummary": "Reticulum bridge not started",
"reason": "Reticulum bridge not started",
"meshListenOnline": False,
}
stats = _reticulum.get_interface_stats() or {}
interfaces = stats.get("interfaces")
if not isinstance(interfaces, list):
interfaces = []
normalised = []
for item in interfaces:
if not isinstance(item, dict):
continue
normalised.append(
{
"name": str(item.get("name") or item.get("short_name") or ""),
"type": str(item.get("type") or ""),
"online": as_bool(item.get("status")),
}
)
hub_interfaces = [
item
for item in normalised
if item.get("type")
in ("TCPClientInterface", "BackboneInterface", "BackboneClientInterface")
and not _is_mesh_listen_inbound_backbone_client(item)
]
# Outbound bootstrap hubs only — exclude local mesh listen (same Backbone type on Linux).
remote_hub_interfaces = [
item
for item in hub_interfaces
if not _is_qortal_mesh_listen_name(str(item.get("name") or ""))
]
online_hubs = [item for item in hub_interfaces if item.get("online")]
online_remote_hubs = [item for item in remote_hub_interfaces if item.get("online")]
local_auto_online = any(
item.get("online") and item.get("type") == "AutoInterface"
for item in normalised
)
if online_hubs:
reachability = "hub-connected"
elif hub_interfaces:
reachability = "disconnected"
elif local_auto_online:
reachability = "lan-only"
else:
reachability = "unknown"
if hub_interfaces:
hub_summary = ", ".join(
[
f"{item.get('name') or item.get('type')}={'online' if item.get('online') else 'offline'}"
for item in hub_interfaces
]
)
elif local_auto_online:
hub_summary = "LAN-only discovery available"
else:
hub_summary = "No active Reticulum interfaces"
mesh_listen_online = False
_mesh_listen_types = frozenset({"BackboneInterface", "TCPServerInterface"})
for item in normalised:
if (
_is_qortal_mesh_listen_name(str(item.get("name") or ""))
and item.get("type") in _mesh_listen_types
and item.get("online")
):
mesh_listen_online = True
break
return {
"reachability": reachability,
"transportEnabled": "transport_id" in stats,
"configuredHubInterfaces": len(hub_interfaces),
"onlineHubInterfaces": len(online_hubs),
"configuredRemoteHubInterfaces": len(remote_hub_interfaces),
"onlineRemoteHubInterfaces": len(online_remote_hubs),
"hubSummary": hub_summary,
"meshListenOnline": mesh_listen_online,
}
def maybe_emit_transport_state(force: bool = False) -> None:
global _last_transport_state
try:
payload = collect_transport_state()
except Exception as exc:
payload = {
"reachability": "unknown",
"transportEnabled": False,
"configuredHubInterfaces": 0,
"onlineHubInterfaces": 0,
"configuredRemoteHubInterfaces": 0,
"onlineRemoteHubInterfaces": 0,
"hubSummary": "Unable to read Reticulum interface stats",
"reason": str(exc),
"meshListenOnline": False,
}
previous = _last_transport_state
if not force and previous == payload:
return
_last_transport_state = payload
emit_event("transport_state", payload)
log(f"[presence_bridge] transport_state {summarize_transport_state(payload)}")
def transport_monitor_loop() -> None:
while True:
try:
maybe_emit_transport_state()
except Exception as exc:
log(f"[presence_bridge] transport monitor error: {exc}")
time.sleep(_TRANSPORT_MONITOR_INTERVAL_SECONDS)
def ensure_transport_monitor_started() -> None:
global _transport_monitor_thread
if _transport_monitor_thread is not None and _transport_monitor_thread.is_alive():
return
_transport_monitor_thread = threading.Thread(
target=transport_monitor_loop,
daemon=True,
name="reticulum-transport-monitor",
)
_transport_monitor_thread.start()
def rns_callback_scheduler_monitor_loop() -> None:
global _audio_rns_callback_scheduler_gap_ms_max
global _audio_rns_callback_scheduler_gap_ms_window
global _audio_rns_callback_scheduler_gap_over_100_count
global _audio_rns_callback_scheduler_gap_over_250_count
global _audio_rns_callback_scheduler_gap_over_500_count
global _audio_rns_callback_scheduler_gap_over_1000_count
interval = _AUDIO_RNS_CALLBACK_SCHEDULER_MONITOR_INTERVAL_SECONDS
last_at = time.monotonic()
while True:
time.sleep(interval)
now = time.monotonic()
elapsed_ms = max(0.0, (now - last_at) * 1000.0)
last_at = now
if elapsed_ms > _audio_rns_callback_scheduler_gap_ms_max:
_audio_rns_callback_scheduler_gap_ms_max = elapsed_ms
if elapsed_ms > _audio_rns_callback_scheduler_gap_ms_window:
_audio_rns_callback_scheduler_gap_ms_window = elapsed_ms
if elapsed_ms >= 100.0:
_audio_rns_callback_scheduler_gap_over_100_count += 1
if elapsed_ms >= 250.0:
_audio_rns_callback_scheduler_gap_over_250_count += 1
if elapsed_ms >= 500.0:
_audio_rns_callback_scheduler_gap_over_500_count += 1
if elapsed_ms >= 1000.0:
_audio_rns_callback_scheduler_gap_over_1000_count += 1
_mark_audio_queue_state_dirty()
def ensure_rns_callback_scheduler_monitor_started() -> None:
global _rns_callback_scheduler_monitor_thread
if (
_rns_callback_scheduler_monitor_thread is not None
and _rns_callback_scheduler_monitor_thread.is_alive()
):
return
_rns_callback_scheduler_monitor_thread = threading.Thread(
target=rns_callback_scheduler_monitor_loop,
daemon=True,
name="reticulum-rns-callback-scheduler-monitor",
)
_rns_callback_scheduler_monitor_thread.start()
def destination_hash_hex(destination_hash: bytes) -> str:
return destination_hash.hex()
def _local_presence_hash_hex() -> Optional[str]:
"""Hex of local RNS destination; skip overlay links and fanout to ourselves."""
if _destination is None:
return None
return destination_hash_hex(_destination.hash)
def _register_peer(
peer_key: str,
peer_identity: Any,
source: str,
) -> None:
"""Register identity for fanout; updates lifecycle by source."""
global _known_peers, _peer_lifecycle
peer_key = str(peer_key or "").strip().lower()
if not peer_key:
return
local_hex = _local_presence_hash_hex()
if local_hex and peer_key == local_hex:
log(
"[presence_bridge] target=presence-reticulum skip_register_peer_self "
f"source={source}"
)
return
is_new = peer_key not in _known_peers
_known_peers[peer_key] = peer_identity
now = time.time()
if peer_key not in _peer_lifecycle:
_peer_lifecycle[peer_key] = {
"last_seen_inbound": None,
"last_send_ok": None,
"last_request_path_at": None,
"ts_seed_until": None,
}
st = _peer_lifecycle[peer_key]
if source in ("inbound", "announce", "wire_kr", "gcall_join"):
st["last_seen_inbound"] = now
_note_overlay_peer_alive(peer_key, source)
if source in ("ts_seed", "recall"):
st["ts_seed_until"] = now + _PEER_TS_SEED_LEASE_SECONDS
if is_new:
peers_sorted = sorted(_known_peers.keys())
log(
"[presence_bridge] target=presence-reticulum peer_learned "
f"peer_hash={peer_key} source={source} known_peers_count={len(_known_peers)} "
f"all_peer_hashes={','.join(peers_sorted)}"
)
_evict_lru_if_needed()
def _mark_candidate_peer(peer_key: str, source: str) -> None:
peer_key = str(peer_key or "").strip().lower()
local_hex = _local_presence_hash_hex()
if local_hex and peer_key == local_hex:
return
now = time.time()
existing = _candidate_peers.get(peer_key) or {}
peer = {
"first_seen_at": existing.get("first_seen_at") or now,
"last_seen_at": now,
"proof_deadline_at": now + _CANDIDATE_PROOF_WINDOW_SECONDS,
"failure_count": int(existing.get("failure_count") or 0),
"source": source,
}
if "last_failure_reason" in existing:
peer["last_failure_reason"] = existing["last_failure_reason"]
_candidate_peers[peer_key] = peer
emit_event(
"candidate_peer_discovered",
{
"peerHash": peer_key,
"source": source,
},
)
log(
"[presence_bridge] target=presence-reticulum candidate_discovered "
f"peer_hash={peer_key} source={source} proof_deadline_at={peer['proof_deadline_at']}"
)
def _note_candidate_failure(peer_key: str, reason: str) -> None:
now = time.time()
existing = _candidate_peers.get(peer_key)
if existing is None:
existing = {
"first_seen_at": now,
"last_seen_at": now,
"proof_deadline_at": now + _CANDIDATE_PROOF_WINDOW_SECONDS,
"failure_count": 0,
"source": "failure",
}
existing["last_seen_at"] = now
existing["failure_count"] = int(existing.get("failure_count") or 0) + 1
existing["last_failure_reason"] = reason
if existing["failure_count"] >= _CANDIDATE_FAILURE_LIMIT:
_candidate_peers.pop(peer_key, None)
log(
"[presence_bridge] target=presence-reticulum candidate_evicted "
f"peer_hash={peer_key} failure_count={existing['failure_count']} reason={reason}"
)
return
_candidate_peers[peer_key] = existing
log(
"[presence_bridge] target=presence-reticulum candidate_failure "
f"peer_hash={peer_key} failure_count={existing['failure_count']} reason={reason}"
)
def _prune_candidate_peers() -> None:
now = time.time()
for peer_key, peer in list(_candidate_peers.items()):
deadline = peer.get("proof_deadline_at")
if isinstance(deadline, (int, float)) and now > float(deadline):
_candidate_peers.pop(peer_key, None)
log(
"[presence_bridge] target=presence-reticulum candidate_timeout "
f"peer_hash={peer_key}"
)
def _overlay_failure_should_suppress(reason: str) -> bool:
reason_key = str(reason or "").strip().lower()
return any(
token in reason_key
for token in (
"timeout",
"no_link",
"no_established_link",
"destination_closed",
"rx_idle_timeout",
)
)
def _overlay_peer_suppressed_until(peer_key: str) -> float:
peer_key = str(peer_key or "").strip().lower()
if not peer_key:
return 0.0
state = _overlay_peer_failures.get(peer_key)
if not isinstance(state, dict):
return 0.0
until = state.get("suppress_until")
if not isinstance(until, (int, float)):
return 0.0
now = time.time()
if float(until) <= now:
_overlay_peer_failures.pop(peer_key, None)
return 0.0
return float(until)
def _overlay_peer_is_suppressed(peer_key: str) -> bool:
return _overlay_peer_suppressed_until(peer_key) > time.time()
def _note_overlay_peer_alive(peer_key: str, source: str) -> None:
peer_key = str(peer_key or "").strip().lower()
if not peer_key:
return
if _overlay_peer_failures.pop(peer_key, None) is not None:
log(
"[presence_bridge] target=presence-reticulum overlay_peer_failure_reset "
f"peer={peer_key} source={source}"
)
def _note_overlay_peer_failure(peer_key: str, reason: str) -> None:
peer_key = str(peer_key or "").strip().lower()
if not peer_key or not _overlay_failure_should_suppress(reason):
return
now = time.time()
state = _overlay_peer_failures.get(peer_key) or {}
count = int(state.get("count") or 0) + 1
suppress_until = state.get("suppress_until")
if count >= _OVERLAY_LINK_FAILURE_SUPPRESS_LIMIT:
suppress_until = now + _OVERLAY_LINK_FAILURE_SUPPRESS_SECONDS
_overlay_peer_failures[peer_key] = {
"count": count,
"last_reason": reason,
"last_failure_at": now,
"suppress_until": suppress_until if isinstance(suppress_until, (int, float)) else None,
}
if isinstance(suppress_until, (int, float)) and float(suppress_until) > now:
log(
"[presence_bridge] target=presence-reticulum overlay_peer_suppressed "
f"peer={peer_key} reason={reason} failures={count} "
f"suppress_seconds={int(float(suppress_until) - now)}"
)
else:
verbose_presence_log(
"[presence_bridge] target=presence-reticulum overlay_peer_failure "
f"peer={peer_key} reason={reason} failures={count}"
)
def _set_verified_overlay_peers(
verified_peers: list[Dict[str, Any]], active_neighbor_hashes: list[str]
) -> None:
global _verified_overlay_peers, _active_overlay_neighbors
now = time.time()
local_hex = _local_presence_hash_hex()
prev_verified = dict(_verified_overlay_peers)
prev_neighbors = dict(_active_overlay_neighbors)
next_verified: Dict[str, Dict[str, Any]] = {}
for peer in verified_peers:
if not isinstance(peer, dict):
continue
peer_hash = str(peer.get("destinationHash") or "").strip().lower()
address = str(peer.get("address") or "").strip()
last_seen = peer.get("lastSeen")
if not peer_hash or not address or not isinstance(last_seen, (int, float)):
continue
if local_hex and peer_hash == local_hex:
continue
if peer_hash not in _known_peers:
ensure_known_peer_from_recall(peer_hash, "ts_seed")
last_seen_seconds = _coerce_epoch_seconds(last_seen)
if last_seen_seconds is not None:
st = _peer_lifecycle.setdefault(
peer_hash,
{
"last_seen_inbound": None,
"last_send_ok": None,
"last_request_path_at": None,
"ts_seed_until": None,
},
)
prev_seen = st.get("last_seen_inbound")
if not isinstance(prev_seen, (int, float)) or last_seen_seconds > float(prev_seen):
st["last_seen_inbound"] = last_seen_seconds
next_verified[peer_hash] = {
"address": address,
"last_seen": float(last_seen),
}
_candidate_peers.pop(peer_hash, None)
_verified_overlay_peers = next_verified
next_neighbors: Dict[str, float] = {}
for raw_hash in active_neighbor_hashes:
if len(next_neighbors) >= _OVERLAY_MAX_OUTBOUND_NEIGHBORS:
break
peer_hash = str(raw_hash or "").strip().lower()
if not peer_hash:
continue
if local_hex and peer_hash == local_hex:
continue
if _overlay_peer_is_suppressed(peer_hash):
continue
if peer_hash not in _known_peers:
ensure_known_peer_from_recall(peer_hash, "ts_seed")
# Fanout list from TS: verified neighbors plus candidate backfill
# (bootstrap). Keep the lease even if local RNS identity recall is
# temporarily empty; _sync_overlay_links will defer opening the link
# until recall/path data is available. Dropping it here can collapse
# verified=N into publish_fanout=0 and drain the overlay.
next_neighbors[peer_hash] = now
retained_neighbors = 0
for peer_hash, seen_at in prev_neighbors.items():
if len(next_neighbors) >= _OVERLAY_MAX_OUTBOUND_NEIGHBORS:
break
if peer_hash in next_neighbors:
continue
if _overlay_peer_is_suppressed(peer_hash):
continue
if not isinstance(seen_at, (int, float)):
continue
if now - float(seen_at) > _OVERLAY_NEIGHBOR_GRACE_SECONDS:
continue
if (
peer_hash not in next_verified
and peer_hash not in prev_verified
and peer_hash not in _candidate_peers
):
continue
if peer_hash not in _known_peers:
ensure_known_peer_from_recall(peer_hash, "ts_seed")
next_neighbors[peer_hash] = float(seen_at)
retained_neighbors += 1
if len(next_neighbors) < _OVERLAY_MAX_OUTBOUND_NEIGHBORS:
candidates: list[tuple[float, str]] = []
for peer_hash, peer in next_verified.items():
peer_key = str(peer_hash or "").strip().lower()
if (
not peer_key
or peer_key in next_neighbors
or (local_hex and peer_key == local_hex)
or _overlay_peer_is_suppressed(peer_key)
):
continue
last_seen = peer.get("last_seen") if isinstance(peer, dict) else None
if not isinstance(last_seen, (int, float)):
last_seen = 0.0
candidates.append((float(last_seen), peer_key))
candidates.sort(key=lambda item: (-item[0], item[1]))
for _last_seen, peer_key in candidates:
if len(next_neighbors) >= _OVERLAY_MAX_OUTBOUND_NEIGHBORS:
break
if peer_key not in _known_peers:
ensure_known_peer_from_recall(peer_key, "ts_seed")
next_neighbors[peer_key] = now
_active_overlay_neighbors = next_neighbors
publish_fanout_count = len(set(_active_overlay_neighbors.keys()) | set(_inbound_overlay_neighbors.keys()))
verbose_presence_log(
"[presence_bridge] target=presence-reticulum overlay_sync "
f"verified={len(_verified_overlay_peers)} outbound_fanout={len(_active_overlay_neighbors)} "
f"inbound_fanout={len(_inbound_overlay_neighbors)} "
f"publish_fanout={publish_fanout_count} "
f"retained={retained_neighbors}"
)
def _overlay_peer_has_established_link(peer_hash: str) -> bool:
peer_key = str(peer_hash or "").strip().lower()
if not peer_key:
return False
with _state_lock:
link_id = _active_overlay_link_id_by_peer_hash.get(peer_key)
if not link_id:
return False
state = _overlay_links_by_id.get(link_id)
return bool(
state is not None
and state.get("established") is True
and state.get("link") is not None
)
def _coerce_epoch_seconds(value: Any) -> Optional[float]:
if not isinstance(value, (int, float)):
return None
ts = float(value)
if ts <= 0:
return None
# Electron sends epoch milliseconds; Python-side timestamps are seconds.
if ts > 10_000_000_000:
ts = ts / 1000.0
return ts
def _overlay_peer_recently_rx_active(peer_hash: str, now: Optional[float] = None) -> bool:
peer_key = str(peer_hash or "").strip().lower()
if not peer_key:
return False
st = _peer_lifecycle.get(peer_key) or {}
last_in = st.get("last_seen_inbound")
last_in_seconds = _coerce_epoch_seconds(last_in)
if last_in_seconds is None:
return False
if now is None:
now = time.time()
return (float(now) - last_in_seconds) <= _OVERLAY_LINK_RX_IDLE_TIMEOUT_SECONDS
def _resolve_overlay_neighbor_hashes(
exclude_hashes: Optional[list[str]] = None,
established_only: bool = False,
) -> list[str]:
_prune_candidate_peers()
exclude = {
str(h).strip().lower() for h in (exclude_hashes or []) if str(h).strip()
}
local_hex = _local_presence_hash_hex()
now = time.time()
out: list[str] = []
for peer_hash in list(_active_overlay_neighbors.keys()):
seen_at = _active_overlay_neighbors.get(peer_hash)
if isinstance(seen_at, (int, float)) and now - float(seen_at) > _OVERLAY_NEIGHBOR_GRACE_SECONDS:
_active_overlay_neighbors.pop(peer_hash, None)
continue
if peer_hash in exclude:
continue
if local_hex and peer_hash == local_hex:
continue
if peer_hash not in _known_peers:
continue
if established_only and not _overlay_peer_has_established_link(peer_hash):
continue
# Refresh the active-neighbor lease on real fanout use. Overlay sync from
# Electron is event-driven, so steady 25 s presence heartbeats must keep a
# healthy neighbor from aging out after the 30 s grace window.
_active_overlay_neighbors[peer_hash] = now
out.append(peer_hash)
for peer_hash in list(_inbound_overlay_neighbors.keys()):
if peer_hash in exclude or peer_hash in out:
continue
if local_hex and peer_hash == local_hex:
continue
if peer_hash not in _known_peers:
continue
if established_only and not _overlay_peer_has_established_link(peer_hash):
continue
if not _overlay_peer_recently_rx_active(peer_hash, now):
_inbound_overlay_neighbors.pop(peer_hash, None)
continue
_inbound_overlay_neighbors[peer_hash] = now
out.append(peer_hash)
return out[:(_OVERLAY_MAX_OUTBOUND_NEIGHBORS + _OVERLAY_MAX_INBOUND_NEIGHBORS)]
def _snapshot_established_overlay_neighbor_hashes(
exclude_hashes: Optional[list[str]] = None,
) -> list[str]:
exclude = {
str(h).strip().lower() for h in (exclude_hashes or []) if str(h).strip()
}
local_hex = _local_presence_hash_hex()
out: list[str] = []
with _state_lock:
candidates = list(_active_overlay_neighbors.keys()) + list(_inbound_overlay_neighbors.keys())
for peer_hash in candidates:
peer_key = str(peer_hash or "").strip().lower()
if not peer_key or peer_key in exclude or peer_key in out:
continue
if local_hex and peer_key == local_hex:
continue
link_id = _active_overlay_link_id_by_peer_hash.get(peer_key) or ""
state = _overlay_links_by_id.get(link_id) if link_id else None
if (
state is None
or state.get("established") is not True
or state.get("link") is None
):
continue
out.append(peer_key)
return out[:(_OVERLAY_MAX_OUTBOUND_NEIGHBORS + _OVERLAY_MAX_INBOUND_NEIGHBORS)]
def _overlay_peer_is_admitted(peer_key: str) -> bool:
peer_key = str(peer_key or "").strip().lower()
if not peer_key:
return False
return peer_key in _active_overlay_neighbors or peer_key in _inbound_overlay_neighbors
def _overlay_peer_is_outbound(peer_key: str) -> bool:
peer_key = str(peer_key or "").strip().lower()
return bool(peer_key and peer_key in _active_overlay_neighbors)
def _overlay_peer_is_inbound(peer_key: str) -> bool:
peer_key = str(peer_key or "").strip().lower()
return bool(peer_key and peer_key in _inbound_overlay_neighbors)
def _promote_recent_verified_overlay_neighbors(
reason: str, exclude_hashes: Optional[Set[str]] = None
) -> int:
global _active_overlay_neighbors
if len(_active_overlay_neighbors) >= _OVERLAY_MAX_OUTBOUND_NEIGHBORS:
return 0
exclude = {
str(h).strip().lower() for h in (exclude_hashes or set()) if str(h).strip()
}
local_hex = _local_presence_hash_hex()
candidates: list[tuple[float, str]] = []
for peer_hash, peer in _verified_overlay_peers.items():
peer_key = str(peer_hash or "").strip().lower()
if not peer_key:
continue
if local_hex and peer_key == local_hex:
continue
if _overlay_peer_is_suppressed(peer_key):
continue
if (
peer_key in exclude
or peer_key in _active_overlay_neighbors
or peer_key in _inbound_overlay_neighbors
):
continue
last_seen = peer.get("last_seen") if isinstance(peer, dict) else None
if not isinstance(last_seen, (int, float)):
last_seen = 0.0
candidates.append((float(last_seen), peer_key))
if not candidates:
return 0
candidates.sort(key=lambda item: (-item[0], item[1]))
now = time.time()
selected: list[str] = []
for _last_seen, peer_key in candidates:
if len(_active_overlay_neighbors) >= _OVERLAY_MAX_OUTBOUND_NEIGHBORS:
break
if peer_key not in _known_peers:
ensure_known_peer_from_recall(peer_key, "ts_seed")
if peer_key not in _known_peers:
continue
_active_overlay_neighbors[peer_key] = now
selected.append(peer_key)
if selected:
verbose_presence_log(
"[presence_bridge] target=presence-reticulum overlay_fanout_promote "
f"reason={reason} selected={len(selected)} total={len(_active_overlay_neighbors)} "
f"fanout_hashes={','.join(selected)}"
)
return len(selected)
def _demote_overlay_fanout_peer(peer_hash: str, reason: str) -> bool:
global _active_overlay_neighbors, _inbound_overlay_neighbors
peer_key = str(peer_hash or "").strip().lower()
if not peer_key:
return False
was_outbound = peer_key in _active_overlay_neighbors
was_inbound = peer_key in _inbound_overlay_neighbors
if not was_outbound and not was_inbound:
return False
_active_overlay_neighbors.pop(peer_key, None)
_inbound_overlay_neighbors.pop(peer_key, None)
_note_overlay_peer_failure(peer_key, reason)
verbose_presence_log(
"[presence_bridge] target=presence-reticulum overlay_fanout_demote "
f"peer={peer_key} reason={reason} outbound={len(_active_overlay_neighbors)} "
f"inbound={len(_inbound_overlay_neighbors)}"
)
if was_outbound:
_promote_recent_verified_overlay_neighbors(reason, {peer_key})
return True
def _get_group_audio_peer_identity(peer_hash: str):
"""RNS identity for group audio using join destination hash + recall.
Group audio is keyed by the joiner's Reticulum destination hash from Electron; it does
not require membership in the verified-overlay snapshot from ``overlay_sync_state``."""
peer_key = str(peer_hash or "").strip().lower()
if not peer_key:
return None
with _state_lock:
ident = _known_peers.get(peer_key)
if ident is not None:
return ident
ensure_known_peer_from_recall(peer_key, "ts_seed")
with _state_lock:
return _known_peers.get(peer_key)
def _evict_lru_if_needed() -> None:
"""Cap _known_peers by dropping least-recently-seen peers (not TS-leased)."""
global _known_peers, _peer_lifecycle
if len(_known_peers) <= _MAX_KNOWN_PEERS:
return
now = time.time()
candidates: list[tuple[float, str]] = []
for pk in list(_known_peers.keys()):
st = _peer_lifecycle.get(pk) or {}
lease = st.get("ts_seed_until")
if isinstance(lease, (int, float)) and lease > now:
continue
last = st.get("last_seen_inbound")
if not isinstance(last, (int, float)):
last = 0.0
candidates.append((float(last), pk))
candidates.sort(key=lambda x: x[0])
need = len(_known_peers) - _MAX_KNOWN_PEERS
for _score, pk in candidates[: max(0, need)]:
_known_peers.pop(pk, None)
_peer_lifecycle.pop(pk, None)
log(
f"[presence_bridge] target=presence-reticulum peer_evicted_lru peer_hash={pk}"
)
def _refresh_ts_seed_only(peer_key: str) -> None:
"""Extend lease for Electron-supplied destination hashes (split-brain sync)."""
now = time.time()
if peer_key not in _peer_lifecycle:
_peer_lifecycle[peer_key] = {
"last_seen_inbound": None,
"last_send_ok": None,
"last_request_path_at": None,
"ts_seed_until": None,
}
_peer_lifecycle[peer_key]["ts_seed_until"] = now + _PEER_TS_SEED_LEASE_SECONDS
def _maybe_prune_stale_peers() -> None:
"""Remove peers with no recent activity and no active TS seed lease."""
global _known_peers, _peer_lifecycle
if _destination is None:
return
now = time.time()
local_hex = destination_hash_hex(_destination.hash)
to_drop: list[str] = []
for pk, st in list(_peer_lifecycle.items()):
if pk == local_hex:
continue
lease = st.get("ts_seed_until")
if isinstance(lease, (int, float)) and lease > now:
continue
last_in = st.get("last_seen_inbound")
last_ok = st.get("last_send_ok")
active = False
if isinstance(last_in, (int, float)) and (now - float(last_in)) <= _PEER_STALE_SECONDS:
active = True
if isinstance(last_ok, (int, float)) and (now - float(last_ok)) <= _PEER_STALE_SECONDS:
active = True
if not active:
to_drop.append(pk)
for pk in to_drop:
_known_peers.pop(pk, None)
_peer_lifecycle.pop(pk, None)
log(f"[presence_bridge] target=presence-reticulum peer_pruned_stale peer_hash={pk}")
def _overlay_bootstrap_peer_sort_key(peer_key: str) -> tuple[int, float, str]:
st = _peer_lifecycle.get(peer_key) or {}
now = time.time()
lease = st.get("ts_seed_until")
last_in = st.get("last_seen_inbound")
last_ok = st.get("last_send_ok")
recent_ts = 0.0
if isinstance(last_in, (int, float)):
recent_ts = max(recent_ts, float(last_in))
if isinstance(last_ok, (int, float)):
recent_ts = max(recent_ts, float(last_ok))
if isinstance(lease, (int, float)) and float(lease) > now:
recent_ts = max(recent_ts, float(lease))
return (0, -recent_ts, peer_key)
if recent_ts > 0:
return (1, -recent_ts, peer_key)
return (2, 0.0, peer_key)
def _bootstrap_overlay_neighbors_if_degraded(reason: str) -> int:
"""
Recover from a drained or low-fanout overlay by temporarily seeding fanout
from known Reticulum/Qortal presence destinations.
This only creates send targets. Peers still become verified solely through
accepted signed Qortal presence or other validated overlay traffic.
"""
global _active_overlay_neighbors
if len(_active_overlay_neighbors) >= _OVERLAY_MIN_HEALTHY_FANOUT:
return 0
local_hex = _local_presence_hash_hex()
candidates: list[str] = []
for peer_key in list(_known_peers.keys()):
if not _valid_presence_destination_hash_hex(peer_key):
continue
if local_hex and peer_key == local_hex:
continue
if _overlay_peer_is_suppressed(peer_key):
continue
if peer_key in _active_overlay_neighbors or peer_key in _inbound_overlay_neighbors:
continue
candidates.append(peer_key)
if not candidates:
return 0
candidates.sort(key=_overlay_bootstrap_peer_sort_key)
now = time.time()
needed = max(0, _OVERLAY_BOOTSTRAP_MAX_OUTBOUND_NEIGHBORS - len(_active_overlay_neighbors))
selected = candidates[:needed]
for peer_key in selected:
_active_overlay_neighbors[peer_key] = now
for peer_key in selected:
_mark_candidate_peer(peer_key, f"bootstrap:{reason}")
log(
"[presence_bridge] target=presence-reticulum overlay_bootstrap "
f"reason={reason} selected={len(selected)} total={len(_active_overlay_neighbors)} "
f"known_peers={len(_known_peers)} "
f"fanout_hashes={','.join(selected)}"
)
return len(selected)
def _request_path_if_eligible(peer_key: str, h: bytes, nudge_budget: list[int]) -> None:
"""Nudge Reticulum path discovery when appropriate (throttled)."""
if nudge_budget[0] <= 0:
return
st = _peer_lifecycle.get(peer_key) or {}
now = time.time()
last_rp = st.get("last_request_path_at")
if isinstance(last_rp, (int, float)) and (now - float(last_rp)) < _REQUEST_PATH_COOLDOWN_SECONDS:
return
has_path = True
try:
has_path = bool(RNS.Transport.has_path(h))
except Exception:
has_path = False
last_ok = st.get("last_send_ok")
recently_sent = isinstance(last_ok, (int, float)) and (now - float(last_ok)) < 180.0
if has_path and recently_sent:
return
try:
RNS.Transport.request_path(h)
if peer_key not in _peer_lifecycle:
_peer_lifecycle[peer_key] = {
"last_seen_inbound": None,
"last_send_ok": None,
"last_request_path_at": None,
"ts_seed_until": None,
}
_peer_lifecycle[peer_key]["last_request_path_at"] = now
nudge_budget[0] -= 1
log(
f"[presence_bridge] target=presence-reticulum request_path peer={peer_key} "
f"has_path={has_path}"
)
except Exception as exc:
log(f"[presence_bridge] target=presence-reticulum request_path_failed peer={peer_key}: {exc}")
def _nudge_overlay_path_for_peer(peer_key: str) -> None:
"""
Ask Reticulum to resolve a destination we need for overlay group_signal fanout.
Throttled; pairs with ensure_known_peer_from_recall on the next tick.
"""
try:
h = bytes.fromhex(peer_key)
except ValueError:
return
if len(h) != 16:
return
now = time.time()
st = _peer_lifecycle.get(peer_key) or {}
last_rp = st.get("last_request_path_at")
if isinstance(last_rp, (int, float)) and (now - float(last_rp)) < _REQUEST_PATH_COOLDOWN_SECONDS:
return
try:
RNS.Transport.request_path(h)
if peer_key not in _peer_lifecycle:
_peer_lifecycle[peer_key] = {
"last_seen_inbound": None,
"last_send_ok": None,
"last_request_path_at": None,
"ts_seed_until": None,
}
_peer_lifecycle[peer_key]["last_request_path_at"] = now
log(
f"[presence_bridge] target=presence-reticulum overlay_path_nudge peer={peer_key} "
"reason=group_signal_unknown_peer"
)
except Exception as exc:
log(
f"[presence_bridge] target=presence-reticulum overlay_path_nudge_failed "
f"peer={peer_key}: {exc}"
)
def _get_call_media_state(peer_hash: str) -> Dict[str, Any]:
state = _call_media_path_state.get(peer_hash)
if state is not None:
return state
state = {
"path_state": "unknown",
"destination_hash_hex": "",
"last_request_path_at": None,
"last_resolved_at": None,
"last_timeout_at": None,
"last_send_ok": None,
"last_send_fail": None,
"last_inbound_at": None,
"last_state_change_at": None,
"last_transition_reason": "",
"consecutive_timeouts": 0,
}
_call_media_path_state[peer_hash] = state
return state
_CALL_MEDIA_PATH_ALLOWED_TRANSITIONS: Dict[str, set[str]] = {
"unknown": {"warming"},
"warming": {"fresh", "stale", "failing"},
"fresh": {"stale"},
"stale": {"warming", "failing", "fresh"},
"failing": {"recovering", "stale"},
"recovering": {"fresh", "failing", "stale"},
}
def _transition_call_media_path_state(
peer_hash: str, next_state: str, reason: str = ""
) -> str:
state = _get_call_media_state(peer_hash)
current = str(state.get("path_state") or "unknown")
if current == next_state:
return current
allowed = _CALL_MEDIA_PATH_ALLOWED_TRANSITIONS.get(current, set())
if next_state not in allowed:
log(
"[presence_bridge] target=reticulum-audio-ipc packet_path_invalid_transition "
f"peer={peer_hash} current={current} next={next_state} reason={reason}"
)
return current
state["path_state"] = next_state
state["last_state_change_at"] = time.time()
state["last_transition_reason"] = reason
return next_state
def _reset_call_media_state(
peer_hash: str, destination_hash: bytes, reason: str = "destination_changed"
) -> Dict[str, Any]:
state = _get_call_media_state(peer_hash)
state["path_state"] = "unknown"
state["destination_hash_hex"] = destination_hash_hex(destination_hash)
state["last_request_path_at"] = None
state["last_resolved_at"] = None
state["last_timeout_at"] = None
state["last_send_ok"] = None
state["last_send_fail"] = None
state["last_inbound_at"] = None
state["last_state_change_at"] = time.time()
state["last_transition_reason"] = reason
state["consecutive_timeouts"] = 0
return state
def _classify_call_media_path_state(peer_hash: str, destination_hash: bytes) -> str:
now = time.time()
state = _get_call_media_state(peer_hash)
dest_hex = destination_hash_hex(destination_hash)
if state.get("destination_hash_hex") != dest_hex:
state = _reset_call_media_state(peer_hash, destination_hash)
has_path = False
try:
has_path = bool(RNS.Transport.has_path(destination_hash))
except Exception:
has_path = False
if not has_path:
if str(state.get("path_state") or "unknown") == "unknown":
return "unknown"
return str(state.get("path_state") or "unknown")
last_send_ok = state.get("last_send_ok")
last_send_fail = state.get("last_send_fail")
last_inbound = state.get("last_inbound_at")
recent_ok = isinstance(last_send_ok, (int, float)) and (
now - float(last_send_ok)
) <= _PACKET_PATH_FRESH_SECONDS
recent_inbound = isinstance(last_inbound, (int, float)) and (
now - float(last_inbound)
) <= _PACKET_PATH_INBOUND_FRESH_SECONDS
recent_fail = isinstance(last_send_fail, (int, float)) and (
now - float(last_send_fail)
) <= _PACKET_PATH_RECENT_FAILURE_SECONDS
if (recent_ok or recent_inbound) and not recent_fail:
return "fresh"
current = str(state.get("path_state") or "unknown")
if current in ("failing", "recovering"):
return current
return "stale"
def _ensure_call_media_path(
peer_hash: str,
destination_hash: bytes,
*,
active_call: bool = True,
allow_wait: bool = True,
reason: str = "send",
await_seconds_override: Optional[float] = None,
) -> tuple[str, bool]:
global _audio_packet_path_requests, _audio_packet_path_resolutions, _audio_packet_path_timeouts
state = _get_call_media_state(peer_hash)
dest_hex = destination_hash_hex(destination_hash)
if state.get("destination_hash_hex") != dest_hex:
state = _reset_call_media_state(peer_hash, destination_hash)
initial_state = _classify_call_media_path_state(peer_hash, destination_hash)
if initial_state == "fresh":
state["consecutive_timeouts"] = 0
return initial_state, True
if initial_state == "stale" and str(state.get("path_state") or "") == "fresh":
_transition_call_media_path_state(peer_hash, "stale", "fresh_expired")
initial_state = "stale"
now = time.time()
last_rp = state.get("last_request_path_at")
request_cooldown = (
_PACKET_PATH_ACTIVE_REQUEST_COOLDOWN_SECONDS
if active_call
else _PACKET_PATH_IDLE_REQUEST_COOLDOWN_SECONDS
)
should_request = not (
isinstance(last_rp, (int, float))
and (now - float(last_rp)) < request_cooldown
)
requested = False
used_request_await = False
resolved = False
await_seconds = (
float(await_seconds_override)
if await_seconds_override is not None
else (
_PACKET_PATH_AWAIT_SECONDS
if active_call
else _PACKET_PATH_IDLE_AWAIT_SECONDS
)
)
if should_request:
current = str(state.get("path_state") or "unknown")
if current == "unknown":
_transition_call_media_path_state(peer_hash, "warming", f"{reason}:request_path")
elif current == "stale":
_transition_call_media_path_state(peer_hash, "warming", f"{reason}:refresh_path")
elif current == "failing":
_transition_call_media_path_state(peer_hash, "recovering", f"{reason}:recover_path")
if allow_wait and await_seconds > 0:
used_request_await = True
resolved, requested = _request_and_await_destination_path(
destination_hash,
await_seconds,
log_context=f"call_media_path peer={peer_hash} reason={reason}",
)
else:
try:
RNS.Transport.request_path(destination_hash)
requested = True
except Exception as exc:
log(
"[presence_bridge] target=reticulum-audio-ipc packet_path_request_failed "
f"peer={peer_hash} err={exc}"
)
if requested:
state["last_request_path_at"] = now
_audio_packet_path_requests += 1
_mark_audio_queue_state_dirty()
if not should_request:
resolved = False
if not resolved and not used_request_await:
if allow_wait and await_seconds > 0:
resolved = _await_destination_path(destination_hash, await_seconds)
else:
try:
resolved = bool(RNS.Transport.has_path(destination_hash))
except Exception:
resolved = False
if resolved:
current = str(state.get("path_state") or "unknown")
if current == "unknown":
_transition_call_media_path_state(peer_hash, "warming", f"{reason}:resolved")
current = "warming"
if current == "failing":
_transition_call_media_path_state(peer_hash, "recovering", f"{reason}:resolved")
_transition_call_media_path_state(peer_hash, "fresh", f"{reason}:resolved")
state["last_resolved_at"] = time.time()
state["consecutive_timeouts"] = 0
_audio_packet_path_resolutions += 1
_mark_audio_queue_state_dirty()
return str(state.get("path_state") or "fresh"), True
try:
resolved = bool(RNS.Transport.has_path(destination_hash))
except Exception:
resolved = False
if resolved:
current = str(state.get("path_state") or "unknown")
if current == "unknown":
_transition_call_media_path_state(peer_hash, "warming", f"{reason}:has_path")
current = "warming"
if current == "failing":
_transition_call_media_path_state(peer_hash, "recovering", f"{reason}:has_path")
_transition_call_media_path_state(peer_hash, "fresh", f"{reason}:has_path")
state["last_resolved_at"] = time.time()
state["consecutive_timeouts"] = 0
_audio_packet_path_resolutions += 1
_mark_audio_queue_state_dirty()
return str(state.get("path_state") or "fresh"), True
_audio_packet_path_timeouts += 1
state["last_timeout_at"] = time.time()
state["consecutive_timeouts"] = int(state.get("consecutive_timeouts") or 0) + 1
current = str(state.get("path_state") or "unknown")
if current == "warming":
_transition_call_media_path_state(peer_hash, "stale", f"{reason}:timeout")
current = "stale"
if current == "stale" and (
int(state.get("consecutive_timeouts") or 0)
>= _PACKET_PATH_WARMING_TIMEOUTS_BEFORE_FAILING
):
_transition_call_media_path_state(peer_hash, "failing", f"{reason}:timeout")
elif current == "recovering":
_transition_call_media_path_state(peer_hash, "failing", f"{reason}:recover_timeout")
_mark_audio_queue_state_dirty()
return str(state.get("path_state") or initial_state), False
def _await_destination_path(destination_hash: bytes, timeout_seconds: float) -> bool:
if timeout_seconds <= 0:
try:
return bool(RNS.Transport.has_path(destination_hash))
except Exception:
return False
deadline = time.time() + timeout_seconds
while True:
try:
resolved = bool(RNS.Transport.has_path(destination_hash))
except Exception:
resolved = False
if resolved:
return True
remaining = deadline - time.time()
if remaining <= 0:
return False
time.sleep(min(_PACKET_PATH_POLL_INTERVAL_SECONDS, remaining))
def _request_and_await_destination_path(
destination_hash: bytes,
timeout_seconds: float,
*,
log_context: str,
) -> tuple[bool, bool]:
try:
if RNS.Transport.has_path(destination_hash):
return True, False
except Exception:
pass
requested = False
try:
await_path = getattr(RNS.Transport, "await_path", None)
if callable(await_path) and timeout_seconds > 0:
requested = True
return bool(await_path(destination_hash, timeout_seconds)), requested
except Exception as exc:
log(
"[presence_bridge] target=presence-reticulum path_await_failed "
f"{log_context} err={exc}"
)
try:
RNS.Transport.request_path(destination_hash)
requested = True
except Exception as exc:
log(
"[presence_bridge] target=presence-reticulum path_request_failed "
f"{log_context} err={exc}"
)
return False, requested
return _await_destination_path(destination_hash, timeout_seconds), requested
def _nudge_overlay_link_path(
peer_key: str,
destination_hash: bytes,
*,
await_seconds: float = 0.0,
) -> bool:
try:
if RNS.Transport.has_path(destination_hash):
return True
except Exception:
pass
now = time.time()
st = _peer_lifecycle.get(peer_key) or {}
last_rp = st.get("last_request_path_at")
should_request = not (
isinstance(last_rp, (int, float))
and (now - float(last_rp)) < _OVERLAY_LINK_PATH_REQUEST_COOLDOWN_SECONDS
)
if should_request:
if await_seconds > 0:
resolved, requested = _request_and_await_destination_path(
destination_hash,
await_seconds,
log_context=f"overlay_link_path peer={peer_key}",
)
if requested:
if peer_key not in _peer_lifecycle:
_peer_lifecycle[peer_key] = {
"last_seen_inbound": None,
"last_send_ok": None,
"last_request_path_at": None,
"ts_seed_until": None,
}
_peer_lifecycle[peer_key]["last_request_path_at"] = now
log(
"[presence_bridge] target=presence-reticulum overlay_link_path_request "
f"peer={peer_key} await={await_seconds} resolved={str(resolved).lower()}"
)
if resolved:
return True
else:
try:
RNS.Transport.request_path(destination_hash)
if peer_key not in _peer_lifecycle:
_peer_lifecycle[peer_key] = {
"last_seen_inbound": None,
"last_send_ok": None,
"last_request_path_at": None,
"ts_seed_until": None,
}
_peer_lifecycle[peer_key]["last_request_path_at"] = now
log(
"[presence_bridge] target=presence-reticulum overlay_link_path_request "
f"peer={peer_key}"
)
except Exception as exc:
log(
"[presence_bridge] target=presence-reticulum overlay_link_path_request_failed "
f"peer={peer_key}: {exc}"
)
if await_seconds > 0:
return _await_destination_path(destination_hash, await_seconds)
return False
def _note_call_media_inbound(peer_hash: str, sender_call_hash: str = "") -> None:
if not peer_hash:
return
state = _get_call_media_state(peer_hash)
now = time.time()
if sender_call_hash:
state["destination_hash_hex"] = str(sender_call_hash or "").strip().lower()
state["last_inbound_at"] = now
state["last_resolved_at"] = now
state["consecutive_timeouts"] = 0
current = str(state.get("path_state") or "unknown")
if current == "unknown":
_transition_call_media_path_state(peer_hash, "warming", "inbound_packet")
current = "warming"
if current == "failing":
_transition_call_media_path_state(peer_hash, "recovering", "inbound_packet")
if str(state.get("path_state") or "") in ("warming", "stale", "recovering"):
_transition_call_media_path_state(peer_hash, "fresh", "inbound_packet")
def _note_call_media_send_result(peer_hash: str, ok: bool) -> None:
state = _get_call_media_state(peer_hash)
now = time.time()
if ok:
state["last_send_ok"] = now
state["last_resolved_at"] = now
state["consecutive_timeouts"] = 0
current = str(state.get("path_state") or "unknown")
if current == "unknown":
_transition_call_media_path_state(peer_hash, "warming", "send_ok")
current = "warming"
if current == "failing":
_transition_call_media_path_state(peer_hash, "recovering", "send_ok")
if str(state.get("path_state") or "") in ("warming", "stale", "recovering"):
_transition_call_media_path_state(peer_hash, "fresh", "send_ok")
else:
state["last_send_fail"] = now
current = str(state.get("path_state") or "unknown")
if current == "fresh":
_transition_call_media_path_state(peer_hash, "stale", "send_fail")
current = "stale"
if current == "stale":
_transition_call_media_path_state(peer_hash, "failing", "send_fail")
def _warm_call_media_path_if_possible(
peer_hash: str,
*,
active_call: bool,
allow_wait: bool,
reason: str,
) -> tuple[str, bool]:
peer_identity = _get_group_audio_peer_identity(peer_hash)
if peer_identity is None:
return "unknown", False
try:
outbound = build_outbound_destination(peer_identity)
except Exception as exc:
log(
"[presence_bridge] target=reticulum-audio-ipc packet_path_build_failed "
f"peer={peer_hash} err={exc}"
)
return "unknown", False
return _ensure_call_media_path(
peer_hash,
outbound.hash,
active_call=active_call,
allow_wait=allow_wait,
reason=reason,
)
def identity_hash_hex(identity: Any) -> str:
raw = getattr(identity, "hash", None)
if isinstance(raw, bytes):
return destination_hash_hex(raw)
return ""
def derive_presence_destination_hash_for_identity(identity: Any) -> str:
try:
outbound = build_outbound_destination(identity)
except Exception:
return ""
return destination_hash_hex(outbound.hash)
def find_peer_hash_for_identity(identity: Any) -> str:
identity_hash = identity_hash_hex(identity)
if not identity_hash:
return ""
for peer_hash, peer_identity in list(_known_peers.items()):
if identity_hash_hex(peer_identity) == identity_hash:
return peer_hash
return ""
def ensure_known_peer_from_recall(
peer_hash_hex: str, registration_source: str = "recall"
) -> bool:
"""
Mirror RNS's known destination into _known_peers when we see traffic but missed the announce.
Uses RNS.Identity.recall(destination_hash).
registration_source: recall | ts_seed (TS-supplied hashes refresh seed lease).
"""
if not peer_hash_hex or _destination is None:
return False
peer_key = peer_hash_hex.lower()
local_hex = destination_hash_hex(_destination.hash)
if peer_key == local_hex:
return False
if peer_key in _known_peers:
if registration_source == "ts_seed":
_refresh_ts_seed_only(peer_key)
return True
try:
h = bytes.fromhex(peer_hash_hex)
except ValueError:
return False
if len(h) != 16:
return False
recalled = RNS.Identity.recall(h)
if recalled is None:
return False
try:
derived = derive_presence_destination_hash_for_identity(recalled)
except Exception as exc:
log(
"[presence_bridge] target=presence-reticulum recall_build_failed "
f"peer={peer_key} err={exc}"
)
return False
if not derived:
log(
"[presence_bridge] target=presence-reticulum recall_build_failed "
f"peer={peer_key} err=empty_derived_hash"
)
return False
if derived != peer_key:
log(
"[presence_bridge] target=presence-reticulum recall_hash_mismatch "
f"peer={peer_key} derived={derived}"
)
return False
_register_peer(peer_key, recalled, registration_source)
return True
def ensure_known_peer_from_wire_kr(public_key_base58: str, peer_hash_hex: str) -> bool:
"""
When Identity.recall(r) failed, derive RNS destination from wire k (Base58) and verify
it matches r. Only works when k decodes to a full RNS public key (64 bytes: X25519+Ed25519).
Qortal's usual 32-byte Ed25519-only k cannot be used here; those peers rely on recall/TS seed.
"""
if not peer_hash_hex or _destination is None:
return False
peer_key = peer_hash_hex.lower()
if peer_key in _known_peers:
return True
local_hex = destination_hash_hex(_destination.hash)
if peer_key == local_hex:
return False
try:
pub_bytes = qortal_base58_decode(public_key_base58)
except Exception:
return False
if len(pub_bytes) != 64:
if peer_key not in _KR_MISMATCH_LOGGED:
_KR_MISMATCH_LOGGED.add(peer_key)
log(
f"[presence_bridge] target=presence-reticulum kr_skip peer={peer_key} "
f"reason=pub_len_{len(pub_bytes)}_not_64_rns_full_key"
)
return False
try:
ident = RNS.Identity(create_keys=False)
ident.load_public_key(pub_bytes)
outbound = RNS.Destination(
ident,
RNS.Destination.OUT,
RNS.Destination.SINGLE,
APP_NAMESPACE,
PRESENCE_ASPECT,
PRESENCE_VERSION,
)
derived = destination_hash_hex(outbound.hash)
except Exception as exc:
log(
f"[presence_bridge] target=presence-reticulum kr_skip peer={peer_key} err={exc}"
)
return False
if derived != peer_key:
if peer_key not in _KR_MISMATCH_LOGGED:
_KR_MISMATCH_LOGGED.add(peer_key)
log(
f"[presence_bridge] target=presence-reticulum kr_mismatch peer={peer_key} "
f"derived={derived}"
)
return False
_register_peer(peer_key, ident, "wire_kr")
return True
def ensure_identity(config_dir: str):
global _identity
identity_path = os.environ.get("QORTAL_RETICULUM_IDENTITY_PATH") or os.path.join(
config_dir, IDENTITY_FILENAME
)
if os.path.exists(identity_path):
loaded = RNS.Identity.from_file(identity_path)
if loaded is not None:
_identity = loaded
return _identity
_identity = RNS.Identity()
_identity.to_file(identity_path)
return _identity
class PresenceAnnounceHandler:
def __init__(self, local_hash: bytes):
self.aspect_filter = f"{APP_NAMESPACE}.{PRESENCE_ASPECT}.{PRESENCE_VERSION}"
self.local_hash = local_hash
def received_announce(self, destination_hash, announced_identity, app_data):
if destination_hash == self.local_hash:
return
peer_hash = destination_hash_hex(destination_hash)
app_data_len = len(app_data) if app_data is not None else 0
log(
f"[presence_bridge] received announce peer={peer_hash} app_data_len={app_data_len}"
)
_register_peer(peer_hash, announced_identity, "announce")
_mark_candidate_peer(peer_hash, "announce")
_retry_pending_overlay_connect_on_announce(peer_hash)
_retry_pending_audio_connect_on_announce(peer_hash)
def build_outbound_destination(peer_identity):
return RNS.Destination(
peer_identity,
RNS.Destination.OUT,
RNS.Destination.SINGLE,
APP_NAMESPACE,
PRESENCE_ASPECT,
PRESENCE_VERSION,
)
def get_overlay_link_id(link) -> Optional[str]:
if link is None:
return None
with _state_lock:
return _overlay_link_ids_by_object.get(id(link))
def get_overlay_link_state(link_id: str) -> Optional[Dict[str, Any]]:
with _state_lock:
return _overlay_links_by_id.get(link_id)
def _overlay_link_is_current(link_id: str, link: Any = None) -> bool:
if not link_id:
return False
with _state_lock:
state = _overlay_links_by_id.get(link_id)
if state is None:
return False
if link is not None and state.get("link") is not link:
return False
if link is not None and getattr(link, "status", None) == getattr(RNS.Link, "CLOSED", object()):
return False
return True
def remove_overlay_link(link_id: str) -> Optional[Dict[str, Any]]:
with _state_lock:
state = _overlay_links_by_id.pop(link_id, None)
if not state:
return None
link = state.get("link")
if link is not None:
_overlay_link_ids_by_object.pop(id(link), None)
peer_hash = str(state.get("peerPresenceHash") or "").strip().lower()
if peer_hash:
existing = _active_overlay_link_id_by_peer_hash.get(peer_hash)
state["_was_active_overlay"] = existing == link_id
if existing == link_id:
_active_overlay_link_id_by_peer_hash.pop(peer_hash, None)
return state
def emit_overlay_link_state(
link_id: str,
state: Dict[str, Any],
reason: str = "",
*,
closed_by_reticulum: bool = False,
) -> None:
now = time.time()
created_at = state.get("created_at")
established_at = state.get("established_at")
last_rx_at = state.get("last_rx_at")
last_send_ok_at = state.get("last_send_ok_at")
last_activity_at = state.get("last_activity_at")
def age_ms(value: Any) -> Optional[int]:
if not isinstance(value, (int, float)):
return None
return max(0, int((now - float(value)) * 1000.0))
emit_event(
"overlay_link_state",
{
"linkId": link_id,
"peerPresenceHash": str(state.get("peerPresenceHash") or ""),
"incoming": state.get("incoming") is True,
"established": state.get("established") is True,
"reason": reason,
"queuedPackets": len(state.get("pending_packets") or []),
"closedByReticulum": closed_by_reticulum,
"lastRxAt": (
float(last_rx_at) * 1000.0
if isinstance(last_rx_at, (int, float))
else None
),
"createdAgeMs": age_ms(created_at),
"establishedAgeMs": age_ms(established_at),
"lastRxAgeMs": age_ms(last_rx_at),
"lastSendOkAgeMs": age_ms(last_send_ok_at),
"lastActivityAgeMs": age_ms(last_activity_at),
},
)
def _overlay_teardown_reason_name(reason: Any) -> str:
if reason == getattr(RNS.Link, "TIMEOUT", object()):
return "timeout"
if reason == getattr(RNS.Link, "INITIATOR_CLOSED", object()):
return "initiator_closed"
if reason == getattr(RNS.Link, "DESTINATION_CLOSED", object()):
return "destination_closed"
if reason is None:
return "closed"
return str(reason)
def _overlay_close_debug_line(link_id: str, state: Dict[str, Any], reason: str) -> str:
now = time.time()
def age_label(key: str) -> str:
value = state.get(key)
if not isinstance(value, (int, float)):
return "na"
return str(max(0, int((now - float(value)) * 1000.0)))
peer_hash = str(state.get("peerPresenceHash") or "").strip().lower() or "unknown"
link = state.get("link")
reticulum_status = getattr(link, "status", None) if link is not None else None
was_active = state.get("_was_active_overlay") is True
return (
"[presence_bridge] target=presence-reticulum overlay_link_close_detail "
f"link={link_id} peer={peer_hash} incoming={str(state.get('incoming') is True).lower()} "
f"was_established={str(state.get('established') is True).lower()} "
f"was_active={str(was_active).lower()} reason={reason} "
f"created_age_ms={age_label('created_at')} "
f"established_age_ms={age_label('established_at')} "
f"last_rx_age_ms={age_label('last_rx_at')} "
f"last_send_ok_age_ms={age_label('last_send_ok_at')} "
f"last_activity_age_ms={age_label('last_activity_at')} "
f"queued={len(state.get('pending_packets') or [])} rns_status={reticulum_status}"
)
def _queue_overlay_packet(state: Dict[str, Any], traffic: str, wire_bytes: bytes) -> None:
pending = state.get("pending_packets")
if pending is None:
pending = deque(maxlen=_OVERLAY_PENDING_PACKET_LIMIT)
state["pending_packets"] = pending
if state.get("established") is not True:
while len(pending) >= _OVERLAY_PENDING_UNESTABLISHED_LIMIT:
pending.popleft()
pending.append((traffic, bytes(wire_bytes)))
def _send_packet_on_link(link, wire_bytes: bytes, log_target: str) -> bool:
try:
packet = RNS.Packet(link, wire_bytes, create_receipt=False)
result = packet.send()
if result is False:
log(f"[presence_bridge] {log_target} packet_send_false")
return False
return True
except Exception as exc:
log(f"[presence_bridge] {log_target} packet_send_exception err={exc}")
return False
def _valid_presence_destination_hash_hex(peer_hash: str) -> bool:
h = str(peer_hash or "").strip().lower()
if len(h) != 32:
return False
try:
bytes.fromhex(h)
except ValueError:
return False
return True
def _dedup_age_ts(state: Dict[str, Any], both_established: bool) -> float:
"""Monotonic-ish sort key: lower = older link (prefer keeping)."""
if both_established:
t = state.get("established_at")
if isinstance(t, (int, float)):
return float(t)
t = state.get("created_at")
if isinstance(t, (int, float)):
return float(t)
return 0.0
t = state.get("created_at")
if isinstance(t, (int, float)):
return float(t)
return 0.0
def _dedup_activity_ts(state: Dict[str, Any]) -> float:
"""Sort key for recently useful links; higher = more useful."""
best = 0.0
for key in ("last_rx_at", "last_send_ok_at", "last_activity_at", "established_at"):
t = state.get(key)
if isinstance(t, (int, float)):
best = max(best, float(t))
return best
def _dedup_has_peer_hash(state: Dict[str, Any], peer_key: str) -> bool:
return str(state.get("peerPresenceHash") or "").strip().lower() == peer_key
def _overlay_link_pressure_sort_key(item: tuple[str, Dict[str, Any]]) -> tuple[int, int, int, float, str]:
link_id, state = item
peer_hash = str(state.get("peerPresenceHash") or "").strip().lower()
active_link_id = _active_overlay_link_id_by_peer_hash.get(peer_hash) if peer_hash else ""
active = bool(active_link_id and active_link_id == link_id)
established = state.get("established") is True
identified = bool(peer_hash)
activity = _dedup_activity_ts(state)
if activity <= 0.0:
created_at = state.get("created_at")
activity = float(created_at) if isinstance(created_at, (int, float)) else 0.0
return (
1 if established else 0,
1 if active else 0,
1 if identified else 0,
activity,
link_id,
)
def _prune_overlay_link_pressure(reason: str = "link_pressure", reserve_slots: int = 0) -> None:
budget = max(0, _OVERLAY_MAX_TOTAL_LINKS - max(0, int(reserve_slots)))
victim_ids: List[str] = []
with _state_lock:
excess = len(_overlay_links_by_id) - budget
if excess <= 0:
return
candidates = sorted(_overlay_links_by_id.items(), key=_overlay_link_pressure_sort_key)
victim_ids = [link_id for link_id, _state in candidates[:excess]]
for link_id in victim_ids:
_teardown_overlay_link_id(link_id, reason)
def _dedup_pick_keep_link(
peer_key: str,
link_id_a: str,
state_a: Dict[str, Any],
link_id_b: str,
state_b: Dict[str, Any],
) -> tuple[str, str]:
"""Return (keep_link_id, teardown_link_id) for two links to the same peer."""
est_a = state_a.get("established") is True
est_b = state_b.get("established") is True
if est_a and not est_b:
return link_id_a, link_id_b
if est_b and not est_a:
return link_id_b, link_id_a
known_a = _dedup_has_peer_hash(state_a, peer_key)
known_b = _dedup_has_peer_hash(state_b, peer_key)
if known_a and not known_b:
return link_id_a, link_id_b
if known_b and not known_a:
return link_id_b, link_id_a
activity_a = _dedup_activity_ts(state_a)
activity_b = _dedup_activity_ts(state_b)
if abs(activity_a - activity_b) > 0.001:
return (link_id_a, link_id_b) if activity_a > activity_b else (link_id_b, link_id_a)
incoming_a = state_a.get("incoming") is True
incoming_b = state_b.get("incoming") is True
if incoming_a != incoming_b:
local_hex = _local_presence_hash_hex()
if local_hex and _valid_presence_destination_hash_hex(peer_key):
# Deterministic duplicate resolution for otherwise equivalent links:
# lower hash keeps outbound, higher hash keeps incoming.
prefer_incoming = local_hex > peer_key
if incoming_a == prefer_incoming:
return link_id_a, link_id_b
return link_id_b, link_id_a
both_est = est_a and est_b
ta = _dedup_age_ts(state_a, both_est)
tb = _dedup_age_ts(state_b, both_est)
if ta != tb:
if both_est:
return (link_id_a, link_id_b) if ta < tb else (link_id_b, link_id_a)
return (link_id_a, link_id_b) if ta > tb else (link_id_b, link_id_a)
return (link_id_a, link_id_b) if link_id_a < link_id_b else (link_id_b, link_id_a)
def _overlay_teardown_should_demote(reason: str) -> bool:
# These are local management events, not proof that the peer cannot keep a
# usable fanout link. Demoting here causes sync churn and can prune good links.
if reason in {
"pruned",
"pruned_orphan",
"dedup_orphan",
"dedup_same_peer",
"announce_retry",
"initiator_closed",
"admission_rejected",
"pruned_unknown_full",
"link_pressure",
"link_pressure_inbound",
"link_pressure_outbound",
"unestablished_timeout",
}:
return False
return True
def _overlay_link_recent_activity_age_seconds(state: Dict[str, Any], now: float) -> Optional[float]:
recent_at = 0.0
for key in ("last_send_ok_at", "last_rx_at", "last_activity_at"):
value = state.get(key)
if isinstance(value, (int, float)):
recent_at = max(recent_at, float(value))
if recent_at <= 0.0:
return None
return max(0.0, now - recent_at)
def _overlay_timeout_close_should_keep_peer(state: Dict[str, Any], reason: str, now: float) -> bool:
if str(reason or "").strip().lower() != "timeout":
return False
age = _overlay_link_recent_activity_age_seconds(state, now)
return (
age is not None
and age <= _OVERLAY_LINK_TIMEOUT_RECENT_ACTIVITY_GRACE_SECONDS
)
def _overlay_mesh_link_count_locked() -> int:
return len(_overlay_links_by_id)
def _admit_overlay_peer_if_allowed(peer_key: str, reason: str, incoming: bool = False) -> bool:
"""Admit a peer into the direction-specific presence overlay mesh budget."""
global _active_overlay_neighbors, _inbound_overlay_neighbors
peer_key = str(peer_key or "").strip().lower()
if not peer_key or not _valid_presence_destination_hash_hex(peer_key):
return False
local_hex = _local_presence_hash_hex()
if local_hex and peer_key == local_hex:
return False
target = _inbound_overlay_neighbors if incoming else _active_overlay_neighbors
direction = "inbound" if incoming else "outbound"
limit = _OVERLAY_MAX_INBOUND_NEIGHBORS if incoming else _OVERLAY_MAX_OUTBOUND_NEIGHBORS
if peer_key in target:
return True
if len(target) >= limit:
verbose_presence_log(
"[presence_bridge] target=presence-reticulum overlay_admission_reject "
f"peer={peer_key} direction={direction} reason={reason} active={len(target)}"
)
return False
target[peer_key] = time.time()
verbose_presence_log(
"[presence_bridge] target=presence-reticulum overlay_admission_accept "
f"peer={peer_key} direction={direction} reason={reason} active={len(target)}"
)
return True
def _overlay_unknown_inbound_allowed() -> bool:
if len(_inbound_overlay_neighbors) >= _OVERLAY_MAX_INBOUND_NEIGHBORS:
return False
with _state_lock:
return _overlay_mesh_link_count_locked() < (
_OVERLAY_MAX_OUTBOUND_NEIGHBORS + _OVERLAY_MAX_INBOUND_NEIGHBORS
)
def _teardown_overlay_link_id(link_id: str, reason: str) -> None:
state = remove_overlay_link(link_id)
if state is None:
return
peer_hash = str(state.get("peerPresenceHash") or "").strip().lower()
verbose_presence_log(_overlay_close_debug_line(link_id, state, reason))
link = state.get("link")
if link is not None:
try:
link.teardown()
except Exception:
pass
state["established"] = False
emit_overlay_link_state(link_id, state, reason)
if peer_hash and _overlay_teardown_should_demote(reason):
_demote_overlay_fanout_peer(peer_hash, f"link_teardown:{reason}")
def _maybe_prune_stale_overlay_links() -> None:
now = time.time()
stale_ids = []
with _state_lock:
for link_id, state in list(_overlay_links_by_id.items()):
if state.get("established") is not True:
created_at = state.get("created_at")
if (
isinstance(created_at, (int, float))
and now - float(created_at) > _OVERLAY_UNESTABLISHED_LINK_TIMEOUT_SECONDS
):
stale_ids.append(link_id)
continue
last_activity = state.get("last_activity_at")
if not isinstance(last_activity, (int, float)):
last_activity = state.get("last_rx_at")
if not isinstance(last_activity, (int, float)):
last_activity = state.get("last_send_ok_at")
if not isinstance(last_activity, (int, float)):
last_activity = state.get("established_at") or state.get("created_at")
if not isinstance(last_activity, (int, float)):
continue
if now - float(last_activity) > _OVERLAY_LINK_RX_IDLE_TIMEOUT_SECONDS:
stale_ids.append(link_id)
for link_id in stale_ids:
state = get_overlay_link_state(link_id)
reason = (
"unestablished_timeout"
if state is not None and state.get("established") is not True
else "rx_idle_timeout"
)
_teardown_overlay_link_id(link_id, reason)
def _register_active_overlay_for_peer(peer_key: str, link_id: str) -> Optional[Dict[str, Any]]:
"""One active overlay link per peer hash; teardown duplicate links."""
peer_key = str(peer_key or "").strip().lower()
if not peer_key or not _valid_presence_destination_hash_hex(peer_key):
return None
state_for_direction = get_overlay_link_state(link_id)
incoming = bool(state_for_direction and state_for_direction.get("incoming") is True)
if not _admit_overlay_peer_if_allowed(peer_key, "register_active", incoming=incoming):
_teardown_overlay_link_id(link_id, "admission_rejected")
return None
lose_id: Optional[str] = None
with _state_lock:
existing_link_id = _active_overlay_link_id_by_peer_hash.get(peer_key)
if existing_link_id == link_id:
return _overlay_links_by_id.get(link_id)
if not existing_link_id:
_active_overlay_link_id_by_peer_hash[peer_key] = link_id
return _overlay_links_by_id.get(link_id)
st_new = _overlay_links_by_id.get(link_id)
st_old = _overlay_links_by_id.get(existing_link_id)
if st_new is None:
if st_old is not None:
return st_old
_active_overlay_link_id_by_peer_hash.pop(peer_key, None)
return None
if st_old is None:
_active_overlay_link_id_by_peer_hash[peer_key] = link_id
return st_new
keep_id, lose_id = _dedup_pick_keep_link(
peer_key,
existing_link_id, st_old, link_id, st_new
)
_active_overlay_link_id_by_peer_hash[peer_key] = keep_id
keep_state = _overlay_links_by_id.get(keep_id)
if lose_id:
log(
"[presence_bridge] target=presence-reticulum overlay_link_duplicate_teardown "
f"peer={peer_key} keep={keep_id} teardown={lose_id}"
)
if keep_state is not None:
log(
"[presence_bridge] target=presence-reticulum overlay_link_canonical_keep "
f"peer={peer_key} link={keep_id} incoming={str(keep_state.get('incoming') is True).lower()} "
f"established={str(keep_state.get('established') is True).lower()}"
)
_teardown_overlay_link_id(lose_id, "dedup_same_peer")
return keep_state
def _dedup_overlay_links_for_peer(
peer_key: str,
preferred_link_id: str = "",
reason: str = "dedup_same_peer",
) -> Optional[Dict[str, Any]]:
"""Collapse all live overlay links for a peer down to one canonical link."""
peer_key = str(peer_key or "").strip().lower()
if not peer_key or not _valid_presence_destination_hash_hex(peer_key):
return None
preferred_link_id = str(preferred_link_id or "")
lose_ids: List[str] = []
keep_id = ""
keep_state: Optional[Dict[str, Any]] = None
with _state_lock:
candidates = [
(link_id, state)
for link_id, state in _overlay_links_by_id.items()
if str(state.get("peerPresenceHash") or "").strip().lower() == peer_key
]
if not candidates:
if _active_overlay_link_id_by_peer_hash.get(peer_key):
_active_overlay_link_id_by_peer_hash.pop(peer_key, None)
return None
if len(candidates) == 1:
keep_id, keep_state = candidates[0]
_active_overlay_link_id_by_peer_hash[peer_key] = keep_id
return keep_state
preferred = next(
((link_id, state) for link_id, state in candidates if link_id == preferred_link_id),
None,
)
active_link_id = _active_overlay_link_id_by_peer_hash.get(peer_key) or ""
active = next(
((link_id, state) for link_id, state in candidates if link_id == active_link_id),
None,
)
keep_id, keep_state = preferred or active or candidates[0]
for candidate_id, candidate_state in candidates:
if candidate_id == keep_id:
continue
next_keep_id, next_lose_id = _dedup_pick_keep_link(
peer_key,
keep_id,
keep_state,
candidate_id,
candidate_state,
)
if next_keep_id == candidate_id:
lose_ids.append(keep_id)
keep_id = candidate_id
keep_state = candidate_state
else:
lose_ids.append(next_lose_id)
_active_overlay_link_id_by_peer_hash[peer_key] = keep_id
keep_state = _overlay_links_by_id.get(keep_id)
for lose_id in dict.fromkeys(lose_ids):
log(
"[presence_bridge] target=presence-reticulum overlay_link_duplicate_teardown "
f"peer={peer_key} keep={keep_id} teardown={lose_id}"
)
_teardown_overlay_link_id(lose_id, reason)
return keep_state
def _flush_overlay_link_pending(link_id: str) -> None:
state = get_overlay_link_state(link_id)
if state is None or state.get("established") is not True:
return
link = state.get("link")
pending = state.get("pending_packets")
if link is None or pending is None:
return
if not _overlay_link_is_current(link_id, link):
return
while pending:
if not _overlay_link_is_current(link_id, link):
return
traffic, wire_bytes = pending[0]
if not _send_packet_on_link(
link,
wire_bytes,
f"target=presence-reticulum overlay_link_flush peer={state.get('peerPresenceHash') or 'unknown'} traffic={traffic}",
):
break
if not _overlay_link_is_current(link_id, link):
return
pending.popleft()
if _overlay_link_is_current(link_id, link):
emit_overlay_link_state(link_id, state, "flush")
def _ensure_overlay_link(
peer_hash: str,
await_path: bool = True,
) -> Optional[Dict[str, Any]]:
peer_key = str(peer_hash or "").strip().lower()
if not peer_key:
return None
local_hex = _local_presence_hash_hex()
if local_hex and peer_key == local_hex:
log(
"[presence_bridge] target=presence-reticulum overlay_link_skipped_self "
f"peer={peer_key}"
)
return None
with _state_lock:
existing_link_id = _active_overlay_link_id_by_peer_hash.get(peer_key)
if existing_link_id:
existing = _overlay_links_by_id.get(existing_link_id)
if existing is not None:
return existing
_active_overlay_link_id_by_peer_hash.pop(peer_key, None)
if not _admit_overlay_peer_if_allowed(peer_key, "outbound", incoming=False):
return None
link_id = ""
state: Optional[Dict[str, Any]] = None
error: Optional[str] = None
outbound = None
try:
with _state_lock:
peer_identity = _known_peers.get(peer_key)
if peer_identity is None:
return None
outbound = build_outbound_destination(peer_identity)
outbound_hash = destination_hash_hex(outbound.hash)
if local_hex and outbound_hash == local_hex:
log(
"[presence_bridge] target=presence-reticulum overlay_link_rejected_self_identity "
f"peer={peer_key} derived={outbound_hash}"
)
_known_peers.pop(peer_key, None)
_peer_lifecycle.pop(peer_key, None)
return None
if outbound_hash != peer_key:
log(
"[presence_bridge] target=presence-reticulum overlay_link_hash_mismatch "
f"peer={peer_key} derived={outbound_hash}"
)
_known_peers.pop(peer_key, None)
_peer_lifecycle.pop(peer_key, None)
return None
if outbound is not None:
if not _nudge_overlay_link_path(
peer_key,
outbound.hash,
await_seconds=_OVERLAY_LINK_PATH_AWAIT_SECONDS if await_path else 0.0,
):
if await_path:
log(
"[presence_bridge] target=presence-reticulum "
"overlay_link_deferred_no_path "
f"peer={peer_key} await={_OVERLAY_LINK_PATH_AWAIT_SECONDS}"
)
return None
with _state_lock:
existing_link_id = _active_overlay_link_id_by_peer_hash.get(peer_key)
if existing_link_id:
existing = _overlay_links_by_id.get(existing_link_id)
if existing is not None:
log(
"[presence_bridge] target=presence-reticulum "
f"overlay_link_reuse_{'incoming' if existing.get('incoming') is True else 'outgoing'} "
f"peer={peer_key} link={existing_link_id}"
)
return existing
_active_overlay_link_id_by_peer_hash.pop(peer_key, None)
if outbound is None:
return None
_prune_overlay_link_pressure("link_pressure_outbound", reserve_slots=1)
with _state_lock:
if len(_overlay_links_by_id) >= _OVERLAY_MAX_TOTAL_LINKS:
log(
"[presence_bridge] target=presence-reticulum overlay_link_rejected_pressure "
f"peer={peer_key} links={len(_overlay_links_by_id)} max={_OVERLAY_MAX_TOTAL_LINKS}"
)
return None
link_id = str(uuid.uuid4())
link = RNS.Link(
outbound,
established_callback=on_outgoing_overlay_link_established,
closed_callback=on_overlay_link_closed,
)
now = time.time()
state = {
"link": link,
"peerPresenceHash": peer_key,
"incoming": False,
"established": False,
"created_at": now,
"pending_packets": deque(maxlen=_OVERLAY_PENDING_PACKET_LIMIT),
}
_overlay_links_by_id[link_id] = state
_overlay_link_ids_by_object[id(link)] = link_id
except Exception as exc:
error = str(exc)
if error is not None:
log(
f"[presence_bridge] target=presence-reticulum overlay_link_connect_failed peer={peer_key}: {error}"
)
return None
if state is None or not link_id:
return None
_register_active_overlay_for_peer(peer_key, link_id)
state = get_overlay_link_state(link_id)
if state is None:
with _state_lock:
fallback_id = _active_overlay_link_id_by_peer_hash.get(peer_key)
if fallback_id:
state = get_overlay_link_state(fallback_id)
if state is None:
return None
st_new = get_overlay_link_state(link_id)
if st_new is not None and st_new.get("incoming") is not True:
emit_overlay_link_state(link_id, st_new, "connecting")
log(
f"[presence_bridge] target=presence-reticulum overlay_link_open_on_demand peer={peer_key}"
)
return state
def _retry_pending_overlay_connect_on_announce(peer_hash: str) -> None:
"""If an outbound reverse dial started before path resolution, retry it after announce arrives."""
peer_key = str(peer_hash or "").strip().lower()
if not peer_key:
return
local_hex = _local_presence_hash_hex()
if local_hex and peer_key == local_hex:
return
link = None
existing_link_id = ""
stale_state: Optional[Dict[str, Any]] = None
with _state_lock:
existing_link_id = _active_overlay_link_id_by_peer_hash.get(peer_key) or ""
if not existing_link_id:
return
existing = _overlay_links_by_id.get(existing_link_id)
if existing is None:
_active_overlay_link_id_by_peer_hash.pop(peer_key, None)
return
if existing.get("incoming") is True or existing.get("established") is True:
return
link = existing.get("link")
if link is not None:
try:
link.set_link_closed_callback(None)
except Exception:
pass
stale_state = remove_overlay_link(existing_link_id)
if link is not None:
try:
link.teardown()
except Exception:
pass
if stale_state is not None:
stale_state["established"] = False
emit_overlay_link_state(existing_link_id, stale_state, "announce_retry")
log(
"[presence_bridge] target=presence-reticulum overlay_link_retry_on_announce "
f"peer={peer_key} previous_link={existing_link_id}"
)
_enqueue_scheduler_task(
"link-management",
"overlay-link-retry-on-announce",
_ensure_overlay_link,
peer_key,
)
def _retry_pending_audio_connect_on_announce(peer_hash: str) -> None:
peer_key = str(peer_hash or "").strip().lower()
if not peer_key:
return
with _state_lock:
desired = _audio_link_desired_by_peer_hash.get(peer_key)
existing_link_id = _outgoing_audio_link_id_by_peer_hash.get(peer_key)
if desired is None or desired.get("desired") is not True:
return
existing = get_audio_link_state(existing_link_id) if existing_link_id else None
if existing is not None and existing.get("established") is True:
return
if _has_viable_audio_link_for_peer(peer_key):
log(
"[presence_bridge] target=reticulum-audio-link audio_link_retry_on_announce_skipped "
f"peer={peer_key} existing_link={existing_link_id or 'none'} reason=viable_link"
)
return
if existing is not None and existing_link_id:
link = existing.get("link")
if link is not None:
try:
link.set_link_closed_callback(None)
except Exception:
pass
try:
link.teardown()
except Exception:
pass
removed = remove_audio_link(existing_link_id)
if removed is not None:
emit_event(
"group_audio_link_closed",
{
"linkId": existing_link_id,
"peerPresenceHash": removed.get("peerPresenceHash") or "",
"peerDestinationHash": removed.get("peerDestinationHash") or "",
"incoming": removed.get("incoming") is True,
"reason": "announce_retry",
},
)
if desired.get("retry_timer") is not None:
_cancel_audio_link_retry_timer(peer_key)
log(
"[presence_bridge] target=reticulum-audio-link audio_link_retry_on_announce "
f"peer={peer_key} existing_link={existing_link_id or 'none'}"
)
_schedule_audio_link_retry(peer_key, "announce", immediate=True)
def _sync_overlay_links() -> None:
_maybe_prune_stale_overlay_links()
_prune_overlay_link_pressure("link_pressure")
_bootstrap_overlay_neighbors_if_degraded("sync")
desired_outbound = set(_active_overlay_neighbors.keys())
desired = desired_outbound | set(_inbound_overlay_neighbors.keys())
for peer_hash in desired_outbound:
if peer_hash not in _known_peers:
ensure_known_peer_from_recall(peer_hash, "ts_seed")
state = _ensure_overlay_link(
peer_hash,
await_path=False,
)
if state is None:
# A sync pass can run while Reticulum is still resolving recall/path
# state. Keep the fanout lease and let explicit closes or real send
# failures decide whether the peer is dead.
continue
for peer_hash, link_id in list(_active_overlay_link_id_by_peer_hash.items()):
if peer_hash in desired:
continue
state = get_overlay_link_state(link_id)
if state is None:
_active_overlay_link_id_by_peer_hash.pop(peer_hash, None)
continue
_teardown_overlay_link_id(link_id, "pruned")
for peer_hash in list(desired):
_dedup_overlay_links_for_peer(peer_hash, reason="dedup_same_peer")
for link_id, state in list(_overlay_links_by_id.items()):
peer_hash = str(state.get("peerPresenceHash") or "").strip().lower()
if not peer_hash:
if (
len(_inbound_overlay_neighbors) >= _OVERLAY_MAX_INBOUND_NEIGHBORS
or len(_overlay_links_by_id) > (
_OVERLAY_MAX_OUTBOUND_NEIGHBORS + _OVERLAY_MAX_INBOUND_NEIGHBORS
)
):
_teardown_overlay_link_id(link_id, "pruned_unknown_full")
continue
active_link_id = _active_overlay_link_id_by_peer_hash.get(peer_hash)
if active_link_id == link_id:
continue
if peer_hash not in desired:
_teardown_overlay_link_id(link_id, "pruned_orphan")
elif active_link_id:
_teardown_overlay_link_id(link_id, "dedup_orphan")
def _resolve_sender_peer_destination_hash(sender_hex: str) -> str:
"""Map wire `r` (destination hash hex) to peer key in _known_peers; recall fallback."""
sender_hex = str(sender_hex or "").strip().lower()
if not sender_hex:
return ""
if sender_hex in _known_peers:
return sender_hex
# Register via recall (same as presence inbound). Previously we only recalled and
# looked up find_peer_hash_for_identity, which stayed empty until another path registered.
if ensure_known_peer_from_recall(sender_hex, "inbound"):
return sender_hex
return ""
def _emit_presence_message(message: Dict[str, Any], link_id: Optional[str] = None) -> bool:
message_type = message.get("t")
message_id = message.get("i")
address = message.get("a")
public_key = message.get("k")
session_id = message.get("n")
timestamp = message.get("m")
signature = message.get("g")
sender_hash = message.get("r")
origin_hash = message.get("o")
overlay_hops_remaining = message.get("q")
if (
not isinstance(message_type, str)
or not isinstance(message_id, str)
or not isinstance(address, str)
or not isinstance(public_key, str)
or not isinstance(session_id, str)
or not isinstance(timestamp, int)
or not isinstance(signature, str)
or not isinstance(sender_hash, str)
):
log("[presence_bridge] ignored malformed presence packet")
return False
sender_hash = sender_hash.strip().lower()
if not _valid_presence_destination_hash_hex(sender_hash):
log("[presence_bridge] ignored malformed presence packet sender_hash")
return False
origin_peer_hash = sender_hash
if isinstance(origin_hash, str) and origin_hash.strip():
candidate_origin_hash = origin_hash.strip().lower()
if not _valid_presence_destination_hash_hex(candidate_origin_hash):
log("[presence_bridge] ignored malformed presence packet origin_hash")
return False
origin_peer_hash = candidate_origin_hash
payload: Dict[str, Any] = {
"address": address,
"publicKey": public_key,
"sessionId": session_id,
}
if message_type == "PRESENCE_ANNOUNCE":
payload["status"] = message.get("s")
payload["clientVersion"] = message.get("c")
elif message_type == "PRESENCE_HEARTBEAT":
payload["status"] = message.get("s")
elif message_type == "PRESENCE_OFFLINE":
payload["status"] = "offline"
else:
log(f"[presence_bridge] ignored unknown presence packet type={message_type}")
return False
_note_presence_pressure("decoded:presence", message_type)
envelope = {
"id": message_id,
"type": message_type,
"senderAddress": address,
"timestamp": timestamp,
"payload": payload,
"signature": signature,
}
_recent_presence_senders.append(sender_hash)
ensure_known_peer_from_recall(sender_hash)
if origin_peer_hash != sender_hash:
ensure_known_peer_from_recall(origin_peer_hash)
if origin_peer_hash not in _known_peers:
ensure_known_peer_from_wire_kr(public_key, origin_peer_hash)
if origin_peer_hash in _known_peers:
_note_overlay_peer_alive(origin_peer_hash, "presence")
st = _peer_lifecycle.setdefault(
origin_peer_hash,
{
"last_seen_inbound": None,
"last_send_ok": None,
"last_request_path_at": None,
"ts_seed_until": None,
},
)
now = time.time()
st["last_seen_inbound"] = now
lease = st.get("ts_seed_until")
if isinstance(lease, (int, float)) and now < float(lease):
log(
"[presence_bridge] target=presence-reticulum ts_seed_confirmed "
f"peer={origin_peer_hash[:24]}..."
)
route: Dict[str, Any] = {
"kind": "reticulum",
"destinationHash": origin_peer_hash,
"overlayHopsRemaining": overlay_hops_remaining
if isinstance(overlay_hops_remaining, int)
else 0,
}
if origin_peer_hash != sender_hash:
route["viaDestinationHash"] = sender_hash
if link_id:
route["linkId"] = link_id
emit_event(
"presence_message",
{
"envelope": envelope,
"route": route,
},
)
verbose_presence_log(
"[presence_bridge] received presence packet "
f"sender={origin_peer_hash} via={sender_hash} "
f"envelope_type={envelope.get('type')} size={len(_call_wire_json_bytes(message))}"
)
return True
def _emit_call_bridge_message(
message: Dict[str, Any], peer_presence_hash: str = "", link_id: Optional[str] = None
) -> bool:
sender_r = message.get("r")
sender_call_hash = sender_r if isinstance(sender_r, str) else ""
if sender_call_hash:
ensure_known_peer_from_recall(sender_call_hash.strip().lower(), "inbound")
resolved_presence_hash = (
peer_presence_hash
if isinstance(peer_presence_hash, str) and peer_presence_hash
else _resolve_sender_peer_destination_hash(sender_call_hash)
)
t = message.get("t")
event_name = (
"group_call_message"
if isinstance(t, str) and t in _GROUP_CALL_WIRE_TYPES
else "call_message"
)
_note_presence_pressure(
"decoded:group_call" if event_name == "group_call_message" else "decoded:call",
str(t or ""),
)
payload: Dict[str, Any] = {
"wire": message,
"senderDestinationHash": sender_call_hash,
"peerPresenceHash": resolved_presence_hash,
}
if link_id:
payload["linkId"] = link_id
emit_event(event_name, payload)
log(
f"[presence_bridge] received {event_name} t={message.get('t')} sender_r={sender_call_hash[:16] if sender_call_hash else ''} size={len(_call_wire_json_bytes(message))}"
)
return True
def _call_relay_dedup_key(kind: str, message: Dict[str, Any], wire_bytes: bytes) -> str:
message_type = message.get("t")
type_key = message_type if isinstance(message_type, str) and message_type else "?"
overlay_id = message.get("X")
if isinstance(overlay_id, str) and overlay_id:
return f"{kind}:{type_key}:x:{overlay_id}"
digest = hashlib.sha256(wire_bytes).hexdigest()
return f"{kind}:{type_key}:h:{digest}"
def _sweep_call_relay_dedup(now: float) -> None:
expired = [
key for key, expires_at in _call_relay_dedup.items()
if not isinstance(expires_at, (int, float)) or float(expires_at) <= now
]
for key in expired:
_call_relay_dedup.pop(key, None)
overflow = len(_call_relay_dedup) - _CALL_RELAY_DEDUP_MAX
if overflow > 0:
for key in list(_call_relay_dedup.keys())[:overflow]:
_call_relay_dedup.pop(key, None)
def _filter_new_call_relay_frames(
kind: str,
messages: list[Dict[str, Any]],
encoded_frames: list[bytes],
message_types: list[str],
) -> tuple[list[Dict[str, Any]], list[bytes], list[str], int]:
global _call_relay_dedup_last_log_at, _call_relay_dedup_suppressed_since_log
now = time.time()
with _state_lock:
_sweep_call_relay_dedup(now)
next_messages: list[Dict[str, Any]] = []
next_frames: list[bytes] = []
next_types: list[str] = []
suppressed = 0
for index, message in enumerate(messages):
wire_bytes = encoded_frames[index]
key = _call_relay_dedup_key(kind, message, wire_bytes)
expires_at = _call_relay_dedup.get(key)
if isinstance(expires_at, (int, float)) and float(expires_at) > now:
suppressed += 1
continue
_call_relay_dedup[key] = now + _CALL_RELAY_DEDUP_TTL_SECONDS
next_messages.append(message)
next_frames.append(wire_bytes)
next_types.append(message_types[index])
if suppressed:
_call_relay_dedup_suppressed_since_log += suppressed
if now - _call_relay_dedup_last_log_at >= 10.0:
log(
"[presence_bridge] target=reticulum-call-relay-dedup "
f"kind={kind} suppressed={_call_relay_dedup_suppressed_since_log} "
f"cache={len(_call_relay_dedup)}"
)
_call_relay_dedup_suppressed_since_log = 0
_call_relay_dedup_last_log_at = now
return next_messages, next_frames, next_types, suppressed
def on_overlay_link_closed(link) -> None:
link_id = get_overlay_link_id(link)
if link_id is None:
return
teardown_reason = getattr(link, "teardown_reason", None)
reason = _overlay_teardown_reason_name(teardown_reason)
now = time.time()
state = remove_overlay_link(link_id)
if state is None:
return
peer_hash = str(state.get("peerPresenceHash") or "").strip().lower()
verbose_presence_log(_overlay_close_debug_line(link_id, state, reason))
state["established"] = False
emit_overlay_link_state(
link_id,
state,
reason,
closed_by_reticulum=True,
)
if peer_hash and _overlay_timeout_close_should_keep_peer(state, reason, now):
age = _overlay_link_recent_activity_age_seconds(state, now)
_note_overlay_peer_alive(peer_hash, "recent_timeout_activity")
verbose_presence_log(
"[presence_bridge] target=presence-reticulum overlay_timeout_kept_peer "
f"peer={peer_hash} recent_activity_age_ms={int((age or 0.0) * 1000.0)}"
)
return
if peer_hash and _overlay_teardown_should_demote(reason):
_demote_overlay_fanout_peer(peer_hash, f"link_closed:{reason}")
def on_overlay_link_remote_identified(link, identity) -> None:
link_id = get_overlay_link_id(link)
if link_id is None:
return
state = get_overlay_link_state(link_id)
if state is None:
return
derived_peer_hash = derive_presence_destination_hash_for_identity(identity)
local_hex = _local_presence_hash_hex()
if derived_peer_hash:
expected = str(state.get("peerPresenceHash") or "").strip().lower()
if local_hex and derived_peer_hash == local_hex:
log(
"[presence_bridge] target=presence-reticulum overlay_remote_identified_self "
f"link={link_id} expected={expected or 'unknown'}"
)
_teardown_overlay_link_id(link_id, "remote_identified_self")
return
if expected and derived_peer_hash != expected:
log(
"[presence_bridge] target=presence-reticulum overlay_remote_identified_mismatch "
f"link={link_id} expected={expected} derived={derived_peer_hash}"
)
_teardown_overlay_link_id(link_id, "remote_identified_mismatch")
return
peer_hash = find_peer_hash_for_identity(identity)
if peer_hash:
state["peerPresenceHash"] = peer_hash
log(
"[presence_bridge] target=presence-reticulum overlay_remote_identified "
f"link={link_id} peer={peer_hash} source=known_identity"
)
else:
peer_hash = str(state.get("peerPresenceHash") or "").strip().lower()
if peer_hash and _valid_presence_destination_hash_hex(peer_hash):
_register_peer(peer_hash, identity, "inbound")
log(
"[presence_bridge] target=presence-reticulum overlay_remote_identified "
f"link={link_id} peer={peer_hash} source=inbound_identity"
)
else:
log(
"[presence_bridge] target=presence-reticulum overlay_remote_identified "
f"link={link_id} peer=unknown source=unbound"
)
emit_overlay_link_state(link_id, state, "identified")
ph_reg = str(state.get("peerPresenceHash") or "").strip().lower()
if ph_reg and _valid_presence_destination_hash_hex(ph_reg):
_note_overlay_peer_alive(ph_reg, "remote_identified")
_register_active_overlay_for_peer(ph_reg, link_id)
_dedup_overlay_links_for_peer(ph_reg, preferred_link_id=link_id)
def _audio_overlay_promotion_allowed(peer_key: str) -> bool:
peer_key = str(peer_key or "").strip().lower()
if not peer_key:
return False
with _state_lock:
active_id = _active_audio_link_id_by_peer_hash.get(peer_key) or ""
if active_id and active_id in _audio_links_by_id:
return True
outgoing_id = _outgoing_audio_link_id_by_peer_hash.get(peer_key) or ""
if outgoing_id and outgoing_id in _audio_links_by_id:
return True
desired = _audio_link_desired_by_peer_hash.get(peer_key)
return bool(desired and desired.get("desired") is True)
def _promote_misclassified_overlay_link_to_audio(
link,
overlay_link_id: str,
peer_key: str,
sender_destination_hash: str,
) -> str:
if link is None or not overlay_link_id:
return ""
peer_key = str(peer_key or "").strip().lower()
if not _audio_overlay_promotion_allowed(peer_key):
return ""
state = get_overlay_link_state(overlay_link_id)
if state is None or state.get("incoming") is not True:
return ""
overlay_peer_hash = str(state.get("peerPresenceHash") or "").strip().lower()
removed = remove_overlay_link(overlay_link_id)
if removed is None:
return ""
if overlay_peer_hash and removed.get("_was_active_overlay") is True:
with _state_lock:
_active_overlay_neighbors.pop(overlay_peer_hash, None)
_inbound_overlay_neighbors.pop(overlay_peer_hash, None)
link_id = str(uuid.uuid4())
now = time.time()
created_at = removed.get("created_at")
audio_state = {
"link": link,
"peerPresenceHash": peer_key,
"peerDestinationHash": str(sender_destination_hash or "").strip().lower(),
"incoming": True,
"established": True,
"established_at": now,
"created_at": created_at if isinstance(created_at, (int, float)) else now,
"last_activity_at": now,
"last_rx_at": now,
"promoted_from_overlay_link_id": overlay_link_id,
}
_ensure_audio_link_lifecycle_fields(audio_state)
with _state_lock:
_audio_links_by_id[link_id] = audio_state
configure_audio_link(link, link_id)
log(
"[presence_bridge] target=reticulum-audio-link overlay_link_promoted_to_audio "
f"overlay_link={overlay_link_id} audio_link={link_id} peer={peer_key}"
)
return link_id
def _promote_overlay_audio_sender_if_allowed(
link,
overlay_link_id: str,
sender_destination_hash: str,
) -> str:
peer_key = _resolve_sender_peer_destination_hash(sender_destination_hash)
return _promote_misclassified_overlay_link_to_audio(
link,
overlay_link_id,
peer_key,
sender_destination_hash,
)
def _qchat_file_overlay_promotion_peer_hash(decoded: Dict[str, Any]) -> str:
peer_hash = str(
decoded.get("downloaderReticulumDestinationHash") or ""
).strip().lower()
return peer_hash if _valid_presence_destination_hash_hex(peer_hash) else ""
def _qchat_file_overlay_promotion_allowed(
transfer_id: str,
peer_hash: str,
) -> bool:
transfer_id = str(transfer_id or "").strip()
peer_hash = str(peer_hash or "").strip().lower()
if not transfer_id or not _valid_presence_destination_hash_hex(peer_hash):
return False
with _state_lock:
pending = _qchat_file_pending_sends_by_transfer.get(transfer_id)
if not isinstance(pending, dict):
return False
return float(pending.get("expires_at") or 0) >= time.time()
def _promote_misclassified_overlay_link_to_qchat_file(
link,
overlay_link_id: str,
transfer_id: str,
peer_hash: str,
) -> str:
if link is None or not overlay_link_id:
return ""
transfer_id = str(transfer_id or "").strip()
peer_hash = str(peer_hash or "").strip().lower()
if not _qchat_file_overlay_promotion_allowed(transfer_id, peer_hash):
return ""
state = get_overlay_link_state(overlay_link_id)
if state is None or state.get("incoming") is not True:
return ""
overlay_peer_hash = str(state.get("peerPresenceHash") or "").strip().lower()
removed = remove_overlay_link(overlay_link_id)
if removed is None:
return ""
if overlay_peer_hash and removed.get("_was_active_overlay") is True:
with _state_lock:
_active_overlay_neighbors.pop(overlay_peer_hash, None)
_inbound_overlay_neighbors.pop(overlay_peer_hash, None)
link_id = _register_incoming_qchat_file_link(link, peer_hash, transfer_id)
if link_id:
log(
"[presence_bridge] target=qchat-file-reticulum overlay_link_promoted_to_qchat_file "
f"overlay_link={overlay_link_id} file_link={link_id} peer={peer_hash} transfer={transfer_id}"
)
return link_id
def _handle_overlay_link_packet(message, packet) -> None:
link = getattr(packet, "link", None)
link_id = get_overlay_link_id(link) if link is not None else None
if link_id is None:
return
state = get_overlay_link_state(link_id)
if state is None:
return
decoded_audio = _decode_group_audio_wire(message)
if decoded_audio is not None:
_room_id, sender_destination_hash, _raw_audio = decoded_audio
audio_link_id = _promote_overlay_audio_sender_if_allowed(
link,
link_id,
sender_destination_hash,
)
if audio_link_id:
on_audio_link_packet(message, packet)
return
try:
decoded = json.loads(message.decode("utf-8"))
except Exception as exc:
log(f"[presence_bridge] invalid overlay link payload: {exc}")
return
if not isinstance(decoded, dict):
return
if decoded.get("t") == _GROUP_AUDIO_HEARTBEAT_WIRE_TYPE:
sender_destination_hash = str(decoded.get("r") or "").strip().lower()
audio_link_id = _promote_overlay_audio_sender_if_allowed(
link,
link_id,
sender_destination_hash,
)
if audio_link_id:
on_audio_link_packet(message, packet)
return
if decoded.get("type") == "QCHAT_FILE_LINK_AUTH":
transfer_id = str(decoded.get("transferId") or "").strip()
peer_hash = _qchat_file_overlay_promotion_peer_hash(decoded)
file_link_id = _promote_misclassified_overlay_link_to_qchat_file(
link,
link_id,
transfer_id,
peer_hash,
)
if file_link_id:
on_qchat_file_link_packet(message, packet)
return
_note_presence_pressure("source:overlay")
state["last_activity_at"] = time.time()
state["last_rx_at"] = time.time()
t = decoded.get("t")
if isinstance(t, str) and t.startswith("PRESENCE_"):
if _emit_presence_message(decoded, link_id):
peer_hash = str(decoded.get("r") or "").strip().lower()
if peer_hash:
previous_peer_hash = str(state.get("peerPresenceHash") or "").strip().lower()
state["peerPresenceHash"] = peer_hash
_note_overlay_peer_alive(peer_hash, "rx_presence")
_register_active_overlay_for_peer(peer_hash, link_id)
emit_reason = (
"rx_presence_identified"
if not previous_peer_hash and previous_peer_hash != peer_hash
else "rx_presence"
)
emit_overlay_link_state(link_id, state, emit_reason)
_dedup_overlay_links_for_peer(peer_hash, preferred_link_id=link_id)
return
_emit_call_bridge_message(
decoded,
str(state.get("peerPresenceHash") or ""),
link_id,
)
def on_overlay_link_packet(message, packet) -> None:
started_at = time.monotonic()
try:
_handle_overlay_link_packet(message, packet)
finally:
_note_callback_duration("overlay", started_at, message)
def _sha256_file_hex(path: str) -> str:
h = hashlib.sha256()
with open(path, "rb") as f:
for chunk in iter(lambda: f.read(1024 * 1024), b""):
h.update(chunk)
return h.hexdigest()
def _resource_file_path(resource) -> Optional[str]:
storage_path = str(getattr(resource, "storagepath", "") or "")
if storage_path and os.path.isfile(storage_path):
return storage_path
data = getattr(resource, "data", None)
data_name = str(getattr(data, "name", "") or "")
if data_name and os.path.isfile(data_name):
return data_name
return None
def _move_file_to_save_path(source_path: str, save_path: str) -> None:
save_dir = os.path.dirname(save_path)
os.makedirs(save_dir, exist_ok=True)
try:
os.replace(source_path, save_path)
return
except OSError:
pass
temp_path = os.path.join(
save_dir,
f".{os.path.basename(save_path)}.part-{uuid.uuid4().hex}",
)
try:
with open(source_path, "rb") as src, open(temp_path, "wb") as out:
shutil.copyfileobj(src, out, 1024 * 1024)
os.replace(temp_path, save_path)
except Exception:
try:
if os.path.isfile(temp_path):
os.unlink(temp_path)
except Exception:
pass
raise
def _write_chunk_to_part_file(source_path: str, save_path: str, offset: int) -> None:
part_path = save_path + ".part"
save_dir = os.path.dirname(save_path)
os.makedirs(save_dir, exist_ok=True)
with open(source_path, "rb") as src, open(part_path, "r+b" if os.path.exists(part_path) else "w+b") as out:
out.seek(offset)
shutil.copyfileobj(src, out, 1024 * 1024)
def _qchat_file_chunk_count(size: int) -> int:
if size <= 0:
return 0
return int(math.ceil(size / float(_QCHAT_FILE_CHUNK_SIZE)))
def _qchat_file_chunk_bounds(size: int, chunk_index: int) -> Tuple[int, int]:
offset = chunk_index * _QCHAT_FILE_CHUNK_SIZE
remaining = max(0, size - offset)
return offset, min(_QCHAT_FILE_CHUNK_SIZE, remaining)
def _qchat_file_emit(status: str, payload: Dict[str, Any]) -> None:
event_payload = dict(payload)
event_payload["status"] = status
emit_event("qchat_file_transfer", event_payload)
def _qchat_file_progress_payload(
state: Dict[str, Any],
progress: float,
size: int,
) -> Dict[str, Any]:
now = time.monotonic()
started_at = float(state.get("progress_started_at") or 0)
if started_at <= 0:
started_at = now
state["progress_started_at"] = started_at
progress = max(0.0, min(1.0, float(progress)))
payload: Dict[str, Any] = {"progress": progress}
elapsed = max(0.001, now - started_at)
if size > 0:
bytes_done = int(size * progress)
payload["bytesTransferred"] = bytes_done
payload["bytesPerSecond"] = int(bytes_done / elapsed)
return payload
def _should_emit_qchat_file_progress(
state: Dict[str, Any],
progress: float,
*,
force: bool = False,
) -> bool:
progress = max(0.0, min(1.0, float(progress)))
if force or progress >= 1.0:
state["last_progress_emit_at"] = time.monotonic()
state["last_progress_emit_value"] = progress
return True
now = time.monotonic()
last_at = float(state.get("last_progress_emit_at") or 0)
last_value = float(state.get("last_progress_emit_value") or -1)
if (
now - last_at >= _QCHAT_FILE_PROGRESS_MIN_INTERVAL_SECONDS
or abs(progress - last_value) >= _QCHAT_FILE_PROGRESS_MIN_DELTA
):
state["last_progress_emit_at"] = now
state["last_progress_emit_value"] = progress
return True
return False
def _identity_from_reticulum_public_key_base64(pk_b64: str):
s = str(pk_b64 or "").strip()
if not s:
raise ValueError("Missing Reticulum identity public key")
pad = "=" * ((4 - len(s) % 4) % 4)
pub_bytes = base64.b64decode(s + pad, validate=True)
if len(pub_bytes) != 64:
raise ValueError("Bad Reticulum identity public key length")
ident = RNS.Identity(create_keys=False)
ident.load_public_key(pub_bytes)
return ident
def _destination_hash_for_identity(identity) -> str:
outbound = build_outbound_destination(identity)
return destination_hash_hex(outbound.hash)
def _identity_matches_destination_hash(identity, expected_hash: str) -> bool:
return _destination_hash_for_identity(identity) == str(expected_hash or "").strip().lower()
def _is_reticulum_destination_hash(value: str) -> bool:
s = str(value or "").strip().lower()
return len(s) == 32 and all(c in "0123456789abcdef" for c in s)
def _parse_qchat_file_peer_identity(peer_hash: str, pk_b64: Any):
if not _is_reticulum_destination_hash(peer_hash):
raise ValueError("Missing or invalid Reticulum destination hash")
if not isinstance(pk_b64, str) or not pk_b64.strip():
raise ValueError("Missing Reticulum identity public key")
identity = _identity_from_reticulum_public_key_base64(pk_b64)
if not _identity_matches_destination_hash(identity, peer_hash):
raise ValueError("Reticulum public key does not match destination hash")
return identity
def _request_qchat_file_path(destination_hash: bytes, peer_hash: str) -> bool:
try:
if RNS.Transport.has_path(destination_hash):
log(
"[presence_bridge] target=qchat-file-reticulum path_ready "
f"peer={peer_hash} source=cache"
)
return True
except Exception:
pass
try:
RNS.Transport.request_path(destination_hash)
log(
"[presence_bridge] target=qchat-file-reticulum path_request_sent "
f"peer={peer_hash}"
)
except Exception as exc:
log(
"[presence_bridge] target=qchat-file-reticulum path_request_failed "
f"peer={peer_hash} err={exc}"
)
try:
await_path = getattr(RNS.Transport, "await_path", None)
if callable(await_path):
resolved = bool(
await_path(destination_hash, _QCHAT_FILE_LINK_OPEN_PATH_AWAIT_SECONDS)
)
log(
"[presence_bridge] target=qchat-file-reticulum path_await "
f"peer={peer_hash} resolved={str(resolved).lower()}"
)
if resolved:
return True
except Exception as exc:
log(
"[presence_bridge] target=qchat-file-reticulum path_await_failed "
f"peer={peer_hash} err={exc}"
)
try:
RNS.Transport.request_path(destination_hash)
except Exception as exc:
log(
"[presence_bridge] target=qchat-file-reticulum path_request_failed "
f"peer={peer_hash} err={exc}"
)
return False
resolved = _await_destination_path(
destination_hash,
_QCHAT_FILE_LINK_OPEN_PATH_AWAIT_SECONDS,
)
log(
"[presence_bridge] target=qchat-file-reticulum path_request "
f"peer={peer_hash} resolved={str(resolved).lower()}"
)
return resolved
def get_qchat_file_link_id(link) -> Optional[str]:
if link is None:
return None
with _state_lock:
return _qchat_file_link_ids_by_object.get(id(link))
def get_qchat_file_link_state(link_id: str) -> Optional[Dict[str, Any]]:
with _state_lock:
return _qchat_file_links_by_id.get(link_id)
def remove_qchat_file_link(link_id: str) -> Optional[Dict[str, Any]]:
with _state_lock:
state = _qchat_file_links_by_id.pop(link_id, None)
if state is not None:
link = state.get("link")
if link is not None:
_qchat_file_link_ids_by_object.pop(id(link), None)
_incoming_unified_peer_hash_by_object.pop(id(link), None)
peer_hash = state.get("peerPresenceHash")
if isinstance(peer_hash, str):
existing = _outgoing_qchat_file_link_id_by_peer_hash.get(peer_hash)
if existing == link_id:
_outgoing_qchat_file_link_id_by_peer_hash.pop(peer_hash, None)
if state is None:
return None
return state
def on_qchat_file_link_closed(link) -> None:
link_id = get_qchat_file_link_id(link)
if link_id is None:
return
state = remove_qchat_file_link(link_id)
if state is not None:
timer = state.pop("auth_timeout_timer", None)
if timer is not None:
try:
timer.cancel()
except Exception:
pass
if state.get("completed") is True:
return
if state.get("qchat_file_chunk_completed") is True:
return
transfer_id = str(state.get("transferId") or "")
peer_hash = str(state.get("peerPresenceHash") or "").strip().lower()
with _state_lock:
receive_pending = _qchat_file_accepts_by_peer.get(peer_hash)
send_pending = _qchat_file_pending_sends_by_transfer.get(transfer_id)
if receive_pending is not None and str(receive_pending.get("transferId") or "") == transfer_id:
return
if send_pending is not None:
return
if state.get("incoming") is not True and int(state.get("open_attempts") or 0) < _QCHAT_FILE_LINK_MAX_OPEN_ATTEMPTS:
transfer_id_retry = transfer_id
peer_hash_retry = peer_hash
def retry() -> None:
if not _enqueue_scheduler_task(
"file-transfer",
"qchat-file-closed-retry",
_run_qchat_file_open_task,
state,
):
_qchat_file_emit(
"failed",
{
"transferId": transfer_id_retry,
"peerPresenceHash": peer_hash_retry,
"fileName": state.get("fileName") or "",
"reason": "file_link_retry_queue_full",
},
)
timer = threading.Timer(_QCHAT_FILE_LINK_RETRY_DELAY_SECONDS, retry)
timer.daemon = True
timer.start()
_qchat_file_emit(
"retrying",
{
"transferId": transfer_id_retry,
"peerPresenceHash": peer_hash_retry,
"fileName": state.get("fileName") or "",
"attempt": int(state.get("open_attempts") or 0) + 1,
"maxAttempts": _QCHAT_FILE_LINK_MAX_OPEN_ATTEMPTS,
},
)
return
if transfer_id:
_qchat_file_emit(
"failed",
{
"transferId": transfer_id,
"peerPresenceHash": peer_hash,
"fileName": state.get("fileName") or "",
"reason": "file_link_closed",
},
)
def _open_qchat_file_link_for_state(state: Dict[str, Any]) -> bool:
peer_hash = str(state.get("peerPresenceHash") or "").strip().lower()
if not peer_hash:
return False
peer_identity = state.get("peerIdentity")
if peer_identity is None:
raise RuntimeError("Missing embedded Reticulum peer identity")
outbound = build_outbound_destination(peer_identity)
if destination_hash_hex(outbound.hash) != peer_hash:
raise RuntimeError("Reticulum public key does not match destination hash")
state["open_attempts"] = int(state.get("open_attempts") or 0) + 1
state["last_open_attempt_at"] = time.time()
_qchat_file_emit(
"connecting",
{
"transferId": state.get("transferId") or "",
"peerPresenceHash": peer_hash,
"fileName": state.get("fileName") or "",
"size": int(state.get("size") or 0),
"attempt": state["open_attempts"],
"maxAttempts": _QCHAT_FILE_LINK_MAX_OPEN_ATTEMPTS,
},
)
path_ready = _request_qchat_file_path(outbound.hash, peer_hash)
if not path_ready:
raise RuntimeError("No Reticulum path for file transfer link")
previous_link = state.get("link")
if previous_link is not None:
_qchat_file_link_ids_by_object.pop(id(previous_link), None)
link_id = str(uuid.uuid4())
link = RNS.Link(
outbound,
established_callback=on_outgoing_qchat_file_link_established,
closed_callback=on_qchat_file_link_closed,
)
state["link"] = link
state["peerDestinationHash"] = destination_hash_hex(outbound.hash)
state["incoming"] = False
state["established"] = False
_qchat_file_links_by_id[link_id] = state
_qchat_file_link_ids_by_object[id(link)] = link_id
_outgoing_qchat_file_link_id_by_peer_hash[peer_hash] = link_id
return True
def _schedule_qchat_file_open_retry(state: Dict[str, Any], reason: str) -> bool:
attempts = int(state.get("open_attempts") or 0)
if attempts >= _QCHAT_FILE_LINK_MAX_OPEN_ATTEMPTS:
return False
transfer_id = str(state.get("transferId") or "")
peer_hash = str(state.get("peerPresenceHash") or "")
def retry() -> None:
_enqueue_scheduler_task(
"file-transfer",
"qchat-file-open-retry",
_run_qchat_file_open_task,
state,
)
timer = threading.Timer(_QCHAT_FILE_LINK_RETRY_DELAY_SECONDS, retry)
timer.daemon = True
timer.start()
_qchat_file_emit(
"retrying",
{
"transferId": transfer_id,
"peerPresenceHash": peer_hash,
"fileName": state.get("fileName") or "",
"attempt": attempts + 1,
"maxAttempts": _QCHAT_FILE_LINK_MAX_OPEN_ATTEMPTS,
"reason": reason,
},
)
return True
def _open_qchat_file_link_async(state: Dict[str, Any]) -> None:
_enqueue_scheduler_task(
"file-transfer",
"qchat-file-open",
_run_qchat_file_open_task,
state,
)
def _run_qchat_file_open_task(state: Dict[str, Any]) -> None:
try:
_open_qchat_file_link_for_state(state)
except Exception as exc:
if _schedule_qchat_file_open_retry(state, str(exc)):
return
_qchat_file_emit(
"failed",
{
"transferId": state.get("transferId") or "",
"peerPresenceHash": state.get("peerPresenceHash") or "",
"fileName": state.get("fileName") or "",
"reason": "link_open_failed",
"error": str(exc),
},
)
def configure_qchat_file_link(link, link_id: str) -> None:
link.set_link_closed_callback(on_qchat_file_link_closed)
link.set_packet_callback(on_qchat_file_link_packet)
link.set_resource_strategy(RNS.Link.ACCEPT_APP)
link.set_resource_callback(on_qchat_file_resource_advertised)
link.set_resource_started_callback(on_qchat_file_resource_started)
link.set_resource_concluded_callback(on_qchat_file_resource_concluded)
_qchat_file_link_ids_by_object[id(link)] = link_id
def _handle_qchat_file_link_packet(message, packet) -> None:
link = getattr(packet, "link", None)
link_id = get_qchat_file_link_id(link) if link is not None else None
if not link_id:
return
state = get_qchat_file_link_state(link_id)
if state is None:
return
try:
decoded = json.loads(message.decode("utf-8"))
except Exception as exc:
log(f"[presence_bridge] invalid qchat file link payload: {exc}")
return
if not isinstance(decoded, dict):
return
_note_presence_pressure("source:qchat_file")
if decoded.get("type") == "QCHAT_FILE_CHUNK_ACK":
try:
chunk_index = int(decoded.get("chunkIndex"))
except Exception:
return
transfer_id = str(decoded.get("transferId") or "").strip()
if transfer_id and transfer_id != str(state.get("transferId") or ""):
return
root = state.get("send_root") if isinstance(state.get("send_root"), dict) else state
active = root.get("active_chunks") if isinstance(root, dict) else None
if not isinstance(active, dict):
return
chunk = active.get(chunk_index)
if not isinstance(chunk, dict):
return
chunk_size = int(chunk.get("size") or decoded.get("chunkSize") or 0)
transfer_complete = _qchat_file_mark_chunk_sent(root, chunk_index, chunk_size)
if transfer_complete:
_qchat_file_close_success_link_after_grace(link, state)
return
state["resource_started"] = False
_enqueue_scheduler_task(
"file-transfer",
"qchat-file-next-chunk-ack",
_start_qchat_file_resource_for_state,
state,
)
return
if decoded.get("type") == "QCHAT_FILE_LINK_AUTH_RESULT":
if decoded.get("ok") is True:
_qchat_file_emit(
"authorized",
{
"transferId": str(decoded.get("transferId") or state.get("transferId") or ""),
"peerPresenceHash": state.get("peerPresenceHash") or "",
"fileName": state.get("fileName") or "",
},
)
else:
_qchat_file_emit(
"failed",
{
"transferId": str(decoded.get("transferId") or state.get("transferId") or ""),
"peerPresenceHash": state.get("peerPresenceHash") or "",
"fileName": state.get("fileName") or "",
"reason": str(decoded.get("reason") or "sender_rejected_auth"),
},
)
try:
link.teardown()
except Exception:
pass
return
if decoded.get("type") != "QCHAT_FILE_LINK_AUTH":
return
transfer_id = str(decoded.get("transferId") or "").strip()
state["transferId"] = transfer_id
_qchat_file_emit(
"auth",
{
"linkId": link_id,
"transferId": transfer_id,
"auth": decoded,
},
)
def on_qchat_file_link_packet(message, packet) -> None:
started_at = time.monotonic()
try:
_handle_qchat_file_link_packet(message, packet)
finally:
_note_callback_duration("qchat_file", started_at, message)
def on_qchat_file_link_remote_identified(link, identity) -> None:
try:
peer_hash = _destination_hash_for_identity(identity)
except Exception:
return
_incoming_unified_peer_hash_by_object[id(link)] = peer_hash
link_id = get_qchat_file_link_id(link)
if link_id:
state = get_qchat_file_link_state(link_id)
if state is not None:
state["peerPresenceHash"] = peer_hash
state["peerDestinationHash"] = peer_hash
def _register_incoming_qchat_file_link(link, peer_hash: str, transfer_id: str) -> str:
link_id = get_qchat_file_link_id(link)
if link_id:
return link_id
now = time.time()
link_id = str(uuid.uuid4())
state = {
"link": link,
"peerPresenceHash": peer_hash,
"peerDestinationHash": peer_hash,
"incoming": True,
"established": True,
"created_at": now,
"established_at": now,
"transferId": transfer_id,
}
with _state_lock:
_qchat_file_links_by_id[link_id] = state
configure_qchat_file_link(link, link_id)
link.set_remote_identified_callback(on_qchat_file_link_remote_identified)
return link_id
def _qchat_file_update_sent_progress(state: Dict[str, Any]) -> None:
size = int(state.get("size") or 0)
sent_bytes = int(state.get("sent_bytes") or 0)
active = state.get("active_chunks")
if isinstance(active, dict):
for chunk in active.values():
try:
sent_bytes += int(chunk.get("size") or 0) * float(chunk.get("progress") or 0)
except Exception:
pass
progress = min(1.0, max(0.0, sent_bytes / float(size))) if size > 0 else 0.0
if not _should_emit_qchat_file_progress(state, progress):
return
_qchat_file_emit(
"sending",
{
"transferId": state.get("transferId") or "",
"peerPresenceHash": state.get("peerPresenceHash") or "",
"fileName": state.get("fileName") or "",
"size": size,
**_qchat_file_progress_payload(state, progress, size),
},
)
def _qchat_file_mark_chunk_sent(state: Dict[str, Any], chunk_index: int, chunk_size: int) -> bool:
active = state.setdefault("active_chunks", {})
if isinstance(active, dict):
chunk = active.get(chunk_index)
if isinstance(chunk, dict):
timer = chunk.pop("ack_timeout_timer", None)
if timer is not None:
try:
timer.cancel()
except Exception:
pass
active.pop(chunk_index, None)
completed = state.setdefault("completed_chunks", set())
if isinstance(completed, set) and chunk_index not in completed:
completed.add(chunk_index)
state["sent_bytes"] = int(state.get("sent_bytes") or 0) + int(chunk_size)
_qchat_file_update_sent_progress(state)
if int(state.get("sent_bytes") or 0) >= int(state.get("size") or 0):
if state.get("completed") is True:
return True
state["completed"] = True
transfer_id = str(state.get("transferId") or "")
if transfer_id:
with _state_lock:
_qchat_file_pending_sends_by_transfer.pop(transfer_id, None)
_qchat_file_emit(
"sent",
{
"transferId": transfer_id,
"peerPresenceHash": state.get("peerPresenceHash") or "",
"fileName": state.get("fileName") or "",
"size": int(state.get("size") or 0),
},
)
return True
return False
def _qchat_file_receiver_transfer_done(peer_hash: str, transfer_id: str) -> None:
for link_id, link_state in list(_qchat_file_links_by_id.items()):
if (
str(link_state.get("peerPresenceHash") or "").strip().lower() == peer_hash
and str(link_state.get("transferId") or "") == transfer_id
):
link = link_state.get("link")
link_state["completed"] = True
remove_qchat_file_link(link_id)
try:
if link is not None:
link.teardown()
except Exception:
pass
def _qchat_file_read_chunk(file_path: str, offset: int, chunk_size: int) -> bytes:
with open(file_path, "rb") as f:
f.seek(offset)
return f.read(chunk_size)
def _send_qchat_file_chunk_ack(link, transfer_id: str, chunk_index: int, chunk_size: int) -> bool:
if link is None:
return False
try:
return bool(
_send_packet_on_link(
link,
json.dumps(
{
"type": "QCHAT_FILE_CHUNK_ACK",
"transferId": transfer_id,
"chunkIndex": chunk_index,
"chunkSize": chunk_size,
},
separators=(",", ":"),
).encode("utf-8"),
(
"target=qchat-file-reticulum chunk_ack "
f"transfer={transfer_id} chunk={chunk_index}"
),
)
)
except Exception as exc:
log(
"[presence_bridge] qchat file chunk ack failed "
f"transfer={transfer_id} chunk={chunk_index}: {exc}"
)
return False
def _qchat_file_close_success_link_after_grace(link, state: Dict[str, Any]) -> None:
state["completed"] = True
link_id_done = get_qchat_file_link_id(link)
if link_id_done:
remove_qchat_file_link(link_id_done)
def close_link() -> None:
try:
if link is not None:
link.teardown()
except Exception:
pass
timer = threading.Timer(_QCHAT_FILE_SUCCESS_LINK_CLOSE_GRACE_SECONDS, close_link)
timer.daemon = True
timer.start()
def _start_qchat_file_resource_for_state(state: Dict[str, Any]) -> bool:
link = state.get("link")
file_path = str(state.get("filePath") or "")
transfer_id = str(state.get("transferId") or "")
peer_hash = str(state.get("peerPresenceHash") or "")
file_name = str(state.get("fileName") or os.path.basename(file_path))
sha256 = str(state.get("sha256") or "").strip().lower()
if link is None or not file_path or not transfer_id:
return False
if state.get("resource_started") is True:
return True
size = os.path.getsize(file_path)
if not state.get("send_root"):
state["send_root"] = state
root = state.get("send_root") if isinstance(state.get("send_root"), dict) else state
chunk_count = _qchat_file_chunk_count(size)
with _state_lock:
next_chunk = int(root.get("next_chunk_index") or 0)
if next_chunk >= chunk_count:
_qchat_file_close_success_link_after_grace(link, state)
return False
chunk_index = next_chunk
chunk_offset, chunk_size = _qchat_file_chunk_bounds(size, chunk_index)
root["next_chunk_index"] = next_chunk + 1
root["transferId"] = transfer_id
root["peerPresenceHash"] = peer_hash
root["fileName"] = file_name
root["size"] = size
root.setdefault("active_chunks", {})[chunk_index] = {
"size": chunk_size,
"progress": 0.0,
}
metadata = {
"kind": "qchat-dm-file",
"transferId": transfer_id,
"fileName": file_name,
"size": size,
"sha256": sha256,
"chunked": True,
"chunkIndex": chunk_index,
"chunkCount": chunk_count,
"chunkOffset": chunk_offset,
"chunkSize": chunk_size,
}
def on_done(resource) -> None:
status = "sent" if getattr(resource, "status", None) == RNS.Resource.COMPLETE else "failed"
if status == "sent":
active = root.setdefault("active_chunks", {})
if isinstance(active, dict) and chunk_index in active:
active[chunk_index]["progress"] = 1.0
def ack_timeout() -> None:
current_active = root.get("active_chunks")
if not isinstance(current_active, dict) or chunk_index not in current_active:
return
if root.get("completed") is True or state.get("completed") is True:
return
_qchat_file_emit(
"failed",
{
"transferId": transfer_id,
"peerPresenceHash": peer_hash,
"fileName": file_name,
"size": size,
"reason": "chunk_ack_timeout",
"chunkIndex": chunk_index,
},
)
link_id_done = get_qchat_file_link_id(link)
if link_id_done:
remove_qchat_file_link(link_id_done)
try:
link.teardown()
except Exception:
pass
timer = threading.Timer(_QCHAT_FILE_CHUNK_ACK_TIMEOUT_SECONDS, ack_timeout)
timer.daemon = True
active[chunk_index]["ack_timeout_timer"] = timer
timer.start()
state["resource_send_complete"] = True
_qchat_file_update_sent_progress(root)
return
else:
_qchat_file_emit(
"failed",
{
"transferId": transfer_id,
"peerPresenceHash": peer_hash,
"fileName": file_name,
"size": size,
"reason": "send_failed",
"chunkIndex": chunk_index,
},
)
link_id_done = get_qchat_file_link_id(link)
if link_id_done:
remove_qchat_file_link(link_id_done)
try:
link.teardown()
except Exception:
pass
return
def on_progress(resource) -> None:
try:
progress = float(resource.get_progress())
except Exception:
progress = 0.0
active = root.setdefault("active_chunks", {})
if isinstance(active, dict) and chunk_index in active:
active[chunk_index]["progress"] = progress
_qchat_file_update_sent_progress(root)
chunk_data = _qchat_file_read_chunk(file_path, chunk_offset, chunk_size)
RNS.Resource(
chunk_data,
link,
metadata=metadata,
auto_compress=False,
callback=on_done,
progress_callback=on_progress,
)
state["resource_started"] = True
_qchat_file_update_sent_progress(root)
return True
def _send_qchat_file_auth_message(link, state: Dict[str, Any], log_label: str) -> bool:
auth_message = state.get("authMessage")
if not isinstance(auth_message, dict):
return False
try:
encoded = json.dumps(auth_message, separators=(",", ":")).encode("utf-8")
ok = _send_packet_on_link(
link,
encoded,
f"target=qchat-file-reticulum {log_label} transfer={state.get('transferId') or ''}",
)
if ok:
_qchat_file_emit(
"auth_sent",
{
"transferId": state.get("transferId") or "",
"peerPresenceHash": state.get("peerPresenceHash") or "",
"fileName": state.get("fileName") or "",
"size": int(state.get("size") or 0),
},
)
previous_timer = state.pop("auth_timeout_timer", None)
if previous_timer is not None:
try:
previous_timer.cancel()
except Exception:
pass
def auth_timeout() -> None:
if state.get("resource_started") is True or state.get("completed") is True:
return
_qchat_file_emit(
"failed",
{
"transferId": state.get("transferId") or "",
"peerPresenceHash": state.get("peerPresenceHash") or "",
"fileName": state.get("fileName") or "",
"reason": "sender_auth_timeout",
"error": "Sender did not authorize the file transfer",
},
)
try:
link.teardown()
except Exception:
pass
timer = threading.Timer(45.0, auth_timeout)
timer.daemon = True
state["auth_timeout_timer"] = timer
timer.start()
return True
_qchat_file_emit(
"failed",
{
"transferId": state.get("transferId") or "",
"peerPresenceHash": state.get("peerPresenceHash") or "",
"fileName": state.get("fileName") or "",
"reason": "auth_send_failed",
},
)
except Exception as exc:
_qchat_file_emit(
"failed",
{
"transferId": state.get("transferId") or "",
"peerPresenceHash": state.get("peerPresenceHash") or "",
"fileName": state.get("fileName") or "",
"reason": "auth_send_failed",
"error": str(exc),
},
)
return False
def on_outgoing_qchat_file_link_established(link) -> None:
link_id = get_qchat_file_link_id(link)
if link_id is None:
return
state = get_qchat_file_link_state(link_id)
if state is None:
return
configure_qchat_file_link(link, link_id)
link.set_remote_identified_callback(on_qchat_file_link_remote_identified)
state["established"] = True
state["established_at"] = time.time()
_qchat_file_emit(
"link_established",
{
"transferId": state.get("transferId") or "",
"peerPresenceHash": state.get("peerPresenceHash") or "",
"fileName": state.get("fileName") or "",
"size": int(state.get("size") or 0),
},
)
try:
if _identity is not None:
link.identify(_identity)
except Exception as exc:
log(f"[presence_bridge] qchat file link identify failed link={link_id}: {exc}")
if isinstance(state.get("authMessage"), dict):
_send_qchat_file_auth_message(link, state, "auth")
return
try:
_start_qchat_file_resource_for_state(state)
except Exception as exc:
_qchat_file_emit(
"failed",
{
"transferId": state.get("transferId") or "",
"peerPresenceHash": state.get("peerPresenceHash") or "",
"fileName": state.get("fileName") or "",
"reason": "resource_start_failed",
"error": str(exc),
},
)
def on_qchat_file_resource_advertised(resource) -> bool:
link = getattr(resource, "link", None)
link_id = get_qchat_file_link_id(link) if link is not None else None
state = get_qchat_file_link_state(link_id) if link_id else None
peer_hash = str((state or {}).get("peerPresenceHash") or "").strip().lower()
if not peer_hash and link is not None:
peer_hash = str(_incoming_unified_peer_hash_by_object.get(id(link)) or "").strip().lower()
if not peer_hash:
return False
now = time.time()
with _state_lock:
pending = _qchat_file_accepts_by_peer.get(peer_hash)
if pending and float(pending.get("expires_at") or 0) < now:
_qchat_file_accepts_by_peer.pop(peer_hash, None)
pending = None
if not pending:
return False
expected_size = int(pending.get("size") or 0)
pending["started_at"] = time.time()
transfer_id = str(pending.get("transferId") or "")
try:
setattr(resource, "_qchat_peer_hash", peer_hash)
setattr(resource, "_qchat_transfer_id", transfer_id)
except Exception:
pass
_register_incoming_qchat_file_link(link, peer_hash, transfer_id)
_qchat_file_emit(
"receiving",
{
"transferId": transfer_id,
"peerPresenceHash": peer_hash,
"fileName": pending.get("fileName"),
"size": expected_size,
},
)
return True
def on_qchat_file_resource_started(resource) -> None:
link = getattr(resource, "link", None)
link_id = get_qchat_file_link_id(link) if link is not None else None
state = get_qchat_file_link_state(link_id) if link_id else None
peer_hash = str((state or {}).get("peerPresenceHash") or "").strip().lower()
pending = _qchat_file_accepts_by_peer.get(peer_hash) if peer_hash else None
if state is not None:
timer = state.pop("auth_timeout_timer", None)
if timer is not None:
try:
timer.cancel()
except Exception:
pass
state["resource_started"] = True
state["qchat_file_chunk_completed"] = False
if not pending:
return
transfer_id = str(pending.get("transferId") or "")
file_name = str(pending.get("fileName") or "")
size = int(pending.get("size") or 0)
def on_progress(res) -> None:
if isinstance(pending.get("completed_chunks"), set):
return
try:
progress = float(res.get_progress())
except Exception:
progress = 0.0
if not _should_emit_qchat_file_progress(pending, progress):
return
_qchat_file_emit(
"receiving",
{
"transferId": transfer_id,
"peerPresenceHash": peer_hash,
"fileName": file_name,
"size": size,
**_qchat_file_progress_payload(pending, progress, size),
},
)
try:
resource.progress_callback(on_progress)
except Exception:
pass
on_progress(resource)
def on_qchat_file_resource_concluded(resource) -> None:
link = getattr(resource, "link", None)
link_id = get_qchat_file_link_id(link) if link is not None else None
state = get_qchat_file_link_state(link_id) if link_id else None
peer_hash = str(
(state or {}).get("peerPresenceHash")
or getattr(resource, "_qchat_peer_hash", "")
or (
_incoming_unified_peer_hash_by_object.get(id(link))
if link is not None
else ""
)
or ""
).strip().lower()
if not peer_hash:
log("[presence_bridge] qchat file resource concluded without peer hash")
return
with _state_lock:
pending = _qchat_file_accepts_by_peer.get(peer_hash)
if pending is None:
resource_transfer_id = str(getattr(resource, "_qchat_transfer_id", "") or "")
for candidate in _qchat_file_accepts_by_peer.values():
if str(candidate.get("transferId") or "") == resource_transfer_id:
pending = candidate
break
if not pending:
log(
"[presence_bridge] qchat file resource concluded without pending receive "
f"peer={peer_hash}"
)
return
transfer_id = str(
pending.get("transferId") or getattr(resource, "_qchat_transfer_id", "") or ""
)
save_path = str(pending.get("savePath") or "")
expected_hash = str(pending.get("sha256") or "").strip().lower()
try:
if getattr(resource, "status", None) != RNS.Resource.COMPLETE:
if state is not None:
state["completed"] = True
_qchat_file_emit(
"failed",
{
"transferId": transfer_id,
"peerPresenceHash": peer_hash,
"reason": "resource_incomplete",
},
)
return
metadata = getattr(resource, "metadata", None)
is_chunked = isinstance(metadata, dict) and metadata.get("chunked") is True
if isinstance(metadata, dict):
metadata_transfer_id = str(metadata.get("transferId") or "")
metadata_file_name = str(metadata.get("fileName") or "")
metadata_size = int(metadata.get("size") or 0)
metadata_sha256 = str(metadata.get("sha256") or "").strip().lower()
expected_size = int(pending.get("size") or 0)
expected_file_name = str(pending.get("fileName") or "")
if (
(metadata_transfer_id and metadata_transfer_id != transfer_id)
or (metadata_file_name and metadata_file_name != expected_file_name)
or (metadata_size and expected_size and metadata_size != expected_size)
or (not is_chunked and metadata_sha256 and expected_hash and metadata_sha256 != expected_hash)
):
if state is not None:
state["completed"] = True
_qchat_file_emit(
"failed",
{
"transferId": transfer_id,
"peerPresenceHash": peer_hash,
"reason": "metadata_mismatch",
},
)
return
source_path = _resource_file_path(resource)
if not source_path:
if state is not None:
state["completed"] = True
_qchat_file_emit(
"failed",
{
"transferId": transfer_id,
"peerPresenceHash": peer_hash,
"reason": "missing_resource_file",
},
)
return
if is_chunked:
chunk_index = int(metadata.get("chunkIndex") or 0)
chunk_count = int(metadata.get("chunkCount") or 0)
chunk_offset = int(metadata.get("chunkOffset") or 0)
chunk_size = int(metadata.get("chunkSize") or 0)
lock = pending.get("chunk_lock")
if lock is None:
lock = threading.RLock()
pending["chunk_lock"] = lock
with lock:
completed_chunks = pending.setdefault("completed_chunks", set())
if chunk_index not in completed_chunks:
_write_chunk_to_part_file(source_path, save_path, chunk_offset)
completed_chunks.add(chunk_index)
pending["received_bytes"] = int(pending.get("received_bytes") or 0) + chunk_size
size = int(pending.get("size") or 0)
progress = min(1.0, max(0.0, int(pending.get("received_bytes") or 0) / float(size))) if size > 0 else 0.0
if _should_emit_qchat_file_progress(pending, progress, force=progress >= 1.0):
_qchat_file_emit(
"receiving",
{
"transferId": transfer_id,
"peerPresenceHash": peer_hash,
"fileName": pending.get("fileName"),
"size": size,
**_qchat_file_progress_payload(pending, progress, size),
},
)
done = chunk_count > 0 and len(completed_chunks) >= chunk_count
if state is not None:
state["resource_started"] = False
state["qchat_file_chunk_completed"] = True
if not done:
if not _send_qchat_file_chunk_ack(link, transfer_id, chunk_index, chunk_size):
if state is not None:
state["completed"] = True
_qchat_file_emit(
"failed",
{
"transferId": transfer_id,
"peerPresenceHash": peer_hash,
"reason": "chunk_ack_send_failed",
"chunkIndex": chunk_index,
},
)
return
part_path = save_path + ".part"
actual_hash = _sha256_file_hex(part_path)
if expected_hash and actual_hash.lower() != expected_hash:
if state is not None:
state["completed"] = True
_qchat_file_emit(
"failed",
{
"transferId": transfer_id,
"peerPresenceHash": peer_hash,
"reason": "hash_mismatch",
"expectedHash": expected_hash,
"actualHash": actual_hash,
},
)
return
os.replace(part_path, save_path)
if not _send_qchat_file_chunk_ack(link, transfer_id, chunk_index, chunk_size):
if state is not None:
state["completed"] = True
_qchat_file_emit(
"failed",
{
"transferId": transfer_id,
"peerPresenceHash": peer_hash,
"reason": "chunk_ack_send_failed",
"chunkIndex": chunk_index,
},
)
return
if state is not None:
state["completed"] = True
with _state_lock:
_qchat_file_accepts_by_peer.pop(peer_hash, None)
_qchat_file_emit(
"received",
{
"transferId": transfer_id,
"peerPresenceHash": peer_hash,
"fileName": pending.get("fileName"),
"path": save_path,
"sha256": actual_hash,
},
)
_qchat_file_receiver_transfer_done(peer_hash, transfer_id)
return
actual_hash = _sha256_file_hex(source_path)
if expected_hash and actual_hash.lower() != expected_hash:
if state is not None:
state["completed"] = True
_qchat_file_emit(
"failed",
{
"transferId": transfer_id,
"peerPresenceHash": peer_hash,
"reason": "hash_mismatch",
"expectedHash": expected_hash,
"actualHash": actual_hash,
},
)
return
_move_file_to_save_path(source_path, save_path)
if state is not None:
state["completed"] = True
with _state_lock:
_qchat_file_accepts_by_peer.pop(peer_hash, None)
_qchat_file_emit(
"received",
{
"transferId": transfer_id,
"peerPresenceHash": peer_hash,
"fileName": pending.get("fileName"),
"path": save_path,
"sha256": actual_hash,
},
)
_qchat_file_receiver_transfer_done(peer_hash, transfer_id)
except Exception as exc:
_qchat_file_emit(
"failed",
{
"transferId": transfer_id,
"peerPresenceHash": peer_hash,
"reason": "save_failed",
"error": str(exc),
},
)
def _configure_overlay_link_resources(link) -> None:
return None
def configure_overlay_link(link, link_id: str) -> None:
link.set_link_closed_callback(on_overlay_link_closed)
link.set_packet_callback(on_overlay_link_packet)
link.set_remote_identified_callback(on_overlay_link_remote_identified)
_configure_overlay_link_resources(link)
_overlay_link_ids_by_object[id(link)] = link_id
def on_outgoing_overlay_link_established(link) -> None:
link_id = get_overlay_link_id(link)
if link_id is None:
return
state = get_overlay_link_state(link_id)
if state is None:
return
if not _overlay_link_is_current(link_id, link):
return
configure_overlay_link(link, link_id)
now = time.time()
state["established"] = True
state["established_at"] = now
state["last_activity_at"] = now
try:
if _identity is not None:
link.identify(_identity)
except Exception as exc:
log(f"[presence_bridge] overlay link identify failed link={link_id}: {exc}")
if not _overlay_link_is_current(link_id, link):
return
emit_overlay_link_state(link_id, state, "established")
ph_out = str(state.get("peerPresenceHash") or "").strip().lower()
if ph_out and _valid_presence_destination_hash_hex(ph_out):
_note_overlay_peer_alive(ph_out, "link_established")
_register_active_overlay_for_peer(ph_out, link_id)
if not _overlay_link_is_current(link_id, link):
return
_flush_overlay_link_pending(link_id)
def _send_wire_to_overlay_peer(
peer_hash: str, wire_bytes: bytes, traffic: str, queue_if_pending: bool = True
) -> bool:
state = _ensure_overlay_link(
peer_hash,
await_path=False,
)
if state is None:
log(
f"[presence_bridge] target=presence-reticulum overlay_link_missing peer={peer_hash} traffic={traffic}"
)
return False
link = state.get("link")
if state.get("established") is True and link is not None:
ok = _send_packet_on_link(
link,
wire_bytes,
f"target=presence-reticulum overlay_link_send peer={peer_hash} traffic={traffic}",
)
if ok:
now = time.time()
state["last_activity_at"] = now
state["last_send_ok_at"] = now
else:
_queue_overlay_packet(state, traffic, wire_bytes)
emit_overlay_link_state(get_overlay_link_id(link) or "", state, traffic)
return False
emit_overlay_link_state(get_overlay_link_id(link) or "", state, traffic)
return True
if queue_if_pending:
_queue_overlay_packet(state, traffic, wire_bytes)
emit_overlay_link_state(
_active_overlay_link_id_by_peer_hash.get(peer_hash, ""),
state,
f"queued:{traffic}",
)
return True
return False
def _send_wire_to_established_overlay_peer(
peer_hash: str, wire_bytes: bytes, traffic: str
) -> bool:
peer_key = str(peer_hash or "").strip().lower()
if not peer_key:
return False
with _state_lock:
link_id = _active_overlay_link_id_by_peer_hash.get(peer_key) or ""
state = _overlay_links_by_id.get(link_id) if link_id else None
link = state.get("link") if state is not None else None
established = state is not None and state.get("established") is True
if not link_id or state is None or link is None or not established:
log(
"[presence_bridge] target=presence-reticulum overlay_link_not_established "
f"peer={peer_key} traffic={traffic}"
)
return False
if not _overlay_link_is_current(link_id, link):
log(
"[presence_bridge] target=presence-reticulum overlay_link_not_current "
f"peer={peer_key} link={link_id} traffic={traffic}"
)
return False
ok = _send_packet_on_link(
link,
wire_bytes,
f"target=presence-reticulum overlay_link_send peer={peer_key} traffic={traffic}",
)
if ok and _overlay_link_is_current(link_id, link):
now = time.time()
state["last_activity_at"] = now
state["last_send_ok_at"] = now
emit_overlay_link_state(link_id, state, traffic)
return True
if _overlay_link_is_current(link_id, link):
emit_overlay_link_state(link_id, state, traffic)
return False
def make_presence_wire(
envelope: Dict[str, Any],
overlay_hops_remaining: Optional[int] = None,
origin_sender_hash: Optional[str] = None,
) -> bytes:
if _destination is None:
raise RuntimeError("Local destination not initialised")
payload = envelope.get("payload")
if not isinstance(payload, dict):
raise RuntimeError("Presence envelope missing payload")
local_sender_hash = destination_hash_hex(_destination.hash)
wire = {
"t": envelope.get("type"),
"i": envelope.get("id"),
"a": payload.get("address"),
"k": payload.get("publicKey"),
"n": payload.get("sessionId"),
"m": envelope.get("timestamp"),
"g": envelope.get("signature"),
"r": local_sender_hash,
}
if isinstance(origin_sender_hash, str):
origin_peer_hash = origin_sender_hash.strip().lower()
if origin_peer_hash:
if not _valid_presence_destination_hash_hex(origin_peer_hash):
raise RuntimeError("Invalid originalSenderHash")
if origin_peer_hash != local_sender_hash:
wire["o"] = origin_peer_hash
if "status" in payload:
wire["s"] = payload.get("status")
if "clientVersion" in payload:
wire["c"] = payload.get("clientVersion")
if isinstance(overlay_hops_remaining, int) and overlay_hops_remaining >= 0:
wire["q"] = overlay_hops_remaining
return json.dumps(wire, separators=(",", ":")).encode("utf-8")
def announce_local_destination(reason: str = "unspecified") -> None:
if _destination is None:
return
_destination.announce(app_data=b"presence")
log(
"[presence_bridge] rns destination announce "
f"at={_log_clock_time()} "
f"reason={reason} "
+ destination_hash_hex(_destination.hash)
)
def _maybe_announce_local_destination_low_verified_overlay_peers() -> None:
"""Extra RNS announce when verified overlay peers < MIN (same cooldown as legacy no-peers path)."""
global _last_no_verified_peers_announce_at
if _destination is None or not _rns_auth_announced:
return
if len(_verified_overlay_peers) >= _MIN_VERIFIED_OVERLAY_PEERS_BEFORE_SKIP_EXTRA_ANNOUNCE:
return
now = time.time()
if (now - _last_no_verified_peers_announce_at) < _NO_VERIFIED_PEERS_ANNOUNCE_COOLDOWN_SECONDS:
return
try:
announce_local_destination(
"low_verified_overlay_peers "
f"verified={len(_verified_overlay_peers)} "
f"min_skip={_MIN_VERIFIED_OVERLAY_PEERS_BEFORE_SKIP_EXTRA_ANNOUNCE}"
)
except Exception as exc:
log(f"[presence_bridge] rns announce low_verified_overlay_peers failed: {exc}")
return
_last_no_verified_peers_announce_at = now
def _cancel_rns_periodic_announce_timer() -> None:
global _rns_periodic_announce_timer
t = _rns_periodic_announce_timer
_rns_periodic_announce_timer = None
if t is not None:
t.cancel()
def _rns_periodic_announce_fire() -> None:
global _rns_periodic_announce_timer, _last_no_verified_peers_announce_at
_rns_periodic_announce_timer = None
if _shutdown.is_set():
return
with _state_lock:
should_announce = _destination is not None and _rns_auth_announced
if not should_announce:
return
def run() -> None:
global _last_no_verified_peers_announce_at
try:
announce_local_destination(
f"periodic interval_sec={RNS_ANNOUNCE_INTERVAL_SEC}"
)
_last_no_verified_peers_announce_at = time.time()
except Exception as exc:
log(f"[presence_bridge] rns announce periodic failed: {exc}")
_enqueue_scheduler_task("control-send", "periodic-announce", run)
_schedule_rns_periodic_announce_timer()
def _schedule_rns_periodic_announce_timer() -> None:
global _rns_periodic_announce_timer
_cancel_rns_periodic_announce_timer()
t = threading.Timer(RNS_ANNOUNCE_INTERVAL_SEC, _rns_periodic_announce_fire)
t.daemon = True
_rns_periodic_announce_timer = t
t.start()
def _rns_announce_on_auth_session_end() -> None:
global _rns_auth_announced, _last_no_verified_peers_announce_at
_rns_auth_announced = False
_last_no_verified_peers_announce_at = 0.0
_cancel_rns_periodic_announce_timer()
def send_presence_wire_to_peer(peer_hash: str, peer_identity, wire_bytes: bytes) -> None:
"""Send presence wire; updates last_send_ok in _peer_lifecycle (TODO: failure vs no-path diagnostics)."""
now = time.time()
try:
outbound = build_outbound_destination(peer_identity)
packet = RNS.Packet(outbound, wire_bytes, create_receipt=False)
result = packet.send()
if peer_hash not in _peer_lifecycle:
_peer_lifecycle[peer_hash] = {
"last_seen_inbound": None,
"last_send_ok": None,
"last_request_path_at": None,
"ts_seed_until": None,
}
st = _peer_lifecycle[peer_hash]
if result is False:
st["last_send_ok"] = None
verbose_presence_log(
f"[presence_bridge] target=presence-reticulum send_failed peer={peer_hash}"
)
else:
st["last_send_ok"] = now
verbose_presence_log(
f"[presence_bridge] target=presence-reticulum sent_presence peer={peer_hash}"
)
except Exception as exc:
if peer_hash in _peer_lifecycle:
_peer_lifecycle[peer_hash]["last_send_ok"] = None
verbose_presence_log(
f"[presence_bridge] target=presence-reticulum send_exception peer={peer_hash}: {exc}"
)
def make_group_audio_wire(room_id: str, raw_audio: bytes) -> bytes:
if _destination is None:
raise RuntimeError("Local destination not initialised")
room_bytes = str(room_id or "").encode("utf-8")
sender_hash = bytes(_destination.hash)
payload = bytes(raw_audio or b"")
if (
not room_bytes
or len(room_bytes) > AUDIO_MAX_ROOM_ID_LEN
or len(sender_hash) > AUDIO_MAX_HASH_LEN
or len(payload) > AUDIO_MAX_PAYLOAD
):
raise ValueError("field too large")
return (
_GROUP_AUDIO_BINARY_MAGIC
+ bytes(
(
_GROUP_AUDIO_BINARY_VERSION,
len(room_bytes),
len(sender_hash),
)
)
+ len(payload).to_bytes(2, "big")
+ room_bytes
+ sender_hash
+ payload
)
def _decode_group_audio_wire(data: bytes) -> Optional[Tuple[str, str, bytes]]:
if not isinstance(data, (bytes, bytearray)):
return None
wire = bytes(data)
if len(wire) < _GROUP_AUDIO_BINARY_HEADER_BYTES:
return None
if wire[:4] != _GROUP_AUDIO_BINARY_MAGIC:
return None
if wire[4] != _GROUP_AUDIO_BINARY_VERSION:
return None
room_len = wire[5]
sender_len = wire[6]
payload_len = int.from_bytes(wire[7:9], "big")
if (
room_len == 0
or room_len > AUDIO_MAX_ROOM_ID_LEN
or sender_len == 0
or sender_len > AUDIO_MAX_HASH_LEN
or payload_len > AUDIO_MAX_PAYLOAD
):
return None
expected_len = _GROUP_AUDIO_BINARY_HEADER_BYTES + room_len + sender_len + payload_len
if len(wire) != expected_len:
return None
offset = _GROUP_AUDIO_BINARY_HEADER_BYTES
try:
room_id = wire[offset : offset + room_len].decode("utf-8")
except Exception:
return None
offset += room_len
sender_hex = wire[offset : offset + sender_len].hex()
offset += sender_len
return room_id, sender_hex, bytes(wire[offset : offset + payload_len])
def get_audio_link_state(link_id: str) -> Optional[Dict[str, Any]]:
with _state_lock:
return _audio_links_by_id.get(link_id)
def get_audio_link_id(link: Any) -> Optional[str]:
with _state_lock:
return _audio_link_ids_by_object.get(id(link))
def _ensure_audio_link_lifecycle_fields(state: Dict[str, Any]) -> Dict[str, Any]:
if "send_lock" not in state:
state["send_lock"] = threading.RLock()
if "generation" not in state:
state["generation"] = 0
if "closing" not in state:
state["closing"] = False
return state
def _audio_link_activity_ts(state: Dict[str, Any]) -> float:
best = 0.0
for key in ("last_rx_at", "last_send_ok_at", "last_activity_at", "established_at", "created_at"):
value = state.get(key)
if isinstance(value, (int, float)):
best = max(best, float(value))
return best
def _audio_link_pick_keep(
peer_key: str,
link_id_a: str,
state_a: Dict[str, Any],
link_id_b: str,
state_b: Dict[str, Any],
) -> tuple[str, str]:
est_a = state_a.get("established") is True
est_b = state_b.get("established") is True
if est_a and not est_b:
return link_id_a, link_id_b
if est_b and not est_a:
return link_id_b, link_id_a
activity_a = _audio_link_activity_ts(state_a)
activity_b = _audio_link_activity_ts(state_b)
if abs(activity_a - activity_b) > 0.001:
return (link_id_a, link_id_b) if activity_a > activity_b else (link_id_b, link_id_a)
incoming_a = state_a.get("incoming") is True
incoming_b = state_b.get("incoming") is True
if incoming_a != incoming_b:
local_hex = _local_presence_hash_hex()
if local_hex and _valid_presence_destination_hash_hex(peer_key):
prefer_incoming = local_hex > peer_key
if incoming_a == prefer_incoming:
return link_id_a, link_id_b
return link_id_b, link_id_a
created_a = float(state_a.get("created_at") or 0.0)
created_b = float(state_b.get("created_at") or 0.0)
if created_a != created_b:
return (link_id_a, link_id_b) if created_a < created_b else (link_id_b, link_id_a)
return (link_id_a, link_id_b) if link_id_a < link_id_b else (link_id_b, link_id_a)
def _teardown_audio_link_id(link_id: str, reason: str) -> None:
state = get_audio_link_state(link_id)
link = state.get("link") if state is not None else None
if link is not None:
try:
link.set_link_closed_callback(None)
except Exception:
pass
try:
link.teardown()
except Exception:
pass
emit_audio_link_closed(link_id, reason)
def _register_active_audio_for_peer(peer_key: str, link_id: str) -> Optional[Dict[str, Any]]:
peer_key = str(peer_key or "").strip().lower()
if not peer_key or not _valid_presence_destination_hash_hex(peer_key):
return None
lose_id = ""
keep_id = link_id
keep_state: Optional[Dict[str, Any]] = None
with _state_lock:
state = _audio_links_by_id.get(link_id)
if state is None:
return None
_ensure_audio_link_lifecycle_fields(state)
state["peerPresenceHash"] = peer_key
if not state.get("peerDestinationHash"):
state["peerDestinationHash"] = peer_key
existing_id = _active_audio_link_id_by_peer_hash.get(peer_key)
if existing_id == link_id:
_outgoing_audio_link_id_by_peer_hash[peer_key] = link_id
return state
if not existing_id:
_active_audio_link_id_by_peer_hash[peer_key] = link_id
_outgoing_audio_link_id_by_peer_hash[peer_key] = link_id
return state
existing = _audio_links_by_id.get(existing_id)
if existing is None:
_active_audio_link_id_by_peer_hash[peer_key] = link_id
_outgoing_audio_link_id_by_peer_hash[peer_key] = link_id
return state
keep_id, lose_id = _audio_link_pick_keep(peer_key, existing_id, existing, link_id, state)
_active_audio_link_id_by_peer_hash[peer_key] = keep_id
_outgoing_audio_link_id_by_peer_hash[peer_key] = keep_id
keep_state = _audio_links_by_id.get(keep_id)
if lose_id and lose_id != keep_id:
log(
"[presence_bridge] target=reticulum-audio-link audio_link_duplicate_teardown "
f"peer={peer_key} keep={keep_id} teardown={lose_id}"
)
_teardown_audio_link_id(lose_id, "dedup_same_peer")
return keep_state
def _canonical_audio_link_id_for_peer(peer_key: str) -> str:
peer_key = str(peer_key or "").strip().lower()
if not peer_key:
return ""
with _state_lock:
active = _active_audio_link_id_by_peer_hash.get(peer_key) or ""
if active and active in _audio_links_by_id:
return active
outgoing = _outgoing_audio_link_id_by_peer_hash.get(peer_key) or ""
if outgoing and outgoing in _audio_links_by_id:
_active_audio_link_id_by_peer_hash[peer_key] = outgoing
return outgoing
return ""
def _best_established_audio_link_id_for_peer(peer_key: str) -> str:
peer_key = str(peer_key or "").strip().lower()
if not peer_key:
return ""
best_link_id = ""
best_state: Optional[Dict[str, Any]] = None
with _state_lock:
for candidate_link_id, state in list(_audio_links_by_id.items()):
if str(state.get("peerPresenceHash") or "").strip().lower() != peer_key:
continue
if state.get("closing") is True or state.get("link") is None:
continue
if state.get("established") is not True:
continue
if not best_link_id or best_state is None:
best_link_id = candidate_link_id
best_state = state
continue
keep_id, _lose_id = _audio_link_pick_keep(
peer_key,
best_link_id,
best_state,
candidate_link_id,
state,
)
if keep_id == candidate_link_id:
best_link_id = candidate_link_id
best_state = state
if best_link_id:
_active_audio_link_id_by_peer_hash[peer_key] = best_link_id
_outgoing_audio_link_id_by_peer_hash[peer_key] = best_link_id
return best_link_id
def _snapshot_audio_link_for_send(
link_id: str,
peer_key_hint: str = "",
) -> Optional[Dict[str, Any]]:
with _state_lock:
state = _audio_links_by_id.get(link_id)
peer_key_hint = str(peer_key_hint or "").strip().lower()
if state is None:
canonical_id = _best_established_audio_link_id_for_peer(peer_key_hint)
if not canonical_id:
canonical_id = _active_audio_link_id_by_peer_hash.get(peer_key_hint) if peer_key_hint else ""
if not canonical_id:
canonical_id = _outgoing_audio_link_id_by_peer_hash.get(peer_key_hint) if peer_key_hint else ""
if not canonical_id:
return None
state = _audio_links_by_id.get(canonical_id)
if state is None:
return None
link_id = canonical_id
_ensure_audio_link_lifecycle_fields(state)
if state.get("closing") is True:
fallback_peer_key = str(state.get("peerPresenceHash") or peer_key_hint).strip().lower()
fallback_id = _best_established_audio_link_id_for_peer(fallback_peer_key)
if not fallback_id or fallback_id == link_id:
return None
fallback_state = _audio_links_by_id.get(fallback_id)
if fallback_state is None:
return None
state = fallback_state
link_id = fallback_id
_ensure_audio_link_lifecycle_fields(state)
peer_key = str(state.get("peerPresenceHash") or peer_key_hint).strip().lower()
canonical_id = _active_audio_link_id_by_peer_hash.get(peer_key) if peer_key else ""
if canonical_id and canonical_id != link_id:
canonical_state = _audio_links_by_id.get(canonical_id)
if (
canonical_state is not None
and canonical_state.get("closing") is not True
and canonical_state.get("established") is True
):
state = canonical_state
link_id = canonical_id
_ensure_audio_link_lifecycle_fields(state)
if state.get("established") is not True:
fallback_id = _best_established_audio_link_id_for_peer(peer_key)
if fallback_id and fallback_id != link_id:
fallback_state = _audio_links_by_id.get(fallback_id)
if fallback_state is not None:
state = fallback_state
link_id = fallback_id
_ensure_audio_link_lifecycle_fields(state)
if state.get("established") is not True:
return {
"ready": False,
"linkId": link_id,
"peerPresenceHash": str(state.get("peerPresenceHash") or ""),
"reason": "audio_link_not_ready",
}
link = state.get("link")
if link is None:
return None
return {
"ready": True,
"linkId": link_id,
"link": link,
"sendLock": state.get("send_lock"),
"generation": int(state.get("generation") or 0),
"peerPresenceHash": str(state.get("peerPresenceHash") or ""),
"peerDestinationHash": str(state.get("peerDestinationHash") or ""),
"incoming": state.get("incoming") is True,
}
def _audio_link_generation_matches(link_id: str, generation: int) -> bool:
with _state_lock:
state = _audio_links_by_id.get(link_id)
if state is None or state.get("closing") is True:
return False
return int(state.get("generation") or 0) == int(generation)
def remove_audio_link(link_id: str) -> Optional[Dict[str, Any]]:
with _state_lock:
state = _audio_links_by_id.pop(link_id, None)
if state is not None:
_ensure_audio_link_lifecycle_fields(state)
state["closing"] = True
state["generation"] = int(state.get("generation") or 0) + 1
link = state.get("link")
if link is not None:
_audio_link_ids_by_object.pop(id(link), None)
peer_hash = state.get("peerPresenceHash")
if isinstance(peer_hash, str):
existing = _outgoing_audio_link_id_by_peer_hash.get(peer_hash)
if existing == link_id:
_outgoing_audio_link_id_by_peer_hash.pop(peer_hash, None)
active = _active_audio_link_id_by_peer_hash.get(peer_hash)
if active == link_id:
_active_audio_link_id_by_peer_hash.pop(peer_hash, None)
if state is None:
return None
timer = state.pop("establish_timeout_timer", None)
if timer is not None:
try:
timer.cancel()
except Exception:
pass
return state
def _get_audio_link_desired_state(peer_key: str) -> Dict[str, Any]:
with _state_lock:
state = _audio_link_desired_by_peer_hash.get(peer_key)
if state is not None:
return state
state = {
"desired": True,
"attempts": 0,
"retry_delay": _AUDIO_LINK_RETRY_MIN_SECONDS,
"retry_timer": None,
"last_open_attempt_at": None,
"last_failure_reason": "",
"max_attempts_emitted": False,
}
_audio_link_desired_by_peer_hash[peer_key] = state
return state
def _cancel_audio_link_retry_timer(peer_key: str) -> None:
with _state_lock:
desired = _audio_link_desired_by_peer_hash.get(peer_key)
if desired is None:
return
timer = desired.get("retry_timer")
desired["retry_timer"] = None
if desired is None:
return
if timer is not None:
try:
timer.cancel()
except Exception:
pass
def _set_audio_link_desired(peer_key: str, desired: bool) -> Dict[str, Any]:
state = _get_audio_link_desired_state(peer_key)
with _state_lock:
was_desired = state.get("desired") is True
state["desired"] = desired
if desired and not was_desired:
state["max_attempts_emitted"] = False
elif not desired:
state["attempts"] = 0
state["retry_delay"] = _AUDIO_LINK_RETRY_MIN_SECONDS
state["last_failure_reason"] = ""
state["max_attempts_emitted"] = False
if desired:
return state
_cancel_audio_link_retry_timer(peer_key)
return state
def _audio_link_attempts_exhausted(desired: Optional[Dict[str, Any]]) -> bool:
if desired is None:
return False
return int(desired.get("attempts") or 0) >= _AUDIO_LINK_MAX_ESTABLISH_ATTEMPTS
def _emit_audio_link_attempts_exhausted(peer_key: str, reason: str, desired: Dict[str, Any]) -> None:
attempts = int(desired.get("attempts") or 0)
with _state_lock:
if desired.get("max_attempts_emitted") is True:
return
desired["last_failure_reason"] = "max_establish_attempts"
desired["retry_timer"] = None
desired["max_attempts_emitted"] = True
log(
"[presence_bridge] target=reticulum-audio-link audio_link_max_establish_attempts "
f"peer={peer_key} attempts={attempts} max={_AUDIO_LINK_MAX_ESTABLISH_ATTEMPTS} reason={reason}"
)
emit_event(
"group_audio_send_failed",
{
"linkId": "",
"peerPresenceHash": peer_key,
"reason": "max_establish_attempts",
"code": "max_establish_attempts",
"transport": "link",
"attempts": attempts,
"maxAttempts": _AUDIO_LINK_MAX_ESTABLISH_ATTEMPTS,
},
)
def _has_viable_audio_link_for_peer(peer_key: str, excluding_link_id: str = "") -> bool:
peer_key = str(peer_key or "").strip().lower()
if not peer_key:
return False
with _state_lock:
for candidate_link_id, state in list(_audio_links_by_id.items()):
if excluding_link_id and candidate_link_id == excluding_link_id:
continue
if str(state.get("peerPresenceHash") or "").strip().lower() != peer_key:
continue
link = state.get("link")
if link is None or state.get("closing") is True:
continue
if state.get("established") is True:
return True
created_at = state.get("created_at")
if isinstance(created_at, (int, float)) and (
time.time() - float(created_at)
) < _AUDIO_LINK_ESTABLISH_TIMEOUT_SECONDS:
return True
return False
def _best_viable_audio_link_id_for_peer(peer_key: str) -> str:
peer_key = str(peer_key or "").strip().lower()
if not peer_key:
return ""
best_link_id = ""
best_state: Optional[Dict[str, Any]] = None
now = time.time()
with _state_lock:
for candidate_link_id, state in list(_audio_links_by_id.items()):
if str(state.get("peerPresenceHash") or "").strip().lower() != peer_key:
continue
if state.get("closing") is True or state.get("link") is None:
continue
established = state.get("established") is True
created_at = state.get("created_at")
pending_recent = isinstance(created_at, (int, float)) and (
now - float(created_at)
) < _AUDIO_LINK_ESTABLISH_TIMEOUT_SECONDS
if not established and not pending_recent:
continue
if not best_link_id:
best_link_id = candidate_link_id
best_state = state
continue
if best_state is None:
best_link_id = candidate_link_id
best_state = state
continue
keep_id, _lose_id = _audio_link_pick_keep(
peer_key,
best_link_id,
best_state,
candidate_link_id,
state,
)
if keep_id == candidate_link_id:
best_link_id = candidate_link_id
best_state = state
if best_link_id:
_active_audio_link_id_by_peer_hash[peer_key] = best_link_id
_outgoing_audio_link_id_by_peer_hash[peer_key] = best_link_id
return best_link_id
def _schedule_audio_link_retry(peer_key: str, reason: str, immediate: bool = False) -> None:
peer_key = str(peer_key or "").strip().lower()
if not peer_key:
return
with _state_lock:
desired = _audio_link_desired_by_peer_hash.get(peer_key)
if desired is None or desired.get("desired") is not True:
return
if _audio_link_attempts_exhausted(desired):
_emit_audio_link_attempts_exhausted(peer_key, reason, desired)
return
if _has_viable_audio_link_for_peer(peer_key):
return
if desired.get("retry_timer") is not None:
return
delay = 0.0 if immediate else float(
desired.get("retry_delay") or _AUDIO_LINK_RETRY_MIN_SECONDS
)
with _state_lock:
desired["last_failure_reason"] = reason
def retry() -> None:
with _state_lock:
desired_state = _audio_link_desired_by_peer_hash.get(peer_key)
if desired_state is None:
return
with _state_lock:
desired_state["retry_timer"] = None
if desired_state.get("desired") is not True:
return
if _audio_link_attempts_exhausted(desired_state):
_emit_audio_link_attempts_exhausted(peer_key, reason, desired_state)
return
if _has_viable_audio_link_for_peer(peer_key):
return
_enqueue_scheduler_task(
"link-management",
f"audio-link-retry:{reason}",
_open_group_audio_link_for_peer,
peer_key,
retry_reason=reason,
)
timer = threading.Timer(delay, retry)
timer.daemon = True
with _state_lock:
desired["retry_timer"] = timer
timer.start()
log(
"[presence_bridge] target=reticulum-audio-link audio_link_retry_scheduled "
f"peer={peer_key} reason={reason} delay={delay:.2f}"
)
def _schedule_audio_link_establish_timeout(link_id: str) -> None:
state = get_audio_link_state(link_id)
if state is None or state.get("incoming") is True:
return
def fire() -> None:
_enqueue_scheduler_task(
"link-management",
"audio-link-establish-timeout",
_handle_audio_link_establish_timeout,
link_id,
)
timer = threading.Timer(_AUDIO_LINK_ESTABLISH_TIMEOUT_SECONDS, fire)
timer.daemon = True
with _state_lock:
state["establish_timeout_timer"] = timer
timer.start()
def _handle_audio_link_establish_timeout(link_id: str) -> None:
current = get_audio_link_state(link_id)
if current is None or current.get("established") is True:
return
peer_key = str(current.get("peerPresenceHash") or "").strip().lower()
link = current.get("link")
if link is not None:
try:
link.set_link_closed_callback(None)
except Exception:
pass
try:
link.teardown()
except Exception:
pass
removed = remove_audio_link(link_id)
if removed is None:
return
log(
"[presence_bridge] target=reticulum-audio-link audio_link_establish_timeout "
f"peer={peer_key} link={link_id}"
)
emit_event(
"group_audio_link_closed",
{
"linkId": link_id,
"peerPresenceHash": removed.get("peerPresenceHash") or "",
"peerDestinationHash": removed.get("peerDestinationHash") or "",
"incoming": removed.get("incoming") is True,
"reason": "establish_timeout",
},
)
_schedule_audio_link_retry(peer_key, "establish_timeout")
def _open_group_audio_link_for_peer(
peer_key: str,
*,
retry_reason: str = "open",
) -> Tuple[bool, Dict[str, Any], str]:
peer_key = str(peer_key or "").strip().lower()
if not peer_key:
return False, {"code": "missing_peer_presence_hash"}, "Missing peerPresenceHash"
if _destination is None:
return False, {"code": "bridge_not_started"}, "Bridge not started"
desired = _set_audio_link_desired(peer_key, True)
with _state_lock:
existing_link_id = (
_active_audio_link_id_by_peer_hash.get(peer_key)
or _outgoing_audio_link_id_by_peer_hash.get(peer_key)
)
if existing_link_id:
existing = get_audio_link_state(existing_link_id)
if existing is not None:
return True, {
"linkId": existing_link_id,
"established": existing.get("established") is True,
}, ""
with _state_lock:
_outgoing_audio_link_id_by_peer_hash.pop(peer_key, None)
_active_audio_link_id_by_peer_hash.pop(peer_key, None)
viable_link_id = _best_viable_audio_link_id_for_peer(peer_key)
if viable_link_id:
existing = get_audio_link_state(viable_link_id)
return True, {
"linkId": viable_link_id,
"established": existing.get("established") is True if existing is not None else False,
}, ""
if _audio_link_attempts_exhausted(desired):
_emit_audio_link_attempts_exhausted(peer_key, retry_reason, desired)
return False, {
"code": "max_establish_attempts",
"attempts": int(desired.get("attempts") or 0),
"maxAttempts": _AUDIO_LINK_MAX_ESTABLISH_ATTEMPTS,
}, "Max group audio link establish attempts reached"
peer_identity = _get_group_audio_peer_identity(peer_key)
if peer_identity is None:
return False, {"code": "unknown_peer_presence_hash"}, "Unknown peer presence hash"
try:
outbound = build_outbound_destination(peer_identity)
outbound_hash = destination_hash_hex(outbound.hash)
if outbound_hash != peer_key:
return False, {
"code": "peer_hash_mismatch",
"derived": outbound_hash,
}, "Reticulum public key does not match destination hash"
desired["attempts"] = int(desired.get("attempts") or 0) + 1
desired["last_open_attempt_at"] = time.time()
path_state, path_ready = _ensure_call_media_path(
peer_key,
outbound.hash,
active_call=True,
allow_wait=True,
reason=f"open_link:{retry_reason}",
await_seconds_override=_AUDIO_LINK_OPEN_PATH_AWAIT_SECONDS,
)
if not path_ready:
desired["retry_delay"] = min(
_AUDIO_LINK_RETRY_MAX_SECONDS,
max(
_AUDIO_LINK_RETRY_MIN_SECONDS,
float(desired.get("retry_delay") or _AUDIO_LINK_RETRY_MIN_SECONDS) * 2,
),
)
_schedule_audio_link_retry(peer_key, f"no_route:{path_state}")
return False, {
"code": "no_route",
"pathState": path_state,
"pathAwaitSeconds": _AUDIO_LINK_OPEN_PATH_AWAIT_SECONDS,
}, "No confirmed Reticulum path for group audio link"
desired["retry_delay"] = _AUDIO_LINK_RETRY_MIN_SECONDS
link_id = str(uuid.uuid4())
link = RNS.Link(
outbound,
established_callback=on_outgoing_audio_link_established,
closed_callback=on_audio_link_closed,
)
audio_state = {
"link": link,
"peerPresenceHash": peer_key,
"peerDestinationHash": outbound_hash,
"incoming": False,
"established": False,
"created_at": time.time(),
"open_reason": retry_reason,
"open_attempt": desired["attempts"],
}
_ensure_audio_link_lifecycle_fields(audio_state)
with _state_lock:
_audio_links_by_id[link_id] = audio_state
_audio_link_ids_by_object[id(link)] = link_id
_outgoing_audio_link_id_by_peer_hash[peer_key] = link_id
_active_audio_link_id_by_peer_hash[peer_key] = link_id
_schedule_audio_link_establish_timeout(link_id)
log(
"[presence_bridge] target=reticulum-audio-link audio_link_opening "
f"peer={peer_key} link={link_id} attempt={desired['attempts']} reason={retry_reason}"
)
return True, {"linkId": link_id, "established": False}, ""
except Exception as exc:
log(
"[presence_bridge] target=reticulum-audio-link audio_link_open_exception "
f"peer={peer_key} reason={retry_reason} err={exc}\n{traceback.format_exc()}"
)
desired["retry_delay"] = min(
_AUDIO_LINK_RETRY_MAX_SECONDS,
max(
_AUDIO_LINK_RETRY_MIN_SECONDS,
float(desired.get("retry_delay") or _AUDIO_LINK_RETRY_MIN_SECONDS) * 2,
),
)
_schedule_audio_link_retry(peer_key, "open_exception")
return False, {"code": "exception"}, str(exc)
def emit_audio_link_established(link_id: str) -> None:
state = get_audio_link_state(link_id)
if state is None:
return
emit_event(
"group_audio_link_established",
{
"linkId": link_id,
"peerPresenceHash": state.get("peerPresenceHash") or "",
"peerDestinationHash": state.get("peerDestinationHash") or "",
"incoming": state.get("incoming") is True,
},
)
def emit_audio_link_closed(link_id: str, reason: str = "") -> None:
state = remove_audio_link(link_id)
if state is None:
return
emit_event(
"group_audio_link_closed",
{
"linkId": link_id,
"peerPresenceHash": state.get("peerPresenceHash") or "",
"peerDestinationHash": state.get("peerDestinationHash") or "",
"incoming": state.get("incoming") is True,
"reason": reason,
},
)
def on_audio_link_closed(link) -> None:
link_id = get_audio_link_id(link)
if link_id is None:
return
state = get_audio_link_state(link_id)
peer_key = ""
incoming = False
if state is not None:
peer_key = str(state.get("peerPresenceHash") or "").strip().lower()
incoming = state.get("incoming") is True
teardown_reason = getattr(link, "teardown_reason", None)
reason = str(teardown_reason) if teardown_reason is not None else "closed"
emit_audio_link_closed(link_id, reason)
if (
not incoming
and reason not in ("local_close", "peer_state_reset")
and not _has_viable_audio_link_for_peer(peer_key)
):
_schedule_audio_link_retry(peer_key, f"closed:{reason}")
def on_audio_link_remote_identified(link, identity) -> None:
link_id = get_audio_link_id(link)
if link_id is None:
return
state = get_audio_link_state(link_id)
if state is None:
return
peer_hash = find_peer_hash_for_identity(identity)
if peer_hash:
with _state_lock:
state["peerPresenceHash"] = peer_hash
state["peerDestinationHash"] = peer_hash
_register_active_audio_for_peer(peer_hash, link_id)
emit_audio_link_established(link_id)
def _handle_audio_link_packet(message, packet) -> None:
received_at_wall_ms = _now_wall_ms()
callback_started_monotonic = time.monotonic()
link = getattr(packet, "link", None)
link_id = get_audio_link_id(link) if link is not None else None
if link_id is None:
return
state = get_audio_link_state(link_id)
if state is None:
return
probe = _audio_link_receive_probe_by_packet_id.pop(id(packet), None)
if isinstance(probe, dict):
stats = _get_audio_route_stats_for_link_id(
link_id,
incoming=state.get("incoming") is True,
)
if stats is not None:
dispatch_mono = float(probe.get("callbackDispatchMonotonic") or 0.0)
enter_mono = float(probe.get("receiveEnterMonotonic") or 0.0)
if dispatch_mono > 0:
dispatch_to_start_ms = (callback_started_monotonic - dispatch_mono) * 1000.0
if dispatch_to_start_ms >= _AUDIO_TIMING_DELAY_LOG_THRESHOLD_MS:
_log_audio_timing_anomaly(
"rns-link-callback-start-delay",
link_id,
f"link={_short_route(link_id)} delay_ms={dispatch_to_start_ms:.3f} "
f"peer={_short_route(state.get('peerPresenceHash'))} "
f"dest={_short_route(state.get('peerDestinationHash'))}",
)
_note_audio_route_bucketed_duration(
stats,
duration_ms=dispatch_to_start_ms,
max_key="linkCallbackDispatchToStartMsMax",
bucket_prefix="linkCallbackDispatchToStart",
)
if enter_mono > 0:
receive_to_start_ms = (callback_started_monotonic - enter_mono) * 1000.0
if receive_to_start_ms >= _AUDIO_TIMING_DELAY_LOG_THRESHOLD_MS:
_log_audio_timing_anomaly(
"rns-link-receive-to-callback-start-delay",
link_id,
f"link={_short_route(link_id)} delay_ms={receive_to_start_ms:.3f} "
f"peer={_short_route(state.get('peerPresenceHash'))} "
f"dest={_short_route(state.get('peerDestinationHash'))}",
)
_note_audio_route_bucketed_duration(
stats,
duration_ms=receive_to_start_ms,
max_key="linkReceiveToCallbackStartMsMax",
)
_mark_audio_queue_state_dirty()
decoded_audio = _decode_group_audio_wire(message)
if decoded_audio is not None:
room_id, sender_call_hash, raw_audio = decoded_audio
if sender_call_hash:
peer_presence_hash = _resolve_sender_peer_destination_hash(sender_call_hash)
with _state_lock:
state["peerDestinationHash"] = sender_call_hash
if peer_presence_hash:
state["peerPresenceHash"] = peer_presence_hash
state["last_rx_at"] = time.time()
state["last_activity_at"] = state["last_rx_at"]
if peer_presence_hash:
_register_active_audio_for_peer(peer_presence_hash, link_id)
canonical_id = _canonical_audio_link_id_for_peer(peer_presence_hash)
if canonical_id and canonical_id != link_id:
return
try:
chunk = _encode_audio_batch_binary(
[
(
link_id,
room_id,
str(state.get("peerPresenceHash") or ""),
str(state.get("peerDestinationHash") or ""),
received_at_wall_ms,
raw_audio,
)
]
)
fd4_ok = _emit_binary_audio(chunk)
fd4_enqueued_at_wall_ms = _now_wall_ms()
_note_audio_route_receive(
"link",
link_id,
room_id,
str(state.get("peerPresenceHash") or ""),
str(state.get("peerDestinationHash") or sender_call_hash or ""),
len(raw_audio),
fd4_enqueued=fd4_ok,
incoming=state.get("incoming") is True,
received_at_wall_ms=received_at_wall_ms,
fd4_enqueued_at_wall_ms=fd4_enqueued_at_wall_ms,
)
except Exception as exc:
_note_audio_route_receive(
"link",
link_id,
room_id,
str(state.get("peerPresenceHash") or ""),
str(state.get("peerDestinationHash") or sender_call_hash or ""),
len(raw_audio),
fd4_enqueued=False,
incoming=state.get("incoming") is True,
received_at_wall_ms=received_at_wall_ms,
)
log(f"[presence_bridge] {_AUDIO_IPC_LOG} fd4=encode-to-parent-failed err={exc}")
return
try:
decoded = json.loads(message.decode("utf-8"))
except Exception as exc:
log(f"[presence_bridge] invalid link audio payload: {exc}")
return
if not isinstance(decoded, dict):
return
if decoded.get("t") == _GROUP_AUDIO_HEARTBEAT_WIRE_TYPE:
sender_call_hash = decoded.get("r")
if isinstance(sender_call_hash, str) and sender_call_hash:
peer_presence_hash = _resolve_sender_peer_destination_hash(sender_call_hash)
with _state_lock:
state["peerDestinationHash"] = sender_call_hash
if peer_presence_hash:
state["peerPresenceHash"] = peer_presence_hash
state["last_rx_at"] = time.time()
state["last_activity_at"] = state["last_rx_at"]
if peer_presence_hash:
_register_active_audio_for_peer(peer_presence_hash, link_id)
_emit_call_bridge_message(
decoded,
str(state.get("peerPresenceHash") or ""),
link_id,
)
return
if decoded.get("t") != _GROUP_AUDIO_WIRE_TYPE:
return
log("[presence_bridge] ignored legacy json/base64 link audio payload")
def on_audio_link_packet(message, packet) -> None:
started_at = time.monotonic()
try:
_handle_audio_link_packet(message, packet)
finally:
_note_callback_duration("audio", started_at, message)
def configure_audio_link(link, link_id: str) -> None:
link.set_link_closed_callback(on_audio_link_closed)
link.set_packet_callback(on_audio_link_packet)
link.set_remote_identified_callback(on_audio_link_remote_identified)
with _state_lock:
state = _audio_links_by_id.get(link_id)
if state is not None:
_ensure_audio_link_lifecycle_fields(state)
_audio_link_ids_by_object[id(link)] = link_id
def on_outgoing_audio_link_established(link) -> None:
link_id = get_audio_link_id(link)
if link_id is None:
return
state = get_audio_link_state(link_id)
if state is None:
return
configure_audio_link(link, link_id)
with _state_lock:
_ensure_audio_link_lifecycle_fields(state)
state["established"] = True
state["established_at"] = time.time()
timer = state.pop("establish_timeout_timer", None)
if timer is not None:
try:
timer.cancel()
except Exception:
pass
peer_key = str(state.get("peerPresenceHash") or "").strip().lower()
if peer_key:
_register_active_audio_for_peer(peer_key, link_id)
with _state_lock:
desired = _audio_link_desired_by_peer_hash.get(peer_key)
if desired is not None:
_cancel_audio_link_retry_timer(peer_key)
with _state_lock:
desired["attempts"] = 0
desired["retry_delay"] = _AUDIO_LINK_RETRY_MIN_SECONDS
desired["last_failure_reason"] = ""
desired["max_attempts_emitted"] = False
try:
if _identity is not None:
link.identify(_identity)
except Exception as exc:
log(f"[presence_bridge] audio link identify failed link={link_id}: {exc}")
log(
"[presence_bridge] target=reticulum-audio-link audio_link_established "
f"peer={peer_key} link={link_id}"
)
emit_audio_link_established(link_id)
def _cancel_inbound_classify_timer(link_key: int) -> None:
timer = _inbound_classify_timers.pop(link_key, None)
if timer is not None:
try:
timer.cancel()
except Exception:
pass
def _register_incoming_overlay_link(link, peer_hash: str = "", reason: str = "incoming") -> str:
peer_key = str(peer_hash or "").strip().lower()
_prune_overlay_link_pressure("link_pressure_inbound", reserve_slots=1)
pressure_reject = False
pressure_links = 0
with _state_lock:
if len(_overlay_links_by_id) >= _OVERLAY_MAX_TOTAL_LINKS:
pressure_reject = True
pressure_links = len(_overlay_links_by_id)
if pressure_reject:
verbose_presence_log(
"[presence_bridge] target=presence-reticulum overlay_inbound_rejected "
f"peer={peer_key or 'unknown'} reason=link_pressure "
f"links={pressure_links} max={_OVERLAY_MAX_TOTAL_LINKS}"
)
try:
link.teardown()
except Exception:
pass
return ""
if peer_key:
if not _admit_overlay_peer_if_allowed(peer_key, f"inbound:{reason}", incoming=True):
verbose_presence_log(
"[presence_bridge] target=presence-reticulum overlay_inbound_rejected "
f"peer={peer_key} reason={reason}"
)
try:
link.teardown()
except Exception:
pass
return ""
elif not _overlay_unknown_inbound_allowed():
verbose_presence_log(
"[presence_bridge] target=presence-reticulum overlay_inbound_rejected "
f"peer=unknown reason={reason} active={len(_inbound_overlay_neighbors)}"
)
try:
link.teardown()
except Exception:
pass
return ""
link_id = str(uuid.uuid4())
now = time.time()
state = {
"link": link,
"peerPresenceHash": peer_key,
"incoming": True,
"established": True,
"established_at": now,
"created_at": now,
"pending_packets": deque(maxlen=_OVERLAY_PENDING_PACKET_LIMIT),
"last_activity_at": now,
"last_rx_at": None,
}
with _state_lock:
_overlay_links_by_id[link_id] = state
configure_overlay_link(link, link_id)
if peer_key:
_register_active_overlay_for_peer(peer_key, link_id)
emit_overlay_link_state(link_id, state, "incoming")
return link_id
def _schedule_inbound_classify_fallback(link) -> None:
link_key = id(link)
def fire() -> None:
with _state_lock:
if link_key not in _pending_inbound_classify_link_ids:
return
_pending_inbound_classify_link_ids.discard(link_key)
_cancel_inbound_classify_timer(link_key)
if (
get_overlay_link_id(link) is not None
or get_audio_link_id(link) is not None
or get_qchat_file_link_id(link) is not None
):
return
log(
"[presence_bridge] WARNING inbound_link_classify_timeout defaulting_to_overlay "
f"link_obj={link_key}"
)
try:
_register_incoming_overlay_link(link)
except Exception as exc:
log(f"[presence_bridge] inbound_link_classify_timeout err={exc}")
timer = threading.Timer(_INBOUND_LINK_CLASSIFY_TIMEOUT_SEC, fire)
timer.daemon = True
_inbound_classify_timers[link_key] = timer
timer.start()
def on_inbound_unified_link_closed(link) -> None:
link_key = id(link)
_cancel_inbound_classify_timer(link_key)
with _state_lock:
_pending_inbound_classify_link_ids.discard(link_key)
if get_overlay_link_id(link):
on_overlay_link_closed(link)
elif get_audio_link_id(link):
on_audio_link_closed(link)
elif get_qchat_file_link_id(link):
on_qchat_file_link_closed(link)
else:
_incoming_unified_peer_hash_by_object.pop(id(link), None)
def _handle_inbound_link_first_packet(message, packet) -> None:
link = getattr(packet, "link", None)
if link is None:
return
link_key = id(link)
with _state_lock:
if link_key not in _pending_inbound_classify_link_ids:
return
_pending_inbound_classify_link_ids.discard(link_key)
_cancel_inbound_classify_timer(link_key)
if _decode_group_audio_wire(message) is not None:
link_id = str(uuid.uuid4())
now = time.time()
audio_state = {
"link": link,
"peerPresenceHash": "",
"peerDestinationHash": "",
"incoming": True,
"established": True,
"established_at": now,
"created_at": now,
"last_activity_at": now,
"last_rx_at": now,
}
_ensure_audio_link_lifecycle_fields(audio_state)
with _state_lock:
_audio_links_by_id[link_id] = audio_state
configure_audio_link(link, link_id)
on_audio_link_packet(message, packet)
return
try:
decoded = json.loads(message.decode("utf-8"))
except Exception as exc:
log(f"[presence_bridge] inbound_link_first_packet non-json err={exc}")
_register_incoming_overlay_link(link, reason="first_packet_non_json")
return
if not isinstance(decoded, dict):
_register_incoming_overlay_link(link, reason="first_packet_non_object")
return
if decoded.get("t") in _AUDIO_LINK_WIRE_TYPES:
link_id = str(uuid.uuid4())
now = time.time()
audio_state = {
"link": link,
"peerPresenceHash": "",
"peerDestinationHash": "",
"incoming": True,
"established": True,
"established_at": now,
"created_at": now,
"last_activity_at": now,
"last_rx_at": now,
}
_ensure_audio_link_lifecycle_fields(audio_state)
with _state_lock:
_audio_links_by_id[link_id] = audio_state
configure_audio_link(link, link_id)
on_audio_link_packet(message, packet)
return
if decoded.get("type") == "QCHAT_FILE_LINK_AUTH":
link_id = _register_incoming_qchat_file_link(
link,
"",
str(decoded.get("transferId") or ""),
)
on_qchat_file_link_packet(message, packet)
return
peer_hash = ""
if isinstance(decoded.get("t"), str) and str(decoded.get("t")).startswith("PRESENCE_"):
peer_hash = str(decoded.get("r") or "").strip().lower()
link_id = _register_incoming_overlay_link(
link,
peer_hash if _valid_presence_destination_hash_hex(peer_hash) else "",
"first_packet",
)
if link_id:
on_overlay_link_packet(message, packet)
def on_inbound_link_first_packet(message, packet) -> None:
started_at = time.monotonic()
try:
_handle_inbound_link_first_packet(message, packet)
finally:
_note_callback_duration("inbound_first", started_at, message)
def on_incoming_unified_link_established(link) -> None:
link_key = id(link)
with _state_lock:
_pending_inbound_classify_link_ids.add(link_key)
link.set_link_closed_callback(on_inbound_unified_link_closed)
link.set_packet_callback(on_inbound_link_first_packet)
link.set_remote_identified_callback(on_qchat_file_link_remote_identified)
link.set_resource_strategy(RNS.Link.ACCEPT_APP)
link.set_resource_callback(on_qchat_file_resource_advertised)
link.set_resource_concluded_callback(on_qchat_file_resource_concluded)
_schedule_inbound_classify_fallback(link)
def _handle_hub_packet_received(data, packet) -> None:
received_at_wall_ms = _now_wall_ms()
decoded_audio = _decode_group_audio_wire(data)
if decoded_audio is not None:
room_id, sender_dest, raw_audio = decoded_audio
peer_presence_hash = _resolve_sender_peer_destination_hash(sender_dest)
try:
chunk = _encode_audio_batch_binary(
[
(
"",
room_id,
peer_presence_hash,
sender_dest,
received_at_wall_ms,
raw_audio,
)
]
)
_note_call_media_inbound(peer_presence_hash, sender_dest)
fd4_ok = _emit_binary_audio(chunk)
fd4_enqueued_at_wall_ms = _now_wall_ms()
_note_audio_route_receive(
"packet",
str(peer_presence_hash or sender_dest or ""),
room_id,
str(peer_presence_hash or ""),
str(sender_dest or ""),
len(raw_audio),
fd4_enqueued=fd4_ok,
received_at_wall_ms=received_at_wall_ms,
fd4_enqueued_at_wall_ms=fd4_enqueued_at_wall_ms,
)
except Exception as exc:
_note_audio_route_receive(
"packet",
str(peer_presence_hash or sender_dest or ""),
room_id,
str(peer_presence_hash or ""),
str(sender_dest or ""),
len(raw_audio),
fd4_enqueued=False,
received_at_wall_ms=received_at_wall_ms,
)
log(f"[presence_bridge] {_AUDIO_IPC_LOG} fd4=encode-to-parent-failed err={exc}")
return
try:
message = json.loads(data.decode("utf-8"))
except Exception as exc:
log(f"[presence_bridge] invalid hub packet payload: {exc}")
return
if not isinstance(message, dict):
log("[presence_bridge] ignored non-object hub packet payload")
return
_note_presence_pressure("source:hub")
t = message.get("t")
if t == _GROUP_AUDIO_WIRE_TYPE:
log("[presence_bridge] ignored legacy json/base64 hub audio payload")
return
if isinstance(t, str) and t.startswith("PRESENCE_"):
_emit_presence_message(message)
return
_emit_call_bridge_message(message)
def on_hub_packet_received(data, packet) -> None:
started_at = time.monotonic()
try:
_handle_hub_packet_received(data, packet)
finally:
_note_callback_duration("hub", started_at, data)
def ensure_started(config_dir: str):
global _reticulum, _identity, _destination
global _announce_handler
with _state_lock:
if _destination is not None:
return _destination
os.makedirs(config_dir, exist_ok=True)
_reticulum = RNS.Reticulum(
configdir=config_dir,
logdest=RNS.LOG_FILE,
require_shared_instance=True,
)
install_rns_shared_rpc_failure_guard()
log(
"[presence_bridge] connected_to_shared_instance="
+ str(getattr(_reticulum, "is_connected_to_shared_instance", None))
)
_identity = ensure_identity(config_dir)
_destination = RNS.Destination(
_identity,
RNS.Destination.IN,
RNS.Destination.SINGLE,
APP_NAMESPACE,
PRESENCE_ASPECT,
PRESENCE_VERSION,
)
_destination.set_proof_strategy(RNS.Destination.PROVE_NONE)
_destination.set_packet_callback(on_hub_packet_received)
_destination.set_link_established_callback(on_incoming_unified_link_established)
_announce_handler = PresenceAnnounceHandler(_destination.hash)
RNS.Transport.register_announce_handler(_announce_handler)
ensure_transport_monitor_started()
ensure_rns_callback_scheduler_monitor_started()
install_rns_shared_frame_probe()
install_rns_transport_inbound_probe()
install_rns_link_receive_probe()
return _destination
def handle_start(req_id: str, payload: Dict[str, Any]) -> None:
config_dir = str(payload.get("configDir") or os.environ.get("QORTAL_RETICULUM_CONFIG_DIR") or "")
if not config_dir:
emit_resp(req_id, False, error="Missing configDir")
return
try:
destination = ensure_started(config_dir)
maybe_emit_transport_state(force=True)
presence_hex = destination_hash_hex(destination.hash)
emit_event(
"ready",
{"destinationHash": presence_hex},
)
emit_resp(
req_id,
True,
payload={"destinationHash": presence_hex},
)
log(f"[presence_bridge] build={PRESENCE_BRIDGE_BUILD}")
except Exception as exc:
emit_resp(req_id, False, error=str(exc))
def handle_publish_presence(req_id: str, payload: Dict[str, Any]) -> None:
envelope = payload.get("envelope")
if not isinstance(envelope, dict):
emit_resp(req_id, False, error="Missing envelope")
return
if _destination is None:
emit_resp(req_id, False, error="Bridge not started")
return
try:
global _last_presence_wire, _rns_auth_announced, _last_no_verified_peers_announce_at
env_type = envelope.get("type") if isinstance(envelope.get("type"), str) else ""
if env_type == "PRESENCE_OFFLINE":
_rns_announce_on_auth_session_end()
elif env_type == "PRESENCE_ANNOUNCE":
if not _rns_auth_announced:
announce_local_destination("authenticated_initial")
_rns_auth_announced = True
_schedule_rns_periodic_announce_timer()
_last_no_verified_peers_announce_at = time.time()
elif env_type == "PRESENCE_HEARTBEAT":
if not _rns_auth_announced:
announce_local_destination("authenticated_recovered_heartbeat")
_rns_auth_announced = True
_schedule_rns_periodic_announce_timer()
_last_no_verified_peers_announce_at = time.time()
wire_bytes = make_presence_wire(envelope, _OVERLAY_DEFAULT_HOPS)
_last_presence_wire = wire_bytes
peer_hashes = _snapshot_established_overlay_neighbor_hashes()
local_hex = destination_hash_hex(_destination.hash)
env_type = envelope.get("type") if isinstance(envelope.get("type"), str) else ""
env_payload = envelope.get("payload")
env_addr = ""
if isinstance(env_payload, dict) and isinstance(env_payload.get("address"), str):
env_addr = str(env_payload.get("address"))
verbose_presence_log(
"[presence_bridge] target=presence-reticulum publish_fanout "
f"peers={len(peer_hashes)} local_presence_hash={local_hex} "
f"type={env_type} peer_addr={env_addr} "
f"fanout_hashes={','.join(peer_hashes)}"
)
sent_peer_hashes: list[str] = []
for peer_hash in peer_hashes:
if _send_wire_to_established_overlay_peer(
peer_hash,
wire_bytes,
"presence_publish",
):
sent_peer_hashes.append(peer_hash)
emit_resp(
req_id,
True,
payload={
"fanoutPeers": len(sent_peer_hashes),
"fanoutHashes": sent_peer_hashes,
"localPresenceHash": local_hex,
},
)
except Exception as exc:
emit_resp(req_id, False, error=str(exc))
def handle_forward_presence(req_id: str, payload: Dict[str, Any]) -> None:
envelope = payload.get("envelope")
if not isinstance(envelope, dict):
emit_resp(req_id, False, error="Missing envelope")
return
if _destination is None:
emit_resp(req_id, False, error="Bridge not started")
return
hops_remaining = payload.get("overlayHopsRemaining")
if not isinstance(hops_remaining, int) or hops_remaining < 0:
emit_resp(req_id, False, error="Missing overlayHopsRemaining")
return
exclude_raw = payload.get("excludeDestinationHashes")
exclude_hashes = (
[str(h).strip().lower() for h in exclude_raw if isinstance(h, str) and h.strip()]
if isinstance(exclude_raw, list)
else []
)
origin_sender_hash = payload.get("originalSenderHash")
if origin_sender_hash is not None and not isinstance(origin_sender_hash, str):
emit_resp(req_id, False, error="Invalid originalSenderHash")
return
try:
wire_bytes = make_presence_wire(
envelope,
hops_remaining,
origin_sender_hash=origin_sender_hash,
)
peer_hashes = _snapshot_established_overlay_neighbor_hashes(exclude_hashes)
sent_peer_hashes: list[str] = []
for peer_hash in peer_hashes:
if _send_wire_to_established_overlay_peer(
peer_hash,
wire_bytes,
"presence_forward",
):
sent_peer_hashes.append(peer_hash)
emit_resp(
req_id,
True,
payload={
"fanoutPeers": len(sent_peer_hashes),
"fanoutHashes": sent_peer_hashes,
},
)
except Exception as exc:
emit_resp(req_id, False, error=str(exc))
def handle_overlay_sync_state(req_id: str, payload: Dict[str, Any]) -> None:
verified_raw = payload.get("verifiedPeers")
active_raw = payload.get("activeNeighborHashes")
verified = verified_raw if isinstance(verified_raw, list) else []
active = active_raw if isinstance(active_raw, list) else []
_set_verified_overlay_peers(verified, [str(h) for h in active])
_sync_overlay_links()
_maybe_announce_local_destination_low_verified_overlay_peers()
emit_resp(req_id, True)
def handle_overlay_note_candidate_failure(req_id: str, payload: Dict[str, Any]) -> None:
peer_hash = str(payload.get("peerHash") or "").strip().lower()
reason = str(payload.get("reason") or "").strip() or "unknown"
if not peer_hash:
emit_resp(req_id, False, error="Missing peerHash")
return
_note_candidate_failure(peer_hash, reason)
emit_resp(req_id, True)
def handle_stop(req_id: str) -> None:
_rns_announce_on_auth_session_end()
emit_resp(req_id, True)
def _encode_group_signal_wire(msg: Dict[str, Any]) -> Dict[str, Any]:
out = _normalize_json_numbers(dict(msg))
out["r"] = destination_hash_hex(_destination.hash)
wire_bytes = _call_wire_json_bytes(out)
if len(wire_bytes) > _MAX_ENCRYPTED_WIRE_BYTES:
return {
"ok": False,
"payload": {
"code": "wire_too_large",
"wireBytes": len(wire_bytes),
"maxWireBytes": _MAX_ENCRYPTED_WIRE_BYTES,
"messageType": out.get("t"),
},
"error": (
f"Wire size {len(wire_bytes)} exceeds encrypted MDU "
f"{_MAX_ENCRYPTED_WIRE_BYTES}"
),
}
return {
"ok": True,
"wire_bytes": wire_bytes,
"message_type": out.get("t"),
}
def _prepare_group_signal_peer(peer_hash: str) -> Optional[Dict[str, Any]]:
peer_key = peer_hash.strip().lower()
if not peer_key:
return {
"payload": {"code": "unknown_peer_presence_hash"},
"error": "Unknown peer presence hash",
}
# Overlay fanout: best-effort recall for overlay links; do not reject with
# unknown_peer_presence_hash before attempting send (RNS may still lack identity).
ensure_known_peer_from_recall(peer_key, "ts_seed")
if peer_key not in _known_peers:
_nudge_overlay_path_for_peer(peer_key)
ensure_known_peer_from_recall(peer_key, "ts_seed")
if not _overlay_peer_is_admitted(peer_key):
_ensure_overlay_link(peer_key)
if peer_key not in _known_peers:
return {
"payload": {"code": "unknown_peer_presence_hash"},
"error": "Unknown peer presence hash",
}
return None
def _send_group_signal_wire_to_peer(peer_hash: str, wire_bytes: bytes) -> Optional[Dict[str, Any]]:
if not _send_wire_to_overlay_peer(
peer_hash,
wire_bytes,
"group_signal",
queue_if_pending=False,
):
_demote_overlay_fanout_peer(peer_hash, "group_signal_no_established_link")
return {
"payload": {"code": "packet_send_false"},
"error": "Packet send returned False",
}
return None
def _encode_call_signal_wire(msg: Dict[str, Any]) -> Dict[str, Any]:
out = _normalize_json_numbers(dict(msg))
out["r"] = destination_hash_hex(_destination.hash)
wire_bytes = _call_wire_json_bytes(out)
if len(wire_bytes) > _MAX_ENCRYPTED_WIRE_BYTES:
return {
"ok": False,
"payload": {
"code": "wire_too_large",
"wireBytes": len(wire_bytes),
"maxWireBytes": _MAX_ENCRYPTED_WIRE_BYTES,
"messageType": out.get("t"),
},
"error": (
f"Wire size {len(wire_bytes)} exceeds encrypted MDU "
f"{_MAX_ENCRYPTED_WIRE_BYTES}"
),
}
return {
"ok": True,
"wire_bytes": wire_bytes,
"message_type": out.get("t"),
}
def _prepare_call_signal_peer(peer_hash: str) -> Optional[Dict[str, Any]]:
peer_key = peer_hash.strip().lower()
if not peer_key:
return {
"payload": {"code": "unknown_peer_presence_hash"},
"error": "Unknown peer presence hash",
}
ensure_known_peer_from_recall(peer_key, "ts_seed")
if peer_key not in _known_peers:
_nudge_overlay_path_for_peer(peer_key)
ensure_known_peer_from_recall(peer_key, "ts_seed")
if not _overlay_peer_is_admitted(peer_key):
_ensure_overlay_link(peer_key)
if peer_key not in _known_peers:
return {
"payload": {"code": "unknown_peer_presence_hash"},
"error": "Unknown peer presence hash",
}
return None
def _send_call_signal_wire_to_peer(peer_hash: str, wire_bytes: bytes) -> Optional[Dict[str, Any]]:
if not _send_wire_to_overlay_peer(
peer_hash,
wire_bytes,
"call_signal",
queue_if_pending=False,
):
_demote_overlay_fanout_peer(peer_hash, "call_signal_no_established_link")
return {
"payload": {"code": "packet_send_false"},
"error": "Packet send returned False",
}
return None
def handle_send_call(req_id: str, payload: Dict[str, Any]) -> None:
peer_hash = str(payload.get("peerPresenceHash") or "")
msg = payload.get("message")
if not peer_hash or not isinstance(msg, dict):
emit_resp(req_id, False, error="Missing peerPresenceHash or message")
return
if _destination is None:
emit_resp(
req_id,
False,
payload={"code": "bridge_not_started"},
error="Bridge not started",
)
return
peer_key = peer_hash.strip().lower()
try:
encoded = _encode_call_signal_wire(msg)
if not encoded.get("ok"):
emit_resp(
req_id,
False,
payload=encoded.get("payload"),
error=str(encoded.get("error") or "Wire encoding failed"),
)
return
wire_bytes = encoded["wire_bytes"]
if len(wire_bytes) > 600:
log(f"[presence_bridge] warning call packet len={len(wire_bytes)}")
failure = _prepare_call_signal_peer(peer_key)
if failure is not None:
emit_resp(
req_id,
False,
payload=failure.get("payload"),
error=str(failure.get("error") or "Unknown peer presence hash"),
)
return
failure = _send_call_signal_wire_to_peer(peer_key, wire_bytes)
if failure is not None:
emit_resp(
req_id,
False,
payload=failure.get("payload"),
error=str(failure.get("error") or "Packet send returned False"),
)
return
emit_resp(req_id, True)
except Exception as exc:
emit_resp(req_id, False, error=str(exc))
def handle_accept_qchat_file_resource(req_id: str, payload: Dict[str, Any]) -> None:
peer_hash = str(payload.get("peerPresenceHash") or "").strip().lower()
pk_b64 = payload.get("reticulumIdentityPublicKeyBase64")
auth_message = payload.get("authMessage")
transfer_id = str(payload.get("transferId") or "").strip()
save_path = str(payload.get("savePath") or "").strip()
file_name = str(payload.get("fileName") or "").strip()
sha256 = str(payload.get("sha256") or "").strip().lower()
try:
size = int(payload.get("size") or 0)
except Exception:
size = 0
if not peer_hash or not transfer_id or not save_path:
emit_resp(req_id, False, error="Missing peerPresenceHash, transferId or savePath")
return
if size <= 0:
emit_resp(req_id, False, error="Missing or invalid file size")
return
if not isinstance(auth_message, dict):
emit_resp(req_id, False, error="Missing Reticulum link auth message")
return
try:
peer_identity = _parse_qchat_file_peer_identity(peer_hash, pk_b64)
except Exception as exc:
emit_resp(
req_id,
False,
payload={"code": "bad_reticulum_identity"},
error=str(exc),
)
return
with _state_lock:
_qchat_file_accepts_by_peer[peer_hash] = {
"transferId": transfer_id,
"savePath": save_path,
"fileName": file_name,
"size": size,
"sha256": sha256,
"peerIdentity": peer_identity,
"authMessage": auth_message,
"received_bytes": 0,
"active_chunks": {},
"completed_chunks": set(),
"chunk_lock": threading.RLock(),
"expires_at": time.time() + 15 * 60,
}
_qchat_file_emit(
"accepted",
{
"transferId": transfer_id,
"peerPresenceHash": peer_hash,
"fileName": file_name,
"size": size,
},
)
links_to_open = min(_QCHAT_FILE_PARALLEL_LINKS, max(1, _qchat_file_chunk_count(size)))
for _ in range(links_to_open):
state = {
"peerPresenceHash": peer_hash,
"peerDestinationHash": "",
"incoming": False,
"established": False,
"transferId": transfer_id,
"fileName": file_name,
"size": size,
"sha256": sha256,
"peerIdentity": peer_identity,
"authMessage": auth_message,
"created_at": time.time(),
}
_open_qchat_file_link_async(state)
emit_resp(req_id, True)
def handle_send_qchat_file_resource(req_id: str, payload: Dict[str, Any]) -> None:
transfer_id = str(payload.get("transferId") or "").strip()
allowed_recipient = str(payload.get("allowedRecipientAddress") or "").strip()
file_path = str(payload.get("filePath") or "").strip()
file_name = str(payload.get("fileName") or os.path.basename(file_path)).strip()
sha256 = str(payload.get("sha256") or "").strip().lower()
try:
expires_at_ms = float(payload.get("expiresAt") or 0)
except Exception:
expires_at_ms = 0
expires_at = expires_at_ms / 1000 if expires_at_ms > 0 else time.time() + 2 * 60 * 60
if not allowed_recipient or not transfer_id or not file_path:
emit_resp(req_id, False, error="Missing allowedRecipientAddress, transferId or filePath")
return
if not os.path.isfile(file_path):
emit_resp(req_id, False, error="File does not exist")
return
try:
size = os.path.getsize(file_path)
with _state_lock:
_qchat_file_pending_sends_by_transfer[transfer_id] = {
"allowedRecipientAddress": allowed_recipient,
"filePath": file_path,
"fileName": file_name,
"size": size,
"sha256": sha256,
"created_at": time.time(),
"expires_at": expires_at,
"next_chunk_index": 0,
"sent_bytes": 0,
"active_chunks": {},
"completed_chunks": set(),
}
_qchat_file_emit(
"registered",
{
"transferId": transfer_id,
"fileName": file_name,
"size": size,
},
)
emit_resp(req_id, True)
except Exception as exc:
emit_resp(req_id, False, error=str(exc))
def handle_authorize_qchat_file_resource(req_id: str, payload: Dict[str, Any]) -> None:
link_id = str(payload.get("linkId") or "").strip()
transfer_id = str(payload.get("transferId") or "").strip()
if not link_id or not transfer_id:
emit_resp(req_id, False, error="Missing linkId or transferId")
return
state = get_qchat_file_link_state(link_id)
if state is None:
emit_resp(req_id, False, payload={"code": "unknown_link_id"}, error="Unknown link id")
return
with _state_lock:
pending = _qchat_file_pending_sends_by_transfer.get(transfer_id)
if not pending:
emit_resp(req_id, False, payload={"code": "unknown_transfer_id"}, error="Unknown transfer id")
return
if float(pending.get("expires_at") or 0) < time.time():
emit_resp(req_id, False, payload={"code": "transfer_expired"}, error="Transfer expired")
return
state.update(
{
"filePath": pending.get("filePath") or "",
"fileName": pending.get("fileName") or "",
"size": int(pending.get("size") or 0),
"sha256": pending.get("sha256") or "",
"transferId": transfer_id,
"send_root": pending,
}
)
try:
link = state.get("link")
if link is not None:
_send_packet_on_link(
link,
json.dumps(
{
"type": "QCHAT_FILE_LINK_AUTH_RESULT",
"ok": True,
"transferId": transfer_id,
},
separators=(",", ":"),
).encode("utf-8"),
f"target=qchat-file-reticulum auth_result_ok transfer={transfer_id}",
)
_start_qchat_file_resource_for_state(state)
emit_resp(req_id, True)
except Exception as exc:
emit_resp(req_id, False, error=str(exc))
def handle_reject_qchat_file_resource(req_id: str, payload: Dict[str, Any]) -> None:
link_id = str(payload.get("linkId") or "").strip()
transfer_id = str(payload.get("transferId") or "").strip()
reason = str(payload.get("reason") or "sender_rejected_auth").strip()
state = get_qchat_file_link_state(link_id)
if state is None:
emit_resp(req_id, False, payload={"code": "unknown_link_id"}, error="Unknown link id")
return
link = state.get("link")
try:
if link is not None:
_send_packet_on_link(
link,
json.dumps(
{
"type": "QCHAT_FILE_LINK_AUTH_RESULT",
"ok": False,
"transferId": transfer_id,
"reason": reason,
},
separators=(",", ":"),
).encode("utf-8"),
f"target=qchat-file-reticulum auth_result_reject transfer={transfer_id}",
)
try:
link.teardown()
except Exception:
pass
emit_resp(req_id, True)
except Exception as exc:
emit_resp(req_id, False, error=str(exc))
def handle_fanout_call(req_id: str, payload: Dict[str, Any]) -> None:
messages = payload.get("messages")
if not isinstance(messages, list) or not messages or any(
not isinstance(msg, dict) for msg in messages
):
emit_resp(req_id, False, error="Missing messages")
return
if _destination is None:
emit_resp(
req_id,
False,
payload={"code": "bridge_not_started"},
error="Bridge not started",
)
return
exclude_raw = payload.get("excludePeerPresenceHashes")
exclude_hashes = (
[str(h).strip().lower() for h in exclude_raw if isinstance(h, str) and h.strip()]
if isinstance(exclude_raw, list)
else []
)
try:
encoded_frames = []
message_types = []
for msg in messages:
encoded = _encode_call_signal_wire(msg)
if not encoded.get("ok"):
emit_resp(
req_id,
False,
payload=encoded.get("payload"),
error=str(encoded.get("error") or "Wire encoding failed"),
)
return
wire_bytes = encoded["wire_bytes"]
if len(wire_bytes) > 600:
log(f"[presence_bridge] warning call packet len={len(wire_bytes)}")
encoded_frames.append(wire_bytes)
message_type = encoded.get("message_type")
message_types.append(message_type if isinstance(message_type, str) else "")
messages, encoded_frames, message_types, suppressed_relay_duplicates = (
_filter_new_call_relay_frames(
"call", messages, encoded_frames, message_types
)
)
if not encoded_frames:
emit_resp(
req_id,
True,
payload={
"fanoutPeers": 0,
"fanoutHashes": [],
"suppressedDuplicateRelay": suppressed_relay_duplicates,
},
)
return
peer_hashes = _snapshot_established_overlay_neighbor_hashes(exclude_hashes)
if not peer_hashes:
emit_resp(
req_id,
False,
payload={"code": "no_route"},
error="No overlay route",
)
return
log(
"[presence_bridge] target=call-signal-reticulum fanout "
f"peers={len(peer_hashes)} exclude_hashes={','.join(exclude_hashes)} "
f"fanout_hashes={','.join(peer_hashes)} "
f"message_types={','.join(t or '?' for t in message_types)} "
f"suppressed_duplicate_relay={suppressed_relay_duplicates}"
)
any_peer_full_delivery = False
last_failure_payload = {"code": "packet_send_false"}
last_failure_error = "Packet send returned False"
saw_failure = False
delivered_peer_hashes: list[str] = []
for peer_hash in peer_hashes:
peer_delivered_all_frames = True
for index, wire_bytes in enumerate(encoded_frames):
if not _send_wire_to_established_overlay_peer(
peer_hash,
wire_bytes,
"call_signal_fanout",
):
saw_failure = True
peer_delivered_all_frames = False
last_failure_payload = {"code": "packet_send_false"}
last_failure_error = "Packet send returned False"
message_type = (
message_types[index]
if index < len(message_types) and message_types[index]
else "?"
)
log(
"[presence_bridge] target=call-signal-reticulum fanout_send_failed "
f"peer_hash={peer_hash} "
f"reason={last_failure_payload.get('code', 'packet_send_false')} "
f"message_type={message_type} "
f"error={last_failure_error}"
)
if peer_delivered_all_frames:
any_peer_full_delivery = True
delivered_peer_hashes.append(peer_hash)
if any_peer_full_delivery:
emit_resp(
req_id,
True,
payload={
"fanoutPeers": len(delivered_peer_hashes),
"fanoutHashes": delivered_peer_hashes,
},
)
return
if saw_failure:
emit_resp(
req_id,
False,
payload=last_failure_payload,
error=last_failure_error,
)
return
emit_resp(
req_id,
False,
payload={"code": "packet_send_false"},
error="Overlay fanout had no successful delivery",
)
except Exception as exc:
emit_resp(req_id, False, error=str(exc))
def handle_send_group_call(req_id: str, payload: Dict[str, Any]) -> None:
peer_hash = str(payload.get("peerPresenceHash") or "")
msg = payload.get("message")
if not peer_hash or not isinstance(msg, dict):
emit_resp(req_id, False, error="Missing peerPresenceHash or message")
return
if _destination is None:
emit_resp(
req_id,
False,
payload={"code": "bridge_not_started"},
error="Bridge not started",
)
return
peer_key = peer_hash.strip().lower()
try:
encoded = _encode_group_signal_wire(msg)
if not encoded.get("ok"):
emit_resp(
req_id,
False,
payload=encoded.get("payload"),
error=str(encoded.get("error") or "Wire encoding failed"),
)
return
failure = _prepare_group_signal_peer(peer_key)
if failure is not None:
emit_resp(
req_id,
False,
payload=failure.get("payload"),
error=str(failure.get("error") or "Unknown peer presence hash"),
)
return
failure = _send_group_signal_wire_to_peer(
peer_key, encoded["wire_bytes"]
)
if failure is not None:
emit_resp(
req_id,
False,
payload=failure.get("payload"),
error=str(failure.get("error") or "Packet send returned False"),
)
return
emit_resp(req_id, True)
except Exception as exc:
emit_resp(req_id, False, error=str(exc))
def handle_fanout_group_call(req_id: str, payload: Dict[str, Any]) -> None:
messages = payload.get("messages")
if not isinstance(messages, list) or not messages or any(
not isinstance(msg, dict) for msg in messages
):
emit_resp(req_id, False, error="Missing messages")
return
if _destination is None:
emit_resp(
req_id,
False,
payload={"code": "bridge_not_started"},
error="Bridge not started",
)
return
exclude_raw = payload.get("excludePeerPresenceHashes")
exclude_hashes = (
[str(h).strip().lower() for h in exclude_raw if isinstance(h, str) and h.strip()]
if isinstance(exclude_raw, list)
else []
)
try:
encoded_frames = []
message_types = []
for msg in messages:
encoded = _encode_group_signal_wire(msg)
if not encoded.get("ok"):
emit_resp(
req_id,
False,
payload=encoded.get("payload"),
error=str(encoded.get("error") or "Wire encoding failed"),
)
return
encoded_frames.append(encoded["wire_bytes"])
message_type = encoded.get("message_type")
message_types.append(message_type if isinstance(message_type, str) else "")
messages, encoded_frames, message_types, suppressed_relay_duplicates = (
_filter_new_call_relay_frames(
"group", messages, encoded_frames, message_types
)
)
if not encoded_frames:
emit_resp(
req_id,
True,
payload={
"fanoutPeers": 0,
"fanoutHashes": [],
"suppressedDuplicateRelay": suppressed_relay_duplicates,
},
)
return
peer_hashes = _snapshot_established_overlay_neighbor_hashes(exclude_hashes)
if not peer_hashes:
emit_resp(
req_id,
False,
payload={"code": "no_route"},
error="No overlay route",
)
return
log(
"[presence_bridge] target=group-signal-reticulum fanout "
f"peers={len(peer_hashes)} exclude_hashes={','.join(exclude_hashes)} "
f"fanout_hashes={','.join(peer_hashes)} "
f"message_types={','.join(t or '?' for t in message_types)} "
f"suppressed_duplicate_relay={suppressed_relay_duplicates}"
)
any_peer_full_delivery = False
last_failure_payload = {"code": "packet_send_false"}
last_failure_error = "Packet send returned False"
saw_failure = False
delivered_peer_hashes: list[str] = []
for peer_hash in peer_hashes:
peer_delivered_all_frames = True
for index, wire_bytes in enumerate(encoded_frames):
if not _send_wire_to_established_overlay_peer(
peer_hash,
wire_bytes,
"group_signal_fanout",
):
saw_failure = True
peer_delivered_all_frames = False
last_failure_payload = {"code": "packet_send_false"}
last_failure_error = "Packet send returned False"
message_type = (
message_types[index]
if index < len(message_types) and message_types[index]
else "?"
)
log(
"[presence_bridge] target=group-signal-reticulum fanout_send_failed "
f"peer_hash={peer_hash} "
f"reason={last_failure_payload.get('code', 'packet_send_false')} "
f"message_type={message_type} "
f"error={last_failure_error}"
)
if peer_delivered_all_frames:
any_peer_full_delivery = True
delivered_peer_hashes.append(peer_hash)
if any_peer_full_delivery:
emit_resp(
req_id,
True,
payload={
"fanoutPeers": len(delivered_peer_hashes),
"fanoutHashes": delivered_peer_hashes,
},
)
return
if saw_failure:
emit_resp(
req_id,
False,
payload=last_failure_payload,
error=last_failure_error,
)
return
emit_resp(
req_id,
False,
payload={"code": "packet_send_false"},
error="Overlay fanout had no successful delivery",
)
except Exception as exc:
emit_resp(req_id, False, error=str(exc))
def handle_open_group_audio_link(req_id: str, payload: Dict[str, Any]) -> None:
peer_hash = str(payload.get("peerPresenceHash") or "")
if not peer_hash:
emit_resp(req_id, False, error="Missing peerPresenceHash")
return
if _destination is None:
emit_resp(
req_id,
False,
payload={"code": "bridge_not_started"},
error="Bridge not started",
)
return
ok, resp_payload, error = _open_group_audio_link_for_peer(
peer_hash.strip().lower(),
retry_reason="command",
)
emit_resp(req_id, ok, payload=resp_payload, error=error or None)
def handle_close_group_audio_link(req_id: str, payload: Dict[str, Any]) -> None:
link_id = str(payload.get("linkId") or "")
close_reason = str(payload.get("reason") or "local_close")
if not link_id:
emit_resp(req_id, False, error="Missing linkId")
return
state = get_audio_link_state(link_id)
if state is None:
emit_resp(
req_id,
False,
payload={"code": "unknown_link_id"},
error="Unknown audio link id",
)
return
peer_key = str(state.get("peerPresenceHash") or "").strip().lower()
with _state_lock:
is_current_outgoing = bool(
peer_key and _outgoing_audio_link_id_by_peer_hash.get(peer_key) == link_id
)
is_current_active = bool(
peer_key and _active_audio_link_id_by_peer_hash.get(peer_key) == link_id
)
is_duplicate_cleanup = (
close_reason.startswith("duplicate-")
or close_reason.startswith("superseded-")
or close_reason.startswith("open-result-")
)
if is_duplicate_cleanup and is_current_active:
emit_resp(req_id, True, payload={"suppressed": True, "reason": "canonical_link"})
log(
"[presence_bridge] target=reticulum-audio-link audio_link_close_suppressed "
f"peer={peer_key} link={link_id} reason={close_reason} active=true"
)
return
if is_current_outgoing:
_set_audio_link_desired(peer_key, False)
link = state.get("link")
try:
if link is not None:
try:
link.set_link_closed_callback(None)
except Exception:
pass
link.teardown()
emit_audio_link_closed(link_id, close_reason or "local_close")
emit_resp(req_id, True)
except Exception as exc:
emit_resp(req_id, False, error=str(exc))
def handle_reset_group_audio_peer_state(req_id: str, payload: Dict[str, Any]) -> None:
peer_key = str(payload.get("peerPresenceHash") or "").strip().lower()
if not peer_key:
emit_resp(req_id, False, error="Missing peerPresenceHash")
return
closed = 0
_set_audio_link_desired(peer_key, False)
with _state_lock:
links_to_close = [
(link_id, state.get("link"))
for link_id, state in list(_audio_links_by_id.items())
if str(state.get("peerPresenceHash") or "").strip().lower() == peer_key
]
for link_id, link in links_to_close:
try:
if link is not None:
try:
link.set_link_closed_callback(None)
except Exception:
pass
link.teardown()
except Exception:
pass
emit_audio_link_closed(link_id, "peer_state_reset")
closed += 1
with _state_lock:
_call_media_path_state.pop(peer_key, None)
_peer_lifecycle.pop(peer_key, None)
_mark_audio_queue_state_dirty()
emit_resp(req_id, True, payload={"closedLinks": closed})
def handle_get_local_identity_public_key(req_id: str, payload: Dict[str, Any]) -> None:
if _identity is None:
emit_resp(
req_id,
False,
payload={"code": "bridge_not_started"},
error="Bridge not started",
)
return
try:
pub = _identity.get_public_key()
if not isinstance(pub, bytes) or len(pub) != 64:
emit_resp(req_id, False, error="Unexpected identity public key length")
return
b64 = base64.b64encode(pub).decode("ascii")
emit_resp(req_id, True, payload={"publicKeyBase64": b64})
except Exception as exc:
emit_resp(req_id, False, error=str(exc))
def handle_register_peer_identity(req_id: str, payload: Dict[str, Any]) -> None:
peer_hash = str(payload.get("peerPresenceHash") or "").strip().lower()
pk_b64 = payload.get("reticulumIdentityPublicKeyBase64")
if not peer_hash or not isinstance(pk_b64, str) or not pk_b64.strip():
emit_resp(req_id, False, error="Missing peerPresenceHash or reticulumIdentityPublicKeyBase64")
return
if _destination is None:
emit_resp(
req_id,
False,
payload={"code": "bridge_not_started"},
error="Bridge not started",
)
return
local_hex = destination_hash_hex(_destination.hash)
if peer_hash == local_hex:
emit_resp(req_id, False, error="Cannot register self")
return
try:
s = pk_b64.strip()
pad = "=" * ((4 - len(s) % 4) % 4)
pub_bytes = base64.b64decode(s + pad, validate=True)
except Exception:
emit_resp(req_id, False, error="Invalid base64")
return
if len(pub_bytes) != 64:
emit_resp(req_id, False, error="Bad public key length")
return
try:
ident = RNS.Identity(create_keys=False)
ident.load_public_key(pub_bytes)
outbound = RNS.Destination(
ident,
RNS.Destination.OUT,
RNS.Destination.SINGLE,
APP_NAMESPACE,
PRESENCE_ASPECT,
PRESENCE_VERSION,
)
derived = destination_hash_hex(outbound.hash)
except Exception as exc:
emit_resp(req_id, False, error=str(exc))
return
if derived != peer_hash:
emit_resp(req_id, False, error="reticulum_public_key_hash_mismatch")
return
_register_peer(peer_hash, ident, "gcall_join")
emit_resp(req_id, True)
def handle_warm_group_audio_path(req_id: str, payload: Dict[str, Any]) -> None:
peer_hash = str(payload.get("peerPresenceHash") or "").strip().lower()
if not peer_hash:
emit_resp(req_id, False, error="Missing peerPresenceHash")
return
if _destination is None:
emit_resp(
req_id,
False,
payload={"code": "bridge_not_started"},
error="Bridge not started",
)
return
path_state, ready = _warm_call_media_path_if_possible(
peer_hash,
active_call=True,
allow_wait=True,
reason="explicit_warm",
)
emit_resp(
req_id,
True,
payload={
"pathState": path_state,
"ready": ready,
},
)
def handle_send_group_audio_link_heartbeat(req_id: str, payload: Dict[str, Any]) -> None:
room_id = str(payload.get("roomId") or "")
command = str(payload.get("command") or "")
if not room_id or command not in ("PING", "PONG"):
emit_resp(req_id, False, error="Missing roomId or invalid heartbeat command")
return
if _destination is None:
emit_resp(
req_id,
False,
payload={"code": "bridge_not_started"},
error="Bridge not started",
)
return
link_id = str(payload.get("linkId") or "").strip()
peer_key = str(payload.get("peerPresenceHash") or "").strip().lower()
state: Optional[Dict[str, Any]] = None
resolved_link_id = link_id
if resolved_link_id:
state = get_audio_link_state(resolved_link_id)
fallback_peer_key = str(
(state or {}).get("peerPresenceHash") or peer_key
).strip().lower()
if (
state is None
or state.get("established") is not True
or state.get("link") is None
):
fallback_id = _best_established_audio_link_id_for_peer(fallback_peer_key)
if fallback_id and fallback_id != resolved_link_id:
fallback_state = get_audio_link_state(fallback_id)
if fallback_state is not None:
state = fallback_state
resolved_link_id = fallback_id
if state is None:
code = "audio_link_not_ready" if fallback_peer_key else "unknown_link_id"
emit_resp(
req_id,
False,
payload={"code": code},
error=(
"Audio link not ready"
if code == "audio_link_not_ready"
else "Unknown audio link id"
),
)
return
else:
if not peer_key:
emit_resp(req_id, False, error="Missing linkId or peerPresenceHash")
return
candidate = _best_established_audio_link_id_for_peer(peer_key)
if not candidate:
with _state_lock:
candidate = (
_active_audio_link_id_by_peer_hash.get(peer_key)
or _outgoing_audio_link_id_by_peer_hash.get(peer_key)
)
if candidate:
state = get_audio_link_state(candidate)
resolved_link_id = candidate
if state is None:
with _state_lock:
candidates = list(_audio_links_by_id.items())
for candidate_link_id, candidate_state in candidates:
if str(candidate_state.get("peerPresenceHash") or "").strip().lower() == peer_key:
state = candidate_state
resolved_link_id = candidate_link_id
break
if state is None:
emit_resp(
req_id,
False,
payload={"code": "audio_link_not_ready"},
error="Audio link not ready",
)
return
link = state.get("link")
if state.get("established") is not True or link is None:
emit_resp(
req_id,
False,
payload={"code": "audio_link_not_ready"},
error="Audio link not ready",
)
return
wire: Dict[str, Any] = {
"t": _GROUP_AUDIO_HEARTBEAT_WIRE_TYPE,
"R": room_id,
"c": command,
"m": int(time.time() * 1000),
}
seq = payload.get("seq")
if isinstance(seq, int) and seq >= 0:
wire["p"] = seq
packet_rx_age_ms = payload.get("packetRxAgeMs")
if isinstance(packet_rx_age_ms, (int, float)):
wire["pa"] = max(-1, min(60000, int(packet_rx_age_ms)))
packet_rx_recent = payload.get("packetRxRecent")
if isinstance(packet_rx_recent, bool):
wire["pr"] = 1 if packet_rx_recent else 0
encoded = _encode_group_signal_wire(wire)
if not encoded.get("ok"):
emit_resp(
req_id,
False,
payload=encoded.get("payload"),
error=str(encoded.get("error") or "Wire encoding failed"),
)
return
try:
packet = RNS.Packet(link, encoded["wire_bytes"], create_receipt=False)
result = packet.send()
if result is False:
emit_resp(
req_id,
False,
payload={"code": "packet_send_false"},
error="Packet send returned False",
)
return
state["last_activity_at"] = time.time()
emit_resp(req_id, True, payload={"linkId": resolved_link_id})
except Exception as exc:
emit_resp(
req_id,
False,
payload={"code": "exception"},
error=str(exc),
)
def handle_command(message: Dict[str, Any]) -> None:
req_id = str(message.get("id") or "")
action = message.get("action")
payload = message.get("payload")
if not req_id:
emit_event(
"error",
{"code": "missing_id", "message": "Command frame missing id"},
)
return
if not isinstance(payload, dict):
payload = {}
if action == "start":
handle_start(req_id, payload)
elif action == "publish_presence":
handle_publish_presence(req_id, payload)
elif action == "forward_presence":
handle_forward_presence(req_id, payload)
elif action == "overlay_sync_state":
handle_overlay_sync_state(req_id, payload)
elif action == "overlay_note_candidate_failure":
handle_overlay_note_candidate_failure(req_id, payload)
elif action == "stop":
handle_stop(req_id)
elif action == "send_call":
handle_send_call(req_id, payload)
elif action == "accept_qchat_file_resource":
handle_accept_qchat_file_resource(req_id, payload)
elif action == "send_qchat_file_resource":
handle_send_qchat_file_resource(req_id, payload)
elif action == "authorize_qchat_file_resource":
handle_authorize_qchat_file_resource(req_id, payload)
elif action == "reject_qchat_file_resource":
handle_reject_qchat_file_resource(req_id, payload)
elif action == "fanout_call":
handle_fanout_call(req_id, payload)
elif action == "send_group_call":
handle_send_group_call(req_id, payload)
elif action == "fanout_group_call":
handle_fanout_group_call(req_id, payload)
elif action == "open_group_audio_link":
handle_open_group_audio_link(req_id, payload)
elif action == "close_group_audio_link":
handle_close_group_audio_link(req_id, payload)
elif action == "reset_group_audio_peer_state":
handle_reset_group_audio_peer_state(req_id, payload)
elif action == "warm_group_audio_path":
handle_warm_group_audio_path(req_id, payload)
elif action == "send_group_audio_link_heartbeat":
handle_send_group_audio_link_heartbeat(req_id, payload)
elif action == "clear_group_audio_diagnostics":
room_id = str(payload.get("roomId") or "")
cleared = _clear_audio_media_route_diagnostics(room_id)
emit_resp(
req_id,
True,
payload={
"clearedMediaRouteDiagnostics": cleared,
"roomId": room_id,
},
)
elif action == "get_group_audio_data_plane_session":
ok, session_payload, error = _ensure_audio_data_plane_server()
if ok:
emit_resp(req_id, True, payload=session_payload)
else:
emit_resp(req_id, False, payload={"code": "audio_data_plane_listen_failed"}, error=error)
elif action == "configure_group_audio_data_plane_routes":
route_count = _configure_audio_data_plane_routes(payload.get("routes"))
emit_resp(req_id, True, payload={"routeCount": route_count})
elif action == "get_local_identity_public_key":
handle_get_local_identity_public_key(req_id, payload)
elif action == "register_peer_identity":
handle_register_peer_identity(req_id, payload)
else:
emit_resp(req_id, False, error=f"Unknown action: {action}")
def stdin_loop() -> None:
for line in sys.stdin:
line = line.strip()
if not line:
continue
try:
message = json.loads(line)
except Exception as exc:
emit_event(
"error",
{"code": "invalid_json", "message": str(exc), "detail": line[:200]},
)
continue
if not isinstance(message, dict) or message.get("type") != "cmd":
emit_event(
"error",
{
"code": "invalid_frame",
"message": "Expected cmd frame",
"detail": str(message)[:200],
},
)
continue
_cmd_queue_bounded.put(message)
_notify_rns_work_available()
_cmd_queue_bounded.put(None)
_notify_rns_work_available()
def main() -> None:
parser = argparse.ArgumentParser(description="Qortal Hub Reticulum presence bridge")
parser.add_argument("--config", action="store", default=None, help="Reticulum config directory")
args = parser.parse_args()
if args.config:
os.environ["QORTAL_RETICULUM_CONFIG_DIR"] = args.config
ensure_started(args.config)
_shutdown.clear()
stdout_thread = threading.Thread(
target=_stdout_writer_loop, name="reticulum-json-out", daemon=False
)
stdout_thread.start()
_start_scheduler_workers()
audio_out_thread = threading.Thread(
target=_audio_binary_out_writer_loop, name="reticulum-audio-out", daemon=True
)
audio_out_thread.start()
audio_in_thread = threading.Thread(
target=_audio_fd3_reader_loop, name="reticulum-audio-in", daemon=True
)
audio_in_thread.start()
rns_thread = threading.Thread(
target=_rns_executor_loop, name="reticulum-rns", daemon=False
)
rns_thread.start()
stdin_thread = threading.Thread(target=stdin_loop, daemon=True)
stdin_thread.start()
stdin_thread.join()
_shutdown.set()
_cmd_queue_bounded.put(None)
_notify_rns_work_available()
rns_thread.join(timeout=60.0)
_stop_scheduler_workers()
try:
_json_resp_queue.put(None, timeout=0.1)
except queue.Full:
pass
try:
_json_event_queue.put_nowait(None)
except queue.Full:
pass
stdout_thread.join(timeout=10.0)
try:
_audio_binary_out_queue.put_nowait(None)
except queue.Full:
pass
audio_out_thread.join(timeout=5.0)
if __name__ == "__main__":
try:
main()
except KeyboardInterrupt:
pass
except Exception as exc:
sys.stdout.write(
json.dumps(
{
"type": "event",
"event": "error",
"payload": {
"code": "fatal",
"message": str(exc),
"detail": traceback.format_exc(limit=5),
},
},
separators=(",", ":"),
)
+ "\n"
)
sys.stdout.flush()