Also known as: OP25, OpenP25
OP25 (short for OpenP25) is an open-source decoder for APCO Project 25, the digital land-mobile radio standard used by many public-safety agencies.1 Built on GNU Radio with Python control logic, OP25 can follow a trunked system’s control channel, track channel grants, retune to voice channels, and decode P25 Phase 1 (and, in maintained forks, Phase 2) traffic — making it a full trunk-tracking scanner rather than a single-channel decoder.
How it works
At the front, OP25 uses a GNU Radio flowgraph to tune a front end, digitally down-convert the channel, demodulate the C4FM/CQPSK signal, and recover symbols. Above that sits a Python state machine that implements P25’s trunking protocol. On the control channel it parses the TSBK signalling messages that announce affiliations, system parameters, and — crucially — channel grants that map a talkgroup’s active call to a voice frequency.
When a grant appears for a talkgroup the operator is watching, OP25 commands the receiver to retune to that voice channel (or, on a wideband capture, selects the right sub-channel), decodes the P25 Phase 1 frames, corrects their FEC, and feeds the IMBE voice frames to a vocoder for audio. When the call ends it returns to the control channel to await the next grant. Maintained forks (the widely used boatbod branch among them) add Phase 2 two-slot TDMA decoding, multi-system scanning, logging, and a web interface. OP25 decodes only unencrypted traffic; encrypted calls are detected but not recovered.
Relevance to SDR
OP25 has long been the go-to open-source software for monitoring P25 systems on an SDR, especially where a hardware scanner is unavailable or too limited (for example, some Phase 2 systems). It demonstrates the complete trunk-tracking pattern — control-channel parsing, grant following, and voice decoding — on commodity hardware, and it is a common reference implementation people study to understand how P25 trunking behaves on the air.
GopherTrunk targets the same problem for P25 but is a wholly separate codebase written in pure Go rather than Python-on-GNU-Radio. Where OP25 assembles its DSP from GNU Radio blocks and orchestrates them in Python, GopherTrunk implements channelization, demodulation, symbol recovery, framing, and the trunking state machine directly in Go and ships as a single static binary. Functionally the two overlap heavily on P25 — both follow control channels and decode unencrypted voice — and GopherTrunk additionally spans other trunking families (DMR, NXDN, TETRA, and more). Neither can decode keyed encryption. OP25 is the established, GNU-Radio-based reference for P25; GopherTrunk is an independent multi-protocol scanner that covers P25 among its supported systems.
Sources
-
OP25 (boatbod fork) — a widely maintained OP25 repository documenting control-channel trunk tracking, Phase 1/Phase 2 decoding, and the GNU Radio DSP chain; background on the standard is in the Project 25 Wikipedia article. ↩