P25 conventional decode mode + conventional-channel attribution (node-26#24, #20)
op25-container
- generate-config takes p25_mode "conventional" + conv_channels [{frequency,
name, nac}]. It builds fixed fsk4 channels (up to 2 on one non-tunable SDR,
DC spike kept off the channels) with no control channel to hunt. Two
channels send audio to UDP 23456/23457, and audio.py -2 + amplify(2) keeps
levels.
- tk_drb_conv.py (a tk_p25.rx_ctl subclass, copied into OP25 apps) reports
voice / NAC / encryption (LC service options + LDU2 ESS algid/keyid) for
conventional channels and applies the per-channel NAC filter, which stock
tk_p25 does not. Analog uses it too.
- Trunked P25 config is unchanged when p25_mode is absent.
drb-edge-node
- radio_config: system kind from type + config.mode (missing = trunked).
- conventional.py normalizes the console: a distinctive LC TGID, else the
channel's last TGID (30 s), else a synthetic per-channel id (freq/100 Hz).
Encrypted rows are never talkers. With exactly one conventional channel,
orphan audio is attributed to it at close, which fixes analog recording
(#20). The synthetic id and the real TGID on one channel never split.
- Health/dashboard: P25 conventional listen tab (/api/listen p25conv), and
conventional decode + encryption checks. The checkin carries radio_channels.
- Tests: edge 296 pass; op25-container 18 (new CI job). Reviewed by
drb-audio-review (findings fixed; simultaneous two-channel mixdown filed
as #26) and drb-qa-review.
Not verified on SDR hardware.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 5.5
parent
1e1dab66b1
commit
d07d312e92
@@ -327,6 +327,11 @@ class MQTTManager:
|
||||
"secondary_sdr_priority": config.secondary_sdr_priority,
|
||||
}
|
||||
payload["sdr_pins"] = config.sdr_pins
|
||||
# Conventional channels (node-26#24): name/freq/NAC and whether the
|
||||
# agency encrypts them — the one decode failure nobody can fix on the
|
||||
# node, so C2 has to be told. Empty list on a trunked system.
|
||||
from app.internal.metadata_watcher import metadata_watcher
|
||||
payload["radio_channels"] = metadata_watcher.conventional_channels
|
||||
secondary = await secondary_sdr_client.status()
|
||||
# Unreachable secondary-sdr: say so with explicit nulls. C2 only
|
||||
# overwrites keys present in the checkin, so omitting them would leave
|
||||
|
||||
Reference in New Issue
Block a user