RTL_SDR_Scanner is a C++20 RTL-SDR spectrum scanner with optional ADS-B / Mode-S decoding. It can sweep a configurable frequency range, post spectrum data to an HTTP receiver, and publish decoded aircraft states.
- Spectrum sweep with FFTW-based power calculation and spectrum stitching.
- ADS-B decoding from 1090 MHz RTL-SDR IQ samples.
- HTTP data push for scan spectra and ADS-B aircraft lists.
- HTTP control server for runtime scan / ADS-B enable flags and scan parameters.
- Namespaced C++ interfaces split by responsibility:
rtl::scanner: SDR device access, persistent reader, scan data models.rtl::sda_b: ADS-B aircraft model and decoder.rtl::tools: logging, HTTP, DSP helpers and async pusher.
Runtime and build dependencies:
- CMake 3.16+
- C++20 compiler
librtlsdrfftw3spdlognlohmann_json- POSIX threads
Example package names on Debian/Ubuntu-like systems:
sudo apt install cmake g++ librtlsdr-dev libfftw3-dev libspdlog-dev nlohmann-json3-devcmake -S . -B build
cmake --build buildThe executable is generated as:
build/RTL_SDR_ScannerShow help:
build/RTL_SDR_Scanner --helpADS-B only:
build/RTL_SDR_Scanner --mode 1Scan only:
build/RTL_SDR_Scanner --mode 2 --start-freq 88 --end-freq 108ADS-B plus scan time slicing:
build/RTL_SDR_Scanner --mode 3 --start-freq 100 --end-freq 160Frequencies passed on the command line are in MHz. Internally, public C++ APIs use Hz unless documented otherwise.
The scanner posts JSON data to:
http://127.0.0.1:23568/api/service
Python helper receivers are available:
python3 python/receiver_raw.py
python3 python/receiver_plot.pyThe control server listens on:
0.0.0.0:23569
Endpoints:
POST /adsb/startPOST /adsb/stopPOST /scan/startPOST /scan/stopPOST /scan/paramGET /status
Example scan parameter update:
curl -X POST http://127.0.0.1:23569/scan/param \
-H 'Content-Type: application/json' \
-d '{"start_freq": 88000000, "end_freq": 108000000}'/scan/param expects Hz, not MHz.
Shared constants are defined in:
#include "constants.hpp"Namespace:
rtl::constantsExamples: SCAN_SAMPLE_RATE, ADSB_FREQ, CONTROL_PORT, FFT_SIZE.
Headers:
#include "scanner/types.hpp"
#include "scanner/rtl_sdr_device.hpp"
#include "scanner/persistent_async_reader.hpp"Namespace:
rtl::scannerPrimary types:
ScanPlanSegmentDataRtlSdrDevicePersistentAsyncReader
PersistentAsyncReader::read() uses a caller-owned output buffer. outLen is both input capacity and output bytes copied.
Headers:
#include "ads_b/aircraft.hpp"
#include "ads_b/ads_b_demodulator.hpp"Namespace:
rtl::sda_bPrimary types:
AircraftADSBDemodulator
ADSBDemodulator::processIq() expects interleaved unsigned 8-bit IQ bytes from librtlsdr.
Headers:
#include "tools/tools.hpp"
#include "tools/pusher.hpp"Namespace:
rtl::toolsPrimary APIs:
initSpdlog()post()get()removeDc()calculateFft()spectrumToDb()spliceSpectrum()detectPeaks()Pusher
- Running against RTL-SDR hardware may require udev rules or root privileges.
- Only one process should own the RTL-SDR device at a time.
- ADS-B decoding is tuned for 1090 MHz at 2 MS/s.
- The control API binds to all interfaces. Use firewall rules or change the bind address before exposing it on untrusted networks.
rtl::tools::getCmdResult()invokes the shell and must not receive untrusted input.- The namespace
rtl::sda_bfollows the current project request. The folder name remainsads_b.
- [] AM_Demodulation
- [] FM_Demodulation
- [] Spectrum smooth
- [] Automatic Modulation Classification (AM and FM)