RadioControl v1.0.0 — KernelSU-Next module for radio engineering

Shannon 5400 AT command terminal, BCM4390 WiFi mode switching,
carrier config override, debugfs browser, RF thermal monitoring,
CP debug, Thread/Wonder radio, satellite/NTN test support.

Verified on Pixel 10 Pro Fold (Tensor G5 / laguna).
This commit is contained in:
sssnake
2026-03-31 04:27:24 -07:00
commit bb8f2aae2a
16 changed files with 4153 additions and 0 deletions

242
service.sh Executable file
View File

@@ -0,0 +1,242 @@
#!/system/bin/sh
# RadioControl — late service script
# Loads kernel modules, starts WebUI, applies WiFi mode
MODDIR=${0%/*}
CONFIG_DIR="/data/adb/radiocontrol"
CONFIG_FILE="$CONFIG_DIR/config.sh"
LOG_FILE="$CONFIG_DIR/radiocontrol.log"
PID_FILE="$CONFIG_DIR/webui.pid"
KMOD_DIR="$MODDIR/common/kmod"
log() {
echo "[$(date '+%Y-%m-%d %H:%M:%S')] $1" >> "$LOG_FILE"
}
mkdir -p "$CONFIG_DIR"
source "$CONFIG_FILE" 2>/dev/null
DETECTED_SOC=$(cat "$CONFIG_DIR/detected_soc" 2>/dev/null)
log "RadioControl service starting (SoC: $DETECTED_SOC)"
#############################
# Load kernel modules
#############################
load_kmod() {
local mod_name="$1"
local mod_path="$KMOD_DIR/${mod_name}.ko"
if [ -f "$mod_path" ]; then
log "Loading kernel module: $mod_name"
insmod "$mod_path" 2>> "$LOG_FILE"
if [ $? -eq 0 ]; then
log " -> $mod_name loaded successfully"
else
log " -> $mod_name FAILED (may need kernel headers rebuild)"
fi
else
log " -> $mod_name.ko not found at $mod_path"
fi
}
# Auto-detect which modules to load based on SoC
if echo "$LOAD_MODULES" | grep -q "wifi_mon"; then
load_kmod "rc_wifi_mon"
fi
if echo "$LOAD_MODULES" | grep -q "shannon_cmd"; then
load_kmod "rc_shannon_cmd"
elif [ "$DETECTED_SOC" = "exynos" ] || [ "$DETECTED_SOC" = "tensor" ]; then
# Auto-load Shannon module for Exynos/Tensor if AT terminal is used
if [ -c /dev/umts_atc0 ] || [ -c /dev/nr_atc0 ]; then
load_kmod "rc_shannon_cmd"
fi
fi
if echo "$LOAD_MODULES" | grep -q "diag_bridge"; then
load_kmod "rc_diag_bridge"
elif [ "$DETECTED_SOC" = "qualcomm" ] && [ -c /dev/diag ]; then
load_kmod "rc_diag_bridge"
fi
#############################
# Detect available modem interfaces
#############################
detect_modem_interfaces() {
local interfaces=""
# Shannon AT channels (Exynos/Tensor) — umts_router is the primary AT interface
for dev in /dev/umts_router /dev/umts_atc0 /dev/umts_atc1 /dev/umts_router0 /dev/nr_atc0; do
[ -c "$dev" ] && interfaces="$interfaces $dev"
done
# Shannon IPC / DM / OEM channels
for dev in /dev/umts_ipc0 /dev/umts_ipc1 /dev/umts_dm0 /dev/umts_rfs0 \
/dev/umts_boot0 /dev/umts_loopback /dev/umts_rcs0 /dev/umts_rcs1 \
/dev/umts_wfc0 /dev/umts_wfc1 /dev/umts_toe0 \
/dev/oem_ipc0 /dev/oem_ipc1 /dev/oem_ipc2 /dev/oem_ipc3 \
/dev/oem_ipc4 /dev/oem_ipc5 /dev/oem_ipc6 /dev/oem_ipc7 \
/dev/gnss_ipc /dev/acd-factory_diag; do
[ -c "$dev" ] && interfaces="$interfaces $dev"
done
# Qualcomm DIAG
[ -c /dev/diag ] && interfaces="$interfaces /dev/diag"
# Qualcomm AT
for dev in /dev/smd7 /dev/ttyHS0 /dev/ttyMSM0 /dev/at_mdm0; do
[ -c "$dev" ] && interfaces="$interfaces $dev"
done
# Our kernel module devices
[ -c /dev/rc_shannon ] && interfaces="$interfaces /dev/rc_shannon"
[ -c /dev/rc_diag ] && interfaces="$interfaces /dev/rc_diag"
echo "$interfaces" > "$CONFIG_DIR/modem_interfaces"
log "Detected modem interfaces:$interfaces"
}
detect_modem_interfaces
#############################
# Detect WiFi driver & capabilities
#############################
detect_wifi_info() {
local info_file="$CONFIG_DIR/wifi_info"
echo "" > "$info_file"
for iface in /sys/class/net/*; do
local name=$(basename "$iface")
if [ -d "$iface/wireless" ] || [ -d "$iface/phy80211" ] || echo "$name" | grep -qE '^(wlan|wifi|wlp)'; then
echo "IFACE=$name" >> "$info_file"
# Driver name
local driver=$(readlink "$iface/device/driver" 2>/dev/null | xargs basename 2>/dev/null)
echo "DRIVER=$driver" >> "$info_file"
# Module name
local module=$(basename "$(readlink "$iface/device/driver/module" 2>/dev/null)" 2>/dev/null)
echo "MODULE=$module" >> "$info_file"
# Firmware path
if [ -f /sys/module/bcmdhd/parameters/firmware_path ]; then
echo "FW_PATH=$(cat /sys/module/bcmdhd/parameters/firmware_path)" >> "$info_file"
echo "WIFI_CHIP=broadcom" >> "$info_file"
elif [ -d /sys/module/scsc_wlan ]; then
echo "WIFI_CHIP=samsung_scsc" >> "$info_file"
[ -f /d/scsc/mx/mxman ] && echo "SCSC_STATE=$(cat /d/scsc/mx/mxman 2>/dev/null)" >> "$info_file"
elif [ -d /sys/module/ath11k ] || [ -d /sys/module/ath12k ]; then
echo "WIFI_CHIP=qualcomm_ath" >> "$info_file"
elif [ -d /sys/module/cnss2 ]; then
echo "WIFI_CHIP=qualcomm_cnss" >> "$info_file"
fi
# Current mode
local mode=$(iw dev "$name" info 2>/dev/null | grep type | awk '{print $2}')
echo "CURRENT_MODE=$mode" >> "$info_file"
# PHY capabilities
local phy=$(iw dev "$name" info 2>/dev/null | grep wiphy | awk '{print $2}')
if [ -n "$phy" ]; then
echo "PHY=phy${phy}" >> "$info_file"
iw phy "phy${phy}" info 2>/dev/null | sed -n '/Supported interface modes/,/^[^\t]/p' | grep '^\s*\*' | sed 's/.*\* /SUPPORTED_MODE=/' >> "$info_file"
# Bands
iw phy "phy${phy}" info 2>/dev/null | grep -E "Band [0-9]" | sed 's/.*Band /BAND=/' >> "$info_file"
fi
# Check monitor mode via rc_wifi_mon
if lsmod 2>/dev/null | grep -q rc_wifi_mon; then
echo "MONITOR_PATCH=loaded" >> "$info_file"
else
echo "MONITOR_PATCH=not_loaded" >> "$info_file"
fi
fi
done
log "WiFi info written to $info_file"
}
# Wait for WiFi to be up
sleep 3
detect_wifi_info
#############################
# Apply WiFi mode if non-default
#############################
if [ -n "$WIFI_MODE" ] && [ "$WIFI_MODE" != "managed" ]; then
sleep 2
local iface=""
for candidate in wlan0 wlan1 wifi0; do
[ -d "/sys/class/net/$candidate" ] && iface="$candidate" && break
done
if [ -n "$iface" ]; then
log "Applying WiFi mode: $WIFI_MODE on $iface"
ip link set "$iface" down 2>/dev/null
case "$WIFI_MODE" in
monitor) iw dev "$iface" set type monitor 2>/dev/null ;;
injection) iw dev "$iface" set type monitor 2>/dev/null
iw dev "$iface" set monitor fcsfail otherbss 2>/dev/null ;;
mesh) iw dev "$iface" set type mesh 2>/dev/null ;;
ap) iw dev "$iface" set type __ap 2>/dev/null ;;
esac
ip link set "$iface" up 2>/dev/null
fi
fi
#############################
# Enumerate debugfs paths
#############################
enumerate_debugfs() {
local dbg_file="$CONFIG_DIR/debugfs_paths"
echo "" > "$dbg_file"
# Modem/radio related debugfs
for path in \
/sys/kernel/debug/modem_diag \
/sys/kernel/debug/diag \
/sys/kernel/debug/msm_subsys \
/sys/kernel/debug/ipc_logging \
/sys/kernel/debug/cnss \
/sys/kernel/debug/wlan \
/sys/kernel/debug/ath11k \
/sys/kernel/debug/ath12k \
/sys/kernel/debug/ipa \
/sys/kernel/debug/scsc \
/sys/kernel/debug/clk \
/sys/kernel/debug/regulator \
/sys/kernel/debug/remoteproc \
/sys/kernel/debug/aoc \
/sys/kernel/debug/trusty \
/sys/kernel/debug/gsa \
/sys/kernel/debug/mali \
/sys/kernel/debug/asv; do
if [ -d "$path" ]; then
echo "$path" >> "$dbg_file"
fi
done
log "debugfs enumeration done ($(wc -l < "$dbg_file") paths found)"
}
enumerate_debugfs
#############################
# Start WebUI server
#############################
if [ -f "$PID_FILE" ]; then
kill $(cat "$PID_FILE") 2>/dev/null
rm -f "$PID_FILE"
fi
log "Starting WebUI on port 8088"
nohup /system/bin/radiocontrol >> "$LOG_FILE" 2>&1 &
echo $! > "$PID_FILE"
log "RadioControl service started (PID: $(cat $PID_FILE))"