Field Guide · term

Also known as: TETRA direct mode facts, DMO bring-up facts

TETRA DMO facts are the direct-mode truths that separate a TETRA DMO receiver that decodes real radios from one that only passes its own tests. GopherTrunk’s DMO bring-up (issue #1003) ran through a false “encrypted” verdict, a noise-driven grant storm, and a colour-recovery blind spot before clear voice decoded — and each wrong turn left behind a fact worth keeping.

The DNB payload geometry is −108/+11, and it was measured, not assumed

A Direct Mode Normal Burst’s two payload blocks sit at BKN1 [L−108, L) and BKN2 [L+11, L+119) dibits relative to the training-sequence lead L. The TMO-copied geometry (−115/+19, which osmo-tetra-dmo uses) is measurably worse: on a real capture the TCH/S CRC yield has a sharp optimum at −108/+11. The general lesson — when two layouts are plausible, sweep and let CRC yield vote — recurs throughout DMO work.

“Encrypted” was a descramble bug: colour 0 still scrambles

The first on-air verdict was “traffic is encrypted”: every speech CRC sat at the ~1/256 chance floor while signalling decoded fine. The radios were in fact clear (TEA0). The bug: the DMO voice path inherited a TMO if colour != 0 shortcut and skipped descrambling at colour 0 — but TETRA scrambling is non-identity at colour 0 (the LFSR seeds to 0xC0000000). Synthetic round-trips scrambled and descrambled consistently, so they passed either way — the self-consistent test trap. The regression now scrambles unconditionally on encode, the way the air does.

The DM colour code is not recoverable from the air — sweep for it

The SCH/S is always colour-0-scrambled, so it always reads colour 0; the colour field’s exact bit offset in the DSB SCH/H is ambiguous on available captures, and hardcoding a guessed offset is the same trap again. GopherTrunk instead recovers the colour empirically: decode candidate colours and keep the one that maximises CRC-valid TCH/S, behind a dominance gate (best ≥ 3× runner-up) that refuses a chance-floor winner. On the verifying capture the true colour won 35 CRC-valid frames against ≤3 for every other — an unambiguous verdict with no manual override.

The colour sweep needs the network MNI folded in

On one operator’s Motorola network (MCC 250 / MNC 1) the sweep found no dominant colour: several candidates rose modestly at once — a pattern one radio scrambling with one label cannot produce. The cause was upstream of the sweep: TETRA seeds the scrambler from the full 30-bit extended colour code, and a sweep over colours 0–63 with an implicit MNI of 0 can never reach an MNI≠0 network’s seed. The DMO SCH/S carries MNI 0 on air (correct parsing, not a bug), so the real mobile network identity must come from configuration (tetra_mcc/tetra_mnc), folded into every candidate seed.

A raw DNB detection is not evidence of traffic

The DNB correlator is an 11-dibit training match at tolerance 2 under 8 filters, so about 1 in a thousand random dibit positions matches by chance — ~18 false DNBs per second on an idle channel at TETRA’s dibit rate. The first live run granted a recording on a silent channel 230 ms after startup. The qualifier that separates traffic from noise is timing structure: one transmitter on one clock puts every burst on a single residue modulo the 255-dibit timeslot, while noise is uniform over all 255. GopherTrunk votes DNB leads onto that slot grid, latches the agreeing residue (learned, never spec-derived — a wrong hardcoded offset would silently kill granting), tracks symbol slips, and drops the latch when the train ends so residual noise cannot keep a finished transmission “alive”. In the decode-status line, dnb_total is a noise meter and dnb_qualified is the number that means traffic — a large gap between them is normal, not a fault.

Operating quirks a DMO listener should expect

DMO grants carry no talkgroup (call-control is not decoded), so recordings file under group 0. The channel lock is sticky across inter-PTT silence — frame-number liveness from the DM-SYNC PDU, not decode rate, keeps a camped channel from being re-hunted. Colour recovery needs ~20 bursts, so a very short first transmission may grant before the colour is known (the voice chain re-recovers it retroactively so leading speech is kept). And with no release PDU on the air, even a healthy DMO call ends on hangtime rather than at the moment of PTT release.

Symptom table

Symptom Looks like Actually Fix / check
Signalling decodes, speech at CRC chance floor Encryption Colour-0 descramble skip, or wrong colour/MNI seed Descramble unconditionally; sweep colours with the configured MNI (#1003)
Colour sweep: several modest winners, none dominant Weak signal / “guessing broken” Wrong MNI in every candidate seed Set tetra_mcc/tetra_mnc and re-sweep
Grants and recordings on a silent channel Real traffic Chance DNB correlations (~18/s) driving the grant Slot-grid qualification; watch dnb_qualified, not dnb_total
dnb_total climbs steadily with no calls Decoder bug Normal correlator false-positive rate Nothing — that counter is a noise meter
Recording ends “at a timeout”, not at PTT release Teardown bug DMO has no release PDU; BFI-only calls die at first hangtime Expect hangtime endings; zero speech frames means a decode problem upstream

Provenance

  • #1003 — the DMO thread end to end: the geometry sweep, the colour-0 descramble fix, empirical colour recovery, the MNI fold, the slot-grid grant qualifier, and the on-air captures behind each.
  • #764 — the verification discipline (a green synthetic is not an on-air verdict) that shaped every step above.

See also