mirror of
https://github.com/kiddin9/op-packages.git
synced 2026-07-27 02:11:19 +08:00
172 lines
4.5 KiB
Bash
Executable File
172 lines
4.5 KiB
Bash
Executable File
#!/bin/sh
|
|
|
|
# SIM slot switcher for HuastLink HC-G60 or ZBT-WE2806-A
|
|
# or similiar cpe OpenWrt-routers
|
|
# by Konstantine Shevlakov at <shevlakov@132lan.ru> 2025-2026
|
|
|
|
# config file stored in /etc/config/ssw
|
|
# define gpios in /etc/config/system
|
|
#
|
|
# mandatory section names of gpio: modem and sim
|
|
# example config file /etc/config/system for gpio_switch
|
|
#
|
|
# config gpio_switch 'modem'
|
|
# option name 'Modem pwr'
|
|
# option gpio_pin '512'
|
|
# option value '1'
|
|
#
|
|
# config gpio_switch 'sim'
|
|
# option name 'SIM switch'
|
|
# option gpio_pin 'sim'
|
|
# option value '1'
|
|
#
|
|
# if gpio not defined on dts and have integer number on gpioswitch then
|
|
# option gpio must have value 'gpioN'. Example /etc/config/ssw:
|
|
#
|
|
# config modem 'modem'
|
|
# option gpio 'gpio512'
|
|
# option value '1'
|
|
#
|
|
# config sim 'sim'
|
|
# option gpio 'sim'
|
|
# option value '1'
|
|
|
|
# Schedule switch section example /etc/config/ssw:
|
|
#
|
|
# config schedule 'schedule'
|
|
# option enable '1'
|
|
# option time_on 'HH:MM' # time to switch to reserve SIM (24h format)
|
|
# option duration '60' # minutes until revert to default SIM (0 = no revert)
|
|
# option apn 'internet' # APN for reserve SIM during schedule switch
|
|
# option period 'daily' # daily | interval | weekly
|
|
# option period_days '3' # for period=interval: every N days
|
|
# option weekday '1' # for period=weekly: 0=Sun 1=Mon … 6=Sat
|
|
|
|
|
|
NODE="SW SIM"
|
|
|
|
# Get Variables
|
|
get_vars(){
|
|
for v in enable interval revert rsrp times_rsrp apn1 apn2; do
|
|
eval $v=$(uci -q get ssw.failover.${v} 2>/dev/null)
|
|
done
|
|
for d in modem sim; do
|
|
for s in gpio value; do
|
|
eval "${d}_${s}=$(uci -q get ssw.${d}.${s} 2>/dev/null)"
|
|
done
|
|
done
|
|
[ -n "$interval" ] || interval=60
|
|
[ -n "$times_rsrp" ] || times_rsrp=5
|
|
|
|
}
|
|
|
|
# SIM Switch
|
|
sw_sim(){
|
|
case $cur_sim in
|
|
0) next_sim=1 ;;
|
|
1) next_sim=0 ;;
|
|
esac
|
|
|
|
echo "0" > /sys/class/gpio/$modem_gpio/value
|
|
echo "$next_sim" > /sys/class/gpio/$sim_gpio/value
|
|
|
|
if [ "$modem_value" = "1" ]; then
|
|
sleep 2
|
|
echo "1" > /sys/class/gpio/$modem_gpio/value
|
|
if [ -x /etc/init.d/smstools3 ]; then
|
|
/etc/init.d/smstools3 restart
|
|
fi
|
|
fi
|
|
set > /tmp/apn.ssw
|
|
}
|
|
|
|
# Check interface state via mwan3
|
|
monitor_mwan3(){
|
|
iface=$(uci show network | awk -F [.] '/devices/{print $2}')
|
|
if [ -r /tmp/run/mwan3/iface_state/$iface ]; then
|
|
link_status=$(cat /tmp/run/mwan3/iface_state/$iface | grep online | wc -l)
|
|
else
|
|
link_status=1
|
|
fi
|
|
}
|
|
|
|
# RSRP average value by modemmanager. Enable signal monitor!
|
|
monitor_rsrp(){
|
|
device="$(uci show network | awk -F [=] '/devices/{gsub("'\''","");print $2}')"
|
|
SIGNAL="$(mmcli -J -m $device --signal-get)"
|
|
CRSRP=$(echo "$SIGNAL" | jsonfilter -e '@["modem"][*]["lte"]["rsrp"]' | awk '{printf "%.0f\n", $1}')
|
|
if ! [ $CRSRP ]; then
|
|
CRSRP=$(echo "$SIGNAL" | jsonfilter -e '@["modem"][*]["5g"]["rsrp"]' | awk '{printf "%.0f\n", $1}')
|
|
fi
|
|
|
|
if [ -n "$CRSRP" ] && [ "$CRSRP" -ne "0" ]; then
|
|
echo $CRSRP >> /tmp/ssw_rsrp.var
|
|
fi
|
|
if [ "$cnt" -eq "$times_rsrp" ]; then
|
|
RSRP=$(awk '{sum+=$1} END { printf "%.0f\n", sum/NR }' /tmp/ssw_rsrp.var)
|
|
cat /dev/null > /tmp/ssw_rsrp.var
|
|
if [ $RSRP -lt $rsrp ]; then
|
|
mon_rsrp=0
|
|
else
|
|
mon_rsrp=1
|
|
fi
|
|
fi
|
|
}
|
|
|
|
# reload iface
|
|
reload_iface(){
|
|
[ "$iface" ] && {
|
|
for i in $iface; do
|
|
ifup $i
|
|
done
|
|
}
|
|
}
|
|
|
|
# Stuff
|
|
cnt=1
|
|
while true; do
|
|
get_vars
|
|
sleep $interval
|
|
|
|
if [ "$enable" = "1" ]; then
|
|
cur_sim=$(cat /sys/class/gpio/$sim_gpio/value)
|
|
monitor_rsrp
|
|
monitor_mwan3
|
|
if [ "$cnt" -eq "$times_rsrp" ]; then
|
|
if [ "$link_status" = "0" -o "$mon_rsrp" = "0" ]; then
|
|
|
|
if [ "$sim_value" -eq "$cur_sim" ]; then
|
|
apn=$apn2
|
|
else
|
|
apn=$apn1
|
|
fi
|
|
iface=$(uci show network | awk -F [.] '/devices/{gsub("'\''","");print $2}' | tail -1)
|
|
if [ $RSRP ]; then
|
|
if [ "$mon_rsrp" = "0" ]; then
|
|
logger -t "$NODE" "Modem interface: $iface is average RSRP= ${RSRP} dBm. Min. value ${rsrp} dBm."
|
|
fi
|
|
if [ "$link_status" = "0" ]; then
|
|
logger -t "$NODE" "Modem interface: $iface is loss connectivity"
|
|
fi
|
|
else
|
|
logger -t "$NODE" "WARNING: RSRP value not exist. Please check \"Resfesh signal\" option of modem interface!"
|
|
fi
|
|
if [ "${#apn}" -gt "0" ]; then
|
|
uci set network.$iface.apn="$apn"
|
|
logger -t "$NODE" "Switch SIM-card slot with APN: $apn"
|
|
else
|
|
logger -t "$NODE" "WARNING: APN not defined. Switch SIM-card slot with default APN."
|
|
uci set network.$iface.apn="internet"
|
|
fi
|
|
|
|
uci commit network
|
|
reload_config network
|
|
sw_sim && sleep 20 && reload_iface &
|
|
fi
|
|
cnt=0
|
|
else
|
|
cnt=$(($cnt+1))
|
|
fi
|
|
fi
|
|
done
|