Files
dmr-talkback/talkback.toml.sample
Cort BuffingtonandClaude Opus 5 600a0677a8 Docs: talkback joins an existing HBlink3 system, it is not one
The 'Connecting it' instructions said to add a MODE: SERVER system for
each instance to log into. That was wrong: HBlink3 systems already exist
and the talkback connects to one as another client, alongside that
system's repeaters. You do not create systems for talkback -- except in
the deliberate case of a dedicated one that other systems bridge to.

Also documents why no bridge is needed for the direct case: a Server
with REPEAT: True forwards every stream to its connected clients except
the source (hblink.py:467), which both delivers traffic to the talkback
and keeps its replay from looping back in. And what the joined system's
ACLs must permit (REG_ACL, SUB_ACL for the replay source, and the TGID
ACL for the slot talkgroups).

README, sample config, and spec sections 1 and 12.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-15 16:18:30 -05:00

120 lines
5.3 KiB
Plaintext

# talkback.toml — configuration for dmr-talkback
#
# Copy this file to talkback.toml (or /etc/talkback/talkback.toml) and edit for
# your deployment. The live config is gitignored — it holds your passphrases.
[global]
# Logging verbosity: "DEBUG" | "INFO" | "WARNING" | "ERROR"
# DEBUG logs every gate decision and is noisy. INFO gives you one line each
# for capture start, capture end, replay start, and replay end, per slot.
log_level = "INFO"
# ---------------------------------------------------------------------------
# Instances
# ---------------------------------------------------------------------------
#
# Each [instance.<name>] is one connection to one server, with its own radio
# ID and its own talkgroups. The name is yours — it labels the log lines.
#
# WHY MORE THAN ONE:
#
# An HBlink3 server hosts several independent "systems". Normally, giving all
# of them a talkback means building a bridge that multiplexes every system into
# one talkback engine — bridge rules to write, and one shared talkback that all
# systems contend for.
#
# Instead, run one instance per system. Each instance logs into an EXISTING
# system, as one more client alongside that system's repeaters — you do not
# create systems for talkback. A Server with REPEAT: True (the normal setting)
# repeats traffic among its clients, so that alone is the whole integration.
# Each system gets its own private talkback on its own TGID, no bridge required,
# and no system can tie up another's.
#
# Bridging everyone into a single instance is still perfectly valid if that is
# what you want — one talkback heard across several systems. Both work; pick
# the one that matches how you want it to behave.
#
# WHAT NOT TO DO: do not point one process at several *different* HBlink3
# servers. Instances are independent, so it would function, but you have then
# made one process a single point of failure for several servers, and the logs
# of unrelated networks end up interleaved. Run a process per server.
#
# HBLINK4: HBlink4 has no "system" concept — the server is the unit. One
# instance per HBlink4 server is the only arrangement that makes sense.
[instance.lawrence]
# The radio ID. This is the HBP login ID and the source radio ID of every
# stream this instance transmits.
#
# NOTHING ROUTES TO IT. Talkback answers group calls only, so this ID is never
# a destination and never enters unit-call routing. It therefore does NOT need
# to be a globally unique registered ID per instance — one ID you already own
# can serve every instance you run, including instances on different systems of
# the same HBlink3 server. Give instances distinct IDs only if you want them to
# show up separately in last-heard.
#
# The one hard rule is per LISTENING SOCKET, not per host: two instances that
# connect to the same ip:port must not share an ID. That is a registration
# constraint — an HBP server keys registered repeaters by radio ID and validates
# the source address per packet, so two connections with one ID to one socket
# fight over the same entry. Each HBlink3 system has its own port, so this only
# bites if you aim two instances at the same system. Rejected at startup.
radio_id = 3120099
# The talkgroup this instance answers, per timeslot. Omit or set 0 to leave a
# slot unused.
#
# ONE TALKGROUP PER SLOT, deliberately. A DMR timeslot carries one call at a
# time, so a list of talkgroups on one slot would advertise capacity that does
# not exist. Two slots means exactly two callers can be served at once, and
# the config says so plainly.
#
# The two slots are fully independent: a caller on TS1 and a caller on TS2 are
# recorded and played back at the same time without interfering.
slot1_tgid = 0
slot2_tgid = 9990
# What this instance connects to: the IP, PORT and PASSPHRASE of an EXISTING
# HBlink3 system, or of an HBlink4 server. Keep it on loopback where that runs
# on the same box — then the passphrase never touches the network.
#
# On HBlink3, also confirm that system's ACLs let the talkback in: REG_ACL for
# registration, SUB_ACL for the radio ID above (it is the source of every
# replay), and the TGID ACL for the slot talkgroups below.
master_ip = "127.0.0.1"
master_port = 54000
passphrase = "s3cr37w0rd"
# How long to wait after the caller unkeys before replaying, in milliseconds.
# Two seconds is long enough that the caller has certainly let go of the PTT.
replay_delay_ms = 2000
# Longest call this instance will record, in seconds. Sizes the capture buffer
# for each active slot at startup (one 55-byte packet per 60 ms), and is a hard
# ceiling: a longer transmission is replayed up to this point, not discarded.
max_capture_secs = 30
# Cosmetic. There is no radio behind this connection; these fill the 302-byte
# RPTC config blob the protocol requires, and they are what dashboards display.
# Frequencies, power, and location are fixed at inert values in the code.
callsign = "TALKBACK"
description = "Voice Test"
location = ""
url = ""
colorcode = "01"
# A second system on the same HBlink3 server, with its own talkback TGID.
# Same radio ID would collide here (same server), so this one differs.
#
# [instance.topeka]
# radio_id = 3120098
# slot2_tgid = 9991
# master_ip = "127.0.0.1"
# master_port = 54010
# passphrase = "s3cr37w0rd"
# callsign = "TALKBACK"
# description = "Voice Test"