Installation

April 25, 2026 · View on GitHub

Covers the central server and remote sensor nodes. Both share the same project layout; the only difference is which services you install and which hardware you plug in.

Base setup (any node)

git clone <this-repo> ~/code/sigint
cd ~/code/sigint
python3 -m venv venv
source venv/bin/activate
pip install -r requirements.txt

After the initial setup, always activate the venv before running commands:

source venv/bin/activate

sudo runs the system Python and bypasses the venv. For commands that need root (server, BLE, WiFi), use the venv's Python directly:

sudo venv/bin/python3 src/sdr.py server configs/server.json

System dependencies (Raspberry Pi / Debian / Ubuntu)

sudo apt-get install -y cmake libusb-1.0-0-dev ffmpeg python3-full python3-venv

librtlsdr (V4-aware fork)

Required for RTL-SDR Blog V4 + pyrtlsdr. The Debian librtlsdr0 package (2.0.x) is missing rtlsdr_set_dithering (pyrtlsdr import fails) and rtlsdr_set_and_get_tuner_bandwidth (rtl_sdr CLI fails). Build the V4-aware fork that ships those symbols (librtlsdr.so.0.9git):

git clone https://github.com/librtlsdr/librtlsdr.git /tmp/librtlsdr
cd /tmp/librtlsdr && mkdir build && cd build
cmake .. -DINSTALL_UDEV_RULES=ON -DDETACH_KERNEL_DRIVER=ON && make -j4
sudo make install && sudo ldconfig

Verify both required symbols are present:

nm -D /usr/local/lib/librtlsdr.so | grep -E 'set_dithering|set_and_get_tuner_bandwidth'

Both must show T (defined). If only one is present, the fork is too old — update.

Blacklist the kernel DVB driver

The kernel auto-claims any RTL2832-based dongle as a DVB-T tuner, blocking userspace SDR access (you'll see usb_claim_interface error -6 and Resource busy). Even the udev rules from the librtlsdr build don't always prevent this on Raspberry Pi OS. Force a blacklist:

echo 'blacklist dvb_usb_rtl28xxu' | sudo tee /etc/modprobe.d/blacklist-rtl.conf
sudo rmmod rtl2832_sdr dvb_usb_rtl28xxu rtl2832 dvb_usb_v2 2>/dev/null

The rmmod only succeeds while no process is using the SDR. If it errors with "Module ... is in use", reboot or unplug+replug the SDR after writing the blacklist file.

Configure systemd unit to find the V4 lib

The agent's spawned scanner subprocess (sdr.py pmr and friends) opens the RTL-SDR via pyrtlsdrlibrtlsdr.so. The dynamic linker default order (/lib/aarch64-linux-gnu first) loads Debian's 2.0.1 lib which is missing V4 symbols. Pin /usr/local/lib for the agent:

# /etc/systemd/system/sigint-agent.service
[Service]
Environment="LD_LIBRARY_PATH=/usr/local/lib"
...

pmr.py automatically inherits this and forces it for the rtl_sdr subprocess too (which itself was built against the V4 fork lib).

WiFi scanner

pip install scapy
sudo apt-get install -y iw

BLE scanner

sudo apt-get install -y bluez bluez-hcidump

ADS-B decoder (readsb)

The Debian readsb package is compiled without RTL-SDR support. You must build from source:

sudo apt-get install -y libzstd-dev libncurses-dev
git clone https://github.com/wiedehopf/readsb.git /tmp/readsb-src
cd /tmp/readsb-src && make -j4 RTLSDR=yes
sudo cp readsb /usr/bin/readsb

AIS decoder (rtl_ais)

The native Python AIS decoder is educational only. Install rtl_ais for real use:

git clone https://github.com/dgiardini/rtl-ais.git /tmp/rtl-ais
cd /tmp/rtl-ais && make && sudo cp rtl_ais /usr/local/bin/

ISM (rtl_433)

sudo apt-get install -y rtl-433

Pager decoder (multimon-ng)

sudo apt-get install -y multimon-ng

Transcription (optional)

Pick one backend:

  • OpenAI API (recommended on Pi): set OPENAI_API_KEY in .env

  • Local Whisper (~1 GB of PyTorch and model weights):

    pip install openai-whisper
    

Optional, for generating test audio:

pip install gtts

macOS

brew install librtlsdr
python3 -m venv venv && source venv/bin/activate
pip install -r requirements.txt
# optional:
pip install openai-whisper gtts

Environment file

Copy .env.example to .env and fill in values (OPENAI_API_KEY, WHISPER_LANGUAGES, TAK_HOST/TAK_PORT):

cp .env.example .env

Next steps