前面讲的配置方式对于上级无线固定不变而且永久存在的情况是好使的。但是如果上级无线找不到的话,OpenWRT让人恶心的地方是下级无线,也就是703n路由器自身提供的无线也无法正常启动。这样如果你没有随身带着网线的话就没有办法登录到703n的web界面了,也就没有办法修改或者禁用上级无线。这不得不说是一个很令人遗憾的事情。
fqrouter的解决方式是在/etc/config/wireless中配置一个或者多个上级无线interface。默认这些上级无线的interface都是被禁用的。这样哪怕是上级无线不存在的话,703n自己的无线也能启动起来。这个默认的禁用动作是由一个启动脚本完成的(/etc/init.d/disable_sta_mode_wifi_interfaces)
然后扫描附近有的无线,如果发现了已经保存的上级无线,就启用对应的无线interface。这个时候会等待10秒钟,如果10秒内没有完成上级无线的连接,这个无线interface又会被重新禁用。这是因为上级无线的密码可能输入错误。这个智能检测并启用无线的动作是由一个hotplug脚本完成(/etc/hotplug.d/net/00-only-enable-connectable-sta-mode-wifi-interface)
智能检测听起来挺容易的,应该是先扫描附近的无线,然后把无线的配置文件更新了,再让无线正常启动起来。但是,诡异的地方在于,如果无线自己没有启动,是没有办法扫描附近的无线的。所以就需要现让本地无线网络按照一个配置启动起来,扫描附近的无线,修改配置文件,再用修改后的配置文件把无线网络重启。
———————————————————————-
if [ -f /tmp/skip-only-enable-connectable-sta-mode-wifi-interface ] ; then logger -s -t fqrouter skip-only-enable-connectable-sta-mode-wifi-interface found return fiif [ "remove" == "$ACTION" -a "wlan0" == "$INTERFACE" ] ; then
/etc/init.d/disable_sta_mode_wifi_interfaces start fi if [ "add" == "$ACTION" -a "wlan0" == "$INTERFACE" ] ; then logger -s -t fqrouter try to bring up sta mode wifi interface sta-mode-wifi-interface-up & fi ——————————————————————————————————————————————————-
#!/bin/sh /etc/rc.commonSTART=19 # just before network start
disable_sta_mode_wifi_interface() {
local section=”$1″ config_get mode $section ‘mode’ config_get ssid $section ‘ssid’ if [ sta == $mode ] ; then logger -s -t fqrouter disable sta mode wifi interface $ssid uci_set wireless $section disabled 1 fi }start() {
config_load ‘wireless’ config_foreach disable_sta_mode_wifi_interface ‘wifi-iface’ uci_commit logger -s -t fqrouter all sta mode wifi interfaces disabled } ————————————————————————————————————————————————–
#!/usr/bin/lua require ‘uci’ require ‘dumper’ require ‘nixio’local pid_file = io.open(‘/tmp/sta-mode-wifi-interface-up.pid’, ‘r’)
if pid_file ~= nil then local that_pid = pid_file:read(‘*a’) io.close(pid_file) os.execute(‘logger -s -t fqrouter sta-mode-wifi-interface-up that pid is: ‘ .. that_pid) local cmdline_file = io.open(‘/proc/’ .. that_pid .. ‘/cmdline’, ‘r’) if cmdline_file ~= nil then io.close(cmdline_file) os.execute(‘logger -s -t fqrouter sta-mode-wifi-interface-up found another instance ‘ .. that_pid) os.exit() end end local this_pid = nixio.getpid() os.execute(‘echo -n ‘ .. this_pid .. ‘ > /tmp/sta-mode-wifi-interface-up.pid’) os.execute(‘logger -s -t fqrouter sta-mode-wifi-interface-up.pid: ‘ .. this_pid) x = uci.cursor() function exit_if_sta_mode_wifi_interface_enabled(section) if ‘sta’ == section.mode and ’0′ == section.disabled then os.execute(‘logger -s -t fqrouter std mod wifi interface ‘ .. section.ssid .. ‘ already enabled’) os.exit() end end x:foreach(‘wireless’, ‘wifi-iface’, exit_if_sta_mode_wifi_interface_enabled) os.execute(‘logger -s -t fqrouter no sta mode wifi interface enabled’)function is_interface_up(ifname)
local f = assert(io.popen(‘ifconfig ‘..ifname, ‘r’)) local output = assert(f:read(‘*a’)) return output:find(‘RUNNING’) end for count=1,10 do if is_interface_up(‘wlan0′) then break end os.execute(‘sleep 1′) end if not is_interface_up(‘wlan0′) then os.execute(‘logger -s -t fqrouter wlan0 not up in given time’) os.exit() end os.execute(‘logger -s -t fqrouter wlan0 is up’)local ssid_list = {}
local ssid_present = {} for i = 1, 3 do local iw = require’luci.sys’.wifi.getiwinfo(‘radio0′) for k, v in ipairs(iw.scanlist or {}) do if v.ssid ~= nil and ssid_present[v.ssid] == nil then table.insert(ssid_list, v.ssid) ssid_present[v.ssid] = v end end os.execute(‘logger -s -t fqrouter “ssid list: ‘ .. table.concat(ssid_list, ‘, ‘) .. ‘”‘) end local no_sta_mode_wifi_interface_configured = true function enable_sta_mode_wifi_interface(section) if ‘sta’ == section.mode then no_sta_mode_wifi_interface_configured = false if ssid_present[section.ssid] ~= nil then os.execute(‘logger -s -t fqrouter found ‘ .. section.ssid) x:set(‘wireless’, section['.name'], ‘disabled’, 0) x:commit(‘wireless’) os.execute(‘touch /tmp/skip-only-enable-connectable-sta-mode-wifi-interface’) os.execute(‘wifi up’) os.execute(‘rm /tmp/skip-only-enable-connectable-sta-mode-wifi-interface’) os.execute(‘sleep 10′) if is_interface_up(‘wlan0-1′) then os.execute(‘rm /tmp/upstream-status’) else os.execute(‘echo “UPSTREAM_TIMEOUT” > /tmp/upstream-status’) os.execute(‘logger -s -t fqrouter sta mode wifi interface not up in given time’) x:set(‘wireless’, section['.name'], ‘disabled’, 1) x:commit(‘wireless’) os.execute(‘touch /tmp/skip-only-enable-connectable-sta-mode-wifi-interface’) os.execute(‘wifi down’) os.execute(‘wifi up’) os.execute(‘rm /tmp/skip-only-enable-connectable-sta-mode-wifi-interface’) end os.exit() end end end x = uci.cursor() x:foreach(‘wireless’, ‘wifi-iface’, enable_sta_mode_wifi_interface) if no_sta_mode_wifi_interface_configured then os.execute(‘echo “UPSTREAM_NOT_CONFIGURED” > /tmp/upstream-status’) os.execute(‘logger -s -t fqrouter no sta mode wifi interface configured’) else os.execute(‘echo “UPSTREAM_NOT_AVAILABLE” > /tmp/upstream-status’) os.execute(‘logger -s -t fqrouter no sta mode wifi interface available’) end ——————————————————————————————–