Skip to content

aiq-ng/sweepcli

Repository files navigation

sweepcli

sweepcli is a command‑line assistant for defensive RF sweeping. It orchestrates commodity software defined radios (SDRs) and common system utilities to help operators perform repeatable, documented inspections of rooms for unwanted radio frequency (RF) emitters.

The tool does not magically detect covert devices by itself – expert interpretation and physical inspection are still required – but it provides a structured workflow and evidence capture pipeline so that sweeps are consistent and findings are tracked over time.

Features

  • Case management: group scans, notes and findings per room.
  • Baseline sweeps: record the quiet RF environment for later comparison.
  • Quick sweeps: capture the current spectrum and highlight anomalies.
  • Targeted inspection: focus on suspicious frequencies with higher resolution.
  • Wi‑Fi and Bluetooth inventory: list nearby devices using nmcli, iwlist, hcitool or bluetoothctl when available.
  • Floorplan annotations: mark objects of interest and include them in reports.
  • Report generation: produce HTML (and optionally PDF) reports with tables of scans, findings and notes.
  • Extensible radio abstraction: support for RTL‑SDR, HackRF and bladeRF (simulation fallback when native tools are absent).

Installation

Clone this repository and install the dependencies:

git clone <repository-url>
cd sweepcli
python3 -m venv .venv
source .venv/bin/activate
pip install -r requirements.txt

Optionally install WeasyPrint if you wish to generate PDF reports:

pip install weasyprint

Usage

The entry point is sweep:

python -m sweepcli --help

Create a case

python -m sweepcli init new myoffice --room "Main Conference Room" --operator Alice --floorplan /path/to/floorplan.png

List existing cases

python -m sweepcli init list

Run a wideband baseline sweep

python -m sweepcli baseline run myoffice --radio rtlsdr --preset vhf_uhf --duration 10

You can also provide a custom span instead of a preset:

python -m sweepcli baseline run myoffice --radio rtlsdr --start 88 --end 108 --duration 10

Perform a wideband quick sweep

python -m sweepcli quick run myoffice --radio rtlsdr --preset vhf_uhf --duration 5

Generate ranked follow-up targets

python -m sweepcli targets generate myoffice --top 15 --min-score 60
python -m sweepcli targets list myoffice

Start a direction-finding session

Use HackRF or RTL-SDR for DF in the current version. bladeRF remains gated for DF until real targeted capture is implemented.

python -m sweepcli df start myoffice --target-id <target-id> --radio hackrf --span 0.5 --duration 5
python -m sweepcli df log myoffice <session-id> --location "Doorway" --orientation "Facing north wall" --signal null --confidence 4 --note "Sharp drop when body shields east side"
python -m sweepcli df conclude myoffice <session-id> "Likely wall clock or cable run near north wall" --confidence 4 --summary "Three repeatable nulls from doorway, desk corner, and projector table."
python -m sweepcli df show myoffice <session-id>

Inspect a specific frequency

python -m sweepcli inspect run myoffice 433.92 --span 0.5 --radio hackrf --compare

Scan Wi‑Fi and Bluetooth

python -m sweepcli wifi scan myoffice
python -m sweepcli bluetooth scan myoffice

Mark objects on the floorplan

Coordinates are normalised (0–1) relative to the image width and height.

python -m sweepcli mark add myoffice "Desk Power Strip" 0.42 0.64 --note "Under desk power strip"

Add a note

python -m sweepcli note add myoffice "Noticed intermittent burst near the wall clock."

Compare existing scans to baseline

python -m sweepcli compare run myoffice --scan-id <scan-id>

Preset coverage by radio

  • rtlsdr: full, vhf_uhf, ism
  • hackrf: full, vhf_uhf, ism
  • bladerf: full, vhf_uhf, ism

Use --preset for the common radio-specific ranges, or override with --start and --end when you need tighter control.

Comprehensive Scan Checklist

Use this checklist when you want a full-room sweep that produces a baseline, a comparison scan, a ranked target list, and narrowband follow-up frequencies for a direction finder.

1. Pre-scan setup

  • Confirm the SDR and required tools are connected and visible in the OS.
  • Choose the radio that matches the coverage you need.
  • Decide whether to use a preset (full, vhf_uhf, ism) or a custom span.
  • Reduce known local RF noise where possible: unused phones, hotspots, test gear, and temporary wireless devices.
  • Create the case and attach a floorplan if you have one.
python -m sweepcli init new myoffice --room "Main Conference Room" --operator Alice --floorplan /path/to/floorplan.png

2. Capture a clean baseline

  • Run the baseline when the room is in its quiet, expected state.
  • Use the same radio and same coverage plan you intend to use for later comparison.
  • Prefer a longer duration for baseline than for quick follow-up scans.
  • Record notes about anything intentionally transmitting during baseline.
python -m sweepcli baseline run myoffice --radio rtlsdr --preset vhf_uhf --duration 10
python -m sweepcli note add myoffice "Baseline captured with office Wi-Fi APs active and conference tablets removed."

3. Run the comparison scan

  • Run a quick wideband scan with the same radio and same preset or custom span.
  • Keep duration and placement consistent where possible.
  • Do not change antennas, gain setup, or room layout unless that change is intentional and documented.
python -m sweepcli quick run myoffice --radio rtlsdr --preset vhf_uhf --duration 5

4. Generate the priority list

  • Generate targets from the latest comparison campaign against the latest baseline.
  • Start with a higher --min-score if you want a short triage list.
  • Use targets list to review the saved ranked set without recomputing it.
python -m sweepcli targets generate myoffice --top 15 --min-score 60
python -m sweepcli targets list myoffice --top 15 --min-score 60

5. Perform targeted follow-up

  • Inspect the highest-ranked frequencies first.
  • Use a narrower span around each priority frequency before moving to direction finding.
  • Add notes for intermittent or bursty signals, and mark nearby physical objects on the floorplan.
python -m sweepcli inspect run myoffice 433.92 --span 0.5 --radio hackrf --compare
python -m sweepcli mark add myoffice "Wall clock" 0.71 0.18 --note "Near intermittent burst source"
python -m sweepcli note add myoffice "433.92 MHz target repeated every 12 seconds during occupied-room test."

5a. Run a manual direction-finding hunt

This version of sweepcli supports manual DF logging, not automatic triangulation. The goal is to capture repeatable operator observations while you use stock antennas and body-shield/null techniques.

  • Start with one ranked target at a time.
  • Confirm the signal is stable enough to hunt with inspect run.
  • Keep the same radio, span, and duration through one DF session.
  • Move in short steps around the room and rotate your body/radio slowly.
  • Log whether the signal becomes stronger, weaker, null, intermittent, or unchanged.
  • Use at least three observation points before concluding a probable source.
  • Prefer HackRF for immediate DF work. Use RTL-SDR as a coarser fallback.
  • Do not use bladeRF for DF in the current version; bladeRF narrowband capture is not implemented yet.
python -m sweepcli df start myoffice --target-id <target-id> --radio hackrf --span 0.5 --duration 5
python -m sweepcli inspect run myoffice 433.92 --span 0.5 --radio hackrf --duration 5
python -m sweepcli df log myoffice <session-id> --location "Doorway" --orientation "Facing north wall" --signal null --confidence 4 --note "Deepest null with torso between radio and wall clock"
python -m sweepcli df log myoffice <session-id> --location "Projector table" --orientation "Facing ceiling mount" --signal weaker --confidence 3
python -m sweepcli df log myoffice <session-id> --location "Desk corner" --orientation "Facing power strip" --signal stronger --confidence 4 --object-id <floorplan-object-id>
python -m sweepcli df conclude myoffice <session-id> "Likely around desk corner power strip or adjacent cable run" --confidence 4 --summary "Three consistent observations; strongest near desk corner, null away from north wall."

6. Package the results

  • Review findings, notes, and targets before leaving the site.
  • Generate a report while the context is still fresh.
  • Preserve any raw artifacts if the sweep may need later review or escalation.
python -m sweepcli report generate myoffice --pdf

Success criteria

  • A baseline campaign exists for the room and coverage range.
  • A comparison campaign exists for the same range.
  • A target set has been generated and reviewed.
  • The top-ranked frequencies have been inspected individually.
  • Each hunted DF target has an active or concluded DF session with structured observations.
  • Concluded DF sessions identify a probable source area or object with an operator confidence score.
  • Notes and floorplan marks capture the physical context of suspicious signals.
  • A report has been generated or the case artifacts have been preserved for handoff.

Generate a report

python -m sweepcli report generate myoffice --pdf

This will produce an HTML (and optionally PDF) report in the case directory (~/.sweepcli/myoffice).

Data storage

By default sweepcli stores all case data in ~/.sweepcli. You can override this by setting the environment variable SWEEPCLI_HOME to another directory. Each case resides in its own subdirectory containing case.json, captured scan CSV files and generated reports.

Limitations

  • The tool cannot detect passive or powered‑off devices. Only transmitting devices can be detected.
  • Anomalies are based on simple heuristics; false positives and negatives are possible. Operator judgement is required.
  • Real scanning commands (rtl_power, hackrf_sweep, etc.) must be installed and available in $PATH. When absent, sweepcli falls back to simulated data for development purposes.
  • Direction finding is operator-assisted in v1. The tool records observations and conclusions; it does not perform true geometric or phase-based geolocation.
  • bladeRF is not yet available for DF because targeted bladeRF capture is not implemented in the current codebase.
  • Wi‑Fi and Bluetooth inventories depend on the presence of appropriate system utilities (nmcli, iwlist, hcitool, bluetoothctl) and the necessary permissions.

Contributing

Feel free to fork this project and submit improvements. Pull requests are welcome!

About

No description, website, or topics provided.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors