DOCUMENTATION / PART 2 — GETTING IT RUNNING2.2

2.2 The radio

Inventory and selection

modules/01_radio.sh --list-tsv                 # every attached SDR, one row each
modules/01_radio.sh --select 0                 # by index, driver or serial
modules/01_radio.sh --select 'pluto:ip:192.168.2.1'
modules/01_radio.sh --caps-tsv                 # frequencies, rates, gains, direction
modules/01_radio.sh --band-check 942           # which band covers this frequency

Each roster row carries nine fields: driver, serial, frequency range, sample rate range, gain range and direction. Direction is derived from the driver, not from the operator's optimism — an RTL-SDR is RX, a HackRF is RX/TX, a PlutoSDR is RX/TX on one chain each (a Pluto+ or a LibreSDR has two of each). Modules that transmit ask 01_radio whether the selected device can, and refuse if it cannot; they never ask you.

Driver coverage: hackrf, bladerf, limesdr, usrp, rtlsdr, pluto, soapy. The pluto driver exists as its own row rather than as a SoapySDR vendor because an AD936x board has a control surface that matters: gain mode must be set to manual before a hardware gain write is honoured, and a Pluto announces itself over two transports (USB and Ethernet) that are distinct devices with distinct URIs. soapy remains for everything else SoapySDR supports, with the honest caveat recorded in Part 4: SoapySDRUtil enumerates and configures but cannot write samples to a file, so a Soapy path that produces a capture must go through gnuradio.

Tuning, planning and recording

modules/01_radio.sh --set-freq 942 --set-rate 2000000 --set-gain 30
modules/01_radio.sh --plan hackrf          # the vendor commands that would run
modules/01_radio.sh --record 10            # ten seconds of raw IQ into captures/

--plan prints the exact vendor command line for the current selection. It is the opposite of Rule 5 in §1.2: a plan is labelled a plan, it is written to a .plan.txt file when the vendor tool is missing, and it is never presented as a capture that happened.

--record writes raw IQ and reports the sample format it wrote, because the consumer has to know: cs8 for HackRF, cu8 for RTL-SDR, sc16 for bladeRF, LimeSDR and USRP, ci16 for a Pluto through libiio, cf32 for a SoapySDR flowgraph. A decoder that assumes the wrong format produces noise that looks like a broken receiver.

One radio, one owner

modules/01_radio.sh --lock-claim recon 12345
modules/01_radio.sh --lock-status-tsv
modules/01_radio.sh --lock-release recon
modules/01_radio.sh --lock-recover

A single SDR cannot be retuned by two modules at once, and the failure mode is nasty: the second module silently retunes the first one's radio mid-capture and the resulting store is a mixture of two experiments. The lock is a claim with an owner and a pid. --lock-recover removes a claim whose owner is dead and refuses one whose owner is alive — the trap most lock implementations fall into is that they let a stale lock be stolen from a running process.