From e9eca55d90c201a255308c322868819a4c209c35 Mon Sep 17 00:00:00 2001 From: NiLuJe Date: Wed, 31 Jul 2019 01:00:51 +0200 Subject: [PATCH] Minor auto_restore_wifi tweaks (#5143) * Try to make sure restoreWifiAsync eventually sends a NetworkConnected event... re: #5109 * Take a page from @shermp's book, and make sure wpa_supplicant managed to connect to the AP before acquiring an IP. Tear down WiFi modules in case of failure. c.f., https://github.com/shermp/Kobo-UNCaGED/pull/21 * Don't let restore-wifi-async.sh enable WiFi behind our back when we're killing it to start Nickel... * Don't even call ping if there's no default gw --- frontend/device/generic/device.lua | 1 + frontend/ui/network/manager.lua | 36 +++++++++++++++++++++++++++-- platform/kobo/nickel.sh | 2 +- platform/kobo/restore-wifi-async.sh | 17 ++++++++++++++ 4 files changed, 53 insertions(+), 3 deletions(-) diff --git a/frontend/device/generic/device.lua b/frontend/device/generic/device.lua index 5aa53fdcd..8feb058ea 100644 --- a/frontend/device/generic/device.lua +++ b/frontend/device/generic/device.lua @@ -187,6 +187,7 @@ function Device:onPowerEvent(ev) local network_manager = require("ui/network/manager") if network_manager.wifi_was_on and G_reader_settings:isTrue("auto_restore_wifi") then network_manager:restoreWifiAsync() + network_manager:scheduleConnectivityCheck() end self:resume() -- restore to previous rotation mode, if need be. diff --git a/frontend/ui/network/manager.lua b/frontend/ui/network/manager.lua index 9cb91cc25..adfbc1323 100644 --- a/frontend/ui/network/manager.lua +++ b/frontend/ui/network/manager.lua @@ -15,6 +15,26 @@ function NetworkMgr:readNWSettings() self.nw_settings = LuaSettings:open(DataStorage:getSettingsDir().."/network.lua") end +-- Used after restoreWifiAsync() to make sure we eventually send a NetworkConnected event, as a few things rely on it (KOSync, c.f. #5109). +function NetworkMgr:connectivityCheck(iter) + -- Give up after a while... + if iter > 6 then + return + end + + if NetworkMgr:isWifiOn() and NetworkMgr:isConnected() then + local Event = require("ui/event") + UIManager:broadcastEvent(Event:new("NetworkConnected")) + logger.info("WiFi successfully restored!") + else + UIManager:scheduleIn(2, function() NetworkMgr:connectivityCheck(iter + 1) end) + end +end + +function NetworkMgr:scheduleConnectivityCheck() + UIManager:scheduleIn(2, function() NetworkMgr:connectivityCheck(1) end) +end + function NetworkMgr:init() -- On Kobo, kill WiFi if NetworkMgr:isWifiOn() and NOT NetworkMgr:isConnected() -- (i.e., if the launcher left the WiFi in an inconsistent state: modules loaded, but no route to gateway). @@ -26,6 +46,7 @@ function NetworkMgr:init() self.wifi_was_on = G_reader_settings:isTrue("wifi_was_on") if self.wifi_was_on and G_reader_settings:isTrue("auto_restore_wifi") then self:restoreWifiAsync() + self:scheduleConnectivityCheck() end end @@ -101,12 +122,23 @@ function NetworkMgr:isConnected() if Device:isAndroid() or Device:isCervantes() or Device:isPocketBook() then return self:isWifiOn() else + -- Pull the default gateway first, so we don't even try to ping anything if there isn't one... + local default_gw + local std_out = io.popen([[/sbin/route -n | awk '$4 == "UG" {print $2}' | tail -n 1]], "r") + if std_out then + default_gw = std_out:read("*all") + std_out:close() + if not default_gw or default_gw == "" then + return false + end + end + -- `-c1` try only once; `-w2` wait 2 seconds -- NOTE: No -w flag available in the old busybox build used on Legacy Kindles... if Device:isKindle() and Device:hasKeyboard() then - return 0 == os.execute([[ping -c1 $(/sbin/route -n | awk '$4 == "UG" {print $2}' | tail -n 1)]]) + return 0 == os.execute("ping -c1 " .. default_gw) else - return 0 == os.execute([[ping -c1 -w2 $(/sbin/route -n | awk '$4 == "UG" {print $2}' | tail -n 1)]]) + return 0 == os.execute("ping -c1 -w2 " .. default_gw) end end end diff --git a/platform/kobo/nickel.sh b/platform/kobo/nickel.sh index c273c1ac8..a8fb057b6 100755 --- a/platform/kobo/nickel.sh +++ b/platform/kobo/nickel.sh @@ -22,7 +22,7 @@ unset OLDPWD EXT_FONT_DIR TESSDATA_PREFIX FROM_NICKEL STARDICT_DATA_DIR LC_ALL K # Make sure we kill the WiFi first, because nickel apparently doesn't like it if it's up... (cf. #1520) # NOTE: That check is possibly wrong on PLATFORM == freescale (because I don't know if the sdio_wifi_pwr module exists there), but we don't terribly care about that. if lsmod | grep -q sdio_wifi_pwr; then - killall udhcpc default.script wpa_supplicant 2>/dev/null + killall restore-wifi-async.sh enable-wifi.sh obtain-ip.sh udhcpc default.script wpa_supplicant 2>/dev/null [ "${WIFI_MODULE}" != "8189fs" ] && [ "${WIFI_MODULE}" != "8192es" ] && wlarm_le -i "${INTERFACE}" down ifconfig "${INTERFACE}" down # NOTE: Kobo's busybox build is weird. rmmod appears to be modprobe in disguise, defaulting to the -r flag... diff --git a/platform/kobo/restore-wifi-async.sh b/platform/kobo/restore-wifi-async.sh index 9e45bd53b..b0ac817e0 100755 --- a/platform/kobo/restore-wifi-async.sh +++ b/platform/kobo/restore-wifi-async.sh @@ -2,8 +2,25 @@ RestoreWifi() { echo "[$(date)] restore-wifi-async.sh: Restarting WiFi" + ./enable-wifi.sh + + # Much like we do in the UI, ensure wpa_supplicant did its job properly, first. + # Pilfered from https://github.com/shermp/Kobo-UNCaGED/pull/21 ;) + wpac_timeout=0 + while ! wpa_cli status | grep -q "wpa_state=COMPLETED"; do + # If wpa_supplicant hasn't connected within 10 seconds, assume it never will, and tear down WiFi + if [ ${wpac_timeout} -ge 40 ]; then + echo "[$(date)] restore-wifi-async.sh: Failed to connect to preferred AP!" + ./disable-wifi.sh + return 1 + fi + usleep 250000 + wpac_timeout=$((wpac_timeout + 1)) + done + ./obtain-ip.sh + echo "[$(date)] restore-wifi-async.sh: Restarted WiFi" }