GopherTrunk v0.2.2 — social announcement drafts
Copy-paste drafts for posting the v0.2.2 release. Two versions below: a longer one for Reddit and a tighter one for Discord.
Release: https://github.com/MattCheramie/GopherTrunk/releases/tag/v0.2.2
Title: GopherTrunk v0.2.2 — USB-disconnect self-healing, P25 TDMA band-plan, ALGID/KID encryption surfaced
Body:
GopherTrunk v0.2.2 is out. GopherTrunk is a pure-Go digital-trunking
radio scanner for RTL-SDR / HackRF / Airspy / Airspy HF+ — P25 (Phase 1 +
2), DMR (with AMBE+2 voice), NXDN, Motorola Type II, EDACS, LTR, MPT 1327,
dPMR, D-STAR, YSF. No CGO, no librtlsdr / libhackrf / libairspy /
libusb at build or runtime, single ~10 MB static binary for Linux, macOS,
and Windows, with a headless daemon, a Bubbletea TUI cockpit, and a
browser-based web operator console.
This is the operational-recovery + Mt Anakie follow-up to v0.2.1. v0.2.1 finally made the Mt Anakie P25 capture decode end-to-end on the bench, but the live deployment surfaced two new failure modes: a NESDR dropping off the USB bus multiple times per day (silently stalling the decoder), and grants arriving on channel IDs the site never broadcasts an IDEN_UP for. Both are fixed now.
What’s new since v0.2.1:
- Full USB-disconnect self-healing (#345). The bulk-IN reaper-death
channel surfaces silent stalls through the ccdecoder retry loop (the
daemon used to go idle at 0% CPU, alive but inert, with frozen event
counters). Control SDRs reacquire by serial on disconnect — best-effort
close of the dead handle, driver re-enumerate, fresh
Open()by the new USB index, per-device hint (PPM / gain / bias-tee) re-applied,Deviceswapped in place in the pool entry,KindSDRDetached+KindSDRAttachedevents republished. Voice SDRs reacquire on grant-time tune failure. A new SDR-pool watchdog (sdr.watchdog_interval_ms, default 30 s, opt-out via-1) re-enumerates registered drivers periodically and re-binds the moment a previously-missing serial reappears, so the next consumer touches a live handle instead of paying the reacquire round-trip mid-use. All recovery is in-process — no daemon restart, no systemd / docker bounce. - P25 TDMA
IdentifierUpdate(TSBK opcode 0x33) wired into the dispatcher. v0.2.1 only wired the VUHF variant (0x34 — channel IDs 2 / 3 / 4 / 6 / 7 / 8 / 14 / 15); the Mt Anakie site survey confirmed it broadcasts IDEN_UP for id=10 only as the TDMA variant (0x33 — covers ids 0 / 1 / 5 / 9 / 11 / 12 / 13). Every Phase 2 grant on a TDMA id used to black-hole withdecode.error stage=no-bandplan. Mt Anakie id=10 + num=176 now resolves to 468.6125 MHz. - Per-channel-ID deferred-grant queue + config-driven band-plan seed.
Grants that reference a channel ID before the matching IDEN_UP lands
are now held in a bounded ring (cap 4 per ID, 5 s TTL) and re-published
against the freshly-applied slot when IDEN_UP arrives — covers the race
where IDEN_UP cadence is slower than the first grant after CC lock. A
new
p25_band_planlist onSystemConfig(channel_id/base_hz/spacing_hz/tx_offset_hz/bandwidth_hz) seeds the band plan at startup so sites that never broadcast IDEN_UP for a given ID can still resolve grants — over-the-air IDEN_UPs override seeded entries. - P25 ALGID / KID encryption metadata surfaced end-to-end (#353). P25
calls used to carry an opaque
enc=trueflag; operators triaging encrypted traffic had no way to tell DES-OFB from AES-256 from ADP without running SDRtrunk on the side. The voice composer now publishes acall.encryptionevent the instant the LDU2 Encryption Sync lands, and a new P25 algorithm-name registry renders0x84 (AES-256)/0x81 (DES-OFB)/0xAA (ADP/RC4)uniformly across the log line, the TUI active-call flag column, and both web panels’ pills + detail views. - Web operator-console polish. Empty WACN / SystemID / RFSS / Site
fields on the systems detail modal used to show a bare em-dash, leaving
operators unable to tell config mistakes from “not yet decoded”. The
scanner snapshot (
hunting/locked/ other) now drives per-field hint copy so the modal explains why those fields are empty. - Repo + docs cleanup. README trimmed from 2,826 → ~210 lines — the
long-form Status and Roadmap chapters moved into their own pages, and
the docs nav surfaces previously-orphan pages (launcher, live-edits,
DMR encryption, release process). Dockerfile bumps
golang:1.24→golang:1.25so builds stop silently downloading the newer toolchain at every run.
Downloads (Linux / macOS / Windows, x64 + ARM64): https://github.com/MattCheramie/GopherTrunk/releases/tag/v0.2.2
Project & docs: https://gophertrunk.org
Heads-up: the v0.x line is still flagged prerelease — actively developed, and feedback / captures / bug reports are very welcome.
Discord
GopherTrunk v0.2.2 is out
Pure-Go digital-trunking scanner for RTL-SDR / HackRF / Airspy — P25, DMR, NXDN, analog trunked, single static binary, zero CGO.
Operational-recovery + Mt Anakie follow-up to v0.2.1.
What’s new since v0.2.1:
- Full USB-disconnect self-healing (#345) — reaper-death surfaced to the decoder so the daemon no longer goes idle at 0% CPU on a silent stall; control + voice SDRs both reacquire by serial in-process (no daemon restart); new pool watchdog re-binds missing serials the moment they reappear.
- P25 TDMA IDEN_UP (opcode 0x33) wired — v0.2.1 only had the VUHF variant (0x34); Mt Anakie’s id=10 is TDMA-only and used to black-hole every grant. Now resolves to 468.6125 MHz.
- Deferred-grant queue + config band-plan seed — grants arriving
before the matching IDEN_UP are held in a bounded ring and re-published
on apply;
p25_band_planconfig list seeds the band plan at startup for sites that never broadcast some IDs. - ALGID / KID encryption metadata end-to-end (#353) — log lines, TUI,
and both web panels render
0x84 (AES-256)/0x81 (DES-OFB)/0xAA (ADP/RC4)uniformly the instant the LDU2 Encryption Sync lands. - Web systems detail modal explains empty WACN/SysID/RFSS/Site — per-field hint copy driven by the scanner hunt state instead of a bare em-dash.
- README trimmed 2,826 → ~210 lines; status + roadmap extracted to their own pages, orphan docs surfaced in the nav.
- Dockerfile bumped to
golang:1.25so builds stop downloading the newer toolchain at every run.
Download: https://github.com/MattCheramie/GopherTrunk/releases/tag/v0.2.2 Docs: https://gophertrunk.org