Also known as: traffic slot mapping, TDMA slot grid anchor, slot demux
TETRA traffic slot mapping is how a voice follower, having retuned to a granted traffic carrier, decides which of the carrier’s four TDMA timeslots each burst belongs to and which call it carries.12 A TETRA carrier interleaves four calls’ slots in time, so extracting a single call means demultiplexing the burst stream — and doing that correctly turns out to depend on not trusting the obvious slot number, but on the per-slot AACH usage marker instead.
Anchoring the grid
One TDMA timeslot is 255 dibits (510 bits); four make a 1020-dibit frame. To place a
burst, the extractor needs an absolute reference for where slot 1 begins. That reference is
the synchronisation burst (SB), transmitted in slot 1 (TN1) of frame 18: its
synchronisation training sequence pins the grid, and a normal burst leading at absolute dibit
L then falls in slot round((L − anchor) / 255) mod 4.
The subtlety is that the SB’s training sequence sits late in the SB burst, after the
frequency-correction and BSCH preamble, so the detected training-sequence leading dibit lands
one NDB-slot before the TN1 traffic burst’s normal-training-sequence position. Adding 3
(≡ −1 mod 4) — the ndbSBSlotShift constant — makes a burst one slot after the anchor read
as TN1, matching the control channel’s granted timeslots. This was verified against a real
same-carrier capture: with the shift applied, grant timeslot 1 and timeslot 2 line up with
the decoded slots. The anchor is refreshed on every SB (once per multiframe) so it tracks slow
clock drift; until an SB is seen the slot is reported as 0 (unknown), and on a traffic-only
carrier with no SB it stays 0.
Why the marker, not the slot
The TDMA slot number is kept for telemetry but is not a reliable demux key on real air. The SB anchor’s intra-slot rounding jitters a call’s bursts across adjacent slot numbers, and the channel-allocation grant’s timeslot field does not map cleanly to the physical slot. The reliable key is the AACH downlink usage marker: the AACH decodes in every downlink slot, a marker of 4 or greater identifies the call occupying that slot, and a granted call’s marker matches the marker carried in its grant. So the voice chain routes each burst by marker, isolating concurrent same-carrier calls that a slot-number scheme would smear together. When the hard AACH decode misses under load, a gated soft-decision fallback recovers the marker from the per-symbol confidences rather than dropping the burst.
Soft-LLR stashing
To let the traffic path decode soft-decision TCH/S without
changing the hard dibit contract, the extractor carries the receiver’s per-symbol complex
differentials in a buffer kept strictly parallel to its dibit buffer. StashSoft hands it the
differentials for the next block, keyed by the same base index; if they ever fall out of
lockstep the soft path is dropped rather than misaligned, and the burst decodes hard-only.
When present, the parallel buffer is sliced by exactly the same BKN1 + BKN2 geometry as the
hard bits to build the descrambled 432-LLR type-5 stream for the burst.
Relevance to SDR
internal/radio/tetra/traffic.go implements the TrafficExtractor: it scans the π/4-DQPSK
dibit stream for Normal Continuous Downlink Bursts, anchors the grid with a synchronisation
training-sequence detector, and emits each burst’s raw or descrambled traffic frame tagged
with both its TDMA slot (slotOf) and its AACH usage marker (usageOf), plus the parallel
soft stream (softFrame). Getting the ndbSBSlotShift and the marker-versus-slot decision
right is what lets GopherTrunk record concurrent TETRA calls on one carrier as separate,
correctly-attributed audio.
Sources
-
Terrestrial Trunked Radio — Wikipedia, on the TETRA slot and burst structure. ↩
-
Time-division multiple access — Wikipedia, on the four-slot TDMA scheme TETRA uses. ↩