今回のコードで何ができるか
OpenWrt の 5GHz チャネルを監視し、動作していない場合は強制的に回復させる。
もっと詳しく
OpenWrt にも DFS (Dynamic Frequency Selection) 機能があり、気象レーダーや航空レーダーの電波を受信すると、一定時間そのチャネルが使えなくなる。
ただ DFS 以外でも、5GHz の電波が止まり、そのまま Wi-Fi が回復しないことがある。
今回のコードでは Wi-Fi での出力を監視し、出力されていない場合には Wi-Fi の再起動を行い、それでも出力が回復しない場合は OpenWrt デバイスを再起動する。
👉 本来は、レーダー波を検知した後 30 分間そのチャンネルが利用停止になりますが、今回のコードは false positive
で DFS が 動作してしまう我が家のような環境を想定しています。
コードで何をしているか
- 5GHz のチャネルが落ちている場合は Wi-Fi を再起動
- それでも回復しない場合はデバイスを再起動
もっと詳しく
-
ステップ 1. 動作中のチャンネル数と動作しているはずのチャンネル数を比較する
- チャンネル数が一致しない場合はステップ 2. へ
- チャンネル数が一致する(=問題がない)場合は
/var/log/wifi_rebooted.log
を削除
-
ステップ 2.
-
/var/log/wifi_rebooted.log
が存在する場合は、以下の 1. と 2. を実行- 再起動の内容を
/etc/config/reboot.log
に書き込む - デバイスを
reboot
(👉 デバイスをreboot
すると、/var/log
内のファイルは全て削除されるため/var/log/wifi_rebooted.log
も削除される。)
- 再起動の内容を
-
そうでない場合は、ステップ 3. へ
-
-
ステップ 3.
- 再起動の内容を
/etc/config/reboot.log
に書き込む - 再起動の日時を
/var/log/wifi_rebooted.log
に書き込む - Wi-Fi を再起動 (
wifi down
してwifi up
)
- 再起動の内容を
使用するコード
#!/bin/sh
# Set country code for wireless radios
configure_country_code() {
local country_code="JP"
uci set wireless.radio0.country="$country_code"
uci set wireless.radio1.country="$country_code"
uci commit wireless
}
# Initialize constants for log file locations
initialize_constants() {
readonly REBOOT_LOG="/etc/config/reboot.log"
readonly WIFI_REBOOTED_LOG="/var/log/wifi_rebooted.log"
}
# Get the current date and time in a specific format
get_current_time() {
echo $(date "+%F %T")
}
# Count the number of access point interfaces
get_expected_channel_count() {
echo $(iw dev | grep "type AP" | wc -l)
}
# Validate the channel count and take necessary actions
validate_channel_count() {
local valid_channel_count=$(iw dev | grep channel | wc -l)
if [[ "$valid_channel_count" -eq "$expected_channel_count" ]]; then
echo "Wireless LAN channel count is as expected (${expected_channel_count})."
[[ -f "$WIFI_REBOOTED_LOG" ]] && rm "$WIFI_REBOOTED_LOG"
exit 0
fi
handle_unexpected_channel_count "$valid_channel_count"
}
# Handle unexpected channel count scenario
handle_unexpected_channel_count() {
local valid_channel_count=$1
echo "Wireless LAN channel count is not as expected (${valid_channel_count})."
if [[ -f "$WIFI_REBOOTED_LOG" ]]; then
log_and_reboot "system_reboot"
exit 0
fi
log_wifi_reboot
reboot_wifi
}
# Log the reboot event and perform system reboot
log_and_reboot() {
local action=$1
echo -e "$current_time\t$action" >> "$REBOOT_LOG"
echo "Now rebooting..."
reboot
}
# Log the wifi reboot event
log_wifi_reboot() {
echo -e "$current_time\twifi_reboot\t$(get_unexpected_channels)" >> "$REBOOT_LOG"
echo "$current_time" > "$WIFI_REBOOTED_LOG"
}
# Get the list of unexpected channels
get_unexpected_channels() {
iwinfo | awk '/Channel: [0-9]+/ { if ($4 >= 36) print $4 "ch"}'
}
# Perform Wi-Fi reboot
reboot_wifi() {
echo "Rebooting Wireless LAN."
wifi down
sleep 5
wifi up
}
# Main script execution
main() {
configure_country_code
initialize_constants
current_time=$(get_current_time)
expected_channel_count=$(get_expected_channel_count)
validate_channel_count
}
main "$@"
コードの使用方法
-
SSH
で OpenWrt デバイスにログインし、- 上記コードを
/etc/config/wifi_channel_monitor.sh
に保存 -
chmod +x /etc/config/wifi_channel_monitor.sh
で実行権限を付与
- 上記コードを
-
ブラウザで OpenWrt にログインし、
System
>Scheduled Tasks
に以下を追加
(日本語画面の場合は、「システム > スケジュールされたタスク」で追加)
*/1 * * * * /etc/config/wifi_channel_monitor.sh
👉
/etc/crontabs/root
に直接書き込んでも良いです。
👉 いつ再起動されたかは、cat /etc/config/reboot.log
で確認できます。
👉 コードを /etc/config/
内に保存する理由は、System
> Backup
で設定のバックアップ(archive)を作成する際、 /etc/config/
は確実にバックアップファイル内に含まれるためです。
参考ページ
OpenWrt の豆知識 (iwinfo
と iw dev
)
iwinfo
と iw dev
では得られる情報が少し異なる。
-
iwinfo
取得できる値から Wi-Fi の稼働状況を確実に確認する方法がない
-
iw dev
取得できる値から Wi-Fi の稼働状況を確実に確認できる
そのため、 Wi-Fi の出力が停止しているかどうかは iw dev
で確認する。