autoupdater-wifi-fallback 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149
  1. #!/usr/bin/lua
  2. local fs = require('nixio.fs')
  3. local uci = require('luci.model.uci').cursor()
  4. local site = require 'gluon.site_config'
  5. local iwinfo = require 'iwinfo'
  6. local configname = 'autoupdater-wifi-fallback'
  7. local util = require 'luci.util'
  8. local settings = uci:get_all(configname, 'settings')
  9. local ut = require('autoupdater-wifi-fallback.util')
  10. local debug = true
  11. -- parse arguments
  12. local force = false
  13. local i = 1
  14. while arg[i] do
  15. if arg[i] == '-f' then
  16. print("I will do what you want")
  17. force = true
  18. end
  19. i = i+1
  20. end
  21. -- preflight checks
  22. if not force then
  23. if settings.enabled ~= '1' or uci:get('autoupdater','settings','enabled') ~= '1' then
  24. if debug then io.stderr:write('connectivity checks or autoupdater are disabled.\n') end
  25. os.exit(0)
  26. end
  27. if fs.stat("/tmp/run/fastd.mesh_vpn.socket", "type") == "socket" then
  28. if debug then io.stderr:write('we have a valid socket for fastd. no fallback required.\n') end
  29. os.exit(0)
  30. end
  31. if tonumber(fs.readfile('/proc/uptime'):match('^([^ ]+) ')) < tonumber(settings.min_uptime_secs) then
  32. if debug then io.stderr:write('we just booted. check skipped.\n') end
  33. os.exit(0)
  34. end
  35. end
  36. local function check_connectivity()
  37. local f = io.open("/sys/kernel/debug/batman_adv/bat0/gateways","r")
  38. if f ~= nil then
  39. f:close()
  40. local wifi = get_wifi_neighbours()
  41. if wifi ~= nil then
  42. for key, interface in ipairs(wifi) do
  43. if os.execute(string.format("batctl ping -t5 -c1 %s > /dev/null 2>&1", interface)) == 0 then
  44. return true
  45. end
  46. end
  47. end
  48. local list = io.lines("/sys/kernel/debug/batman_adv/bat0/gateways")
  49. for line in list do
  50. local gateway_mac = line:match("^=?>? +([0-9a-f:]+)")
  51. if gateway_mac ~= nil then
  52. if os.execute(string.format("batctl ping -t5 -c1 %s > /dev/null 2>&1", gateway_mac)) == 0 then
  53. return true
  54. end
  55. end
  56. end
  57. end
  58. -- connectivity check against updateserver
  59. local updateHosts = get_update_hosts()
  60. while #updateHosts > 0 do
  61. host = table.remove(updateHosts)
  62. if os.execute("ping -w2 -c1 " .. host .. " > /dev/null 2>&1") == 0 then
  63. return true
  64. end
  65. end
  66. return false
  67. end
  68. local function run_autoupdater()
  69. -- TODO:should be called with -f !
  70. os.execute("/usr/sbin/autoupdater -f")
  71. end
  72. local function switch_to_fallback_mode(wifiNetwork)
  73. print("I will connect to: " .. wifiNetwork)
  74. local disabled_radios = {'fallback'}
  75. uci:foreach('wireless', 'wifi-iface',
  76. function(s)
  77. uci:set('wireless', s['.name'], 'disabled', '1')
  78. end
  79. )
  80. uci:set('wireless', 'fallback', 'ssid', wifiNetwork)
  81. uci:set('wireless', 'fallback', 'disabled', 0)
  82. uci:save('wireless')
  83. io.popen("wifi")
  84. os.execute("sleep 5")
  85. os.execute("iw dev fallback connect -w " .. wifiNetwork)
  86. os.execute("echo \"2\" > /proc/sys/net/ipv6/conf/fallback/accept_ra")
  87. os.execute("sleep 20")
  88. end
  89. local function revert_to_standard_mode(restart_network)
  90. print("Going back to standard config")
  91. uci:revert('wireless')
  92. uci:save('wireless')
  93. if restart_network then
  94. os.execute("/etc/init.d/network restart")
  95. os.execute("sleep 30")
  96. end
  97. end
  98. if is_in_fallback_mode() then
  99. revert_to_standard_mode(false)
  100. run_autoupdater()
  101. -- if there really is a firmware update, we should not reach this point
  102. os.execute("/etc/init.d/network restart")
  103. os.exit(0)
  104. end
  105. if not check_connectivity() then
  106. local offset = 2 * 3600
  107. if fs.stat("/tmp/run/fastd.mesh_vpn.socket", "type") == "socket" then offset = 4 * 3600 end
  108. local unreachable_since = settings.unreachable_since
  109. if unreachable_since == nil then
  110. uci:set(configname, 'settings', 'unreachable_since', os.time())
  111. unreachable_since = os.time()
  112. else
  113. uci:set(configname, 'settings', 'last_run', os.time())
  114. end
  115. uci:save(configname)
  116. if tonumber(unreachable_since) + offset < os.time() or force then
  117. wifiNetwork = get_available_wifi_networks()
  118. if wifiNetwork then
  119. switch_to_fallback_mode(wifiNetwork)
  120. run_autoupdater()
  121. -- this is only reached if no updated happened
  122. revert_to_standard_mode(true)
  123. end
  124. end
  125. else
  126. uci:delete(configname, 'settings','unreachable_since')
  127. uci:delete(configname, 'settings','last_run')
  128. uci:save(configname)
  129. end