mirror of
https://github.com/smittix/intercept.git
synced 2026-06-29 21:52:08 -07:00
Remove Iridium (demo-only) and add version display
- Remove Iridium satellite decoding feature (was placeholder/demo only) - Delete routes/iridium.py - Remove Iridium UI elements from index.html - Remove Iridium CSS styles - Remove Iridium dependencies and logger - Clean up SDR docstrings mentioning Iridium - Add version number display (fixes #31) - Add VERSION constant to config.py - Add --version / -V CLI flag to intercept.py - Display version badge in web UI header
This commit is contained in:
@@ -8,7 +8,6 @@ def register_blueprints(app):
|
||||
from .bluetooth import bluetooth_bp
|
||||
from .adsb import adsb_bp
|
||||
from .satellite import satellite_bp
|
||||
from .iridium import iridium_bp
|
||||
from .gps import gps_bp
|
||||
|
||||
app.register_blueprint(pager_bp)
|
||||
@@ -17,5 +16,4 @@ def register_blueprints(app):
|
||||
app.register_blueprint(bluetooth_bp)
|
||||
app.register_blueprint(adsb_bp)
|
||||
app.register_blueprint(satellite_bp)
|
||||
app.register_blueprint(iridium_bp)
|
||||
app.register_blueprint(gps_bp)
|
||||
|
||||
@@ -1,205 +0,0 @@
|
||||
"""Iridium monitoring routes.
|
||||
|
||||
NOTE: This module is currently in DEMO MODE. The burst detection generates
|
||||
simulated data for demonstration purposes. Real Iridium decoding requires
|
||||
gr-iridium or iridium-toolkit which are not yet integrated.
|
||||
"""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import json
|
||||
import queue
|
||||
import random
|
||||
import shutil
|
||||
import subprocess
|
||||
import threading
|
||||
import time
|
||||
from datetime import datetime
|
||||
from typing import Any, Generator
|
||||
|
||||
from flask import Blueprint, jsonify, request, Response
|
||||
|
||||
import app as app_module
|
||||
from utils.logging import iridium_logger as logger
|
||||
from utils.validation import validate_frequency, validate_device_index, validate_gain
|
||||
from utils.sse import format_sse
|
||||
from utils.sdr import SDRFactory, SDRType
|
||||
|
||||
iridium_bp = Blueprint('iridium', __name__, url_prefix='/iridium')
|
||||
|
||||
# Flag indicating this is demo mode (simulated data)
|
||||
DEMO_MODE = True
|
||||
|
||||
|
||||
def monitor_iridium(process):
|
||||
"""
|
||||
Monitor Iridium capture and detect bursts.
|
||||
|
||||
NOTE: Currently generates SIMULATED data for demonstration.
|
||||
Real Iridium decoding is not yet implemented.
|
||||
"""
|
||||
try:
|
||||
burst_count = 0
|
||||
# Send initial demo mode warning
|
||||
app_module.satellite_queue.put({
|
||||
'type': 'info',
|
||||
'message': '⚠️ DEMO MODE: Generating simulated Iridium bursts for demonstration'
|
||||
})
|
||||
|
||||
while process.poll() is None:
|
||||
data = process.stdout.read(1024)
|
||||
if data:
|
||||
if len(data) > 0 and burst_count < 100:
|
||||
# DEMO: Generate simulated bursts (1% chance per read)
|
||||
if random.random() < 0.01:
|
||||
burst = {
|
||||
'type': 'burst',
|
||||
'demo': True, # Flag as demo data
|
||||
'time': datetime.now().strftime('%H:%M:%S.%f')[:-3],
|
||||
'frequency': f"{1616 + random.random() * 10:.3f}",
|
||||
'data': f"[SIMULATED] Frame data - Burst #{burst_count + 1}"
|
||||
}
|
||||
app_module.satellite_queue.put(burst)
|
||||
app_module.iridium_bursts.append(burst)
|
||||
burst_count += 1
|
||||
|
||||
time.sleep(0.1)
|
||||
except Exception as e:
|
||||
logger.error(f"Monitor error: {e}")
|
||||
|
||||
|
||||
@iridium_bp.route('/tools')
|
||||
def check_iridium_tools():
|
||||
"""Check for Iridium decoding tools."""
|
||||
has_iridium = shutil.which('iridium-extractor') is not None or shutil.which('iridium-parser') is not None
|
||||
has_rtl = shutil.which('rtl_fm') is not None
|
||||
return jsonify({
|
||||
'available': has_iridium or has_rtl,
|
||||
'demo_mode': DEMO_MODE,
|
||||
'message': 'Demo mode active - generating simulated data' if DEMO_MODE else None
|
||||
})
|
||||
|
||||
|
||||
@iridium_bp.route('/start', methods=['POST'])
|
||||
def start_iridium():
|
||||
"""Start Iridium burst capture (DEMO MODE - simulated data)."""
|
||||
with app_module.satellite_lock:
|
||||
if app_module.satellite_process and app_module.satellite_process.poll() is None:
|
||||
return jsonify({'status': 'error', 'message': 'Iridium capture already running'}), 409
|
||||
|
||||
data = request.json or {}
|
||||
|
||||
# Validate inputs
|
||||
try:
|
||||
freq = validate_frequency(data.get('freq', '1626.0'), min_mhz=1610.0, max_mhz=1650.0)
|
||||
gain = validate_gain(data.get('gain', '40'))
|
||||
device = validate_device_index(data.get('device', '0'))
|
||||
except ValueError as e:
|
||||
return jsonify({'status': 'error', 'message': str(e)}), 400
|
||||
|
||||
sample_rate = data.get('sampleRate', '2.048e6')
|
||||
# Validate sample rate format
|
||||
try:
|
||||
float(sample_rate.replace('e', 'E'))
|
||||
except (ValueError, AttributeError):
|
||||
return jsonify({'status': 'error', 'message': 'Invalid sample rate format'}), 400
|
||||
|
||||
# Get SDR type from request
|
||||
sdr_type_str = data.get('sdr_type', 'rtlsdr')
|
||||
try:
|
||||
sdr_type = SDRType(sdr_type_str)
|
||||
except ValueError:
|
||||
sdr_type = SDRType.RTL_SDR
|
||||
|
||||
# Check for required tools based on SDR type
|
||||
if sdr_type == SDRType.RTL_SDR:
|
||||
if not shutil.which('iridium-extractor') and not shutil.which('rtl_fm'):
|
||||
return jsonify({
|
||||
'status': 'error',
|
||||
'message': 'Iridium tools not found. Requires rtl_fm or iridium-extractor.'
|
||||
}), 503
|
||||
else:
|
||||
if not shutil.which('rx_fm'):
|
||||
return jsonify({
|
||||
'status': 'error',
|
||||
'message': f'rx_fm not found for {sdr_type.value}. Install SoapySDR tools.'
|
||||
}), 503
|
||||
|
||||
try:
|
||||
# Create device object and build command via abstraction layer
|
||||
sdr_device = SDRFactory.create_default_device(sdr_type, index=device)
|
||||
builder = SDRFactory.get_builder(sdr_type)
|
||||
|
||||
# Parse sample rate
|
||||
sample_rate_hz = int(float(sample_rate))
|
||||
|
||||
# Build FM demodulation command
|
||||
cmd = builder.build_fm_demod_command(
|
||||
device=sdr_device,
|
||||
frequency_mhz=float(freq),
|
||||
sample_rate=sample_rate_hz,
|
||||
gain=float(gain),
|
||||
ppm=None,
|
||||
modulation='fm',
|
||||
squelch=None
|
||||
)
|
||||
|
||||
app_module.satellite_process = subprocess.Popen(
|
||||
cmd,
|
||||
stdout=subprocess.PIPE,
|
||||
stderr=subprocess.PIPE
|
||||
)
|
||||
|
||||
thread = threading.Thread(target=monitor_iridium, args=(app_module.satellite_process,), daemon=True)
|
||||
thread.start()
|
||||
|
||||
return jsonify({
|
||||
'status': 'started',
|
||||
'demo_mode': DEMO_MODE,
|
||||
'message': 'Demo mode active - data is simulated' if DEMO_MODE else None
|
||||
})
|
||||
except FileNotFoundError as e:
|
||||
logger.error(f"Tool not found: {e}")
|
||||
return jsonify({'status': 'error', 'message': f'Tool not found: {e.filename}'}), 503
|
||||
except Exception as e:
|
||||
logger.error(f"Start error: {e}")
|
||||
return jsonify({'status': 'error', 'message': str(e)}), 500
|
||||
|
||||
|
||||
@iridium_bp.route('/stop', methods=['POST'])
|
||||
def stop_iridium():
|
||||
"""Stop Iridium capture."""
|
||||
with app_module.satellite_lock:
|
||||
if app_module.satellite_process:
|
||||
app_module.satellite_process.terminate()
|
||||
try:
|
||||
app_module.satellite_process.wait(timeout=5)
|
||||
except subprocess.TimeoutExpired:
|
||||
app_module.satellite_process.kill()
|
||||
app_module.satellite_process = None
|
||||
|
||||
return jsonify({'status': 'stopped'})
|
||||
|
||||
|
||||
@iridium_bp.route('/stream')
|
||||
def stream_iridium():
|
||||
"""SSE stream for Iridium bursts."""
|
||||
def generate():
|
||||
last_keepalive = time.time()
|
||||
keepalive_interval = 30.0
|
||||
|
||||
while True:
|
||||
try:
|
||||
msg = app_module.satellite_queue.get(timeout=1)
|
||||
last_keepalive = time.time()
|
||||
yield format_sse(msg)
|
||||
except queue.Empty:
|
||||
now = time.time()
|
||||
if now - last_keepalive >= keepalive_interval:
|
||||
yield format_sse({'type': 'keepalive'})
|
||||
last_keepalive = now
|
||||
|
||||
response = Response(generate(), mimetype='text/event-stream')
|
||||
response.headers['Cache-Control'] = 'no-cache'
|
||||
response.headers['X-Accel-Buffering'] = 'no'
|
||||
return response
|
||||
Reference in New Issue
Block a user