Created
September 26, 2020 06:40
-
-
Save erdoukki/dbb22c9315bad4139d7b08d34f538319 to your computer and use it in GitHub Desktop.
Select wireless channel automatically
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/awk -f | |
# Coded by: Vladislav Grigoryev <vg[dot]aetera[at]gmail[dot]com> | |
# License: GNU General Public License (GPL) version 3+ | |
# Description: Select wireless channel automatically | |
function get_iwphy() { | |
cmd = "iw phy" | |
while(cmd | getline) { | |
if($0 ~ /^\s*Wiphy\s/) | |
phy = gensub(/^\s*\w*\s(\w+)$/, "\\1", 1, $0) | |
else if($0 ~ /^\s*Band\s/) | |
band = gensub(/^\s*\w*\s([0-9]+):$/, "\\1", 1, $0) | |
else if($0 ~ /^\s*\*\s*[0-9]+\s*MHz.*dBm/) { | |
freq = gensub(/^.*\s([0-9]+)\s*MHz.*$/, "\\1", 1, $0) | |
chan = gensub(/^.*\[([0-9]+)\].*$/, "\\1", 1, $0) | |
iwphy[phy, freq, "band"] = band | |
iwphy[phy, freq, "chan"] = chan | |
} | |
} | |
close(cmd) | |
} | |
function get_iwdev() { | |
cmd = "iw dev" | |
while(cmd | getline) { | |
if($0 ~ /^\s*phy\x23/) | |
phy = gensub(/^\s*(\w+)\x23([0-9]+)$/, "\\1\\2", 1, $0) | |
else if($0 ~ /^\s*Interface\s/) | |
dev = gensub(/^\s*\w*\s(\w+)$/, "\\1", 1, $0) | |
else if($0 ~ /^\s*channel\s/) { | |
freq = gensub(/^.*\(([0-9]+)\s*MHz\).*$/, "\\1", 1, $0) | |
iwdev[phy, dev, "freq"] = freq | |
} | |
} | |
close(cmd) | |
} | |
function get_iwconf() { | |
for(iwdev_subs in iwdev) { | |
split(iwdev_subs, iwdev_sub, SUBSEP) | |
if(iwdev_sub[3] != "freq") continue | |
phy = iwdev_sub[1] | |
dev = iwdev_sub[2] | |
if(phy_conf == "") phy_conf = phy | |
if(phy_conf != phy) continue | |
dev_conf = dev | |
freq_conf = iwdev[phy_conf, dev_conf, "freq"] | |
band_conf = iwphy[phy_conf, freq_conf, "band"] | |
} | |
} | |
function get_iwscan() { | |
cmd = "iw dev "dev_conf" scan" | |
while(cmd | getline) { | |
if($0 ~ /^\s*BSS\s/) | |
bssid = gensub(/^\s*\w*\s*([:0-9a-f]+).*$/, "\\1", 1, $0) | |
else if($0 ~ /^\s*freq:/) { | |
freq = gensub(/^\s*\w*:\s*([0-9]+).*$/, "\\1", 1, $0) | |
iwscan[bssid, "freq"] = freq | |
} | |
else if($0 ~ /^\s*signal:/) { | |
signal = gensub(/^\s*\w*:\s*([-.0-9]+).*$/, "\\1", 1, $0) + 0 | |
iwscan[bssid, "signal"] = signal | |
if(signal < - 100) quality = 0 | |
else if(signal < - 50) quality = 2 * (signal + 100) | |
else quality = 100 | |
iwscan[bssid, "quality"] = quality | |
} | |
else if($0 ~ /^\s*SSID:/) { | |
ssid = gensub(/^\s*\w*:\s*(.*)$/, "\\1", 1, $0) | |
iwscan[bssid, "ssid"] = ssid | |
} | |
} | |
close(cmd) | |
} | |
function get_iwload() { | |
for(iwphy_subs in iwphy) { | |
split(iwphy_subs, iwphy_sub, SUBSEP) | |
if(iwphy_sub[3] != "chan") continue | |
phy = iwphy_sub[1] | |
freq = iwphy_sub[2] | |
band = iwphy[phy, freq, "band"] | |
load = iwphy[phy, freq, "load"] | |
if(band != band_conf) continue | |
for(iwscan_subs in iwscan) { | |
split(iwscan_subs, iwscan_sub, SUBSEP) | |
if(iwscan_sub[2] != "freq") continue | |
bssid = iwscan_sub[1] | |
freq_bssid = iwscan[bssid, "freq"] | |
signal = iwscan[bssid, "signal"] | |
freq_diff = freq - freq_bssid | |
if(freq_diff < 0) freq_diff = - freq_diff | |
if(freq_diff < 5) signal_factor = 100 | |
else if(freq_diff < 10) signal_factor = 95 | |
else if(freq_diff < 15) signal_factor = 85 | |
else if(freq_diff < 20) signal_factor = 15 | |
else if(freq_diff < 25) signal_factor = 5 | |
else signal_factor = 0 | |
if(signal < - 100) load += 0 | |
else load += (signal + 100) * signal_factor | |
iwphy[phy, freq, "load"] = load | |
} | |
} | |
} | |
function get_iwstatus() { | |
for(iwphy_subs in iwphy) { | |
split(iwphy_subs, iwphy_sub, SUBSEP) | |
if(iwphy_sub[3] != "chan") continue | |
phy = iwphy_sub[1] | |
freq = iwphy_sub[2] | |
band = iwphy[phy, freq, "band"] | |
load = iwphy[phy, freq, "load"] | |
if(band != band_conf) continue | |
if(load_optim != "" && load_optim < load) continue | |
freq_optim = freq | |
load_optim = load | |
} | |
status_conf = "-" | |
iwphy[phy_conf, freq_conf, "status"] = status_conf | |
status_optim = iwphy[phy_conf, freq_optim, "status"] "+" | |
iwphy[phy_conf, freq_optim, "status"] = status_optim | |
} | |
function get_iwchan() { | |
freq_diff = freq_conf - freq_optim | |
load_conf = iwphy[phy_conf, freq_conf, "load"] | |
load_optim = iwphy[phy_conf, freq_optim, "load"] | |
load_diff = load_conf - load_optim | |
if(freq_diff < 0) freq_diff = - freq_diff | |
if(freq_diff < freq_thr || load_diff < load_thr) return | |
chan_optim = iwphy[phy_conf, freq_optim, "chan"] | |
printf "%d\n", chan_optim | |
} | |
function print_iwinfo() { | |
printf "Phy:\t%s\nDev:\t%s\nBand:\t%s\nFreqTh:\t%d\nLoadTh:\t%d\n", | |
phy_conf, dev_conf, band_conf, freq_thr, load_thr | |
} | |
function print_iwscan() { | |
cmd = "sort -n" | |
printf "\nFreq\tChannel\tSignal\tQuality\tBSSID\t\t\tSSID\n" | |
for(iwscan_subs in iwscan) { | |
split(iwscan_subs, iwscan_sub, SUBSEP) | |
if(iwscan_sub[2] != "ssid") continue | |
bssid = iwscan_sub[1] | |
freq = iwscan[bssid, "freq"] | |
chan = iwphy[phy_conf, freq, "chan"] | |
signal = iwscan[bssid, "signal"] | |
quality = iwscan[bssid, "quality"] | |
ssid = iwscan[bssid, "ssid"] | |
printf "%d\t%d\t%d\t%d\t%s\t%s\n", freq, chan, signal, quality, | |
bssid, ssid | cmd | |
} | |
close(cmd) | |
} | |
function print_iwlist() { | |
cmd = "sort -n" | |
printf "\nFreq\tChannel\tLoad\tStatus\n" | |
for(iwphy_subs in iwphy) { | |
split(iwphy_subs, iwphy_sub, SUBSEP) | |
if(iwphy_sub[3] != "chan") continue | |
phy = iwphy_sub[1] | |
freq = iwphy_sub[2] | |
band = iwphy[phy, freq, "band"] | |
chan = iwphy[phy, freq, "chan"] | |
load = iwphy[phy, freq, "load"] | |
status = iwphy[phy, freq, "status"] | |
if(band != band_conf) continue | |
printf "%d\t%d\t%d\t%s\n", freq, chan, load, status | cmd | |
} | |
close(cmd) | |
} | |
BEGIN { | |
subcmd = ARGV[1] | |
phy_conf = ARGV[2] | |
freq_thr = ARGV[3] | |
load_thr = ARGV[4] | |
if(subcmd == "") subcmd = "help" | |
if(freq_thr == "") freq_thr = 15 | |
if(load_thr == "") load_thr = 1000 | |
if(subcmd == "help") | |
printf "awk -f iwchan.awk [show|get|help] [phy] [freq_thr] [load_thr]\n" | |
else if(subcmd == "get" || subcmd == "show") { | |
get_iwphy() | |
get_iwdev() | |
get_iwconf() | |
get_iwscan() | |
get_iwload() | |
get_iwstatus() | |
if(subcmd == "get") get_iwchan() | |
else if(subcmd == "show") { | |
print_iwinfo() | |
print_iwscan() | |
print_iwlist() | |
} | |
} | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# awk -f iwchan.awk help | |
awk -f iwchan.awk [show|get|help] [phy] [freq_thr] [load_thr] | |
# awk -f iwchan.awk get | |
5 | |
# awk -f iwchan.awk show | |
Phy: phy0 | |
Dev: wlp2s0 | |
Band: 1 | |
FreqTh: 15 | |
LoadTh: 1000 | |
Freq Channel Signal Quality BSSID SSID | |
2412 1 -63 74 90:94:e4:ef:0c:66 vghome | |
2412 1 -74 52 10:fe:ed:2a:1f:cc Dead Moroz-z-z | |
2437 6 -72 56 c4:6e:1f:65:65:02 TP-LINK_656502 | |
2457 10 -65 70 d8:0d:17:21:ff:a6 TP-Link_FFA6 | |
2457 10 -83 34 c4:6e:1f:70:ed:6e TP-LINK_ED6E | |
2462 11 -57 86 c0:25:e9:c4:b8:68 CityLink-12 | |
2467 12 -58 84 54:04:a6:c7:34:ac quick3 | |
Freq Channel Load Status | |
2412 1 6300 - | |
2417 2 6125 | |
2422 3 5775 | |
2427 4 3325 | |
2432 5 2975 + | |
2437 6 3060 | |
2442 7 3655 | |
2447 8 7655 | |
2452 9 9645 | |
2457 10 12995 | |
2462 11 13230 | |
2467 12 12705 | |
2472 13 8425 |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# Description: OpenWrt iwchan wrapper script | |
IWCHAN="/path/to/iwchan.awk" | |
PHYID="0" | |
CHAN="$(awk -f "${IWCHAN}" get "phy${PHYID}" 2> /dev/null)" | |
if [ -z "${CHAN}" ]; then exit 0; fi | |
uci set wireless."radio${PHYID}".channel="${CHAN}" | |
wifi reload |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment