P25 conventional is unsupported — "P25" always means trunked, so White Plains PD (Toughny) can never decode #24
Closed
opened 2026-10-04 15:28:06 -04:00 by logan
·
3 comments
No Branch/Tag Specified
main
feat/45-trunk-recorder
fix/44-upload-spool
feat/41-disk-reporting
fix/41-updater-prune
fix/discord-voice-join
fix/updater-safe-directory
fix/28-amd64-images
fix/18-install-token-argv
fix/19-image-tag-skew
feat/discord-system
feat/24-p25-conventional
feat/local-ui-usable
fix/14-15-provision-ota
feat/sdr-pins
feat/secondary-sdr-priority
feat/second-sdr-adsb-ais
feat/publish-public-images
fix/install-rerun-pickup
pulse-recorder
v1.1.0
v1
Labels
Clear labels
area/ai-pipeline
area/auth
area/billing
area/correlation
area/discord
area/frontend
area/governance
area/growth
area/infra-deploy
area/legal
area/map
area/mqtt
area/node-ota
area/osint
area/recording-audio
area/sdr-radio
area/transcription
board
board:agenda
Scene/entity extraction, summarizer, AI providers, embeddings
AuthN/Z, roles, tenancy/org scoping, API keys, credentials
Plans, entitlements, AI spend accounting and caps
Incident correlation, linking, lifecycle, severity, corr_debug
Discord bot, radio bots, voice streams, bot tokens, webhooks
Web UI: Next.js app and the edge-node local dashboard
Board process, minutes, unattended runner, agent tooling
Go-to-market, outreach, cold email, discovery conversations
CI/CD, VM, registry, Firestore rules/indexes deploy, Terraform/Caddy
ToS, retention, licences/DAAs, CAN-SPAM, E&O, name suppression
Live map: pins, paths, tiles, legend, geocoding
Node-C2 MQTT, checkins, commands, node sweeper, dynsec
Node install, enrollment, OTA updater, image skew
External feeds: cameras, 511, ADS-B, AIS, outages, and their licences
Call capture, boundaries, PulseAudio, ring buffer, trimming, attribution
OP25 decode, SDR hardware/tuning, conventional, second SDR, mesh radio
STT, transcript correction, place verification, name accuracy
Board process: minutes and board-filed items
Needs board scoping at the next sitting; CEO removes the label once scoped
kind
behavior-bug
Wrong product behavior; the instrument reads it correctly
kind
measurement-bug
Corrupts the recording/instrument (debug data, evals, health checks), not behavior
priority
p0
Drop everything: prod broken, live exposure, or owner-ruled P0
priority
p1
Next up: blocks a gate, a customer, or core incident quality
priority
p2
Normal: real defect or planned work, schedule in turn
priority
p3
Low: minor, cosmetic, or someday
status
blocked
Waiting on an external party, spend, or another issue
status
in-progress
Branch or PR open against it
status
needs-decision
Waiting on an owner or board ruling before work
status
needs-info
Root cause or repro unknown; needs a reading first
type
bug
Something built is wrong: code, data, or a measurement
type
chore
Maintenance, refactor, tests, pinning, cleanup: no user-visible change
type
decision
A ruling to make or record: board minutes, owner calls, legal reviews
type
docs
Docs, runbooks, CLAUDE.md, skills, SOPs
type
feature
New capability or an extension of an existing one
type
security
Security, privacy, credential or tenant-isolation exposure
type
tracking
Tracker, checklist, initiative or punch-list spanning several changes
Milestone
No items
No Milestone
Projects
Clear projects
No projects
Notifications
Due Date
No due date set.
Dependencies
No dependencies set.
Reference: logan/node-26#24
Reference in New Issue
Block a user
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.
Found 2026-10-04 diagnosing why Toughny (online, approved, updater checking in) has never recorded a call.
Cause: the "White Plains" system (server, id 84db8d52…) is
type: P25with control channels460.4, 460.425. Per RadioReference (forum thread Feb 2021 + Westchester County DB), White Plains PD is P25 conventional: 460.400 = PD1 dispatch, 460.425 = PD3 tac. There is no trunking control channel.op25_controller.py(P25 branch, ~L181-204) always builds atk_p25.pytrunking config withcontrol_channel_list= those frequencies anddemod_type=cqpsk, so OP25 hunts forever for TSBK control data that never comes.Needed: a
P25 conventionaldecode mode — fixed frequency, no trunking section, C4FM (fsk4) demod, optional NAC; and a way to cover two channels (460.400 / 460.425 are 25 kHz apart, one SDR can carry both as two OP25 channels). Attribution: P25 conventional voice carries a TGID in LDU1 link control, so calls may be attributable — verify what OP25's terminal reports for conventional, becausemetadata_watcherdrops any call with no talkgroup (see #20, same failure family for analog).Server side: system editor needs a conventional option so admins don't enter voice frequencies as control channels; ideally warn when a P25 "control channel" is in a band/list that RadioReference marks conventional.
Unverified: whether WPPD encrypts (would make this moot); RadioReference wiki snippet also mentions White Plains PD on Westchester County P25 TG 28 — check whether that's current. Interim option: point Toughny at the Westchester County PD (trunked) system, which works on RPI-Node-01.
PRs open, not merged:
Simultaneous traffic on two channels is filed as #26.
White Plains editor values after deploy
Leave NAC blank until the node's dashboard shows the NAC it actually hears. Toughny's Decoding check will show either "NAC 0x…" or "Encrypted — AES-256 …".
Unverified on hardware.
Post-merge check (2026-10-04): GO to roll to nodes. No code fix was needed, so there's no PR.
/healthgit_sha). c2-core 525 pass.80a0e88: edge-node 287 pass, 9 skipped (host-updater tests needflock, which macOS doesn't have). flake8 is clean. op25-container 18 pass.op25-client:80a0e88=:stableandedge-node:80a0e88=:latest, both built 17:22.v1already points at80a0e88, so a node picks this up on its next "Update Node" request. drb-update.sh fetches--force --tags, checks outrefs/tags/v1, pulls:stable/:latestand force-recreates.system_config.normalize, then the MQTT push, thenradio_config.build_generate_payload, thenconventional_config(it matches upstreamp25_conventional_example.json, and audio.py -2 binds 23456/23457), then tk_drb_conv, thenconventional.normalize/attribution, then upload, where the synthetic tgid resolves to the channel name on C2.tk_p25.pywith simulated frames. The NAC filter is applied, tgid/voice/NAC/encryption are reported, there's one call_log entry per call, and encrypted calls are skipped. The image's OP25 clone is unpinned, which I filed as #29.#26 does not block the rollout. Trunked and single-channel nodes are unaffected. For White Plains, start Toughny on PD1 Dispatch only. With one channel, every sound is attributed (sole-channel rule) and #26 can't happen. Add PD3 Tac once #26 is fixed or overlap has been measured on the hardware.
Still unverified: real decode on hardware, and whether WPPD encrypts. The node's Decoding check will answer the encryption question.
Shipped in PR #27 (merge
80a0e88) and rolled out to the nodes on v1. Follow-ups are tracked in #26 (two conventional channels share one stream) and #33 (a wrong NAC silently records nothing).