Multi-radio client/server application with C++20 backend and Qt6 frontend.
The backend is now intentionally minimal and keeps only the API contract used by the frontend. It no longer depends on RTL-SDR, hardware tuning paths, DSP decode pipeline, or dynamic plugin loading.
- gRPC client/server API (
proto/radio.proto) with bearer-token auth. - Receiver control API (
list/get/start/stop/set mode/set mode config). - Telemetry streams:
- receiver events
- decoded messages (reserved channel, currently backend-generated none)
- audio frames
- API-only virtual receiver runtime (synthetic audio + status/events for integration).
- Qt6 frontend compatibility preserved.
proto/: gRPC + protobuf contract.backend/: API server runtime and minimal receiver/event/audio engine.frontend/: Qt6 desktop client.tests/: core + API behavior tests.
./scripts/bootstrap_deps.sh -yServer-only environment (skip Qt):
./scripts/bootstrap_deps.sh --headless -ycmake -S . -B build \
-DMR_BUILD_SERVER=ON \
-DMR_BUILD_FRONTEND=ON \
-DMR_BUILD_TESTS=ON
cmake --build build -jMR_BIND_ADDRESS=0.0.0.0:50051 \
MR_AUTH_TOKEN=multi-radio-dev-token \
MR_LOG_DIR=./logs \
./build/backend/multi_radio_serverCreate client.ini:
grpc_target=127.0.0.1:50051
auth_token=multi-radio-dev-tokenRun:
./build/frontend/multi_radio_clientOptional config path:
MR_CLIENT_CONFIG=/path/to/client.ini ./build/frontend/multi_radio_clientThe ncurses MVP reuses the same client.ini and consumes radar snapshots over gRPC.
It renders the radar pane through gnuplot in terminal text mode, so gnuplot
must be installed on the machine where you run it.
Build with TUI enabled:
cmake -S . -B build \
-DMR_BUILD_SERVER=ON \
-DMR_BUILD_FRONTEND=OFF \
-DMR_BUILD_TUI=ON \
-DMR_BUILD_TESTS=OFF
cmake --build build --target multi_radio_tui -jRun:
./build/frontend/multi_radio_tuiOptional center override:
./build/frontend/multi_radio_tui --center-lat 57.7 --center-lon 11.9Selecting VDES ASM uses the vdes_iq_recorder null-demodulator. It does not
emit decoded messages; it writes raw interleaved int16 IQ plus a JSON sidecar.
MR_IQ_RECORD_DIR=./recordings/vdes \
MR_IQ_RECORD_PREFIX=vdes \
MR_IQ_RECORD_MAX_BYTES=268435456 \
./build/backend/multi_radio_serverOutput files are named like:
recordings/vdes/vdes_20260519T120000Z_161950000_2048000_0.iq16
recordings/vdes/vdes_20260519T120000Z_161950000_2048000_0.json
Replay a recording through the first-pass VDES PHY diagnostic plugin:
./build/tools/vdes_replay \
--iq recordings/vdes/vdes_20260519T120000Z_161950000_2048000_0.iq16 \
--rate 2048000 \
--freq 161950000 \
--diag-blocks 1 \
--jsonlVCPKG_ROOT=~/vcpkg ./scripts/build_windows_frontend.shArtifact:
build-win-frontend/frontend/multi_radio_client.exe
The repository now includes docker/raspberry_pi2_armhf/Dockerfile for an
armhf cross-build environment targeting Raspberry Pi 2.
Build the image:
docker build -t multi-radio-rpi2 -f docker/raspberry_pi2_armhf/Dockerfile .Run the cross-build:
docker run --rm \
-v "$PWD":/src \
-v "$PWD/out/rpi2":/out \
-v /home/maves/projects/dump1090:/deps/dump1090 \
multi-radio-rpi2The container:
- configures and builds in an isolated container-only build directory
- installs armhf protobuf/gRPC/liquid/FFTW/RTL-SDR dependencies through Debian multiarch
- cross-builds
rnnoiseinto/opt/rpi2-prefix - builds
dump1090/libmodesfrom/deps/dump1090withmake libraryandmake library-install - installs
libmodesinto the armhf prefix under/opt/rpi2-prefix/usr/local
Artifacts are copied to:
out/rpi2/buildout/rpi2/prefix
ctest --test-dir build --output-on-failure