Files
dmrlink3/dmrlink-SAMPLE.cfg
Cort BuffingtonandClaude Opus 4.8 d727041259 reporting: normalize peer vocabulary + add Unix-socket transport (Step 5)
Mirrors the hblink3 Step 5 work for the IPSC side:

  * peer -> peer_connected / peer_disconnected (the message type now carries
    the lifecycle; the dashboard consumes the new names). dmrlink3 has no
    'stream' event -- its bridge_event/ping/bridge are IPSC-specific and are
    deliberately left as-is (see the hblink/dmrlink dashboard-parity note:
    IPSC ping is a firewall timer, not an app-level keepalive).

  * Unix-socket transport for a same-box dashboard: REPORT_TRANSPORT=unix binds
    start_unix_server on REPORT_SOCKET (stale socket file cleared first); the
    dashboard connects via open_unix_connection(DMRLINK_SOCKET) when
    DMRLINK_TRANSPORT=unix. TCP stays the default for remote dashboards. A local
    socket can't NIC-flap or be conntrack-evicted, retiring the silent-severance
    class for local dashboards (filesystem perms replace the IP ACL).

Both REPORT_TRANSPORT/REPORT_SOCKET and DMRLINK_TRANSPORT/DMRLINK_SOCKET are
optional (fallback to tcp), so existing configs keep working unchanged.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-12 12:19:02 -05:00

224 lines
8.0 KiB
INI

# DMRlink3 SAMPLE CONFIGURATION FILE
#
# Rename to dmrlink.cfg and fill in your values.
#
# DMRlink3 is a Python 3 / asyncio port of dmrlink for Motorola MOTOTRBO
# IPSC (IP Site Connect) network bridging and monitoring.
#
# GLOBAL CONFIGURATION ITEMS
#
# USE_ACL - Master ACL enable switch. True to enforce ACLs, False to pass all traffic.
# SUB_ACL - Global subscriber ID ACL; gates source IDs propagating through the bridge.
# Format: ACTION:entry[,entry...] (PERMIT or DENY; entries are single IDs,
# ranges like 3120000-3120999, or ALL). ACLs are cheap — see ACLS.md.
# PERMIT:list = allow only those; DENY:list = allow all but those.
#
[GLOBAL]
PATH: ./
USE_ACL: True
SUB_ACL: PERMIT:ALL
# NETWORK REPORTING CONFIGURATION
# REPORT_NETWORKS controls what happens each reporting interval:
#
# (empty) - No reporting
# PRINT - Pretty-print peer/master state to STDOUT (debugging only)
# NETWORK - Open a TCP listener and push NDJSON events to clients.
# The companion dashboard connects here.
#
# REPORT_RCM - Forward Repeater Call Monitor packets to reporting clients.
# Requires RCM: True and CON_APP: True on each IPSC system.
#
# REPORT_INTERVAL - Seconds between periodic config/bridge snapshots
# REPORT_TRANSPORT- 'tcp' (default) or 'unix'. Use 'unix' when the dashboard
# runs on the SAME host: it connects over a local Unix-domain
# socket that can't NIC-flap or be conntrack-evicted, so the
# silently-severed-link problem can't happen. 'tcp' for a
# remote dashboard.
# REPORT_PORT - TCP port when REPORT_TRANSPORT = tcp (REPORT_NETWORKS = NETWORK)
# REPORT_SOCKET - Filesystem path for the listening socket when
# REPORT_TRANSPORT = unix (e.g. /tmp/dmrlink3-report.sock).
# Filesystem permissions govern access; REPORT_CLIENTS is
# ignored on a Unix socket.
# REPORT_CLIENTS - Comma-separated list of client IPs allowed to connect,
# or * to allow any host (TCP only)
#
# PRINT_PEERS_INC_MODE - Include mode byte decode in PRINT output
# PRINT_PEERS_INC_FLAGS - Include flags byte decode in PRINT output
#
[REPORTS]
REPORT_NETWORKS: NETWORK
REPORT_RCM: False
REPORT_INTERVAL: 60
REPORT_TRANSPORT: tcp
REPORT_PORT: 4321
REPORT_SOCKET: /tmp/dmrlink3-report.sock
REPORT_CLIENTS: 127.0.0.1
PRINT_PEERS_INC_MODE: False
PRINT_PEERS_INC_FLAGS: False
# SYSTEM LOGGER CONFIGURATION
# LOG_FILE - Full path for file-based handlers; use /dev/null otherwise.
# LOG_HANDLERS - Comma-separated list (no spaces) of one or more:
# null console console-timed file file-timed syslog
# LOG_LEVEL - DEBUG, INFO, WARNING, ERROR, or CRITICAL
# LOG_NAME - Logger name shown in log output
#
[LOGGER]
LOG_FILE: /var/log/dmrlink3/dmrlink3.log
LOG_HANDLERS: console-timed
LOG_LEVEL: INFO
LOG_NAME: DMRlink3
# SUBSCRIBER / PEER / TGID ALIAS LOOKUPS
#
# *** IMPORTANT: The dashboard is the canonical owner of alias files. ***
# *** Set TRY_DOWNLOAD: False here and let the dashboard download, ***
# *** store, and refresh them. Loading subscriber_ids.json here costs ***
# *** 500+ MB of RSS per bridge process — avoid it if you can. ***
#
# If you still want callsigns in the bridge log, set PATH to your
# dashboard's directory (e.g. dashboard/) and leave TRY_DOWNLOAD: False —
# the dashboard keeps the files current and the bridge just reads them.
# STALE_DAYS is only relevant when TRY_DOWNLOAD: True.
#
# TRY_DOWNLOAD - Download alias files on startup (default: False)
# PATH - Directory where alias files live
# LOCAL_FILE - Additional local ID file (False = disabled)
# STALE_DAYS - Re-download after this many days (only if TRY_DOWNLOAD: True)
#
[ALIASES]
USE_ALIASES: False
TRY_DOWNLOAD: False
LOCAL_FILE: False
PATH: dashboard/
PEER_FILE: peer_ids.json
SUBSCRIBER_FILE: subscriber_ids.json
TGID_FILE: talkgroup_ids.json
PEER_URL: https://www.radioid.net/static/rptrs.json
SUBSCRIBER_URL: https://www.radioid.net/static/users.json
STALE_DAYS: 7
# IPSC NETWORK DEFINITIONS
#
# [SECTION_NAME] - Arbitrary name; used to identify the system throughout
# dmrlink3 and in bridge rule files. Must be unique.
#
# ENABLED - True to connect; False to skip without removing config
# RADIO_ID - DMR Radio ID dmrlink3 presents to this IPSC network
# IP - Local IP to bind (leave blank to bind all interfaces)
# PORT - Local UDP port (must be unique per system)
# ALIVE_TIMER - Seconds between keep-alive transmissions
# MAX_MISSED - Keep-alives missed before dropping master/peer connection
# PEER_OPER - Signal operational status to peers (True is correct)
# IPSC_MODE - DIGITAL, ANALOG, or NONE
# TS1_LINK - Is timeslot 1 linked?
# TS2_LINK - Is timeslot 2 linked?
# CSBK_CALL - Process CSBK packets (False; dmrlink3 cannot use them)
# RCM - Repeater Call Monitoring (requires CON_APP: True)
# CON_APP - Third-party console application flag (set True)
# XNL_CALL - XCMP/XNL processing (False; not supported)
# XNL_MASTER - XNL master flag (False)
# DATA_CALL - Accept data calls
# VOICE_CALL - Accept voice calls
# MASTER_PEER - True if dmrlink3 is the IPSC master for this network
# AUTH_ENABLED - Use HMAC-SHA1 packet authentication
# AUTH_KEY - Authentication key (up to 40 hex characters)
# MASTER_IP - IP of the IPSC master (ignored when MASTER_PEER: True)
# MASTER_PORT - UDP port of the IPSC master (ignored when MASTER_PEER: True)
# GROUP_HANGTIME - Group call hangtime in seconds
# REG_ACL - Peer registration ACL. Only enforced when MASTER_PEER: True
# (peers cannot control who registers on their master's system).
# Same format as SUB_ACL. Omit or set PERMIT:ALL to allow all.
[SAMPLE-PEER]
ENABLED: True
RADIO_ID: 12345
IP:
PORT: 50000
ALIVE_TIMER: 5
MAX_MISSED: 20
PEER_OPER: True
IPSC_MODE: DIGITAL
TS1_LINK: True
TS2_LINK: True
CSBK_CALL: False
RCM: True
CON_APP: True
XNL_CALL: False
XNL_MASTER: False
DATA_CALL: True
VOICE_CALL: True
MASTER_PEER: False
AUTH_ENABLED: True
AUTH_KEY: 1A2B3C
MASTER_IP: 1.2.3.4
MASTER_PORT: 50000
GROUP_HANGTIME: 5
# REG_ACL is ignored when MASTER_PEER: False — peers don't control registration
REG_ACL: PERMIT:ALL
# TRUNK SYSTEM DEFINITION (Trunk v2 — server-to-server)
#
# A TRUNK system is a direct bilateral UDP link between two DMRlink3 instances.
# It carries full IPSC GROUP_VOICE payloads but is NOT an IPSC network: no
# registration, keepalive, peer list, or timeslot restriction, and simultaneous
# voice streams pass without contention checking. It is the IPSC-side equivalent
# of OpenBridge. Authentication is by source IP + port only (no per-packet HMAC).
#
# SYSTEM_TYPE - Must be TRUNK to activate this code path
# RADIO_ID - DMR Radio ID dmrlink3 presents in forwarded packets
# IP - Local IP to bind (leave blank for all interfaces)
# PORT - Local UDP port to listen on (must be unique per system)
# PEER_IP - Remote trunk peer IP address
# PEER_PORT - Remote trunk peer UDP port
# GROUP_HANGTIME - Seconds before a silent stream is considered ended
#
# In bridge_rules.py, list TRUNK systems exactly like IPSC systems.
# They are automatically added to the TRUNKS contention-bypass list
# and their TGID ingress filter is built from the bridge rules at startup.
#
[SAMPLE-TRUNK]
ENABLED: False
SYSTEM_TYPE: TRUNK
RADIO_ID: 3129100
IP:
PORT: 50100
PEER_IP: 203.0.113.1
PEER_PORT: 50100
GROUP_HANGTIME: 5
[SAMPLE-MASTER]
ENABLED: False
RADIO_ID: 54321
IP: 192.168.1.1
PORT: 50001
ALIVE_TIMER: 5
MAX_MISSED: 20
PEER_OPER: True
IPSC_MODE: DIGITAL
TS1_LINK: True
TS2_LINK: True
CSBK_CALL: False
RCM: True
CON_APP: True
XNL_CALL: False
XNL_MASTER: False
DATA_CALL: True
VOICE_CALL: True
MASTER_PEER: True
AUTH_ENABLED: True
AUTH_KEY: 1A2B3C
# MASTER_IP and MASTER_PORT are ignored when MASTER_PEER is True
GROUP_HANGTIME: 5
REG_ACL: PERMIT:ALL