mirror of
https://github.com/smittix/intercept.git
synced 2026-06-08 14:11:54 -07:00
Consolidate setup scripts into single setup.sh
Merge the improved setup-dev.sh logic into setup.sh and remove the separate dev script. The consolidated script includes: - Stricter bash error handling (set -Eeuo pipefail) - Cleaner output with info/ok/warn/fail helpers - gpsd installation for GPS daemon support - Required tools verification with hard fail - Source build fallback for dump1090 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
-400
@@ -1,400 +0,0 @@
|
||||
#!/usr/bin/env bash
|
||||
# INTERCEPT Setup Script (best-effort installs, hard-fail verification)
|
||||
|
||||
# ---- Force bash even if launched with sh ----
|
||||
if [ -z "${BASH_VERSION:-}" ]; then
|
||||
echo "[x] This script must be run with bash (not sh)."
|
||||
echo " Run: bash $0"
|
||||
exec bash "$0" "$@"
|
||||
fi
|
||||
|
||||
set -Eeuo pipefail
|
||||
|
||||
# Ensure admin paths are searchable (many tools live here)
|
||||
export PATH="/usr/local/sbin:/usr/sbin:/sbin:/opt/homebrew/sbin:/opt/homebrew/bin:$PATH"
|
||||
|
||||
# ----------------------------
|
||||
# Pretty output
|
||||
# ----------------------------
|
||||
RED='\033[0;31m'
|
||||
GREEN='\033[0;32m'
|
||||
YELLOW='\033[1;33m'
|
||||
BLUE='\033[0;34m'
|
||||
NC='\033[0m'
|
||||
|
||||
info() { echo -e "${BLUE}[*]${NC} $*"; }
|
||||
ok() { echo -e "${GREEN}[✓]${NC} $*"; }
|
||||
warn() { echo -e "${YELLOW}[!]${NC} $*"; }
|
||||
fail() { echo -e "${RED}[x]${NC} $*"; }
|
||||
|
||||
on_error() {
|
||||
local line="$1"
|
||||
local cmd="${2:-unknown}"
|
||||
fail "Setup failed at line ${line}: ${cmd}"
|
||||
exit 1
|
||||
}
|
||||
trap 'on_error $LINENO "$BASH_COMMAND"' ERR
|
||||
|
||||
# ----------------------------
|
||||
# Banner
|
||||
# ----------------------------
|
||||
echo -e "${BLUE}"
|
||||
echo " ___ _ _ _____ _____ ____ ____ _____ ____ _____ "
|
||||
echo " |_ _| \\ | |_ _| ____| _ \\ / ___| ____| _ \\_ _|"
|
||||
echo " | || \\| | | | | _| | |_) | | | _| | |_) || | "
|
||||
echo " | || |\\ | | | | |___| _ <| |___| |___| __/ | | "
|
||||
echo " |___|_| \\_| |_| |_____|_| \\_\\\\____|_____|_| |_| "
|
||||
echo -e "${NC}"
|
||||
echo "INTERCEPT - Setup Script"
|
||||
echo "============================================"
|
||||
echo
|
||||
|
||||
# ----------------------------
|
||||
# Helpers
|
||||
# ----------------------------
|
||||
cmd_exists() {
|
||||
local c="$1"
|
||||
command -v "$c" >/dev/null 2>&1 && return 0
|
||||
[[ -x "/usr/sbin/$c" || -x "/sbin/$c" || -x "/usr/local/sbin/$c" || -x "/opt/homebrew/sbin/$c" ]] && return 0
|
||||
return 1
|
||||
}
|
||||
|
||||
have_any() {
|
||||
local c
|
||||
for c in "$@"; do
|
||||
cmd_exists "$c" && return 0
|
||||
done
|
||||
return 1
|
||||
}
|
||||
|
||||
need_sudo() {
|
||||
if [[ "$(id -u)" -eq 0 ]]; then
|
||||
SUDO=""
|
||||
ok "Running as root"
|
||||
else
|
||||
if cmd_exists sudo; then
|
||||
SUDO="sudo"
|
||||
else
|
||||
fail "sudo is not installed and you're not root."
|
||||
echo "Either run as root or install sudo first."
|
||||
exit 1
|
||||
fi
|
||||
fi
|
||||
}
|
||||
|
||||
detect_os() {
|
||||
if [[ "${OSTYPE:-}" == "darwin"* ]]; then
|
||||
OS="macos"
|
||||
elif [[ -f /etc/debian_version ]]; then
|
||||
OS="debian"
|
||||
else
|
||||
OS="unknown"
|
||||
fi
|
||||
info "Detected OS: ${OS}"
|
||||
[[ "$OS" != "unknown" ]] || { fail "Unsupported OS (macOS + Debian/Ubuntu only)."; exit 1; }
|
||||
}
|
||||
|
||||
# ----------------------------
|
||||
# Required tool checks (with alternates)
|
||||
# ----------------------------
|
||||
missing_required=()
|
||||
|
||||
check_required() {
|
||||
local label="$1"; shift
|
||||
local desc="$1"; shift
|
||||
|
||||
if have_any "$@"; then
|
||||
ok "${label} - ${desc}"
|
||||
else
|
||||
warn "${label} - ${desc} (missing, required)"
|
||||
missing_required+=("$label")
|
||||
fi
|
||||
}
|
||||
|
||||
check_tools() {
|
||||
info "Checking required tools..."
|
||||
missing_required=()
|
||||
|
||||
echo
|
||||
info "Core SDR:"
|
||||
check_required "rtl_fm" "RTL-SDR FM demodulator" rtl_fm
|
||||
check_required "rtl_test" "RTL-SDR device detection" rtl_test
|
||||
check_required "multimon-ng" "Pager decoder" multimon-ng
|
||||
check_required "rtl_433" "433MHz sensor decoder" rtl_433 rtl433
|
||||
check_required "dump1090" "ADS-B decoder" dump1090
|
||||
|
||||
echo
|
||||
info "GPS:"
|
||||
check_required "gpsd" "GPS daemon" gpsd
|
||||
|
||||
echo
|
||||
info "Audio:"
|
||||
check_required "ffmpeg" "Audio encoder/decoder" ffmpeg
|
||||
|
||||
echo
|
||||
info "WiFi:"
|
||||
check_required "airmon-ng" "Monitor mode helper" airmon-ng
|
||||
check_required "airodump-ng" "WiFi scanner" airodump-ng
|
||||
check_required "aireplay-ng" "Injection/deauth" aireplay-ng
|
||||
check_required "hcxdumptool" "PMKID capture" hcxdumptool
|
||||
check_required "hcxpcapngtool" "PMKID/pcapng conversion" hcxpcapngtool
|
||||
|
||||
echo
|
||||
info "Bluetooth:"
|
||||
check_required "bluetoothctl" "Bluetooth controller CLI" bluetoothctl
|
||||
check_required "hcitool" "Bluetooth scan utility" hcitool
|
||||
check_required "hciconfig" "Bluetooth adapter config" hciconfig
|
||||
|
||||
echo
|
||||
info "SoapySDR:"
|
||||
check_required "SoapySDRUtil" "SoapySDR CLI utility" SoapySDRUtil
|
||||
echo
|
||||
}
|
||||
|
||||
# ----------------------------
|
||||
# Python venv + deps
|
||||
# ----------------------------
|
||||
check_python_version() {
|
||||
if ! cmd_exists python3; then
|
||||
fail "python3 not found."
|
||||
[[ "$OS" == "macos" ]] && echo "Install with: brew install python"
|
||||
[[ "$OS" == "debian" ]] && echo "Install with: sudo apt-get install python3"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
local ver
|
||||
ver="$(python3 -c 'import sys; print(f"{sys.version_info.major}.{sys.version_info.minor}")')"
|
||||
info "Python version: ${ver}"
|
||||
|
||||
python3 - <<'PY'
|
||||
import sys
|
||||
raise SystemExit(0 if sys.version_info >= (3,9) else 1)
|
||||
PY
|
||||
ok "Python version OK (>= 3.9)"
|
||||
}
|
||||
|
||||
install_python_deps() {
|
||||
info "Setting up Python virtual environment..."
|
||||
check_python_version
|
||||
|
||||
if [[ ! -f requirements.txt ]]; then
|
||||
warn "requirements.txt not found; skipping Python dependency install."
|
||||
return 0
|
||||
fi
|
||||
|
||||
if [[ ! -d venv ]]; then
|
||||
python3 -m venv venv
|
||||
ok "Created venv/"
|
||||
else
|
||||
ok "Using existing venv/"
|
||||
fi
|
||||
|
||||
# shellcheck disable=SC1091
|
||||
source venv/bin/activate
|
||||
|
||||
python -m pip install --upgrade pip setuptools wheel >/dev/null
|
||||
ok "Upgraded pip tooling"
|
||||
|
||||
info "Installing Python requirements..."
|
||||
python -m pip install -r requirements.txt
|
||||
ok "Python dependencies installed"
|
||||
echo
|
||||
}
|
||||
|
||||
# ----------------------------
|
||||
# macOS install (Homebrew)
|
||||
# ----------------------------
|
||||
ensure_brew() {
|
||||
cmd_exists brew && return 0
|
||||
warn "Homebrew not found. Installing Homebrew..."
|
||||
/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"
|
||||
|
||||
if [[ -x /opt/homebrew/bin/brew ]]; then
|
||||
eval "$(/opt/homebrew/bin/brew shellenv)"
|
||||
elif [[ -x /usr/local/bin/brew ]]; then
|
||||
eval "$(/usr/local/bin/brew shellenv)"
|
||||
fi
|
||||
|
||||
cmd_exists brew || { fail "Homebrew install failed. Install manually then re-run."; exit 1; }
|
||||
}
|
||||
|
||||
brew_install() {
|
||||
local pkg="$1"
|
||||
if brew list --formula "$pkg" >/dev/null 2>&1; then
|
||||
ok "brew: ${pkg} already installed"
|
||||
return 0
|
||||
fi
|
||||
info "brew: installing ${pkg}..."
|
||||
brew install "$pkg"
|
||||
ok "brew: installed ${pkg}"
|
||||
}
|
||||
|
||||
install_macos_packages() {
|
||||
ensure_brew
|
||||
info "Installing packages via Homebrew..."
|
||||
|
||||
brew_install librtlsdr
|
||||
brew_install multimon-ng
|
||||
brew_install ffmpeg
|
||||
brew_install rtl_433
|
||||
|
||||
# ADS-B (may not exist)
|
||||
warn "Attempting dump1090 install via Homebrew (may be unavailable)..."
|
||||
(brew_install dump1090-mutability) || true
|
||||
|
||||
brew_install aircrack-ng
|
||||
brew_install hcxtools
|
||||
brew_install soapysdr
|
||||
brew_install gpsd
|
||||
|
||||
warn "macOS note: hcitool/hciconfig are Linux (BlueZ) utilities and often unavailable on macOS."
|
||||
echo
|
||||
}
|
||||
|
||||
# ----------------------------
|
||||
# Debian/Ubuntu install (APT)
|
||||
# ----------------------------
|
||||
apt_install() { $SUDO apt-get install -y --no-install-recommends "$@" >/dev/null; }
|
||||
|
||||
apt_try_install_any() {
|
||||
local p
|
||||
for p in "$@"; do
|
||||
if $SUDO apt-get install -y --no-install-recommends "$p" >/dev/null 2>&1; then
|
||||
ok "apt: installed ${p}"
|
||||
return 0
|
||||
fi
|
||||
done
|
||||
return 1
|
||||
}
|
||||
|
||||
install_dump1090_from_source_debian() {
|
||||
info "dump1090 not available via APT. Building from source (required)..."
|
||||
|
||||
apt_install build-essential git pkg-config \
|
||||
librtlsdr-dev libusb-1.0-0-dev \
|
||||
libncurses-dev tcl-dev python3-dev
|
||||
|
||||
local orig_dir tmp_dir
|
||||
orig_dir="$(pwd)"
|
||||
tmp_dir="$(mktemp -d)"
|
||||
|
||||
cleanup() { cd "$orig_dir" >/dev/null 2>&1 || true; rm -rf "$tmp_dir"; }
|
||||
trap cleanup EXIT
|
||||
|
||||
info "Cloning FlightAware dump1090..."
|
||||
git clone --depth 1 https://github.com/flightaware/dump1090.git "$tmp_dir/dump1090" >/dev/null 2>&1 \
|
||||
|| { fail "Failed to clone FlightAware dump1090"; exit 1; }
|
||||
|
||||
cd "$tmp_dir/dump1090"
|
||||
info "Compiling FlightAware dump1090..."
|
||||
if make BLADERF=no RTLSDR=yes >/dev/null 2>&1; then
|
||||
$SUDO install -m 0755 dump1090 /usr/local/bin/dump1090
|
||||
ok "dump1090 installed successfully (FlightAware)."
|
||||
return 0
|
||||
fi
|
||||
|
||||
warn "FlightAware build failed. Falling back to antirez/dump1090..."
|
||||
rm -rf "$tmp_dir/dump1090"
|
||||
git clone --depth 1 https://github.com/antirez/dump1090.git "$tmp_dir/dump1090" >/dev/null 2>&1 \
|
||||
|| { fail "Failed to clone antirez dump1090"; exit 1; }
|
||||
|
||||
cd "$tmp_dir/dump1090"
|
||||
info "Compiling antirez dump1090..."
|
||||
make >/dev/null 2>&1 || { fail "Failed to build dump1090 from source (required)."; exit 1; }
|
||||
|
||||
$SUDO install -m 0755 dump1090 /usr/local/bin/dump1090
|
||||
ok "dump1090 installed successfully (antirez)."
|
||||
}
|
||||
|
||||
setup_udev_rules_debian() {
|
||||
[[ -d /etc/udev/rules.d ]] || { warn "udev not found; skipping RTL-SDR udev rules."; return 0; }
|
||||
|
||||
local rules_file="/etc/udev/rules.d/20-rtlsdr.rules"
|
||||
[[ -f "$rules_file" ]] && { ok "RTL-SDR udev rules already present: $rules_file"; return 0; }
|
||||
|
||||
info "Installing RTL-SDR udev rules..."
|
||||
$SUDO tee "$rules_file" >/dev/null <<'EOF'
|
||||
SUBSYSTEM=="usb", ATTRS{idVendor}=="0bda", ATTRS{idProduct}=="2838", MODE="0666"
|
||||
SUBSYSTEM=="usb", ATTRS{idVendor}=="0bda", ATTRS{idProduct}=="2832", MODE="0666"
|
||||
EOF
|
||||
$SUDO udevadm control --reload-rules || true
|
||||
$SUDO udevadm trigger || true
|
||||
ok "udev rules installed. Unplug/replug your RTL-SDR if connected."
|
||||
echo
|
||||
}
|
||||
|
||||
install_debian_packages() {
|
||||
need_sudo
|
||||
info "Updating APT package lists..."
|
||||
$SUDO apt-get update -y >/dev/null
|
||||
|
||||
info "Installing required packages via APT..."
|
||||
apt_install rtl-sdr
|
||||
apt_install multimon-ng
|
||||
apt_install ffmpeg
|
||||
|
||||
apt_try_install_any rtl-433 rtl433 || true
|
||||
|
||||
apt_install aircrack-ng || true
|
||||
apt_install hcxdumptool || true
|
||||
apt_install hcxtools || true
|
||||
apt_install bluez bluetooth || true
|
||||
apt_install soapysdr-tools || true
|
||||
apt_install gpsd gpsd-clients || true
|
||||
|
||||
# dump1090: apt first; source fallback; hard fail inside if it can't build
|
||||
if ! cmd_exists dump1090; then
|
||||
apt_try_install_any dump1090-fa dump1090-mutability dump1090 || true
|
||||
fi
|
||||
cmd_exists dump1090 || install_dump1090_from_source_debian
|
||||
|
||||
setup_udev_rules_debian
|
||||
}
|
||||
|
||||
# ----------------------------
|
||||
# Final summary / hard fail
|
||||
# ----------------------------
|
||||
final_summary_and_hard_fail() {
|
||||
check_tools
|
||||
|
||||
echo "============================================"
|
||||
if [[ "${#missing_required[@]}" -eq 0 ]]; then
|
||||
ok "All REQUIRED tools are installed."
|
||||
else
|
||||
fail "Missing REQUIRED tools:"
|
||||
for t in "${missing_required[@]}"; do echo " - $t"; done
|
||||
echo
|
||||
fail "Exiting because required tools are missing."
|
||||
echo
|
||||
warn "If you are on macOS: hcitool/hciconfig are Linux (BlueZ) tools and may not be installable."
|
||||
warn "If you truly require them everywhere, you must restrict supported platforms or provide alternatives."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo
|
||||
echo "To start INTERCEPT:"
|
||||
echo " source venv/bin/activate"
|
||||
echo " sudo python intercept.py"
|
||||
echo
|
||||
echo "Then open http://localhost:5050 in your browser"
|
||||
echo
|
||||
}
|
||||
|
||||
# ----------------------------
|
||||
# MAIN
|
||||
# ----------------------------
|
||||
main() {
|
||||
detect_os
|
||||
|
||||
if [[ "$OS" == "macos" ]]; then
|
||||
install_macos_packages
|
||||
else
|
||||
install_debian_packages
|
||||
fi
|
||||
|
||||
install_python_deps
|
||||
final_summary_and_hard_fail
|
||||
}
|
||||
|
||||
main "$@"
|
||||
|
||||
@@ -1,26 +1,43 @@
|
||||
#!/bin/bash
|
||||
#
|
||||
# INTERCEPT Setup Script
|
||||
# Installs dependencies for macOS and Debian/Ubuntu
|
||||
#
|
||||
#!/usr/bin/env bash
|
||||
# INTERCEPT Setup Script (best-effort installs, hard-fail verification)
|
||||
|
||||
# Don't exit on errors - we handle them explicitly
|
||||
set +e
|
||||
# ---- Force bash even if launched with sh ----
|
||||
if [ -z "${BASH_VERSION:-}" ]; then
|
||||
echo "[x] This script must be run with bash (not sh)."
|
||||
echo " Run: bash $0"
|
||||
exec bash "$0" "$@"
|
||||
fi
|
||||
|
||||
# Pause briefly after each action so output is readable
|
||||
PAUSE_TIME=1
|
||||
set -Eeuo pipefail
|
||||
|
||||
pause() {
|
||||
sleep $PAUSE_TIME
|
||||
}
|
||||
# Ensure admin paths are searchable (many tools live here)
|
||||
export PATH="/usr/local/sbin:/usr/sbin:/sbin:/opt/homebrew/sbin:/opt/homebrew/bin:$PATH"
|
||||
|
||||
# Colors for output
|
||||
# ----------------------------
|
||||
# Pretty output
|
||||
# ----------------------------
|
||||
RED='\033[0;31m'
|
||||
GREEN='\033[0;32m'
|
||||
YELLOW='\033[1;33m'
|
||||
BLUE='\033[0;34m'
|
||||
NC='\033[0m' # No Color
|
||||
NC='\033[0m'
|
||||
|
||||
info() { echo -e "${BLUE}[*]${NC} $*"; }
|
||||
ok() { echo -e "${GREEN}[✓]${NC} $*"; }
|
||||
warn() { echo -e "${YELLOW}[!]${NC} $*"; }
|
||||
fail() { echo -e "${RED}[x]${NC} $*"; }
|
||||
|
||||
on_error() {
|
||||
local line="$1"
|
||||
local cmd="${2:-unknown}"
|
||||
fail "Setup failed at line ${line}: ${cmd}"
|
||||
exit 1
|
||||
}
|
||||
trap 'on_error $LINENO "$BASH_COMMAND"' ERR
|
||||
|
||||
# ----------------------------
|
||||
# Banner
|
||||
# ----------------------------
|
||||
echo -e "${BLUE}"
|
||||
echo " ___ _ _ _____ _____ ____ ____ _____ ____ _____ "
|
||||
echo " |_ _| \\ | |_ _| ____| _ \\ / ___| ____| _ \\_ _|"
|
||||
@@ -28,619 +45,356 @@ echo " | || \\| | | | | _| | |_) | | | _| | |_) || | "
|
||||
echo " | || |\\ | | | | |___| _ <| |___| |___| __/ | | "
|
||||
echo " |___|_| \\_| |_| |_____|_| \\_\\\\____|_____|_| |_| "
|
||||
echo -e "${NC}"
|
||||
echo "Signal Intelligence Platform - Setup Script"
|
||||
echo "INTERCEPT - Setup Script"
|
||||
echo "============================================"
|
||||
echo ""
|
||||
echo
|
||||
|
||||
# ----------------------------
|
||||
# Helpers
|
||||
# ----------------------------
|
||||
cmd_exists() {
|
||||
local c="$1"
|
||||
command -v "$c" >/dev/null 2>&1 && return 0
|
||||
[[ -x "/usr/sbin/$c" || -x "/sbin/$c" || -x "/usr/local/sbin/$c" || -x "/opt/homebrew/sbin/$c" ]] && return 0
|
||||
return 1
|
||||
}
|
||||
|
||||
have_any() {
|
||||
local c
|
||||
for c in "$@"; do
|
||||
cmd_exists "$c" && return 0
|
||||
done
|
||||
return 1
|
||||
}
|
||||
|
||||
need_sudo() {
|
||||
if [[ "$(id -u)" -eq 0 ]]; then
|
||||
SUDO=""
|
||||
ok "Running as root"
|
||||
else
|
||||
if cmd_exists sudo; then
|
||||
SUDO="sudo"
|
||||
else
|
||||
fail "sudo is not installed and you're not root."
|
||||
echo "Either run as root or install sudo first."
|
||||
exit 1
|
||||
fi
|
||||
fi
|
||||
}
|
||||
|
||||
# Detect OS
|
||||
detect_os() {
|
||||
if [[ "$OSTYPE" == "darwin"* ]]; then
|
||||
OS="macos"
|
||||
PKG_MANAGER="brew"
|
||||
elif [[ -f /etc/debian_version ]]; then
|
||||
OS="debian"
|
||||
PKG_MANAGER="apt"
|
||||
else
|
||||
OS="unknown"
|
||||
PKG_MANAGER="unknown"
|
||||
fi
|
||||
echo -e "${BLUE}Detected OS:${NC} $OS"
|
||||
if [[ "${OSTYPE:-}" == "darwin"* ]]; then
|
||||
OS="macos"
|
||||
elif [[ -f /etc/debian_version ]]; then
|
||||
OS="debian"
|
||||
else
|
||||
OS="unknown"
|
||||
fi
|
||||
info "Detected OS: ${OS}"
|
||||
[[ "$OS" != "unknown" ]] || { fail "Unsupported OS (macOS + Debian/Ubuntu only)."; exit 1; }
|
||||
}
|
||||
|
||||
# Check if a command exists (also check /usr/sbin for Debian)
|
||||
check_cmd() {
|
||||
command -v "$1" &> /dev/null || [ -x "/usr/sbin/$1" ] || [ -x "/sbin/$1" ]
|
||||
}
|
||||
# ----------------------------
|
||||
# Required tool checks (with alternates)
|
||||
# ----------------------------
|
||||
missing_required=()
|
||||
|
||||
# Check if a package is installable (Debian)
|
||||
pkg_available() {
|
||||
local candidate
|
||||
candidate=$(apt-cache policy "$1" 2>/dev/null | grep "Candidate:" | awk '{print $2}')
|
||||
[ -n "$candidate" ] && [ "$candidate" != "(none)" ]
|
||||
}
|
||||
check_required() {
|
||||
local label="$1"; shift
|
||||
local desc="$1"; shift
|
||||
|
||||
# Setup sudo command
|
||||
setup_sudo() {
|
||||
if [ "$(id -u)" -eq 0 ]; then
|
||||
SUDO=""
|
||||
echo -e "${BLUE}Running as root${NC}"
|
||||
elif check_cmd sudo; then
|
||||
SUDO="sudo"
|
||||
else
|
||||
echo -e "${RED}Error: Not running as root and sudo is not installed${NC}"
|
||||
exit 1
|
||||
fi
|
||||
}
|
||||
|
||||
# ============================================
|
||||
# PYTHON DEPENDENCIES
|
||||
# ============================================
|
||||
install_python_deps() {
|
||||
echo ""
|
||||
echo -e "${BLUE}[3/3] Installing Python dependencies...${NC}"
|
||||
|
||||
if ! check_cmd python3; then
|
||||
echo -e "${RED}Error: Python 3 is not installed${NC}"
|
||||
if [[ "$OS" == "macos" ]]; then
|
||||
echo "Install with: brew install python@3.11"
|
||||
else
|
||||
echo "Install with: sudo apt install python3"
|
||||
fi
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Check Python version
|
||||
PYTHON_VERSION=$(python3 -c 'import sys; print(f"{sys.version_info.major}.{sys.version_info.minor}")')
|
||||
PYTHON_MAJOR=$(python3 -c 'import sys; print(sys.version_info.major)')
|
||||
PYTHON_MINOR=$(python3 -c 'import sys; print(sys.version_info.minor)')
|
||||
echo "Python version: $PYTHON_VERSION"
|
||||
|
||||
if [ "$PYTHON_MAJOR" -lt 3 ] || ([ "$PYTHON_MAJOR" -eq 3 ] && [ "$PYTHON_MINOR" -lt 9 ]); then
|
||||
echo -e "${RED}Error: Python 3.9 or later is required (you have $PYTHON_VERSION)${NC}"
|
||||
if [[ "$OS" == "macos" ]]; then
|
||||
echo "Upgrade with: brew install python@3.11"
|
||||
else
|
||||
echo "Upgrade with: sudo apt install python3.11"
|
||||
fi
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Install dependencies
|
||||
if [ -n "$VIRTUAL_ENV" ]; then
|
||||
echo "Using virtual environment: $VIRTUAL_ENV"
|
||||
pip install -r requirements.txt || echo -e "${YELLOW}Warning: Some Python packages may have failed${NC}"
|
||||
elif [ -f "venv/bin/activate" ]; then
|
||||
echo "Found existing venv, activating..."
|
||||
source venv/bin/activate
|
||||
pip install -r requirements.txt || echo -e "${YELLOW}Warning: Some Python packages may have failed${NC}"
|
||||
else
|
||||
# Try pip install, fall back to venv if needed (PEP 668)
|
||||
if python3 -m pip install -r requirements.txt 2>/dev/null; then
|
||||
echo -e "${GREEN}Python dependencies installed${NC}"
|
||||
return
|
||||
fi
|
||||
|
||||
echo -e "${YELLOW}Creating virtual environment...${NC}"
|
||||
if [ -d "venv" ] && [ ! -f "venv/bin/activate" ]; then
|
||||
rm -rf venv
|
||||
fi
|
||||
|
||||
# Install python3-venv if needed
|
||||
if [[ "$OS" == "debian" ]]; then
|
||||
$SUDO apt-get install -y python3-venv 2>/dev/null || true
|
||||
fi
|
||||
|
||||
if ! python3 -m venv venv; then
|
||||
echo -e "${RED}Error: Failed to create virtual environment${NC}"
|
||||
echo -e "${YELLOW}Continuing with system tool installation...${NC}"
|
||||
return
|
||||
fi
|
||||
|
||||
source venv/bin/activate
|
||||
pip install -r requirements.txt || echo -e "${YELLOW}Warning: Some Python packages may have failed${NC}"
|
||||
|
||||
echo ""
|
||||
echo -e "${YELLOW}NOTE: Virtual environment created.${NC}"
|
||||
echo "Activate with: source venv/bin/activate"
|
||||
fi
|
||||
|
||||
echo -e "${GREEN}Python dependencies installed${NC}"
|
||||
}
|
||||
|
||||
# ============================================
|
||||
# TOOL CHECKING
|
||||
# ============================================
|
||||
check_tool() {
|
||||
local cmd=$1
|
||||
local desc=$2
|
||||
local category=$3
|
||||
if check_cmd "$cmd"; then
|
||||
echo -e " ${GREEN}✓${NC} $cmd - $desc"
|
||||
return 0
|
||||
else
|
||||
echo -e " ${RED}✗${NC} $cmd - $desc ${YELLOW}(not found)${NC}"
|
||||
MISSING_TOOLS+=("$cmd")
|
||||
case "$category" in
|
||||
core) MISSING_CORE=true ;;
|
||||
audio) MISSING_AUDIO=true ;;
|
||||
wifi) MISSING_WIFI=true ;;
|
||||
bluetooth) MISSING_BLUETOOTH=true ;;
|
||||
esac
|
||||
return 1
|
||||
fi
|
||||
if have_any "$@"; then
|
||||
ok "${label} - ${desc}"
|
||||
else
|
||||
warn "${label} - ${desc} (missing, required)"
|
||||
missing_required+=("$label")
|
||||
fi
|
||||
}
|
||||
|
||||
check_tools() {
|
||||
echo ""
|
||||
echo -e "${BLUE}[1/3] Checking external tools...${NC}"
|
||||
echo ""
|
||||
info "Checking required tools..."
|
||||
missing_required=()
|
||||
|
||||
MISSING_TOOLS=()
|
||||
MISSING_CORE=false
|
||||
MISSING_AUDIO=false
|
||||
MISSING_WIFI=false
|
||||
MISSING_BLUETOOTH=false
|
||||
echo
|
||||
info "Core SDR:"
|
||||
check_required "rtl_fm" "RTL-SDR FM demodulator" rtl_fm
|
||||
check_required "rtl_test" "RTL-SDR device detection" rtl_test
|
||||
check_required "multimon-ng" "Pager decoder" multimon-ng
|
||||
check_required "rtl_433" "433MHz sensor decoder" rtl_433 rtl433
|
||||
check_required "dump1090" "ADS-B decoder" dump1090
|
||||
|
||||
echo "Core SDR Tools:"
|
||||
check_tool "rtl_fm" "RTL-SDR FM demodulator" "core"
|
||||
check_tool "rtl_test" "RTL-SDR device detection" "core"
|
||||
check_tool "multimon-ng" "Pager decoder" "core"
|
||||
check_tool "rtl_433" "433MHz sensor decoder" "core"
|
||||
check_tool "dump1090" "ADS-B decoder" "core"
|
||||
echo
|
||||
info "GPS:"
|
||||
check_required "gpsd" "GPS daemon" gpsd
|
||||
|
||||
echo ""
|
||||
echo "Audio Tools:"
|
||||
check_tool "ffmpeg" "Audio encoder for streaming" "audio"
|
||||
echo
|
||||
info "Audio:"
|
||||
check_required "ffmpeg" "Audio encoder/decoder" ffmpeg
|
||||
|
||||
echo ""
|
||||
echo "WiFi Tools:"
|
||||
check_tool "airmon-ng" "WiFi monitor mode" "wifi"
|
||||
check_tool "airodump-ng" "WiFi scanner" "wifi"
|
||||
# aireplay-ng is optional (for deauth)
|
||||
if check_cmd aireplay-ng; then
|
||||
echo -e " ${GREEN}✓${NC} aireplay-ng - Deauthentication (optional)"
|
||||
fi
|
||||
# PMKID tools are optional
|
||||
if check_cmd hcxdumptool; then
|
||||
echo -e " ${GREEN}✓${NC} hcxdumptool - PMKID capture (optional)"
|
||||
else
|
||||
echo -e " ${YELLOW}-${NC} hcxdumptool - PMKID capture (optional)"
|
||||
fi
|
||||
if check_cmd hcxpcapngtool; then
|
||||
echo -e " ${GREEN}✓${NC} hcxpcapngtool - Hash extraction (optional)"
|
||||
else
|
||||
echo -e " ${YELLOW}-${NC} hcxpcapngtool - Hash extraction (optional)"
|
||||
fi
|
||||
echo
|
||||
info "WiFi:"
|
||||
check_required "airmon-ng" "Monitor mode helper" airmon-ng
|
||||
check_required "airodump-ng" "WiFi scanner" airodump-ng
|
||||
check_required "aireplay-ng" "Injection/deauth" aireplay-ng
|
||||
check_required "hcxdumptool" "PMKID capture" hcxdumptool
|
||||
check_required "hcxpcapngtool" "PMKID/pcapng conversion" hcxpcapngtool
|
||||
|
||||
echo ""
|
||||
echo "Bluetooth Tools:"
|
||||
check_tool "hcitool" "Bluetooth scanner" "bluetooth"
|
||||
check_tool "bluetoothctl" "Bluetooth controller" "bluetooth"
|
||||
check_tool "hciconfig" "Bluetooth adapter config" "bluetooth"
|
||||
echo
|
||||
info "Bluetooth:"
|
||||
check_required "bluetoothctl" "Bluetooth controller CLI" bluetoothctl
|
||||
check_required "hcitool" "Bluetooth scan utility" hcitool
|
||||
check_required "hciconfig" "Bluetooth adapter config" hciconfig
|
||||
|
||||
echo ""
|
||||
echo "Optional (LimeSDR/HackRF):"
|
||||
if check_cmd SoapySDRUtil; then
|
||||
echo -e " ${GREEN}✓${NC} SoapySDRUtil - SoapySDR support"
|
||||
else
|
||||
echo -e " ${YELLOW}-${NC} SoapySDRUtil - Not installed (optional)"
|
||||
fi
|
||||
|
||||
if [ ${#MISSING_TOOLS[@]} -gt 0 ]; then
|
||||
echo ""
|
||||
echo -e "${YELLOW}Some tools are missing.${NC}"
|
||||
else
|
||||
echo ""
|
||||
echo -e "${GREEN}All tools installed!${NC}"
|
||||
fi
|
||||
echo
|
||||
info "SoapySDR:"
|
||||
check_required "SoapySDRUtil" "SoapySDR CLI utility" SoapySDRUtil
|
||||
echo
|
||||
}
|
||||
|
||||
# ============================================
|
||||
# macOS INSTALLATION
|
||||
# ============================================
|
||||
install_macos_tools() {
|
||||
echo ""
|
||||
echo -e "${BLUE}[2/3] Installing tools (macOS)...${NC}"
|
||||
echo ""
|
||||
# ----------------------------
|
||||
# Python venv + deps
|
||||
# ----------------------------
|
||||
check_python_version() {
|
||||
if ! cmd_exists python3; then
|
||||
fail "python3 not found."
|
||||
[[ "$OS" == "macos" ]] && echo "Install with: brew install python"
|
||||
[[ "$OS" == "debian" ]] && echo "Install with: sudo apt-get install python3"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [ ${#MISSING_TOOLS[@]} -eq 0 ]; then
|
||||
echo -e "${GREEN}All tools are already installed!${NC}"
|
||||
return
|
||||
fi
|
||||
local ver
|
||||
ver="$(python3 -c 'import sys; print(f"{sys.version_info.major}.{sys.version_info.minor}")')"
|
||||
info "Python version: ${ver}"
|
||||
|
||||
# Check for Homebrew
|
||||
if ! check_cmd brew; then
|
||||
echo -e "${YELLOW}Homebrew is not installed. Installing...${NC}"
|
||||
echo ""
|
||||
/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"
|
||||
|
||||
# Add brew to PATH for this session
|
||||
if [[ -f /opt/homebrew/bin/brew ]]; then
|
||||
eval "$(/opt/homebrew/bin/brew shellenv)"
|
||||
elif [[ -f /usr/local/bin/brew ]]; then
|
||||
eval "$(/usr/local/bin/brew shellenv)"
|
||||
fi
|
||||
|
||||
if ! check_cmd brew; then
|
||||
echo -e "${RED}Failed to install Homebrew. Install manually:${NC}"
|
||||
show_macos_manual
|
||||
return
|
||||
fi
|
||||
fi
|
||||
|
||||
echo -e "${YELLOW}Installing missing tools automatically...${NC}"
|
||||
echo ""
|
||||
|
||||
# Core SDR tools
|
||||
if $MISSING_CORE; then
|
||||
echo ""
|
||||
echo -e "${BLUE}Installing Core SDR tools...${NC}"
|
||||
|
||||
echo " Installing librtlsdr..."
|
||||
brew install librtlsdr || echo -e "${YELLOW} Warning: librtlsdr installation failed${NC}"
|
||||
|
||||
echo " Installing multimon-ng..."
|
||||
brew install multimon-ng || echo -e "${YELLOW} Warning: multimon-ng installation failed${NC}"
|
||||
|
||||
echo " Installing rtl_433..."
|
||||
brew install rtl_433 || echo -e "${YELLOW} Warning: rtl_433 installation failed${NC}"
|
||||
|
||||
# dump1090
|
||||
if ! check_cmd dump1090; then
|
||||
echo " Installing dump1090..."
|
||||
brew install dump1090-mutability || \
|
||||
echo -e "${YELLOW} Note: dump1090 may need manual installation${NC}"
|
||||
fi
|
||||
fi
|
||||
|
||||
# Audio tools
|
||||
if $MISSING_AUDIO; then
|
||||
echo ""
|
||||
echo -e "${BLUE}Installing Audio tools...${NC}"
|
||||
echo " Installing ffmpeg..."
|
||||
brew install ffmpeg || echo -e "${YELLOW} Warning: ffmpeg installation failed${NC}"
|
||||
fi
|
||||
|
||||
# WiFi tools
|
||||
if $MISSING_WIFI; then
|
||||
echo ""
|
||||
echo -e "${BLUE}Installing WiFi tools...${NC}"
|
||||
echo " Installing aircrack-ng..."
|
||||
brew install aircrack-ng || echo -e "${YELLOW} Warning: aircrack-ng installation failed${NC}"
|
||||
echo " Installing hcxtools (PMKID capture)..."
|
||||
brew install hcxtools || echo -e "${YELLOW} Warning: hcxtools installation failed${NC}"
|
||||
fi
|
||||
|
||||
echo ""
|
||||
echo -e "${GREEN}Tool installation complete!${NC}"
|
||||
python3 - <<'PY'
|
||||
import sys
|
||||
raise SystemExit(0 if sys.version_info >= (3,9) else 1)
|
||||
PY
|
||||
ok "Python version OK (>= 3.9)"
|
||||
}
|
||||
|
||||
show_macos_manual() {
|
||||
echo ""
|
||||
echo -e "${BLUE}Manual installation (macOS):${NC}"
|
||||
echo ""
|
||||
echo "# Required tools"
|
||||
echo "brew install librtlsdr multimon-ng rtl_433 ffmpeg"
|
||||
echo ""
|
||||
echo "# ADS-B tracking"
|
||||
echo "brew install dump1090-mutability"
|
||||
echo ""
|
||||
echo "# WiFi scanning (optional)"
|
||||
echo "brew install aircrack-ng hcxtools"
|
||||
install_python_deps() {
|
||||
info "Setting up Python virtual environment..."
|
||||
check_python_version
|
||||
|
||||
if [[ ! -f requirements.txt ]]; then
|
||||
warn "requirements.txt not found; skipping Python dependency install."
|
||||
return 0
|
||||
fi
|
||||
|
||||
if [[ ! -d venv ]]; then
|
||||
python3 -m venv venv
|
||||
ok "Created venv/"
|
||||
else
|
||||
ok "Using existing venv/"
|
||||
fi
|
||||
|
||||
# shellcheck disable=SC1091
|
||||
source venv/bin/activate
|
||||
|
||||
python -m pip install --upgrade pip setuptools wheel >/dev/null
|
||||
ok "Upgraded pip tooling"
|
||||
|
||||
info "Installing Python requirements..."
|
||||
python -m pip install -r requirements.txt
|
||||
ok "Python dependencies installed"
|
||||
echo
|
||||
}
|
||||
|
||||
# ============================================
|
||||
# BUILD DUMP1090 FROM SOURCE
|
||||
# ============================================
|
||||
install_dump1090_from_source() {
|
||||
echo " Installing build dependencies..."
|
||||
$SUDO apt-get install -y build-essential git librtlsdr-dev libusb-1.0-0-dev \
|
||||
pkg-config libncurses-dev debhelper tcl-dev python3-dev || true
|
||||
# ----------------------------
|
||||
# macOS install (Homebrew)
|
||||
# ----------------------------
|
||||
ensure_brew() {
|
||||
cmd_exists brew && return 0
|
||||
warn "Homebrew not found. Installing Homebrew..."
|
||||
/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"
|
||||
|
||||
# Save current directory
|
||||
local orig_dir=$(pwd)
|
||||
local tmp_dir=$(mktemp -d)
|
||||
if [[ -x /opt/homebrew/bin/brew ]]; then
|
||||
eval "$(/opt/homebrew/bin/brew shellenv)"
|
||||
elif [[ -x /usr/local/bin/brew ]]; then
|
||||
eval "$(/usr/local/bin/brew shellenv)"
|
||||
fi
|
||||
|
||||
echo " Cloning dump1090 repository..."
|
||||
if ! git clone --depth 1 https://github.com/flightaware/dump1090.git "$tmp_dir/dump1090" 2>&1; then
|
||||
echo -e "${RED} Failed to clone dump1090 repository${NC}"
|
||||
rm -rf "$tmp_dir"
|
||||
return 1
|
||||
fi
|
||||
|
||||
cd "$tmp_dir/dump1090"
|
||||
|
||||
echo " Compiling dump1090 (this may take a minute)..."
|
||||
# Try to build - use BLADERF=no to skip BladeRF dependency
|
||||
if make BLADERF=no RTLSDR=yes 2>&1; then
|
||||
echo " Installing dump1090 to /usr/local/bin..."
|
||||
$SUDO cp dump1090 /usr/local/bin/
|
||||
$SUDO chmod +x /usr/local/bin/dump1090
|
||||
echo -e "${GREEN} dump1090 installed successfully!${NC}"
|
||||
else
|
||||
echo -e "${RED} Failed to compile dump1090${NC}"
|
||||
echo " Trying simpler antirez version..."
|
||||
|
||||
# Try the simpler antirez version as fallback
|
||||
cd "$tmp_dir"
|
||||
rm -rf dump1090
|
||||
if git clone --depth 1 https://github.com/antirez/dump1090.git 2>&1; then
|
||||
cd dump1090
|
||||
if make 2>&1; then
|
||||
$SUDO cp dump1090 /usr/local/bin/
|
||||
$SUDO chmod +x /usr/local/bin/dump1090
|
||||
echo -e "${GREEN} dump1090 (antirez) installed successfully!${NC}"
|
||||
else
|
||||
echo -e "${RED} Failed to compile dump1090${NC}"
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
|
||||
# Cleanup
|
||||
cd "$orig_dir"
|
||||
rm -rf "$tmp_dir"
|
||||
cmd_exists brew || { fail "Homebrew install failed. Install manually then re-run."; exit 1; }
|
||||
}
|
||||
|
||||
# ============================================
|
||||
# DEBIAN INSTALLATION
|
||||
# ============================================
|
||||
install_debian_tools() {
|
||||
echo ""
|
||||
echo -e "${BLUE}[2/3] Installing tools (Debian/Ubuntu)...${NC}"
|
||||
echo ""
|
||||
|
||||
echo "Updating package lists..."
|
||||
$SUDO apt-get update -qq
|
||||
|
||||
# Always try to install all tools - apt will skip already installed ones
|
||||
echo ""
|
||||
echo -e "${BLUE}Installing Core SDR tools...${NC}"
|
||||
|
||||
# Install rtl-sdr
|
||||
echo " Installing rtl-sdr..."
|
||||
if $SUDO apt-get install -y rtl-sdr; then
|
||||
echo -e "${GREEN} rtl-sdr installed${NC}"
|
||||
else
|
||||
echo -e "${YELLOW} Warning: rtl-sdr installation failed${NC}"
|
||||
fi
|
||||
pause
|
||||
|
||||
# Install multimon-ng
|
||||
echo " Installing multimon-ng..."
|
||||
if $SUDO apt-get install -y multimon-ng; then
|
||||
echo -e "${GREEN} multimon-ng installed${NC}"
|
||||
else
|
||||
echo -e "${YELLOW} Warning: multimon-ng installation failed${NC}"
|
||||
fi
|
||||
pause
|
||||
|
||||
# rtl-433 (package name varies by distribution)
|
||||
echo " Installing rtl-433..."
|
||||
if $SUDO apt-get install -y rtl-433 2>/dev/null; then
|
||||
echo -e "${GREEN} rtl-433 installed${NC}"
|
||||
elif $SUDO apt-get install -y rtl433 2>/dev/null; then
|
||||
echo -e "${GREEN} rtl433 installed${NC}"
|
||||
else
|
||||
echo -e "${YELLOW} Note: rtl-433 not in repositories${NC}"
|
||||
echo " Install manually from: https://github.com/merbanan/rtl_433"
|
||||
fi
|
||||
pause
|
||||
|
||||
# dump1090 (package varies by distribution)
|
||||
echo " Installing dump1090..."
|
||||
if check_cmd dump1090; then
|
||||
echo -e "${GREEN} dump1090 already installed${NC}"
|
||||
elif $SUDO apt-get install -y dump1090-fa 2>/dev/null; then
|
||||
echo -e "${GREEN} dump1090-fa installed${NC}"
|
||||
elif $SUDO apt-get install -y dump1090-mutability 2>/dev/null; then
|
||||
echo -e "${GREEN} dump1090-mutability installed${NC}"
|
||||
elif $SUDO apt-get install -y dump1090 2>/dev/null; then
|
||||
echo -e "${GREEN} dump1090 installed${NC}"
|
||||
else
|
||||
# Build from source as fallback
|
||||
echo -e "${YELLOW} dump1090 not in repositories, building from source...${NC}"
|
||||
install_dump1090_from_source
|
||||
fi
|
||||
pause
|
||||
|
||||
# Audio tools
|
||||
echo ""
|
||||
echo -e "${BLUE}Installing Audio tools...${NC}"
|
||||
echo " Installing ffmpeg..."
|
||||
if $SUDO apt-get install -y ffmpeg; then
|
||||
echo -e "${GREEN} ffmpeg installed${NC}"
|
||||
else
|
||||
echo -e "${YELLOW} Warning: ffmpeg installation failed${NC}"
|
||||
fi
|
||||
pause
|
||||
|
||||
# WiFi tools
|
||||
echo ""
|
||||
echo -e "${BLUE}Installing WiFi tools...${NC}"
|
||||
echo " Installing aircrack-ng..."
|
||||
if $SUDO apt-get install -y aircrack-ng; then
|
||||
echo -e "${GREEN} aircrack-ng installed${NC}"
|
||||
else
|
||||
echo -e "${YELLOW} Warning: aircrack-ng installation failed${NC}"
|
||||
fi
|
||||
pause
|
||||
|
||||
# PMKID capture tools
|
||||
echo " Installing hcxdumptool (PMKID capture)..."
|
||||
if $SUDO apt-get install -y hcxdumptool; then
|
||||
echo -e "${GREEN} hcxdumptool installed${NC}"
|
||||
else
|
||||
echo -e "${YELLOW} Warning: hcxdumptool installation failed${NC}"
|
||||
fi
|
||||
pause
|
||||
|
||||
echo " Installing hcxtools (hash extraction)..."
|
||||
if $SUDO apt-get install -y hcxtools; then
|
||||
echo -e "${GREEN} hcxtools installed${NC}"
|
||||
else
|
||||
echo -e "${YELLOW} Warning: hcxtools installation failed${NC}"
|
||||
fi
|
||||
pause
|
||||
|
||||
# Bluetooth tools
|
||||
echo ""
|
||||
echo -e "${BLUE}Installing Bluetooth tools...${NC}"
|
||||
echo " Installing bluez..."
|
||||
if $SUDO apt-get install -y bluez bluetooth; then
|
||||
echo -e "${GREEN} bluez installed${NC}"
|
||||
else
|
||||
echo -e "${YELLOW} Warning: bluez installation failed${NC}"
|
||||
fi
|
||||
pause
|
||||
|
||||
echo ""
|
||||
echo -e "${GREEN}Tool installation complete!${NC}"
|
||||
pause
|
||||
|
||||
# Setup udev rules
|
||||
setup_udev_rules
|
||||
|
||||
# Verify installation
|
||||
echo ""
|
||||
echo -e "${BLUE}Verifying installation...${NC}"
|
||||
verify_tools
|
||||
brew_install() {
|
||||
local pkg="$1"
|
||||
if brew list --formula "$pkg" >/dev/null 2>&1; then
|
||||
ok "brew: ${pkg} already installed"
|
||||
return 0
|
||||
fi
|
||||
info "brew: installing ${pkg}..."
|
||||
brew install "$pkg"
|
||||
ok "brew: installed ${pkg}"
|
||||
}
|
||||
|
||||
show_debian_manual() {
|
||||
echo ""
|
||||
echo -e "${BLUE}Manual installation (Debian/Ubuntu):${NC}"
|
||||
echo ""
|
||||
echo "# Required tools"
|
||||
echo "sudo apt install rtl-sdr multimon-ng rtl-433 ffmpeg"
|
||||
echo ""
|
||||
echo "# ADS-B tracking"
|
||||
echo "sudo apt install dump1090-mutability # or dump1090-fa"
|
||||
echo ""
|
||||
echo "# WiFi scanning (optional)"
|
||||
echo "sudo apt install aircrack-ng hcxdumptool hcxtools"
|
||||
echo ""
|
||||
echo "# Bluetooth scanning (optional)"
|
||||
echo "sudo apt install bluez bluetooth"
|
||||
install_macos_packages() {
|
||||
ensure_brew
|
||||
info "Installing packages via Homebrew..."
|
||||
|
||||
brew_install librtlsdr
|
||||
brew_install multimon-ng
|
||||
brew_install ffmpeg
|
||||
brew_install rtl_433
|
||||
|
||||
# ADS-B (may not exist)
|
||||
warn "Attempting dump1090 install via Homebrew (may be unavailable)..."
|
||||
(brew_install dump1090-mutability) || true
|
||||
|
||||
brew_install aircrack-ng
|
||||
brew_install hcxtools
|
||||
brew_install soapysdr
|
||||
brew_install gpsd
|
||||
|
||||
warn "macOS note: hcitool/hciconfig are Linux (BlueZ) utilities and often unavailable on macOS."
|
||||
echo
|
||||
}
|
||||
|
||||
verify_tools() {
|
||||
local all_ok=true
|
||||
# ----------------------------
|
||||
# Debian/Ubuntu install (APT)
|
||||
# ----------------------------
|
||||
apt_install() { $SUDO apt-get install -y --no-install-recommends "$@" >/dev/null; }
|
||||
|
||||
echo ""
|
||||
if check_cmd rtl_fm; then
|
||||
echo -e " ${GREEN}✓${NC} rtl_fm"
|
||||
else
|
||||
echo -e " ${RED}✗${NC} rtl_fm - NOT INSTALLED"
|
||||
all_ok=false
|
||||
fi
|
||||
|
||||
if check_cmd multimon-ng; then
|
||||
echo -e " ${GREEN}✓${NC} multimon-ng"
|
||||
else
|
||||
echo -e " ${RED}✗${NC} multimon-ng - NOT INSTALLED"
|
||||
all_ok=false
|
||||
fi
|
||||
|
||||
if check_cmd rtl_433; then
|
||||
echo -e " ${GREEN}✓${NC} rtl_433"
|
||||
else
|
||||
echo -e " ${YELLOW}-${NC} rtl_433 - not installed (optional)"
|
||||
fi
|
||||
|
||||
if check_cmd dump1090; then
|
||||
echo -e " ${GREEN}✓${NC} dump1090"
|
||||
else
|
||||
echo -e " ${YELLOW}-${NC} dump1090 - not installed (optional)"
|
||||
fi
|
||||
|
||||
if check_cmd ffmpeg; then
|
||||
echo -e " ${GREEN}✓${NC} ffmpeg"
|
||||
else
|
||||
echo -e " ${RED}✗${NC} ffmpeg - NOT INSTALLED"
|
||||
all_ok=false
|
||||
fi
|
||||
|
||||
if check_cmd airmon-ng; then
|
||||
echo -e " ${GREEN}✓${NC} aircrack-ng"
|
||||
else
|
||||
echo -e " ${YELLOW}-${NC} aircrack-ng - not installed (optional)"
|
||||
fi
|
||||
|
||||
if ! $all_ok; then
|
||||
echo ""
|
||||
echo -e "${YELLOW}Some required tools failed to install. You may need to install them manually.${NC}"
|
||||
apt_try_install_any() {
|
||||
local p
|
||||
for p in "$@"; do
|
||||
if $SUDO apt-get install -y --no-install-recommends "$p" >/dev/null 2>&1; then
|
||||
ok "apt: installed ${p}"
|
||||
return 0
|
||||
fi
|
||||
done
|
||||
return 1
|
||||
}
|
||||
|
||||
setup_udev_rules() {
|
||||
if [ -f /etc/udev/rules.d/20-rtlsdr.rules ]; then
|
||||
echo -e "${GREEN}udev rules already configured${NC}"
|
||||
return
|
||||
fi
|
||||
install_dump1090_from_source_debian() {
|
||||
info "dump1090 not available via APT. Building from source (required)..."
|
||||
|
||||
echo ""
|
||||
echo -e "${BLUE}Setting up RTL-SDR udev rules...${NC}"
|
||||
$SUDO bash -c 'cat > /etc/udev/rules.d/20-rtlsdr.rules << EOF
|
||||
apt_install build-essential git pkg-config \
|
||||
librtlsdr-dev libusb-1.0-0-dev \
|
||||
libncurses-dev tcl-dev python3-dev
|
||||
|
||||
local orig_dir tmp_dir
|
||||
orig_dir="$(pwd)"
|
||||
tmp_dir="$(mktemp -d)"
|
||||
|
||||
cleanup() { cd "$orig_dir" >/dev/null 2>&1 || true; rm -rf "$tmp_dir"; }
|
||||
trap cleanup EXIT
|
||||
|
||||
info "Cloning FlightAware dump1090..."
|
||||
git clone --depth 1 https://github.com/flightaware/dump1090.git "$tmp_dir/dump1090" >/dev/null 2>&1 \
|
||||
|| { fail "Failed to clone FlightAware dump1090"; exit 1; }
|
||||
|
||||
cd "$tmp_dir/dump1090"
|
||||
info "Compiling FlightAware dump1090..."
|
||||
if make BLADERF=no RTLSDR=yes >/dev/null 2>&1; then
|
||||
$SUDO install -m 0755 dump1090 /usr/local/bin/dump1090
|
||||
ok "dump1090 installed successfully (FlightAware)."
|
||||
return 0
|
||||
fi
|
||||
|
||||
warn "FlightAware build failed. Falling back to antirez/dump1090..."
|
||||
rm -rf "$tmp_dir/dump1090"
|
||||
git clone --depth 1 https://github.com/antirez/dump1090.git "$tmp_dir/dump1090" >/dev/null 2>&1 \
|
||||
|| { fail "Failed to clone antirez dump1090"; exit 1; }
|
||||
|
||||
cd "$tmp_dir/dump1090"
|
||||
info "Compiling antirez dump1090..."
|
||||
make >/dev/null 2>&1 || { fail "Failed to build dump1090 from source (required)."; exit 1; }
|
||||
|
||||
$SUDO install -m 0755 dump1090 /usr/local/bin/dump1090
|
||||
ok "dump1090 installed successfully (antirez)."
|
||||
}
|
||||
|
||||
setup_udev_rules_debian() {
|
||||
[[ -d /etc/udev/rules.d ]] || { warn "udev not found; skipping RTL-SDR udev rules."; return 0; }
|
||||
|
||||
local rules_file="/etc/udev/rules.d/20-rtlsdr.rules"
|
||||
[[ -f "$rules_file" ]] && { ok "RTL-SDR udev rules already present: $rules_file"; return 0; }
|
||||
|
||||
info "Installing RTL-SDR udev rules..."
|
||||
$SUDO tee "$rules_file" >/dev/null <<'EOF'
|
||||
SUBSYSTEM=="usb", ATTRS{idVendor}=="0bda", ATTRS{idProduct}=="2838", MODE="0666"
|
||||
SUBSYSTEM=="usb", ATTRS{idVendor}=="0bda", ATTRS{idProduct}=="2832", MODE="0666"
|
||||
EOF'
|
||||
$SUDO udevadm control --reload-rules
|
||||
$SUDO udevadm trigger
|
||||
echo -e "${GREEN}udev rules installed!${NC}"
|
||||
echo "Please unplug and replug your RTL-SDR if connected."
|
||||
EOF
|
||||
$SUDO udevadm control --reload-rules || true
|
||||
$SUDO udevadm trigger || true
|
||||
ok "udev rules installed. Unplug/replug your RTL-SDR if connected."
|
||||
echo
|
||||
}
|
||||
|
||||
# ============================================
|
||||
install_debian_packages() {
|
||||
need_sudo
|
||||
info "Updating APT package lists..."
|
||||
$SUDO apt-get update -y >/dev/null
|
||||
|
||||
info "Installing required packages via APT..."
|
||||
apt_install rtl-sdr
|
||||
apt_install multimon-ng
|
||||
apt_install ffmpeg
|
||||
|
||||
apt_try_install_any rtl-433 rtl433 || true
|
||||
|
||||
apt_install aircrack-ng || true
|
||||
apt_install hcxdumptool || true
|
||||
apt_install hcxtools || true
|
||||
apt_install bluez bluetooth || true
|
||||
apt_install soapysdr-tools || true
|
||||
apt_install gpsd gpsd-clients || true
|
||||
|
||||
# dump1090: apt first; source fallback; hard fail inside if it can't build
|
||||
if ! cmd_exists dump1090; then
|
||||
apt_try_install_any dump1090-fa dump1090-mutability dump1090 || true
|
||||
fi
|
||||
cmd_exists dump1090 || install_dump1090_from_source_debian
|
||||
|
||||
setup_udev_rules_debian
|
||||
}
|
||||
|
||||
# ----------------------------
|
||||
# Final summary / hard fail
|
||||
# ----------------------------
|
||||
final_summary_and_hard_fail() {
|
||||
check_tools
|
||||
|
||||
echo "============================================"
|
||||
if [[ "${#missing_required[@]}" -eq 0 ]]; then
|
||||
ok "All REQUIRED tools are installed."
|
||||
else
|
||||
fail "Missing REQUIRED tools:"
|
||||
for t in "${missing_required[@]}"; do echo " - $t"; done
|
||||
echo
|
||||
fail "Exiting because required tools are missing."
|
||||
echo
|
||||
warn "If you are on macOS: hcitool/hciconfig are Linux (BlueZ) tools and may not be installable."
|
||||
warn "If you truly require them everywhere, you must restrict supported platforms or provide alternatives."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo
|
||||
echo "To start INTERCEPT:"
|
||||
echo " source venv/bin/activate"
|
||||
echo " sudo python intercept.py"
|
||||
echo
|
||||
echo "Then open http://localhost:5050 in your browser"
|
||||
echo
|
||||
}
|
||||
|
||||
# ----------------------------
|
||||
# MAIN
|
||||
# ============================================
|
||||
# ----------------------------
|
||||
main() {
|
||||
detect_os
|
||||
detect_os
|
||||
|
||||
if [[ "$OS" == "unknown" ]]; then
|
||||
echo -e "${RED}Unsupported OS. This script supports macOS and Debian/Ubuntu.${NC}"
|
||||
exit 1
|
||||
fi
|
||||
if [[ "$OS" == "macos" ]]; then
|
||||
install_macos_packages
|
||||
else
|
||||
install_debian_packages
|
||||
fi
|
||||
|
||||
if [[ "$OS" == "debian" ]]; then
|
||||
setup_sudo
|
||||
fi
|
||||
|
||||
# Check and install system tools FIRST
|
||||
check_tools
|
||||
|
||||
if [[ "$OS" == "macos" ]]; then
|
||||
install_macos_tools
|
||||
else
|
||||
install_debian_tools
|
||||
fi
|
||||
|
||||
# Install Python dependencies AFTER system tools
|
||||
install_python_deps
|
||||
|
||||
echo ""
|
||||
echo "============================================"
|
||||
echo -e "${GREEN}Setup complete!${NC}"
|
||||
echo ""
|
||||
echo "To start INTERCEPT:"
|
||||
|
||||
if [ -d "venv" ]; then
|
||||
echo " source venv/bin/activate"
|
||||
if [[ "$OS" == "debian" ]]; then
|
||||
echo " sudo venv/bin/python intercept.py"
|
||||
else
|
||||
echo " sudo python3 intercept.py"
|
||||
fi
|
||||
else
|
||||
if [[ "$OS" == "debian" ]]; then
|
||||
echo " sudo python3 intercept.py"
|
||||
else
|
||||
echo " sudo python3 intercept.py"
|
||||
fi
|
||||
fi
|
||||
|
||||
echo ""
|
||||
echo "Then open http://localhost:5050 in your browser"
|
||||
echo ""
|
||||
install_python_deps
|
||||
final_summary_and_hard_fail
|
||||
}
|
||||
|
||||
main "$@"
|
||||
|
||||
|
||||
Reference in New Issue
Block a user