Files
openwrt-build-helper/reports/2026-10-28-cudy-tr3000-wwan-watchdog.md

217 lines
8.0 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# Cudy TR3000:部署 Wi-Fi 上联看门狗与日志优化
- 日期:2026-10-28
- 设备:Cudy TR3000 256MB v1(`cudy-tr3000.tail694d4.ts.net`,远程)
- 系统:OpenWrt 25.12.6 r33311-981c978eff,mediatek/filogic
- 无线:MT7981,mt76 驱动
- 相关报告:[`2026-10-28-linksys-mx8500-wwan-recovery.md`](2026-10-28-linksys-mx8500-wwan-recovery.md)
## 背景
Linksys MX8500 上发现 Wi-Fi 上联(STA)会卡在“已关联但发不出包”的状态,且不会自动恢复(见相关报告)。本次把同一套看门狗和日志设置部署到 Cudy TR3000,并检查它是否存在同样的问题。
这台路由器是远程设备,唯一在用的上联就是 Wi-Fi。改 Wi-Fi 设置会导致一段时间断线,所以只做了不影响 Wi-Fi 的改动。
## 现状
| 接口 | 设备 | 射频 | 上游 | 状态 |
|---|---|---|---|---|
| wwan5 | `phy1-sta0` | radio1(5G) | eduroam(WPA2-Enterprise,PEAP/MSCHAPv2) | 在用,mwan3 online |
| wwan2 | `phy0-sta0` | radio0(2.4G) | eduroam | `wireless.wifinet2.disabled='1'`,未启用 |
| wan | `eth0` | — | 有线 | 无载波,未使用 |
注意射频编号和 MX8500 相反:这台的 5G 是 radio1 / phy1,2.4G 是 radio0 / phy0。
5G 射频上同样存在热点与 STA 频宽不一致:
| | 频宽 | 中心频率 |
|---|---|---|
| 热点 `phy1-ap0` | HE80 | 5290 MHz |
| STA `phy1-sta0` | 20 MHz(eduroam 只给 20 MHz) | 5260 MHz |
信道 52 是 DFS 信道。
## 检查结果:没有发现 MX8500 的故障
| 项目 | MX8500 故障时 | Cudy wwan5 |
|---|---|---|
| 连接时长 | 约 5 分钟后失效 | 30728 s(约 8.5 小时,开机至今未断) |
| tx failed / tx packets | 5775 / 6263(约 92%) | 67345 / 2242239(约 3%) |
| tx 速率 | HE-MCS0 NSS1,8.6 Mbit/s | HE-MCS11 NSS2,286.7 Mbit/s |
| 信号 | -53 dBm | -51 dBm |
| mwan3 离线记录 | 有 | 日志覆盖 17:43 起,无任何 offline 事件 |
结论:mt76 驱动目前没有表现出 ath11k 的“半死”问题。频宽不一致本身不一定会触发故障。
## 修改内容
### 1. 部署看门狗 `/usr/sbin/wwan-watchdog`
逻辑与 MX8500 的第二版相同(判定方式、确认次数、恢复步骤、退避),只有两处按本机调整:
| 项目 | MX8500 | Cudy TR3000 | 原因 |
|---|---|---|---|
| 探测地址 `PROBE_IPS` | `223.5.5.5 1.1.1.1` | `1.1.1.1 8.8.8.8` | 设备在美国 |
| 接口映射 | wwan2→phy1/radio1,wwan5→phy0/radio0 | wwan2→phy0/radio0,wwan5→phy1/radio1 | 射频编号相反 |
**eduroam 网关 172.27.64.1 不回 ping**(实测 100% 丢包,但外网正常)。MX8500 的第一版看门狗只 ping 网关、且第一次失败就重连,放在这里会每分钟强制重连一次。现在的版本是“网关或任一探测地址能通就算正常”,并且要连续两次失败才动手,所以不受影响。代价是“网关通但 mwan3 离线”这条提示在这台上不会出现。
恢复步骤:
| 检测结果 | 处理 |
|---|---|
| 正常 | 清零计数 |
| 不通,第 1 次 | 只记日志,等下一次确认 |
| 不通,第 2、3 次 | `REASSOCIATE`(eduroam 会重新走一次 EAP 认证) |
| 不通,第 4 次 | `wifi up radio1` |
| 之后仍不通 | 每 10 次检测重启一次射频 |
wwan2 当前未启用,`ifstatus wwan2` 不是 up,看门狗会直接跳过它。以后启用 wwan2 不需要改脚本。
相关改动:
- `/etc/crontabs/root`:新增 `* * * * * /usr/sbin/wwan-watchdog`(原来没有任何定时任务),并 `cron enable`
- `/etc/mwan3.user`:追加 `disconnected` 事件时调用看门狗(备份:`/root/mwan3.user.bak`)
- `/etc/sysupgrade.conf`:加入 `/usr/sbin/wwan-watchdog` 和 `/etc/mwan3.user`
部署过程中发现:BusyBox 的 `crontab -` 从管道读入时会写出空文件。所以这里直接写 `/etc/crontabs/root`,然后重启 cron。
### 2. 日志缓冲调大
`system.@system[0].log_size` 从 128 改为 1024(KB),出故障时能回溯更久的记录。
### 未改动
- **5G 频宽**:保持 HE80,没有和 STA 对齐。对齐只能降到 HE20,5G 热点带宽会降到约 1/4,而 TR3000 没有 6 GHz 可以补充;且目前没有任何故障证据。如果以后看门狗日志里出现 wwan5 卡死(判定故障时记录的 tx failed 暴涨、速率掉到 MCS0),再考虑改。
- **`99-fix-same-subnet-routing`**:MX8500 用它给两条同时在线的 Wi-Fi 上联加源地址策略路由。这台目前只有 wwan5 一条上联,不需要。以后同时启用 wwan2 时再评估。
- **HE overrides**:这台已经是完整版 `wpad-mbedtls`,但和 MX8500 一样不支持 `disable_he`(OpenWrt 25.12 没有打开 `CONFIG_HE_OVERRIDES`)。目前不需要。
## 验证
```
$ crontab -l
* * * * * /usr/sbin/wwan-watchdog
$ logread | grep wwan-watchdog
... cron.err crond[...]: USER root pid ... cmd /usr/sbin/wwan-watchdog # 每分钟运行
(无 wwan-watchdog: 开头的动作日志,即没有误触发)
$ mwan3 interfaces | grep wwan5
interface wwan5 is online and tracking is active (online 08h:45m:53s, ...)
```
部署后观察期间 wwan5 未断线,看门狗未触发。
查看看门狗动作:
```sh
logread -e wwan-watchdog | grep -v crond
```
## 回滚
```sh
sed -i '\#/usr/sbin/wwan-watchdog#d' /etc/crontabs/root && /etc/init.d/cron restart
cp /root/mwan3.user.bak /etc/mwan3.user
rm /usr/sbin/wwan-watchdog
sed -i '\#^/usr/sbin/wwan-watchdog$#d; \#^/etc/mwan3.user$#d' /etc/sysupgrade.conf
uci set system.@system[0].log_size='128' && uci commit system && /etc/init.d/log restart
```
不要用 `crontab -l | grep -v ... | crontab -`:在 BusyBox 上会清空整个 crontab。
## 附录:脚本全文
### `/usr/sbin/wwan-watchdog`
```sh
#!/bin/sh
# Recover Wi-Fi STA uplinks that stay associated but stop passing traffic.
# Called every minute by cron and on mwan3 "disconnected" events.
PATH=/usr/sbin:/usr/bin:/sbin:/bin
STATE_DIR=/tmp/wwan-watchdog
TAG=wwan-watchdog
PROBE_IPS="1.1.1.1 8.8.8.8"
exec 9>/var/lock/wwan-watchdog.lock
flock -n 9 || exit 0
mkdir -p "$STATE_DIR"
log() { logger -t "$TAG" "$*"; }
tx_stats() {
iw dev "$1" station dump 2>/dev/null | awk '
/tx packets/ { p = $3 }
/tx failed/ { f = $3 }
/tx bitrate/ { r = $3 " " $4 " " $5 }
END { print "tx=" p " failed=" f " rate=" r }'
}
# Healthy if the gateway or any probe address answers through this device
link_ok() {
local dev="$1" gw="$2" ip
for ip in "$gw" $PROBE_IPS; do
ping -c 2 -W 2 -I "$dev" "$ip" >/dev/null 2>&1 && return 0
done
return 1
}
check() {
local iface="$1" dev="$2" radio="$3"
local count_file="$STATE_DIR/$iface"
local up gw count
up=$(ifstatus "$iface" 2>/dev/null | jsonfilter -e '@.up')
[ "$up" = "true" ] || { rm -f "$count_file"; return; }
gw=$(ifstatus "$iface" | jsonfilter -e '@.route[@.target="0.0.0.0"].nexthop' | head -n 1)
[ -n "$gw" ] || return
if link_ok "$dev" "$gw"; then
[ -f "$count_file" ] && log "$iface: link passing traffic again"
rm -f "$count_file"
if ping -c 2 -W 2 -I "$dev" "$gw" >/dev/null 2>&1 && \
mwan3 interfaces 2>/dev/null | grep -q "interface $iface is offline"; then
log "$iface: gateway reachable but mwan3 offline (login expired or upstream down?)"
fi
return
fi
count=$(( $(cat "$count_file" 2>/dev/null || echo 0) + 1 ))
echo "$count" > "$count_file"
case "$count" in
1)
log "$iface: gateway $gw and probes unreachable via $dev ($(tx_stats "$dev")), confirming next check"
;;
2|3)
log "$iface: still unreachable (check $count, $(tx_stats "$dev")), reassociating"
ubus call "wpa_supplicant.$dev" control '{"command":"REASSOCIATE"}' >/dev/null 2>&1
;;
4)
log "$iface: still unreachable after reassociate ($(tx_stats "$dev")), restarting $radio"
wifi up "$radio"
;;
*)
# Back off: retry the radio restart every 10 failed checks
if [ $(( count % 10 )) -eq 4 ]; then
log "$iface: unreachable for $count checks, restarting $radio again"
wifi up "$radio"
fi
;;
esac
}
check wwan2 phy0-sta0 radio0
check wwan5 phy1-sta0 radio1
```
### `/etc/mwan3.user`(追加部分)
```sh
[ "$ACTION" = "disconnected" ] && case "$INTERFACE" in
wwan2|wwan5) /usr/sbin/wwan-watchdog & ;;
esac
```