fix(hackrf): resolve 'Tools Missing' on RPi when hackrf_info is present

Two root causes behind HackRF showing as unavailable when tools are installed:

1. get_tool_path() didn't search /usr/local/bin on Linux. HackRF tools built
   from source (as in the Dockerfile) land there, but the path wasn't checked
   when sudo/service environments have a restricted PATH.

2. check_hackrf() only tested hackrf_transfer, but the health check tests
   hackrf_info — both come from the same apt package but a user could have one
   visible and not the other. Now either binary confirms the tools are present.
   hackrf_transfer is still required for actual RX/TX operations.

Fixes #212

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
James Smith
2026-05-03 09:24:22 +01:00
parent b78ca51db1
commit 3b480eb183
2 changed files with 1357 additions and 1210 deletions
+405 -414
View File
@@ -7,16 +7,16 @@ import shutil
import subprocess
from typing import Any
logger = logging.getLogger('intercept.dependencies')
logger = logging.getLogger("intercept.dependencies")
# Additional paths to search for tools (e.g., /usr/sbin on Debian)
EXTRA_TOOL_PATHS = ['/usr/sbin', '/sbin']
# Additional paths to search for tools (e.g., /usr/sbin on Debian, /usr/local/bin for source builds)
EXTRA_TOOL_PATHS = ["/usr/local/bin", "/usr/sbin", "/sbin"]
# Tools installed to non-standard locations (not on PATH)
KNOWN_TOOL_PATHS: dict[str, list[str]] = {
'auto_rx.py': [
'/opt/radiosonde_auto_rx/auto_rx/auto_rx.py',
'/opt/auto_rx/auto_rx.py',
"auto_rx.py": [
"/opt/radiosonde_auto_rx/auto_rx/auto_rx.py",
"/opt/auto_rx/auto_rx.py",
],
}
@@ -36,12 +36,12 @@ def get_tool_path(name: str) -> str | None:
# Prefer native Homebrew binaries on Apple Silicon to avoid mixing Rosetta
# /usr/local tools with arm64 Python/runtime.
if platform.system() == 'Darwin':
if platform.system() == "Darwin":
machine = platform.machine().lower()
preferred_paths: list[str] = []
if machine in {'arm64', 'aarch64'}:
preferred_paths.append('/opt/homebrew/bin')
preferred_paths.append('/usr/local/bin')
if machine in {"arm64", "aarch64"}:
preferred_paths.append("/opt/homebrew/bin")
preferred_paths.append("/usr/local/bin")
for base in preferred_paths:
full_path = os.path.join(base, name)
@@ -78,31 +78,32 @@ def _get_soapy_env() -> dict[str, str]:
See: https://github.com/smittix/intercept/issues/77
"""
import platform
env = os.environ.copy()
if platform.system() == 'Darwin':
if platform.system() == "Darwin":
# Homebrew paths for Apple Silicon and Intel Macs
homebrew_paths = ['/opt/homebrew', '/usr/local']
homebrew_paths = ["/opt/homebrew", "/usr/local"]
lib_paths = []
module_paths = []
for base in homebrew_paths:
lib_path = f'{base}/lib'
lib_path = f"{base}/lib"
if os.path.isdir(lib_path):
lib_paths.append(lib_path)
# SoapySDR modules are in lib/SoapySDR/modules<version>
soapy_mod_base = f'{base}/lib/SoapySDR'
soapy_mod_base = f"{base}/lib/SoapySDR"
if os.path.isdir(soapy_mod_base):
module_paths.append(soapy_mod_base)
if lib_paths:
current_dyld = env.get('DYLD_LIBRARY_PATH', '')
env['DYLD_LIBRARY_PATH'] = ':'.join(lib_paths + ([current_dyld] if current_dyld else []))
current_dyld = env.get("DYLD_LIBRARY_PATH", "")
env["DYLD_LIBRARY_PATH"] = ":".join(lib_paths + ([current_dyld] if current_dyld else []))
# Set SOAPY_SDR_ROOT if we found Homebrew installation
for base in homebrew_paths:
if os.path.isdir(f'{base}/lib/SoapySDR'):
env['SOAPY_SDR_ROOT'] = base
if os.path.isdir(f"{base}/lib/SoapySDR"):
env["SOAPY_SDR_ROOT"] = base
break
return env
@@ -114,7 +115,7 @@ def check_soapy_factory(factory_name: str) -> bool:
# Run SoapySDRUtil --info and look for the factory in 'Available factories'
# Use macOS-aware environment to find Homebrew-installed modules
env = _get_soapy_env()
result = subprocess.run(['SoapySDRUtil', '--info'], capture_output=True, text=True, env=env)
result = subprocess.run(["SoapySDRUtil", "--info"], capture_output=True, text=True, env=env)
if result.returncode != 0:
return False
@@ -134,395 +135,390 @@ def check_soapy_factory(factory_name: str) -> bool:
# Comprehensive tool dependency definitions
TOOL_DEPENDENCIES = {
'pager': {
'name': 'Pager Decoding',
'tools': {
'rtl_fm': {
'required': True,
'description': 'RTL-SDR FM demodulator',
'install': {
'apt': 'sudo apt install rtl-sdr',
'brew': 'brew install librtlsdr',
'manual': 'https://osmocom.org/projects/rtl-sdr/wiki'
}
},
'multimon-ng': {
'required': True,
'description': 'Digital transmission decoder',
'install': {
'apt': 'sudo apt install multimon-ng',
'brew': 'brew install multimon-ng',
'manual': 'https://github.com/EliasOenal/multimon-ng'
}
},
'rtl_test': {
'required': False,
'description': 'RTL-SDR device detection',
'install': {
'apt': 'sudo apt install rtl-sdr',
'brew': 'brew install librtlsdr',
'manual': 'https://osmocom.org/projects/rtl-sdr/wiki'
}
}
}
},
'sensor': {
'name': '433MHz Sensors',
'tools': {
'rtl_433': {
'required': True,
'description': 'ISM band decoder for sensors, weather stations, TPMS',
'install': {
'apt': 'sudo apt install rtl-433',
'brew': 'brew install rtl_433',
'manual': 'https://github.com/merbanan/rtl_433'
}
}
}
},
'wifi': {
'name': 'WiFi Reconnaissance',
'tools': {
'airmon-ng': {
'required': True,
'description': 'Monitor mode controller',
'install': {
'apt': 'sudo apt install aircrack-ng',
'brew': 'Not available on macOS',
'manual': 'https://aircrack-ng.org'
}
},
'airodump-ng': {
'required': True,
'description': 'WiFi network scanner',
'install': {
'apt': 'sudo apt install aircrack-ng',
'brew': 'Not available on macOS',
'manual': 'https://aircrack-ng.org'
}
},
'aireplay-ng': {
'required': False,
'description': 'Deauthentication / packet injection',
'install': {
'apt': 'sudo apt install aircrack-ng',
'brew': 'Not available on macOS',
'manual': 'https://aircrack-ng.org'
}
},
'aircrack-ng': {
'required': False,
'description': 'Handshake verification',
'install': {
'apt': 'sudo apt install aircrack-ng',
'brew': 'brew install aircrack-ng',
'manual': 'https://aircrack-ng.org'
}
},
'hcxdumptool': {
'required': False,
'description': 'PMKID capture tool',
'install': {
'apt': 'sudo apt install hcxdumptool',
'brew': 'brew install hcxtools',
'manual': 'https://github.com/ZerBea/hcxdumptool'
}
},
'hcxpcapngtool': {
'required': False,
'description': 'PMKID hash extractor',
'install': {
'apt': 'sudo apt install hcxtools',
'brew': 'brew install hcxtools',
'manual': 'https://github.com/ZerBea/hcxtools'
}
}
}
},
'bluetooth': {
'name': 'Bluetooth Scanning',
'tools': {
'hcitool': {
'required': False,
'description': 'Bluetooth HCI tool (legacy)',
'install': {
'apt': 'sudo apt install bluez',
'brew': 'Not available on macOS (use native)',
'manual': 'http://www.bluez.org'
}
},
'bluetoothctl': {
'required': True,
'description': 'Modern Bluetooth controller',
'install': {
'apt': 'sudo apt install bluez',
'brew': 'Not available on macOS (use native)',
'manual': 'http://www.bluez.org'
}
},
'hciconfig': {
'required': False,
'description': 'Bluetooth adapter configuration',
'install': {
'apt': 'sudo apt install bluez',
'brew': 'Not available on macOS',
'manual': 'http://www.bluez.org'
}
}
}
},
'aircraft': {
'name': 'Aircraft Tracking (ADS-B)',
'tools': {
'dump1090': {
'required': False,
'description': 'Mode S / ADS-B decoder (preferred)',
'install': {
'apt': 'sudo apt install dump1090-mutability (or build dump1090-fa from source)',
'brew': 'brew install dump1090-mutability',
'manual': 'https://github.com/flightaware/dump1090'
"pager": {
"name": "Pager Decoding",
"tools": {
"rtl_fm": {
"required": True,
"description": "RTL-SDR FM demodulator",
"install": {
"apt": "sudo apt install rtl-sdr",
"brew": "brew install librtlsdr",
"manual": "https://osmocom.org/projects/rtl-sdr/wiki",
},
'alternatives': ['dump1090-mutability', 'dump1090-fa']
},
'rtl_adsb': {
'required': False,
'description': 'Simple ADS-B decoder',
'install': {
'apt': 'sudo apt install rtl-sdr',
'brew': 'brew install librtlsdr',
'manual': 'https://osmocom.org/projects/rtl-sdr/wiki'
}
}
}
},
'acars': {
'name': 'Aircraft Messaging (ACARS)',
'tools': {
'acarsdec': {
'required': True,
'description': 'ACARS VHF decoder',
'install': {
'apt': 'Run ./setup.sh (builds from source)',
'brew': 'Run ./setup.sh (builds from source)',
'manual': 'https://github.com/TLeconte/acarsdec'
}
}
}
},
'ais': {
'name': 'Vessel Tracking (AIS)',
'tools': {
'AIS-catcher': {
'required': True,
'description': 'AIS receiver and decoder',
'install': {
'apt': 'Download .deb from https://github.com/jvde-github/AIS-catcher/releases',
'brew': 'brew install aiscatcher',
'manual': 'https://github.com/jvde-github/AIS-catcher/releases'
}
}
}
},
'aprs': {
'name': 'APRS Tracking',
'tools': {
'direwolf': {
'required': False,
'description': 'APRS/packet radio decoder (preferred)',
'install': {
'apt': 'sudo apt install direwolf',
'brew': 'brew install direwolf',
'manual': 'https://github.com/wb2osz/direwolf'
}
},
'multimon-ng': {
'required': False,
'description': 'Alternative AFSK1200 decoder',
'install': {
'apt': 'sudo apt install multimon-ng',
'brew': 'brew install multimon-ng',
'manual': 'https://github.com/EliasOenal/multimon-ng'
}
}
}
},
'satellite': {
'name': 'Satellite Tracking',
'tools': {
'skyfield': {
'required': True,
'description': 'Python orbital mechanics library',
'install': {
'pip': 'pip install skyfield',
'manual': 'https://rhodesmill.org/skyfield/'
"multimon-ng": {
"required": True,
"description": "Digital transmission decoder",
"install": {
"apt": "sudo apt install multimon-ng",
"brew": "brew install multimon-ng",
"manual": "https://github.com/EliasOenal/multimon-ng",
},
'python_module': True
}
}
},
"rtl_test": {
"required": False,
"description": "RTL-SDR device detection",
"install": {
"apt": "sudo apt install rtl-sdr",
"brew": "brew install librtlsdr",
"manual": "https://osmocom.org/projects/rtl-sdr/wiki",
},
},
},
},
'sdr_hardware': {
'name': 'SDR Hardware Support',
'tools': {
'SoapySDRUtil': {
'required': False,
'description': 'Universal SDR abstraction (required for LimeSDR, HackRF)',
'install': {
'apt': 'sudo apt install soapysdr-tools',
'brew': 'brew install soapysdr',
'manual': 'https://github.com/pothosware/SoapySDR'
}
},
'rx_fm': {
'required': False,
'description': 'SoapySDR FM receiver (for non-RTL hardware)',
'install': {
'manual': 'Part of SoapySDR utilities or build from source'
}
},
'LimeUtil': {
'required': False,
'description': 'LimeSDR native utilities',
'install': {
'apt': 'sudo apt install limesuite',
'brew': 'brew install limesuite',
'manual': 'https://github.com/myriadrf/LimeSuite'
}
},
'SoapyLMS7': {
'required': False,
'description': 'SoapySDR plugin for LimeSDR',
'soapy_factory': 'lime',
'install': {
'apt': 'sudo apt install soapysdr-module-lms7',
'brew': 'brew install soapylms7',
'manual': 'https://github.com/myriadrf/LimeSuite'
}
},
'hackrf_info': {
'required': False,
'description': 'HackRF native utilities',
'install': {
'apt': 'sudo apt install hackrf',
'brew': 'brew install hackrf',
'manual': 'https://github.com/greatscottgadgets/hackrf'
}
},
'SoapyHackRF': {
'required': False,
'description': 'SoapySDR plugin for HackRF',
'soapy_factory': 'hackrf',
'install': {
'apt': 'sudo apt install soapysdr-module-hackrf',
'brew': 'brew install soapyhackrf',
'manual': 'https://github.com/pothosware/SoapyHackRF'
}
},
'readsb': {
'required': False,
'description': 'ADS-B decoder with SoapySDR support',
'install': {
'apt': 'Build from source with SoapySDR support',
'brew': 'Build from source with SoapySDR support',
'manual': 'https://github.com/wiedehopf/readsb'
}
"sensor": {
"name": "433MHz Sensors",
"tools": {
"rtl_433": {
"required": True,
"description": "ISM band decoder for sensors, weather stations, TPMS",
"install": {
"apt": "sudo apt install rtl-433",
"brew": "brew install rtl_433",
"manual": "https://github.com/merbanan/rtl_433",
},
}
}
},
},
'subghz': {
'name': 'SubGHz Transceiver',
'tools': {
'hackrf_transfer': {
'required': True,
'description': 'HackRF IQ capture and replay',
'install': {
'apt': 'sudo apt install hackrf',
'brew': 'brew install hackrf',
'manual': 'https://github.com/greatscottgadgets/hackrf'
}
"wifi": {
"name": "WiFi Reconnaissance",
"tools": {
"airmon-ng": {
"required": True,
"description": "Monitor mode controller",
"install": {
"apt": "sudo apt install aircrack-ng",
"brew": "Not available on macOS",
"manual": "https://aircrack-ng.org",
},
},
'hackrf_sweep': {
'required': False,
'description': 'HackRF wideband spectrum sweep',
'install': {
'apt': 'sudo apt install hackrf',
'brew': 'brew install hackrf',
'manual': 'https://github.com/greatscottgadgets/hackrf'
}
"airodump-ng": {
"required": True,
"description": "WiFi network scanner",
"install": {
"apt": "sudo apt install aircrack-ng",
"brew": "Not available on macOS",
"manual": "https://aircrack-ng.org",
},
},
'rtl_433': {
'required': False,
'description': 'Protocol decoder for SubGHz signals',
'install': {
'apt': 'sudo apt install rtl-433',
'brew': 'brew install rtl_433',
'manual': 'https://github.com/merbanan/rtl_433'
}
}
}
"aireplay-ng": {
"required": False,
"description": "Deauthentication / packet injection",
"install": {
"apt": "sudo apt install aircrack-ng",
"brew": "Not available on macOS",
"manual": "https://aircrack-ng.org",
},
},
"aircrack-ng": {
"required": False,
"description": "Handshake verification",
"install": {
"apt": "sudo apt install aircrack-ng",
"brew": "brew install aircrack-ng",
"manual": "https://aircrack-ng.org",
},
},
"hcxdumptool": {
"required": False,
"description": "PMKID capture tool",
"install": {
"apt": "sudo apt install hcxdumptool",
"brew": "brew install hcxtools",
"manual": "https://github.com/ZerBea/hcxdumptool",
},
},
"hcxpcapngtool": {
"required": False,
"description": "PMKID hash extractor",
"install": {
"apt": "sudo apt install hcxtools",
"brew": "brew install hcxtools",
"manual": "https://github.com/ZerBea/hcxtools",
},
},
},
},
'radiosonde': {
'name': 'Radiosonde Tracking',
'tools': {
'auto_rx.py': {
'required': True,
'description': 'Radiosonde weather balloon decoder',
'install': {
'apt': 'Run ./setup.sh (clones from GitHub)',
'brew': 'Run ./setup.sh (clones from GitHub)',
'manual': 'https://github.com/projecthorus/radiosonde_auto_rx'
}
}
}
"bluetooth": {
"name": "Bluetooth Scanning",
"tools": {
"hcitool": {
"required": False,
"description": "Bluetooth HCI tool (legacy)",
"install": {
"apt": "sudo apt install bluez",
"brew": "Not available on macOS (use native)",
"manual": "http://www.bluez.org",
},
},
"bluetoothctl": {
"required": True,
"description": "Modern Bluetooth controller",
"install": {
"apt": "sudo apt install bluez",
"brew": "Not available on macOS (use native)",
"manual": "http://www.bluez.org",
},
},
"hciconfig": {
"required": False,
"description": "Bluetooth adapter configuration",
"install": {
"apt": "sudo apt install bluez",
"brew": "Not available on macOS",
"manual": "http://www.bluez.org",
},
},
},
},
'tscm': {
'name': 'TSCM Counter-Surveillance',
'tools': {
'rtl_power': {
'required': False,
'description': 'Wideband spectrum sweep for RF analysis',
'install': {
'apt': 'sudo apt install rtl-sdr',
'brew': 'brew install librtlsdr',
'manual': 'https://osmocom.org/projects/rtl-sdr/wiki'
}
"aircraft": {
"name": "Aircraft Tracking (ADS-B)",
"tools": {
"dump1090": {
"required": False,
"description": "Mode S / ADS-B decoder (preferred)",
"install": {
"apt": "sudo apt install dump1090-mutability (or build dump1090-fa from source)",
"brew": "brew install dump1090-mutability",
"manual": "https://github.com/flightaware/dump1090",
},
"alternatives": ["dump1090-mutability", "dump1090-fa"],
},
'rtl_fm': {
'required': True,
'description': 'RF signal demodulation',
'install': {
'apt': 'sudo apt install rtl-sdr',
'brew': 'brew install librtlsdr',
'manual': 'https://osmocom.org/projects/rtl-sdr/wiki'
}
"rtl_adsb": {
"required": False,
"description": "Simple ADS-B decoder",
"install": {
"apt": "sudo apt install rtl-sdr",
"brew": "brew install librtlsdr",
"manual": "https://osmocom.org/projects/rtl-sdr/wiki",
},
},
'rtl_433': {
'required': False,
'description': 'ISM band device decoding',
'install': {
'apt': 'sudo apt install rtl-433',
'brew': 'brew install rtl_433',
'manual': 'https://github.com/merbanan/rtl_433'
}
},
'airmon-ng': {
'required': False,
'description': 'WiFi monitor mode for network scanning',
'install': {
'apt': 'sudo apt install aircrack-ng',
'brew': 'Not available on macOS',
'manual': 'https://aircrack-ng.org'
}
},
'bluetoothctl': {
'required': False,
'description': 'Bluetooth device scanning',
'install': {
'apt': 'sudo apt install bluez',
'brew': 'Not available on macOS (use native)',
'manual': 'http://www.bluez.org'
}
},
},
"acars": {
"name": "Aircraft Messaging (ACARS)",
"tools": {
"acarsdec": {
"required": True,
"description": "ACARS VHF decoder",
"install": {
"apt": "Run ./setup.sh (builds from source)",
"brew": "Run ./setup.sh (builds from source)",
"manual": "https://github.com/TLeconte/acarsdec",
},
}
}
},
},
"ais": {
"name": "Vessel Tracking (AIS)",
"tools": {
"AIS-catcher": {
"required": True,
"description": "AIS receiver and decoder",
"install": {
"apt": "Download .deb from https://github.com/jvde-github/AIS-catcher/releases",
"brew": "brew install aiscatcher",
"manual": "https://github.com/jvde-github/AIS-catcher/releases",
},
}
},
},
"aprs": {
"name": "APRS Tracking",
"tools": {
"direwolf": {
"required": False,
"description": "APRS/packet radio decoder (preferred)",
"install": {
"apt": "sudo apt install direwolf",
"brew": "brew install direwolf",
"manual": "https://github.com/wb2osz/direwolf",
},
},
"multimon-ng": {
"required": False,
"description": "Alternative AFSK1200 decoder",
"install": {
"apt": "sudo apt install multimon-ng",
"brew": "brew install multimon-ng",
"manual": "https://github.com/EliasOenal/multimon-ng",
},
},
},
},
"satellite": {
"name": "Satellite Tracking",
"tools": {
"skyfield": {
"required": True,
"description": "Python orbital mechanics library",
"install": {"pip": "pip install skyfield", "manual": "https://rhodesmill.org/skyfield/"},
"python_module": True,
}
},
},
"sdr_hardware": {
"name": "SDR Hardware Support",
"tools": {
"SoapySDRUtil": {
"required": False,
"description": "Universal SDR abstraction (required for LimeSDR, HackRF)",
"install": {
"apt": "sudo apt install soapysdr-tools",
"brew": "brew install soapysdr",
"manual": "https://github.com/pothosware/SoapySDR",
},
},
"rx_fm": {
"required": False,
"description": "SoapySDR FM receiver (for non-RTL hardware)",
"install": {"manual": "Part of SoapySDR utilities or build from source"},
},
"LimeUtil": {
"required": False,
"description": "LimeSDR native utilities",
"install": {
"apt": "sudo apt install limesuite",
"brew": "brew install limesuite",
"manual": "https://github.com/myriadrf/LimeSuite",
},
},
"SoapyLMS7": {
"required": False,
"description": "SoapySDR plugin for LimeSDR",
"soapy_factory": "lime",
"install": {
"apt": "sudo apt install soapysdr-module-lms7",
"brew": "brew install soapylms7",
"manual": "https://github.com/myriadrf/LimeSuite",
},
},
"hackrf_info": {
"required": False,
"description": "HackRF native utilities",
"install": {
"apt": "sudo apt install hackrf",
"brew": "brew install hackrf",
"manual": "https://github.com/greatscottgadgets/hackrf",
},
},
"SoapyHackRF": {
"required": False,
"description": "SoapySDR plugin for HackRF",
"soapy_factory": "hackrf",
"install": {
"apt": "sudo apt install soapysdr-module-hackrf",
"brew": "brew install soapyhackrf",
"manual": "https://github.com/pothosware/SoapyHackRF",
},
},
"readsb": {
"required": False,
"description": "ADS-B decoder with SoapySDR support",
"install": {
"apt": "Build from source with SoapySDR support",
"brew": "Build from source with SoapySDR support",
"manual": "https://github.com/wiedehopf/readsb",
},
},
},
},
"subghz": {
"name": "SubGHz Transceiver",
"tools": {
"hackrf_transfer": {
"required": True,
"description": "HackRF IQ capture and replay",
"install": {
"apt": "sudo apt install hackrf",
"brew": "brew install hackrf",
"manual": "https://github.com/greatscottgadgets/hackrf",
},
},
"hackrf_sweep": {
"required": False,
"description": "HackRF wideband spectrum sweep",
"install": {
"apt": "sudo apt install hackrf",
"brew": "brew install hackrf",
"manual": "https://github.com/greatscottgadgets/hackrf",
},
},
"rtl_433": {
"required": False,
"description": "Protocol decoder for SubGHz signals",
"install": {
"apt": "sudo apt install rtl-433",
"brew": "brew install rtl_433",
"manual": "https://github.com/merbanan/rtl_433",
},
},
},
},
"radiosonde": {
"name": "Radiosonde Tracking",
"tools": {
"auto_rx.py": {
"required": True,
"description": "Radiosonde weather balloon decoder",
"install": {
"apt": "Run ./setup.sh (clones from GitHub)",
"brew": "Run ./setup.sh (clones from GitHub)",
"manual": "https://github.com/projecthorus/radiosonde_auto_rx",
},
}
},
},
"tscm": {
"name": "TSCM Counter-Surveillance",
"tools": {
"rtl_power": {
"required": False,
"description": "Wideband spectrum sweep for RF analysis",
"install": {
"apt": "sudo apt install rtl-sdr",
"brew": "brew install librtlsdr",
"manual": "https://osmocom.org/projects/rtl-sdr/wiki",
},
},
"rtl_fm": {
"required": True,
"description": "RF signal demodulation",
"install": {
"apt": "sudo apt install rtl-sdr",
"brew": "brew install librtlsdr",
"manual": "https://osmocom.org/projects/rtl-sdr/wiki",
},
},
"rtl_433": {
"required": False,
"description": "ISM band device decoding",
"install": {
"apt": "sudo apt install rtl-433",
"brew": "brew install rtl_433",
"manual": "https://github.com/merbanan/rtl_433",
},
},
"airmon-ng": {
"required": False,
"description": "WiFi monitor mode for network scanning",
"install": {
"apt": "sudo apt install aircrack-ng",
"brew": "Not available on macOS",
"manual": "https://aircrack-ng.org",
},
},
"bluetoothctl": {
"required": False,
"description": "Bluetooth device scanning",
"install": {
"apt": "sudo apt install bluez",
"brew": "Not available on macOS (use native)",
"manual": "http://www.bluez.org",
},
},
},
},
}
@@ -532,16 +528,11 @@ def check_all_dependencies() -> dict[str, dict[str, Any]]:
results: dict[str, dict[str, Any]] = {}
for mode, config in TOOL_DEPENDENCIES.items():
mode_result = {
'name': config['name'],
'tools': {},
'ready': True,
'missing_required': []
}
mode_result = {"name": config["name"], "tools": {}, "ready": True, "missing_required": []}
for tool, tool_config in config['tools'].items():
for tool, tool_config in config["tools"].items():
# Check if it's a Python module
if tool_config.get('python_module'):
if tool_config.get("python_module"):
try:
__import__(tool)
installed = True
@@ -549,23 +540,23 @@ def check_all_dependencies() -> dict[str, dict[str, Any]]:
logger.debug(f"Failed to import {tool}: {type(e).__name__}: {e}")
installed = False
# Check using SoapySDRUtil if specified
elif tool_config.get('soapy_factory'):
installed = check_soapy_factory(tool_config['soapy_factory'])
elif tool_config.get("soapy_factory"):
installed = check_soapy_factory(tool_config["soapy_factory"])
else:
# Check for alternatives
alternatives = tool_config.get('alternatives', [])
alternatives = tool_config.get("alternatives", [])
installed = check_tool(tool) or any(check_tool(alt) for alt in alternatives)
mode_result['tools'][tool] = {
'installed': installed,
'required': tool_config['required'],
'description': tool_config['description'],
'install': tool_config['install']
mode_result["tools"][tool] = {
"installed": installed,
"required": tool_config["required"],
"description": tool_config["description"],
"install": tool_config["install"],
}
if tool_config['required'] and not installed:
mode_result['ready'] = False
mode_result['missing_required'].append(tool)
if tool_config["required"] and not installed:
mode_result["ready"] = False
mode_result["missing_required"].append(tool)
results[mode] = mode_result
+952 -796
View File
File diff suppressed because it is too large Load Diff