Field Guide · term

Also known as: status symbol, status dibit, interstitial symbol

A P25 status symbol is an interstitial dibit that the transmitter weaves into the C4FM symbol stream at a fixed cadence — one 2-bit symbol after every 70 payload bits — carrying inbound/outbound channel-busy signalling for the trunking layer.1 Because these symbols sit between the frame’s real bits rather than in a dedicated field, a P25 Phase 1 deframer must account for and remove them before it can read the NID, voice, or Link Control that they interrupt.

70 payload bits st 70 payload bits st 70 payload bits stride = 72 bits · strip the "st" dibits → contiguous 1680-bit payload · repeat ×24 per LDU
Every 70 payload bits are followed by one 2-bit status symbol; the deframer copies the 70-bit runs and drops the interleaved dibits, turning a 1728-bit on-air LDU into a 1680-bit payload plus 24 status symbols.

How it works

The status symbol exists because a subscriber unit needs to know, in near-real-time, whether the channel it is transmitting on is clear — the busy/idle signalling that keeps a trunked system from colliding. Rather than spend a whole frame field on it, P25 spreads a stream of 2-bit status symbols evenly through every data unit at a guaranteed cadence, so a radio always has a fresh status reading no matter where in a frame it happens to be listening. The two bits encode states such as “inbound channel busy”, “unknown/idle”, and “outbound activity”, read by the trunking controller and subscriber, not by the payload decoder.

The cadence is the load-bearing constant: one status symbol after every 70 payload bits. In a full LDU that repeats 24 times, so the 1728-bit on-air frame is 24 runs of 70 payload + 2 status = 72 bits. A decoder reverses the interleave with a fixed stride: copy 70 bits, skip 2, repeat 24 times, yielding the 1680-bit payload the rest of the pipeline expects. GopherTrunk’s StripStatusSymbols does exactly this, and StatusSymbols pulls the 24 skipped dibits out separately for anyone who wants the trunking-layer signalling.

In practice

The status interval is defined against payload position, not against the frame sync or the symbol clock, so a decoder that miscounts — off by even one dibit — will slice every field after the first status symbol out of the wrong bits. This is why the strip pass runs on a whole, already-synchronised 1728-bit unit: the frame sync word and NID at the very start are inside the first 70-bit run and read normally, but voice subframe boundaries, LC/ES blocks, and Low-Speed Data all live past several status insertions and depend on the count being exact.

The symbols also complicate sync itself. Because they are physically present in the demodulated dibit stream, the raw symbol positions do not map one-to-one onto frame bits, and a status-symbol phase fault shows up as bit errors clustered near a frame’s tail — one of the signatures GopherTrunk’s closest-miss diagnostics use to tell a status miscount apart from plain SNR-limited corruption.

Relevance to SDR

internal/radio/p25/phase1/ldu.go holds the canonical constants — LDUStatusInterval = 70, LDUStatusSymbolCount = 24, LDUStatusSymbolBits = 48 — and a compile-time assertion that 48 (FS) + 64 (NID) + 9·144 (voice) + 240 (LC/ES) + 32 (LSD) + 48 (status) = 1728, so a field that silently grows or shrinks fails to build. StripStatusSymbols produces the payload every downstream extractor consumes, StatusSymbols exposes the signalling dibits, and InjectStatusSymbols is the inverse used to synthesise on-air test frames. Getting the strip right is a precondition for everything in the LDU — the voice frames, the Link Control word, and the Low-Speed Data are all read from the stripped 1680-bit payload, so a one-dibit error here silently corrupts the whole frame body.

Sources

  1. Project 25 — Wikipedia, on the P25 standard and its Phase 1 data-unit structure. 

See also