Files
driver-manager/scripts/rtl_mode_switch.sh

242 lines
8.7 KiB
Bash
Executable File

#!/system/bin/sh
# RTL-SDR Mode Switcher
# Switches between DVB-T (digital TV), FM Radio, and SDR scanner modes
# Manages the userspace process that controls the RTL-SDR dongle
#
# Only one mode can use the dongle at a time. This script kills
# the active process before starting a new one.
MODDIR="/data/adb/modules/driver-manager"
CONFDIR="$MODDIR/config"
LOGFILE="$MODDIR/driver-manager.log"
PIDDIR="$MODDIR/run"
STREAMDIR="$MODDIR/streams"
TERMUX="/data/data/com.termux/files/usr/bin"
RTL_TCP="$TERMUX/rtl_tcp"
RTL_FM="$TERMUX/rtl_fm"
RTL_ADSB="$TERMUX/rtl_adsb"
RTL_POWER="$TERMUX/rtl_power"
HACKRF="$TERMUX/hackrf_transfer"
mkdir -p "$PIDDIR" "$STREAMDIR"
mlog() {
echo "$(date '+%Y-%m-%d %H:%M:%S') [rtl_switch] $1" >> "$LOGFILE"
}
# Kill any running RTL process that holds the dongle
kill_rtl() {
for pidfile in "$PIDDIR"/rtl_*.pid; do
[ -f "$pidfile" ] || continue
PID=$(cat "$pidfile")
if [ -n "$PID" ] && kill -0 "$PID" 2>/dev/null; then
kill "$PID" 2>/dev/null
sleep 1
kill -9 "$PID" 2>/dev/null
mlog "Killed PID $PID ($(basename "$pidfile" .pid))"
fi
rm -f "$pidfile"
done
# Also catch any strays — both real and stealth names
pkill -f rtl_tcp 2>/dev/null
pkill -f rtl_fm 2>/dev/null
pkill -f rtl_adsb 2>/dev/null
pkill -f rtl_power 2>/dev/null
pkill -f dvbt_rx 2>/dev/null
pkill -f sdr_tv 2>/dev/null
sleep 1
}
# Start rtl_tcp server — base layer for all modes
# Apps connect to localhost:1234 for I/Q data
start_rtl_tcp() {
PORT=$(cat "$CONFDIR/rtl_tcp_port" 2>/dev/null || echo "1234")
GAIN=$(cat "$CONFDIR/rtl_gain" 2>/dev/null || echo "0")
SRATE=$(cat "$CONFDIR/rtl_samplerate" 2>/dev/null || echo "2048000")
FREQ=$(cat "$CONFDIR/rtl_freq" 2>/dev/null || echo "100000000")
if [ -x "$RTL_TCP" ]; then
"$RTL_TCP" -a 127.0.0.1 -p "$PORT" -f "$FREQ" -s "$SRATE" -g "$GAIN" &
echo $! > "$PIDDIR/rtl_tcp.pid"
mlog "rtl_tcp started on port $PORT (freq=$FREQ srate=$SRATE gain=$GAIN)"
else
mlog "ERROR: rtl_tcp not found — install in Termux: pkg install rtl-sdr"
return 1
fi
}
MODE="$1"
[ -z "$MODE" ] && MODE=$(cat "$CONFDIR/rtl_mode" 2>/dev/null || echo "off")
case "$MODE" in
# =================================================================
# DVB-T Digital TV Mode
# =================================================================
# Receives DVB-T signal, outputs MPEG-TS stream
# Stream is served via HTTP on port 8554 for Kodi to consume
dvbt)
kill_rtl
FREQ=$(cat "$CONFDIR/dvbt_freq" 2>/dev/null || echo "506000000")
BW=$(cat "$CONFDIR/dvbt_bandwidth" 2>/dev/null || echo "8")
TXMODE=$(cat "$CONFDIR/dvbt_txmode" 2>/dev/null || echo "8k")
CONSTELLATION=$(cat "$CONFDIR/dvbt_constellation" 2>/dev/null || echo "64qam")
CODERATE=$(cat "$CONFDIR/dvbt_coderate" 2>/dev/null || echo "2/3")
GUARD=$(cat "$CONFDIR/dvbt_guard" 2>/dev/null || echo "1/32")
KODI_PORT=$(cat "$CONFDIR/kodi_stream_port" 2>/dev/null || echo "8554")
# Use the sdr_tv.py DVB-T receiver if available
SDR_TV="$MODDIR/scripts/sdr_tv.py"
DVBT_RX="$MODDIR/scripts/dvbt_rx.py"
if [ -x "$TERMUX/python3" ] && [ -f "$SDR_TV" ]; then
# Pipe MPEG-TS to a local HTTP server for Kodi
# Using socat or a simple netcat HTTP wrapper
FIFO="$STREAMDIR/dvbt.ts"
rm -f "$FIFO"
mkfifo "$FIFO" 2>/dev/null
# Start DVB-T receiver, output MPEG-TS to FIFO
"$TERMUX/python3" "$SDR_TV" dvbt \
--freq "$FREQ" \
--bandwidth "$BW" \
--transmission-mode "$TXMODE" \
--constellation "$CONSTELLATION" \
--code-rate "$CODERATE" \
--guard-interval "$GUARD" \
> "$FIFO" 2>>"$LOGFILE" &
echo $! > "$PIDDIR/rtl_dvbt.pid"
# HTTP stream server — serves MPEG-TS on port for Kodi
# Kodi connects to http://127.0.0.1:8554/dvbt.ts
(while true; do
cat "$FIFO" | {
read -r _ # wait for connection
echo -e "HTTP/1.1 200 OK\r\nContent-Type: video/mp2t\r\nConnection: close\r\n\r"
cat
} | nc -l -p "$KODI_PORT" 2>/dev/null
done) &
echo $! > "$PIDDIR/rtl_dvbt_http.pid"
mlog "DVB-T started: freq=$FREQ bw=${BW}MHz mode=$TXMODE"
mlog "Kodi stream: http://127.0.0.1:$KODI_PORT"
elif [ -x "$TERMUX/rtl_tcp" ]; then
# Fallback: just start rtl_tcp, let an Android DVB app handle it
echo "$FREQ" > "$CONFDIR/rtl_freq"
start_rtl_tcp
mlog "DVB-T fallback: rtl_tcp on port 1234, use SDR Touch or rtl_tcp_andro"
else
mlog "ERROR: no DVB-T tools found"
fi
echo "dvbt" > "$CONFDIR/rtl_mode"
;;
# =================================================================
# FM Radio Mode
# =================================================================
fm)
kill_rtl
FREQ=$(cat "$CONFDIR/fm_freq" 2>/dev/null || echo "100000000")
GAIN=$(cat "$CONFDIR/rtl_gain" 2>/dev/null || echo "0")
if [ -x "$TERMUX/rtl_fm" ]; then
# Demodulate FM and pipe to audio output
"$TERMUX/rtl_fm" -f "$FREQ" -M wbfm -s 200000 -r 48000 -g "$GAIN" - 2>>"$LOGFILE" | \
"$TERMUX/play" -r 48000 -b 16 -c 1 -e signed-integer -t raw - 2>/dev/null &
echo $! > "$PIDDIR/rtl_fm.pid"
mlog "FM radio started: freq=$FREQ gain=$GAIN"
else
mlog "ERROR: rtl_fm not found — install in Termux: pkg install rtl-sdr"
fi
echo "fm" > "$CONFDIR/rtl_mode"
;;
# =================================================================
# SDR Scanner Mode
# =================================================================
# Starts rtl_tcp server for any SDR app to connect
sdr)
kill_rtl
start_rtl_tcp
echo "sdr" > "$CONFDIR/rtl_mode"
;;
# =================================================================
# ADS-B Aircraft Tracking
# =================================================================
adsb)
kill_rtl
if [ -x "$TERMUX/rtl_adsb" ]; then
"$TERMUX/rtl_adsb" -g 50 > "$STREAMDIR/adsb_output.txt" 2>>"$LOGFILE" &
echo $! > "$PIDDIR/rtl_adsb.pid"
mlog "ADS-B tracking started (1090 MHz)"
else
mlog "ERROR: rtl_adsb not found"
fi
echo "adsb" > "$CONFDIR/rtl_mode"
;;
# =================================================================
# Spectrum Scanner
# =================================================================
spectrum)
kill_rtl
RANGE=$(cat "$CONFDIR/spectrum_range" 2>/dev/null || echo "24M:1800M")
if [ -x "$TERMUX/rtl_power" ]; then
"$TERMUX/rtl_power" -f "$RANGE" -g 50 -i 1 "$STREAMDIR/spectrum_data.csv" 2>>"$LOGFILE" &
echo $! > "$PIDDIR/rtl_spectrum.pid"
mlog "Spectrum scan started: $RANGE"
else
mlog "ERROR: rtl_power not found"
fi
echo "spectrum" > "$CONFDIR/rtl_mode"
;;
# =================================================================
# HackRF TX/RX Mode
# =================================================================
hackrf)
kill_rtl
# HackRF uses its own USB interface, doesn't conflict with RTL-SDR
# Just set the mode flag — apps handle the rest
mlog "HackRF mode set — use hackrf_transfer or rtl_tcp_andro"
echo "hackrf" > "$CONFDIR/rtl_mode"
;;
# =================================================================
# Off
# =================================================================
off)
kill_rtl
mlog "All SDR processes stopped"
echo "off" > "$CONFDIR/rtl_mode"
;;
# =================================================================
# Status
# =================================================================
status)
CURRENT=$(cat "$CONFDIR/rtl_mode" 2>/dev/null || echo "off")
echo "Mode: $CURRENT"
for pidfile in "$PIDDIR"/rtl_*.pid; do
[ -f "$pidfile" ] || continue
PID=$(cat "$pidfile")
NAME=$(basename "$pidfile" .pid)
if kill -0 "$PID" 2>/dev/null; then
echo " $NAME: running (PID $PID)"
else
echo " $NAME: dead"
fi
done
;;
*)
echo "Usage: rtl_mode_switch.sh {dvbt|fm|sdr|adsb|spectrum|hackrf|off|status}"
exit 1
;;
esac