#!/bin/bash
sleep 35
# 设置日志输出函数,同时输出到控制台和文件
log_output() {
echo "$1" | tee -a /tmp/1.txt
}
# 网络切换状态变量
switch_count=0 # 连续切换计数器
good_signal_count=0 # 连续满足条件的次数
min_good_count=12 # 需要连续满足条件的次数
good_5g_threshold=8 # 5G信号好的阈值
good_wifi_threshold=40 # WiFi信号好的阈值
last_target_network="" # 上次目标网络类型
last_switch_time=0 # 上次切换时间戳(秒)
min_switch_interval=1 # 最小切换间隔(秒)
# 辅助函数:提取SINR值(兼容所有网络模式)
extract_sinr() {
local qeng_output="$1"
local sinr_value="0" # 默认值
if [ -z "$qeng_output" ]; then
echo "$sinr_value"
return
fi
# 先清理输入数据,去除换行符和回车符
local clean_output=$(echo "$qeng_output" | tr -d '\r\n' | tr -s ' ')
# 检查是否包含NR5G-SA模式
if echo "$clean_output" | grep -q "NR5G-SA"; then
# SA模式:SINR在第15个字段
sinr_value=`echo "$clean_output" | awk -F ":" '{print $2}' | awk -F "," '{print $15}'`
# 检查是否包含NR5G-NSA模式
elif echo "$clean_output" | grep -q "NR5G-NSA"; then
# NSA模式:NR5G-NSA部分,SINR在第6个字段
sinr_value=`echo "$clean_output" | awk -F ":" '{print $2}' | awk -F "," '{print $6}'`
# 检查是否包含LTE模式
elif echo "$clean_output" | grep -q "LTE"; then
# LTE模式:SINR在第17个字段
sinr_value=`echo "$clean_output" | awk -F ":" '{print $2}' | awk -F "," '{print $17}'`
# 检查是否包含WCDMA模式
elif echo "$clean_output" | grep -q "WCDMA"; then
# WCDMA模式:没有SINR字段,默认为0
sinr_value="0"
else
# 其他情况,尝试从第15个字段提取(兼容原有逻辑)
sinr_value=`echo "$clean_output" | awk -F ":" '{print $2}' | awk -F "," '{print $15}'`
fi
# 验证SINR值是否为有效数字,如果不是则返回0
if ! [[ "$sinr_value" =~ ^-?[0-9]+$ ]]; then
# log_output "5G信号强度无效: $sinr_value,set 0"
sinr_value=""
fi
echo "$sinr_value"
}
# 辅助函数:检测当前网络状态
detect_current_network() {
# 检查是否存在wlan0的默认路由
local wlan0_route=$(ip route show default dev wlan0 2>/dev/null)
if [ -z "$wlan0_route" ]; then
# 不存在wlan0默认路由,说明使用的是5G
echo "5g"
else
# 存在wlan0默认路由,检查metric值
local metric=$(echo "$wlan0_route" | awk '{print $NF}')
if [ "$metric" = "50" ]; then
# metric为50,表示正在使用wifi
echo "wifi"
else
# metric不是50,说明正在使用5G
echo "5g"
fi
fi
}
# 辅助函数:切换到5G网络(设置wifi metric为600)
switch_to_5g() {
log_output "切换到5G网络:设置wifi metric为600"
# 获取当前wlan0的默认路由信息
local current_route=$(ip route show default dev wlan0 2>/dev/null)
if [ -z "$current_route" ]; then
log_output "没有找到wlan0的默认路由,无法切换"
return 1
fi
# 提取网关信息
local gateway=$(echo "$current_route" | awk '{print $3}')
if [ -z "$gateway" ] || [ "$gateway" = "dev" ]; then
log_output "无法获取wlan0的网关信息"
return 1
fi
# 删除原路由并添加新metric的路由
ip route del default dev wlan0 2>/dev/null
ip route add default via "$gateway" dev wlan0 metric 600 2>/dev/null
if [ $? -eq 0 ]; then
log_output "5G网络切换成功"
return 0
else
log_output "5G网络切换失败"
return 1
fi
}
# 辅助函数:切换到WiFi网络(设置wifi metric为50)
switch_to_wifi() {
log_output "切换到WiFi网络:设置wifi metric为50"
# 获取当前wlan0的默认路由信息
local current_route=$(ip route show default dev wlan0 2>/dev/null)
if [ -z "$current_route" ]; then
log_output "没有找到wlan0的默认路由,无法切换"
return 1
fi
# 提取网关信息
local gateway=$(echo "$current_route" | awk '{print $3}')
if [ -z "$gateway" ] || [ "$gateway" = "dev" ]; then
log_output "无法获取wlan0的网关信息"
return 1
fi
# 删除原路由并添加新metric的路由
ip route del default dev wlan0 2>/dev/null
ip route add default via "$gateway" dev wlan0 metric 50 2>/dev/null
if [ $? -eq 0 ]; then
log_output "WiFi网络切换成功"
return 0
else
log_output "WiFi网络切换失败"
return 1
fi
}
# 开机时获取当前网络状态
log_output "正在检测当前网络状态..."
current_network=$(detect_current_network)
log_output "检测到当前使用${current_network}网络"
while [ 1 ]
do
log_size=`ls -l /tmp/1.txt | awk -F " " '{print $5}'`
if [ $log_size -gt 50000000 ];then
mv /tmp/1.txt /root/1.txt
fi
log_output "============================================="
date | tee -a /tmp/1.txt
# 更新当前网络状态(防止外部因素导致状态变化)
current_network=$(detect_current_network)
# 获取5G信号强度
fiveg=`echo -e 'at+qeng="servingcell"\r\n' | busybox microcom /dev/ttyUSB3 -s 115200 -t 1000`
if [ "$fiveg" == "" ];then
sleep 2
fi
echo $fiveg | awk -F ":" '{print $2}' | tee -a /tmp/1.txt
five5_strength=$(extract_sinr "$fiveg")
# 获取WiFi信号强度
wifi=`nmcli -t -f active,ssid,signal device wifi | grep yes`
wifi_sig=`echo $wifi | awk -F "yes:" '{print $2}' | awk -F ":" '{print $2}'`
log_output "5g_strength: $five5_strength"
log_output "wifi_strength: $wifi_sig"
log_output "current_network: $current_network"
# 检查信号强度是否为有效数字(支持负数),如果不是则跳过本次循环
if ! [[ "$five5_strength" =~ ^-?[0-9]+$ ]]; then
log_output "5G信号强度无效: $five5_strength"
five5_strength="-99"
fi
if ! [[ "$wifi_sig" =~ ^-?[0-9]+$ ]]; then
log_output "WiFi信号强度无效: $wifi_sig"
wifi_sig="-99"
fi
# 网络切换逻辑
should_switch=false
target_network=""
# 优先使用5G的逻辑
if [ $five5_strength -gt $good_5g_threshold ]; then
if [ "$current_network" != "5g" ]; then
# 5G信号好,检查目标网络是否变化
if [ "$last_target_network" != "5g" ]; then
# 目标网络变化,重新开始计数
good_signal_count=1
last_target_network="5g"
else
# 目标网络不变,继续计数
good_signal_count=$((good_signal_count + 1))
fi
log_output "5G信号好,连续满足条件次数: $good_signal_count/$min_good_count"
if [ $good_signal_count -ge $min_good_count ]; then
should_switch=true
target_network="5g"
log_output "准备切换到5G网络"
fi
else
log_output "5G网络已激活且信号良好"
good_signal_count=0 # 重置计数
last_target_network=""
fi
elif [ $wifi_sig -gt $good_wifi_threshold ]; then
# 5G信号不好但WiFi信号好
if [ "$current_network" != "wifi" ]; then
# WiFi信号好,检查目标网络是否变化
if [ "$last_target_network" != "wifi" ]; then
# 目标网络变化,重新开始计数
good_signal_count=1
last_target_network="wifi"
else
# 目标网络不变,继续计数
good_signal_count=$((good_signal_count + 1))
fi
log_output "WiFi信号好,连续满足条件次数: $good_signal_count/$min_good_count"
if [ $good_signal_count -ge $min_good_count ]; then
should_switch=true
target_network="wifi"
log_output "准备切换到WiFi网络"
fi
else
log_output "WiFi网络已激活且信号良好"
good_signal_count=0 # 重置计数
last_target_network=""
fi
else
# 两个信号都不好,优先使用5G
if [ "$current_network" != "5g" ]; then
# 两个信号都不好,检查目标网络是否变化
if [ "$last_target_network" != "5g" ]; then
# 目标网络变化,重新开始计数
good_signal_count=1
last_target_network="5g"
else
# 目标网络不变,继续计数
good_signal_count=$((good_signal_count + 1))
fi
log_output "两个信号都不好,优先5G,连续满足条件次数: $good_signal_count/$min_good_count"
if [ $good_signal_count -ge $min_good_count ]; then
should_switch=true
target_network="5g"
log_output "准备切换到5G网络"
fi
else
log_output "两个信号都不好,保持当前5G网络"
good_signal_count=0 # 重置计数
last_target_network=""
fi
fi
# 执行网络切换
if [ "$should_switch" = true ]; then
# 检查是否满足最小切换间隔
current_time=$(date +%s)
time_since_last_switch=$((current_time - last_switch_time))
if [ $time_since_last_switch -lt $min_switch_interval ]; then
remaining_time=$((min_switch_interval - time_since_last_switch))
log_output "距离上次切换时间不足,还需等待 $remaining_time 秒"
sleep 1
continue
fi
log_output "执行网络切换: $current_network -> $target_network"
if [ "$target_network" = "5g" ]; then
# 切换到5G: 设置wifi metric为600
if switch_to_5g; then
current_network="5g"
good_signal_count=0 # 重置计数
switch_count=$((switch_count + 1))
last_switch_time=$(date +%s) # 更新切换时间
fi
elif [ "$target_network" = "wifi" ]; then
# 切换到WiFi: 设置wifi metric为50
if switch_to_wifi; then
current_network="wifi"
good_signal_count=0 # 重置计数
switch_count=$((switch_count + 1))
last_switch_time=$(date +%s) # 更新切换时间
fi
fi
else
log_output "无需切换网络,保持当前状态"
fi
log_output "切换次数: $switch_count"
done