#!/usr/bin/lua local fs = require('nixio.fs') local uci = require('luci.model.uci').cursor() local site = require 'gluon.site_config' local iwinfo = require 'iwinfo' local configname = 'autoupdater-wifi-fallback' local util = require 'luci.util' local settings = uci:get_all(configname, 'settings') local ut = require('autoupdater-wifi-fallback.util') local debug = true -- parse arguments local force = false local i = 1 while arg[i] do if arg[i] == '-f' then print("I will do what you want") force = true end i = i+1 end -- preflight checks if not force then if settings.enabled ~= '1' or uci:get('autoupdater','settings','enabled') ~= '1' then if debug then io.stderr:write('connectivity checks or autoupdater are disabled.\n') end os.exit(0) end if fs.stat("/tmp/run/fastd.mesh_vpn.socket", "type") == "socket" then if debug then io.stderr:write('we have a valid socket for fastd. no fallback required.\n') end os.exit(0) end if tonumber(fs.readfile('/proc/uptime'):match('^([^ ]+) ')) < tonumber(settings.min_uptime_secs) then if debug then io.stderr:write('we just booted. check skipped.\n') end os.exit(0) end end local function check_connectivity() local f = io.open("/sys/kernel/debug/batman_adv/bat0/gateways","r") if f ~= nil then f:close() local wifi = get_wifi_neighbours() if wifi ~= nil then for key, interface in ipairs(wifi) do if os.execute(string.format("batctl ping -t5 -c1 %s > /dev/null 2>&1", interface)) == 0 then return true end end end local list = io.lines("/sys/kernel/debug/batman_adv/bat0/gateways") for line in list do local gateway_mac = line:match("^=?>? +([0-9a-f:]+)") if gateway_mac ~= nil then if os.execute(string.format("batctl ping -t5 -c1 %s > /dev/null 2>&1", gateway_mac)) == 0 then return true end end end end -- connectivity check against updateserver local updateHosts = get_update_hosts() while #updateHosts > 0 do host = table.remove(updateHosts) if os.execute("ping -w2 -c1 " .. host .. " > /dev/null 2>&1") == 0 then return true end end return false end local function run_autoupdater() -- TODO:should be called with -f ! os.execute("/usr/sbin/autoupdater -f") end local function switch_to_fallback_mode(wifiNetwork) print("I will connect to: " .. wifiNetwork) local disabled_radios = {'fallback'} uci:foreach('wireless', 'wifi-iface', function(s) uci:set('wireless', s['.name'], 'disabled', '1') end ) uci:set('wireless', 'fallback', 'ssid', wifiNetwork) uci:set('wireless', 'fallback', 'disabled', 0) uci:save('wireless') io.popen("wifi") os.execute("sleep 5") os.execute("iw dev fallback connect -w " .. wifiNetwork) os.execute("echo \"2\" > /proc/sys/net/ipv6/conf/fallback/accept_ra") os.execute("sleep 20") end local function revert_to_standard_mode(restart_network) print("Going back to standard config") uci:revert('wireless') uci:save('wireless') if restart_network then os.execute("/etc/init.d/network restart") os.execute("sleep 30") end end if is_in_fallback_mode() then revert_to_standard_mode(false) run_autoupdater() -- if there really is a firmware update, we should not reach this point os.execute("/etc/init.d/network restart") os.exit(0) end if not check_connectivity() then local offset = 2 * 3600 if fs.stat("/tmp/run/fastd.mesh_vpn.socket", "type") == "socket" then offset = 4 * 3600 end local unreachable_since = settings.unreachable_since if unreachable_since == nil then uci:set(configname, 'settings', 'unreachable_since', os.time()) unreachable_since = os.time() else uci:set(configname, 'settings', 'last_run', os.time()) end uci:save(configname) if tonumber(unreachable_since) + offset < os.time() or force then wifiNetwork = get_available_wifi_networks() if wifiNetwork then switch_to_fallback_mode(wifiNetwork) run_autoupdater() -- this is only reached if no updated happened revert_to_standard_mode(true) end end else uci:delete(configname, 'settings','unreachable_since') uci:delete(configname, 'settings','last_run') uci:save(configname) end