Mode switcher (rtl_mode_switch.sh) handles exclusive dongle access between DVB-T, FM, SDR scanner, ADS-B, spectrum, and HackRF modes. DVB-T pipeline: RTL-SDR -> GNU Radio demod -> MPEG-TS -> HTTP -> Kodi. Kodi setup script generates M3U playlist for PVR IPTV Simple Client. Includes dvbt_rx.py and sdr_tv.py from dvbt-rx project. WebUI updated with mode switcher, channel selector, and Kodi controls.
236 lines
8.6 KiB
Bash
Executable File
236 lines
8.6 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"
|
|
TERMUX="/data/data/com.termux/files/usr/bin"
|
|
STREAMDIR="$MODDIR/streams"
|
|
|
|
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
|
|
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 "$TERMUX/rtl_tcp" ]; then
|
|
"$TERMUX/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
|