Skip to content

Repository files navigation

SDR-Shark

Python React SDR ML

SDR-Shark is an applied RF signal-intelligence platform and web-based software defined radio console for live spectrum monitoring, waterfall visualization, protocol-aware signal activity, and decoder-assisted RF discovery. It combines a Python/Flask backend with a React frontend and can receive samples either directly through SoapySDR or through sdr-gateway.

The project demonstrates the system layer around RF ML: live device streaming, browser visualization, signal feature extraction, decoder plugin orchestration, service deployment, and integration points for models from rf-signal-intelligence.

The project is intended for lawful RF engineering, lab validation, education, spectrum monitoring, and passive signal-awareness workflows. Operators are responsible for complying with all applicable radio, privacy, and computer misuse laws in their jurisdiction.

SDR-Shark public Docker demo frequency-hopping signal

Public Demo Mode

SDR-Shark includes a hardware-free public demo that generates deterministic synthetic IQ replay data locally. The demo is public-safe: it shows a stationary receiver watching a Bluetooth-like frequency-hopping emitter move across the passband, along with tones, moving noise floor, and burst activity, without committing real RF captures or requiring SDR hardware.

Portfolio case study: RTG Spectrum SDR-Shark

Run the public Docker demo in one command:

docker compose -f docker-compose.demo.yml up --build

Then open the LAN URL for this machine, usually:

http://<machine-ip>:8080

Stop it with:

docker compose -f docker-compose.demo.yml down

Local source demo:

./scripts/demo.sh

The script binds to 0.0.0.0, tries port 80 first, and falls back to 8080 when low-port bind is unavailable without elevated permissions. Open the LAN URL printed by the script, usually:

http://<machine-ip>:8080

Stop the demo with:

./scripts/demo_stop.sh

See docs/demo.md for API checks, troubleshooting, and replay details.

What This Proves

  • One-command Docker path for reviewers, customers, and collaborators.
  • Stationary receiver view of a Bluetooth-like frequency-hopping 2.4 GHz emitter.
  • Browser-based spectrum and waterfall UI driven by replayed IQ.
  • Backend FFT, max-hold, persistence, and replay session plumbing.
  • Hardware-aware SDR architecture that can run live, gateway-backed, or replay-backed.
  • A safe portfolio demo path for RF workflow review without exposing local RF environment data.

Public Demo Evidence

The captures below were generated from the Docker demo using the synthetic public-demo-2p4ghz replay session. The receiver stays centered while the synthetic Bluetooth-like emitter hops across the passband.

Live replay dashboard Spectrum and waterfall detail Signal activity panel
SDR-Shark public replay dashboard SDR-Shark public replay spectrum and waterfall SDR-Shark public replay signal activity panel

Interface Evidence

Scanner setup SDR settings Signal analysis
SDR-Shark scanner setup dialog SDR-Shark SDR settings dialog SDR-Shark signal analysis dialog

What It Does

  • Displays a live spectrum trace and waterfall with GPU-backed rendering support.
  • Supports direct SoapySDR receive and gateway-backed receive through sdr-gateway.
  • Shares one wideband IQ stream with multiple decoder plugins.
  • Shows decoded signal activity cards for Bluetooth Low Energy, Bluetooth Classic, WiFi/802.11, Zigbee/802.15.4, FM broadcast, ADS-B, and GPS status.
  • Provides scanner mode for repeated dwell plans across 2.4 GHz ISM, FM, sub-GHz, ADS-B, LTE awareness bands, and WiFi 5.8 GHz.
  • Tracks Pattern-of-Life information in the activity panel, including multi-day seen/streak pills.
  • Provides optional FM station verification and playback from the live wideband IQ stream.
  • Supports top-right modal workflows for settings, scanner, analysis, classifiers, GPS, and related controls.
  • Provides integration points for RF/IQ classifiers and streaming inference.

Architecture

SDR-Shark has three main layers:

  • frontend/: React UI for the live plot, waterfall, scanner, settings dialogs, GPS dialog, and decoded signal activity panel.
  • backend/src/sdr_plot_backend/: Flask API, SDR adapter, scanner controller, protocol plugin adapters, and shared IQ tap plumbing.
  • scripts/: local start, service management, gateway mode, and one-script installation helpers.

Receive modes:

  • SDR_BACKEND=gateway: SDR-Shark connects to sdr-gateway using SDR_SERVER_URL and an optional SDR_GATEWAY_API_TOKEN. This is the packaged default because it supports shared-radio deployments.
  • SDR_BACKEND=soapy: SDR-Shark opens the radio locally using SoapySDR.
  • replay: internal/plugin workflows can consume recorded or replayed IQ where supported.

Hardware

The direct SoapySDR path can work with any radio supported by the installed SoapySDR modules. Common devices include HackRF, bladeRF, RTL-SDR, Airspy, Sidekiq, and other Soapy-compatible receivers.

High-rate features such as 60 MHz 2.4 GHz scanning require hardware and host I/O that can sustain the requested bandwidth. For narrowband features such as ADS-B, FM, and sub-GHz monitoring, lower bandwidth devices may be sufficient.

Docker

A container build also exists (root Dockerfile, not the legacy one under docker/ - see docker/README.md), deployed on station1 and dev-desktop. See docker/README.md for the deploy commands (default rfiq mode vs. direct-SoapySDR/gateway overrides) and a list of real bugs found and fixed getting the original Dockerfiles working, before building your own image from scratch.

Quick Install

On Debian/Ubuntu-like systems, the recommended one-script install is:

cd /home/jake/workspace/SDR/SDR-Shark
chmod +x scripts/install.sh
./scripts/install.sh

This installs common system dependencies when apt-get is available, creates .venv, installs the backend, installs frontend packages, and builds the frontend.

To install and start SDR-Shark as a systemd service in one command:

cd /home/jake/workspace/SDR/SDR-Shark
./scripts/install.sh --enable-service

To skip system package installation, for example on a prepared machine:

./scripts/install.sh --no-system-packages

Manual Install

Install system dependencies:

sudo apt-get update
sudo apt-get install -y \
  build-essential cargo curl git gpsd gpsd-clients gunicorn libliquid-dev \
  npm python3-dev python3-pip python3-venv soapysdr-tools sox tshark wireshark-common

Create and populate the Python environment:

cd /home/jake/workspace/SDR/SDR-Shark
python3 -m venv .venv
source .venv/bin/activate
python -m pip install --upgrade pip wheel setuptools
python -m pip install -r requirements.txt
python -m pip install -e backend

Install and build the frontend:

cd /home/jake/workspace/SDR/SDR-Shark/frontend
npm install
npm run build

Optional FM channelizer build:

cd /home/jake/workspace/SDR/SDR-Shark
bash backend/src/sdr_plot_backend/native/build_fm_channelizer.sh

Running Locally

Start the backend from the repository root:

cd /home/jake/workspace/SDR/SDR-Shark
source .venv/bin/activate
./scripts/start.sh

For frontend development:

cd /home/jake/workspace/SDR/SDR-Shark/frontend
npm start

The development frontend normally runs on http://localhost:3000 and proxies API calls to the backend. The backend normally listens on 0.0.0.0:5000.

Running as a systemd Service

Install or refresh the service:

cd /home/jake/workspace/SDR/SDR-Shark
./scripts/sdr-shark-service.sh install

Enable and start it:

./scripts/sdr-shark-service.sh enable
./scripts/sdr-shark-service.sh start

Common service commands:

./scripts/sdr-shark-service.sh status
./scripts/sdr-shark-service.sh logs
./scripts/sdr-shark-service.sh restart
./scripts/sdr-shark-service.sh stop

The helper writes the unit to /etc/systemd/system/sdr-shark.service and service defaults to /etc/default/sdr-shark.

Example /etc/default/sdr-shark:

SDR_BACKEND='gateway'
SDR_SHARK_LOG_DIR='/var/log/sdr-shark'
SDR_SHARK_BLUETOOTH_LOG_DIR='/var/log/sdr-shark'
GPSD_HOST='127.0.0.1'
GPSD_PORT='2948'

For direct SoapySDR mode:

SDR_BACKEND='soapy'

For gateway mode with a non-default gateway URL or authenticated gateway:

SDR_BACKEND='gateway'
SDR_SERVER_URL='http://127.0.0.1:8080'
SDR_GATEWAY_API_TOKEN='replace-with-your-token-if-required'

After editing /etc/default/sdr-shark, restart:

sudo systemctl restart sdr-shark

SDR Backend Configuration

Direct SoapySDR mode:

SDR_BACKEND=soapy ./scripts/start.sh

Verify SoapySDR:

SoapySDRUtil --find
python -c "import SoapySDR; print('SoapySDR ok')"

Limit device probing:

export SDR_SOAPY_DRIVERS=hackrf,bladerf,rtlsdr,airspy,sidekiq

Gateway mode:

SDR_BACKEND=gateway SDR_SERVER_URL=http://127.0.0.1:8080 ./scripts/start.sh

Or use the helper:

./scripts/run_gateway.sh

SoapySDR warnings and vendor output are written to /var/log/sdr-shark/soapysdr.log by default. To show them on stderr while debugging:

export SDR_SOAPY_LOG_STDERR=1

Plugin Installation

Decoder plugins have additional dependencies. See Plugin Installation for detailed setup of:

  • RF Sentinel-backed Bluetooth, Zigbee, WiFi, and FM support.
  • WiFi MAC frame decoding through GNU Radio, gr-ieee802-11, tshark/pyshark-compatible JSONL/PCAP flows.
  • ADS-B Rust decoder support.
  • GPSD service setup.
  • Liquid-DSP FM channelizer support.

Most plugins are enabled by default and become active only when the tuned receive window overlaps their supported frequency range.

GPSD Setup

Install GPSD:

sudo apt-get install -y gpsd gpsd-clients

Configure /etc/default/gpsd. A common USB GPS setup is:

START_DAEMON="true"
USBAUTO="true"
DEVICES=""
GPSD_OPTIONS="-n"

Enable and start GPSD:

sudo systemctl enable --now gpsd

Verify GPSD:

gpspipe -w
ss -ltnp | grep gpsd

Configure SDR-Shark in /etc/default/sdr-shark:

GPSD_HOST='127.0.0.1'
GPSD_PORT='2948'

Some GPSD installs listen on 2947; set GPSD_PORT='2947' if that is what your system exposes.

Disable the GPS plugin:

SDR_SHARK_GPS_PLUGIN='0'

Scanner Mode

Open Scanner from the top-right toolbar. Scanner mode builds a repeated dwell plan and retunes SDR-Shark while decoders run.

Key behavior:

  • 2.4 GHz ISM protocols share one dwell percentage because Zigbee, Thread, WiFi 2.4 GHz, Bluetooth Classic, and BLE overlap.
  • 2.4 GHz ISM scanning uses two wideband passes: low and high portions of the band at up to 60 MHz bandwidth.
  • FM discovery is capped at 5% of the scan cycle so broadcast discovery does not dominate multi-protocol scanning.
  • Other selected bands keep individual percentages.
  • The scan plan table shows order, center frequency, bandwidth, protocols, dwell time, and revisit period.
  • When scanner mode retunes, SDR-Shark auto-levels the Y axis for the new band.

Signal Activity and Pattern of Life

The Signal Activity panel groups decoded protocol activity into cards. Device-oriented detections can be folded by protocol and manufacturer/type. SDR-Shark also records a browser-local Pattern-of-Life cache that tracks compatible fields such as seen_days, seen_day_count, first_seen_date, and last_seen_date.

Pattern-of-Life pills show whether something was seen today, how many recent days it appeared, and whether it has a multi-day streak. This is intended as a field-use convenience and can later be backed by a shared database or RF Sentinel-compatible history store.

Logs and Runtime Data

Default log locations:

  • Service logs: journalctl -u sdr-shark -f
  • SDR-Shark logs: /var/log/sdr-shark
  • SoapySDR vendor output: /var/log/sdr-shark/soapysdr.log
  • Bluetooth events: /var/log/sdr-shark/bluetooth-events-current.jsonl
  • Bluetooth archive: /var/log/sdr-shark/archive/<date-time>/
  • WiFi decoder PCAP/JSONL paths: configurable; see Plugin Installation

Development Workflow

Backend development:

cd /home/jake/workspace/SDR/SDR-Shark
source .venv/bin/activate
python3 -m sdr_plot_backend

Frontend development:

cd /home/jake/workspace/SDR/SDR-Shark/frontend
npm start

Production frontend build check:

cd /home/jake/workspace/SDR/SDR-Shark/frontend
npm run build

Recommended before submitting changes:

git status --short
npm run build

Collaborating

Contributions should be scoped, testable, and respectful of existing operator workflows. Good changes usually include:

  • A short description of the operational problem being solved.
  • A clear default behavior that does not break existing receivers or services.
  • Environment variables for hardware- or site-specific settings.
  • Documentation updates for new service, plugin, or decoder requirements.
  • A build or smoke-test result in the pull request notes.

When working on SDR or decoder changes, avoid assuming exclusive access to a radio. SDR-Shark often runs alongside sdr-gateway and other consumers, so shared IQ tap behavior and clean shutdown are important.

Future Improvements

Potential areas for future work:

  • Persistent backend Pattern-of-Life storage shared with RF Sentinel.
  • More complete WiFi MAC management frame enrichment and SSID/BSSID history.
  • Additional protocol plugins for cellular awareness, LoRa, TPMS, VLF/LF/MF, and other ISM bands.
  • Better replay/session recording tools for detector validation.
  • More GPU rendering options and waterfall palette controls.
  • Role-based access control for multi-user deployments.
  • Packaged releases for Debian/Ubuntu and containerized lab deployments.
  • Automated hardware capability detection for bandwidth, gain ranges, and safe scanner plans.

Licensing

SDR-Shark is source-available for personal, educational, research, evaluation, and other non-commercial use. All commercial rights are retained by Jacob Ramey. Commercial use, paid deployment, commercial hosting, integration into commercial products or services, contract deliverables, managed service offerings, or other revenue-generating use requires prior written permission.

This project may interoperate with third-party datasets, models, SDR drivers, decoder projects, protocol specifications, and external tools. Jacob Ramey makes no ownership claim over those third-party materials; they remain subject to their original licenses, terms, and redistribution restrictions.

For commercial licensing, integration, support, or permission inquiries, contact:

About

No description, website, or topics provided.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages