Recognise trunking control channels, and refuse to sit on them

A trunked system keeps one frequency transmitting a data stream around
the clock so its radios know where each conversation has been put.  There
is no speech on it and it never stops, which makes it the strongest and
most useless signal in the band: the scanner parked on 856.561 MHz for
the full record limit, saved four minutes of buzzing, and found it again
on the next sweep.

Five signatures, matched against a constant-envelope stream that never
pauses: 3600 baud two-level (Motorola SMARTNET/SmartZone), 9600 (EDACS),
1200 (MPT-1327), 4800 four-level (P25 or DMR Tier III), 2400 (NXDN).
The first two are believed at once -- nothing else sends at those rates
without pausing.  The rest share their shape with a digital voice call on
the same system, so they wait for the carrier to run unbroken past
--control-seconds, longer than a conversation goes without a breath.
Being in a trunked allocation raises confidence but is never required;
trunking is licensed on business pairs all over the spectrum.

One is named on screen, abandoned within a second or so, and its capture
deleted.  --keep-control records them for a decoder; --lockout-control
writes them into the lock-out list.

Three things had to be fixed to get there.

The simulator's "pseudo-random" symbols were a counter: multiplying the
symbol index by an odd constant and taking it modulo the level count
returns the low bits, so two-level FSK came out 0,1,0,1.  Every FSK test
in the suite was measuring a tone.  Its FSK is now shaped the way GFSK
and C4FM shape a stream, too, square-edged keying being a signal no
licensed transmitter would radiate.

The symbol-rate estimator locked onto harmonics -- 3600 baud read as
18000 -- because a transition impulse train is a comb of equal lines; it
now walks down to the fundamental.  The squared envelope is no longer a
candidate: it is not a transition signal, and its DC lobe made every
random OOK signal measure ninety baud.  The search starts at 200 Hz
rather than 40, below which it was reading drift, which is how a bare
carrier was awarded a symbol rate.  And a clean two-level signal counted
zero discriminator levels, because its modes land in the first and last
histogram bin, where find_peaks cannot see them.

Separately: locking out a frequency wrote to the settings file even under
--no-config, which has no settings file by definition.  It now writes
only where it read from, and --simulate never writes at all -- an
invented frequency would sit in a real config for ever, skipping whatever
genuine signal happened to land near it.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_016PsWPTweCT6pwxKngvVxcg
This commit is contained in:
The Dust Council 2026-08-22 14:22:49 -07:00
parent ba6c925351
commit 4a272eb1d5
14 changed files with 984 additions and 53 deletions

View file

@ -1,5 +1,5 @@
.\" Generated by packaging/make-man.py -- do not edit by hand.
.TH BANDSAUNTER 1 "2026-08-22" "bandsaunter 2026-08-22_01" "User Commands"
.TH BANDSAUNTER 1 "2026-08-22" "bandsaunter 2026-08-22_02" "User Commands"
.SH NAME
bandsaunter \- scan, record and identify radio signals with an RTL-SDR
.SH SYNOPSIS
@ -293,10 +293,10 @@ Record these \[em] which kinds of content are worth keeping.
.br
Setting name \fBaccept\fR, default \fBvoice, cw, digital\fR.
.br
Accepts: one of: voice, cw, digital, carrier, noise.
Accepts: one of: voice, cw, digital, trunk, carrier, noise.
.RS
.PP
Which kinds of transmission are worth keeping: speech, Morse, data, plain unmodulated carriers, and noise. Most people want voice, cw and digital. Add carrier if you are hunting beacons or interference sources, and noise only for diagnosing why nothing is being recorded.
Which kinds of transmission are worth keeping: speech, Morse, data, trunking control channels, plain unmodulated carriers, and noise. Most people want voice, cw and digital. Add carrier if you are hunting beacons or interference sources, trunk if you are collecting control channels for a decoder, and noise only for diagnosing why nothing is being recorded.
.RE
.TP
.B --min-signal-score
@ -343,6 +343,37 @@ Accepts: at least 0.5.
How long a recording gets to prove it contains something. If nothing recognisable has appeared by then it is abandoned and deleted, and the sweep moves on rather than sitting on an open but empty channel.
.RE
.PP
.SS Trunking
.TP
.B --skip-control / --keep-control --no-skip-control
Skip trunk control channels \[em] spot a trunked system's control channel and move straight on.
.br
Setting name \fBskip_control\fR, default \fByes\fR.
.RS
.PP
Trunked radio systems -- the kind police, fire and large businesses use -- keep one frequency transmitting a data stream around the clock. It tells the radios which channel to jump to for each conversation; it carries no speech and it never goes quiet. To a scanner it looks like a very strong, very interesting signal, so without this setting the receiver parks on it, records the whole record limit of buzzing, and finds it again on the next sweep. With this on it is recognised within a second or two, named on screen, and skipped. Leave it on unless you are deliberately collecting control channel data to feed to a decoder.
.RE
.TP
.B --control-seconds
Control channel patience \[em] unbroken carrier a digital-voice look-alike must hold (s).
.br
Setting name \fBcontrol_seconds\fR, default \fB20 s\fR.
.br
Accepts: at least 1.
.RS
.PP
Only matters for P25, DMR and NXDN. On those systems the control channel and an ordinary digital conversation look identical for the first few seconds, and the only thing that tells them apart is that the conversation eventually pauses and the control channel never does. This is how long a signal has to keep going without a break before it is judged to be a control channel. Raise it if digital voice calls are being skipped by mistake; lower it if you are tired of waiting out control channels. It has no effect on the older Motorola and EDACS systems, which are recognised immediately from their symbol rate.
.RE
.TP
.B --lockout-control / --no-lockout-control
Lock out control channels \[em] add every control channel found to the lock-out list.
.br
Setting name \fBlockout_control\fR, default \fBno\fR.
.RS
.PP
Write each control channel into the lock-out list as it is found, so the scanner stops even looking at it. Skipping one already costs only a second or two, so this is worth turning on mainly if you scan the same band constantly and want the list built for you. With 'Remember lock-outs' also on, the entries are saved to your settings file and survive a restart.
.RE
.PP
.SS Receiver
.TP
.B -d --device
@ -755,6 +786,14 @@ bandsaunter scan \-r 144M\-148M \-\-lockout "162.55M, 450M\-455M"
A single frequency is widened by
.BR \-\-lockout\-width ;
a span is used exactly as written.
.PP
Two runs never write anything back.
.B \-\-no\-config
has no settings file to write to, since the point of it is to leave the saved
settings alone; and
.B \-\-simulate
is looking at an invented band, whose frequencies would be nonsense in a real
settings file. Both still lock out for the run in hand, and say so.
.SH KEYS DURING A SCAN
.TP
.B q
@ -784,6 +823,60 @@ every transmission on one frequency is appended to a single growing file for
that frequency, with a spoken date and time before each one, so a scan can be
played back as a recording of that channel rather than clicked through as
hundreds of fragments.
.SH TRUNKED SYSTEMS
Police, fire and large business radio in the US mostly runs on
.IR trunked
systems. Instead of giving each department its own frequency, the system owns
a pool of channels and hands one out for each conversation as it happens. To
make that work, one frequency in the pool is given over entirely to a data
stream that runs day and night, telling every radio in the fleet where to go
next. That frequency is the
.IR "control channel" .
.PP
A control channel is the worst thing a scanner can find. It is loud, it is
perfectly steady, it never stops, and there is nothing on it to listen to \[em]
just a harsh buzz. A scanner without special handling parks on it for the
whole record limit, saves the file, and then finds it again on the next sweep,
for as long as it is left running.
.PP
bandsaunter recognises one from the shape of the signal, names the system on
screen, deletes what it captured and moves on, usually within a second or
two. What it looks for is a constant\-envelope data stream that never pauses,
at a symbol rate belonging to a known trunking standard:
.RS
.PP
3600 baud two\-level \[em] Motorola SMARTNET / SmartZone (Type I and II).
.br
9600 baud two\-level \[em] EDACS and ProVoice.
.br
1200 baud two\-level \[em] MPT\-1327.
.br
4800 baud four\-level \[em] P25 or DMR Tier III.
.br
2400 baud four\-level \[em] NXDN and NEXEDGE.
.RE
.PP
The first two are recognised at once: nothing else transmits at those rates
without pausing. The others share their shape with an ordinary digital voice
call on the same system, so they are only called a control channel once the
carrier has run unbroken for
.B \-\-control\-seconds
(20 s by default) \[em] long enough that a real conversation would have taken
a breath. Raise that figure if digital voice calls are being skipped by
mistake.
.PP
Being inside a band where trunking is common raises confidence but is never
required: trunking is licensed on business pairs all over the spectrum.
.PP
Use
.B \-\-keep\-control
to record control channels anyway, which is what you want if you are feeding
them to a decoder. Use
.B \-\-lockout\-control
to have each one written into the lock\-out list as it is found, so the
scanner stops looking at it at all; with
.B \-\-save\-lockouts
on, that list survives a restart.
.SH HF RECEPTION
These receivers cannot normally tune below about 24 MHz. Below that they can
sample the antenna directly instead, which opens up shortwave: broadcast,

View file

@ -237,6 +237,14 @@ bandsaunter scan \-r 144M\-148M \-\-lockout "162.55M, 450M\-455M"
A single frequency is widened by
.BR \-\-lockout\-width ;
a span is used exactly as written.
.PP
Two runs never write anything back.
.B \-\-no\-config
has no settings file to write to, since the point of it is to leave the saved
settings alone; and
.B \-\-simulate
is looking at an invented band, whose frequencies would be nonsense in a real
settings file. Both still lock out for the run in hand, and say so.
.SH KEYS DURING A SCAN
.TP
.B q
@ -266,6 +274,60 @@ every transmission on one frequency is appended to a single growing file for
that frequency, with a spoken date and time before each one, so a scan can be
played back as a recording of that channel rather than clicked through as
hundreds of fragments.
.SH TRUNKED SYSTEMS
Police, fire and large business radio in the US mostly runs on
.IR trunked
systems. Instead of giving each department its own frequency, the system owns
a pool of channels and hands one out for each conversation as it happens. To
make that work, one frequency in the pool is given over entirely to a data
stream that runs day and night, telling every radio in the fleet where to go
next. That frequency is the
.IR "control channel" .
.PP
A control channel is the worst thing a scanner can find. It is loud, it is
perfectly steady, it never stops, and there is nothing on it to listen to \[em]
just a harsh buzz. A scanner without special handling parks on it for the
whole record limit, saves the file, and then finds it again on the next sweep,
for as long as it is left running.
.PP
bandsaunter recognises one from the shape of the signal, names the system on
screen, deletes what it captured and moves on, usually within a second or
two. What it looks for is a constant\-envelope data stream that never pauses,
at a symbol rate belonging to a known trunking standard:
.RS
.PP
3600 baud two\-level \[em] Motorola SMARTNET / SmartZone (Type I and II).
.br
9600 baud two\-level \[em] EDACS and ProVoice.
.br
1200 baud two\-level \[em] MPT\-1327.
.br
4800 baud four\-level \[em] P25 or DMR Tier III.
.br
2400 baud four\-level \[em] NXDN and NEXEDGE.
.RE
.PP
The first two are recognised at once: nothing else transmits at those rates
without pausing. The others share their shape with an ordinary digital voice
call on the same system, so they are only called a control channel once the
carrier has run unbroken for
.B \-\-control\-seconds
(20 s by default) \[em] long enough that a real conversation would have taken
a breath. Raise that figure if digital voice calls are being skipped by
mistake.
.PP
Being inside a band where trunking is common raises confidence but is never
required: trunking is licensed on business pairs all over the spectrum.
.PP
Use
.B \-\-keep\-control
to record control channels anyway, which is what you want if you are feeding
them to a decoder. Use
.B \-\-lockout\-control
to have each one written into the lock\-out list as it is found, so the
scanner stops looking at it at all; with
.B \-\-save\-lockouts
on, that list survives a restart.
.SH HF RECEPTION
These receivers cannot normally tune below about 24 MHz. Below that they can
sample the antenna directly instead, which opens up shortwave: broadcast,