P25 End to End is a 14-part deep dive into the GopherTrunk P25 stack — the protocol GopherTrunk locks more often than any other, followed from a raw 4800-symbol-per-second C4FM carrier all the way to recorded, named, multi-site-tracked voice. Where Protocol Decoders surveyed P25 across three episodes, this series walks every layer at full depth: frame sync and the NID, TSBKs and the trellis, Multi-Block Trunking (the PDU that used to be dropped as noise), channel identifiers and band plans, the CQPSK/LSM linear path, Phase 2 TDMA, IMBE voice, encryption signalling and policy, sites and roaming, and the wideband engine that watches a whole system at once.
The running thread is that P25 in GopherTrunk is a family of twin paths — Phase 1 and Phase 2, C4FM and CQPSK, single-channel and wideband, live and replay — and every twin pair is a place where a fix can land on one side and silently miss the other, the lesson the Two Pipelines postmortem taught the hard way. The series ends honestly: Part 12 is about the weak-signal gap in the Phase 1 C4FM voice path and the capture contributions that would close it.
Every post reads three ways: a TL;DR + cheat-sheet for skimmers, bold headers, tables, and diagrams for the medium read, and full prose with real code for the deep read.
New here? Start with the Digital Trunking module for how a trunked system is laid out, then come back for the P25 specifics.<ol class="post-list series-list"><li class="post-card"> <h2 class="post-card__title">P25 End to End, Part 1: C4FM & the Shape of a P25 Carrier</h2> <p class="post-card__meta"> Deep dives </p><p class="post-card__desc">What a P25 Phase 1 carrier actually is — 4800 symbols per second of four-level FSK in a 12.5 kHz channel, dibits riding on ±600 and ±1800 Hz deviations, and the FM-discriminator → matched-filter → slicer chain GopherTrunk sizes around a 48 kHz channel rate.</p></li><li class="post-card"> <h2 class="post-card__title">P25 End to End, Part 2: Frame Sync, the NID & What ‘Locked’ Means</h2> <p class="post-card__meta"> Deep dives </p><p class="post-card__desc">How GopherTrunk turns a raw P25 dibit stream into frames — the 48-bit frame sync word, the BCH(63,16)-protected NID carrying NAC and DUID, the status symbols hiding every 36th dibit, and the tiered alignment search that decides when a control channel is really locked.</p></li><li class="post-card"> <h2 class="post-card__title">P25 End to End, Part 3: TSBKs — The Control Channel’s Workhorse</h2> <p class="post-card__meta"> Deep dives </p><p class="post-card__desc">Inside the P25 Trunking Signaling Block — 12 bytes through a 1/2-rate trellis and interleaver into 98 channel dibits, the CRC variant many references get wrong, the opcode families that run a trunked system, and the SCCB byte-offset bug a round-trip test blessed.</p></li><li class="post-card"> <h2 class="post-card__title">P25 End to End, Part 4: Multi-Block Trunking — The PDU That Isn’t Noise</h2> <p class="post-card__meta"> Deep dives </p><p class="post-card__desc">Why a PDU on a P25 control channel is Multi-Block Trunking, not garbage — the AMBT header and data blocks with their two different CRCs, the neighbour sites and WACN that only arrive this way, and why a “MBT data CRC failed” line next to a clean decode is two frames, not a contradiction.</p></li><li class="post-card"> <h2 class="post-card__title">P25 End to End, Part 5: Channel Identifiers & Band Plans — From Channel Number to Hertz</h2> <p class="post-card__meta"> Deep dives </p><p class="post-card__desc">How a P25 grant’s 16-bit channel field becomes a frequency — the IDEN_UP band-plan broadcasts in their 0x3D, 0x34 and 0x33 dialects, the base-plus-spacing arithmetic in BandPlan.Frequency, and what happens when a grant arrives before the table that decodes it.</p></li><li class="post-card"> <h2 class="post-card__title">P25 End to End, Part 6: CQPSK & LSM — The Linear Twin Path</h2> <p class="post-card__meta"> Deep dives </p><p class="post-card__desc">P25 Phase 1’s second physical layer — the opt-in CQPSK/LSM demodulator GopherTrunk runs when an FM discriminator produces near-random dibits, its T/2 fractionally-spaced CMA equalizer and carrier-recovery chain, and the hard rule that simulcast does not imply LSM.</p></li><li class="post-card"> <h2 class="post-card__title">P25 End to End, Part 7: Phase 2 TDMA — Two Voices per Carrier</h2> <p class="post-card__meta"> Deep dives </p><p class="post-card__desc">How P25 Phase 2 fits two voice calls in one 12.5 kHz channel — H-DQPSK at 6000 symbols per second, the 360 ms superframe and ISCH slot typing, MAC PDUs in place of TSBKs, and the FEC hand-off that silently defaulted to zero on one pipeline.</p></li><li class="post-card"> <h2 class="post-card__title">P25 End to End, Part 8: IMBE Voice — From LDU to WAV</h2> <p class="post-card__meta"> Deep dives </p><p class="post-card__desc">How P25 Phase 1 voice travels — the 1728-bit LDU carrying nine IMBE frames woven between link-control words, the Golay and Hamming FEC that turns 144 channel bits into 88, and the composer chain in GopherTrunk that gates, decodes and records a call.</p></li><li class="post-card"> <h2 class="post-card__title">P25 End to End, Part 9: Encryption Signalling — Flags, Metadata & Policy</h2> <p class="post-card__meta"> Deep dives </p><p class="post-card__desc">Where a P25 call’s encryption actually lives on the air — the grant’s protected bit, the LDU2 Encryption Sync carrying the Message Indicator, Algorithm ID and Key ID, and Phase 2’s MAC_PTT — and how GopherTrunk turns those signals into per-system tuner and recording policy.</p></li><li class="post-card"> <h2 class="post-card__title">P25 End to End, Part 10: Sites, WACNs & Roaming a Multi-Site System</h2> <p class="post-card__meta"> Deep dives </p><p class="post-card__desc">The P25 identity ladder — a 20-bit WACN, 12-bit System ID, RFSS and Site — and the status broadcasts that carry it in TSBK and multi-block AMBT forms. How GopherTrunk votes a system’s identity out of noisy frames, accumulates a neighbour map, and roams by hunting control channels.</p></li><li class="post-card"> <h2 class="post-card__title">P25 End to End, Part 11: Wideband P25 — Watching the Whole System at Once</h2> <p class="post-card__meta"> Deep dives </p><p class="post-card__desc">One wide capture, many control channels — the tuner-bank architecture behind role wideband, per-call voice taps carved from the same IQ stream, and the twin down-converter paths (the wideband DDCBank vs the single-channel Downconverter) whose drift let the fix for issue 764 miss the replay symptom in issue 771.</p></li><li class="post-card"> <h2 class="post-card__title">P25 End to End, Part 12: The Weak-Signal Gap — P1 Voice’s Missing Levers</h2> <p class="post-card__meta"> Deep dives </p><p class="post-card__desc">Why P25 Phase 1 C4FM voice is GopherTrunk’s least-equipped decode path — an FM-discriminator chain with no channel equalizer and hard-decision IMBE FEC, a measured ~24 dB gap to the coherent reference, and the weak-signal voice capture that gates the fix.</p></li><li class="post-card"> <h2 class="post-card__title">P25 End to End, Part 13: Testing P25 Without a Tower</h2> <p class="post-card__meta"> Deep dives </p><p class="post-card__desc">How GopherTrunk tests a P25 decoder with no transmitter in reach — literal byte vectors that catch what round-trips cannot, impairment-swept synthetic carriers with a hard CI loss budget, committed real-air capture fixtures, and rate-invariance tests that prove where a bug is not.</p></li></ol><p class="blog-feed-link"> See all deep dives or subscribe via RSS. </p>