NetworkManager: isWifiOn isConnected consistent usage.

cervantes kindle kobo remarkable: use sysfs carrier file to determine connection state

cleanup hasWifiManager checks

gateway check: use ip if available

Fixes: #10087
Closes: #10092
reviewable/pr10096/r1
yparitcher 1 year ago
parent 67d0808494
commit 0e53631f48

@ -292,12 +292,13 @@ function Device:initNetworkManager(NetworkMgr)
android.openWifiSettings()
end
function NetworkMgr:isWifiOn()
function NetworkMgr:isConnected()
local ok = android.getNetworkInfo()
ok = tonumber(ok)
if not ok then return false end
return ok == 1
end
NetworkMgr.isWifiOn = NetworkMgr.isConnected
end
function Device:performHapticFeedback(type)

@ -12,20 +12,6 @@ local function getProductId()
return product_id
end
local function isConnected()
-- read carrier state from sysfs (for eth0)
local file = io.open("/sys/class/net/eth0/carrier", "rb")
-- file exists while Wi-Fi module is loaded.
if not file then return 0 end
-- 0 means not connected, 1 connected
local out = file:read("*number")
file:close()
return out or 0
end
local function isMassStorageSupported()
-- we rely on 3rd party package for that. It should be installed as part of KOReader prerequisites,
local safemode_version = io.open("/usr/share/safemode/version", "rb")
@ -190,9 +176,8 @@ function Cervantes:initNetworkManager(NetworkMgr)
function NetworkMgr:restoreWifiAsync()
os.execute("./restore-wifi-async.sh")
end
function NetworkMgr:isWifiOn()
return 1 == isConnected()
end
NetworkMgr.isWifiOn = NetworkMgr.sysfsWifiOn
NetworkMgr.isConnected = NetworkMgr.sysfsCarrierConnected
end
-- power functions: suspend, resume, reboot, poweroff

@ -268,7 +268,7 @@ function Device:onPowerEvent(ev)
logger.dbg("Resuming...")
local UIManager = require("ui/uimanager")
UIManager:unschedule(self.suspend)
if self:hasWifiManager() and not self:isEmulator() then
if self:hasWifiManager() then
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()

@ -69,24 +69,6 @@ local function isWifiUp()
end
--]]
-- Faster lipc-less variant ;).
local function isWifiUp()
-- Read carrier state from sysfs (so far, all Kindles appear to use wlan0)
-- NOTE: We can afford to use CLOEXEC, as devices too old for it don't support Wi-Fi anyway ;).
local file = io.open("/sys/class/net/wlan0/carrier", "re")
-- File only exists while Wi-Fi module is loaded.
if not file then
return false
end
-- 0 means not connected, 1 connected
local out = file:read("*number")
file:close()
return true, out == 1
end
--[[
Test if a kindle device is flagged as a Special Offers device (i.e., ad supported) (FW >= 5.x)
--]]
@ -200,7 +182,12 @@ function Kindle:initNetworkManager(NetworkMgr)
end
end
NetworkMgr.isWifiOn = isWifiUp
function NetworkMgr:getNetworkInterfaceName()
return "wlan0" -- so far, all Kindles appear to use wlan0
end
NetworkMgr.isWifiOn = NetworkMgr.sysfsWifiOn
NetworkMgr.isConnected = NetworkMgr.sysfsCarrierConnected
end
function Kindle:supportsScreensaver()

@ -30,31 +30,6 @@ local function koboEnableWifi(toggle)
end
end
-- NOTE: Cheap-ass way of checking if Wi-Fi seems to be enabled...
-- Since the crux of the issues lies in race-y module unloading, this is perfectly fine for our usage.
local function koboIsWifiOn()
local needle = os.getenv("WIFI_MODULE") or "sdio_wifi_pwr"
local nlen = #needle
-- /proc/modules is usually empty, unless Wi-Fi or USB is enabled
-- We could alternatively check if lfs.attributes("/proc/sys/net/ipv4/conf/" .. os.getenv("INTERFACE"), "mode") == "directory"
-- c.f., also what Cervantes does via /sys/class/net/eth0/carrier to check if the interface is up.
-- That said, since we only care about whether *modules* are loaded, this does the job nicely.
local f = io.open("/proc/modules", "re")
if not f then
return false
end
local found = false
for haystack in f:lines() do
if haystack:sub(1, nlen) == needle then
found = true
break
end
end
f:close()
return found
end
-- checks if standby is available on the device
local function checkStandby()
logger.dbg("Kobo: checking if standby is possible ...")
@ -876,7 +851,8 @@ function Kobo:initNetworkManager(NetworkMgr)
os.execute("./restore-wifi-async.sh")
end
NetworkMgr.isWifiOn = koboIsWifiOn
NetworkMgr.isWifiOn = NetworkMgr.sysfsWifiOn
NetworkMgr.isConnected = NetworkMgr.sysfsCarrierConnected
end
function Kobo:setTouchEventHandler()
@ -1059,7 +1035,7 @@ function Kobo:standby(max_duration)
--[[
-- On most devices, attempting to PM with a Wi-Fi module loaded will horribly crash the kernel, so, don't?
-- NOTE: Much like suspend, our caller should ensure this never happens, hence this being commented out ;).
if koboIsWifiOn() then
if NetworkMgr:isWifiOn() then
-- AutoSuspend relies on NetworkMgr:getWifiState to prevent this, so, if we ever trip this, it's a bug ;).
logger.err("Kobo standby: cannot standby with Wi-Fi modules loaded! (NetworkMgr is confused: this is a bug)")
return

@ -368,9 +368,10 @@ function PocketBook:initNetworkManager(NetworkMgr)
end
end
function NetworkMgr:isWifiOn()
function NetworkMgr:isConnected()
return band(inkview.QueryNetwork(), C.NET_CONNECTED) ~= 0
end
NetworkMgr.isWifiOn = NetworkMgr.isConnected
end
function PocketBook:getSoftwareVersion()

@ -194,9 +194,8 @@ function Remarkable:initNetworkManager(NetworkMgr)
NetworkMgr:setWirelessBackend("wpa_supplicant", {ctrl_interface = "/var/run/wpa_supplicant/wlan0"})
NetworkMgr.isWifiOn = function()
return NetworkMgr:isConnected()
end
NetworkMgr.isWifiOn = NetworkMgr.sysfsWifiOn
NetworkMgr.isConnected = NetworkMgr.sysfsCarrierConnected
end
function Remarkable:setDateTime(year, month, day, hour, min, sec)

@ -128,7 +128,6 @@ local Emulator = Device:extend{
hasNaturalLight = yes,
hasNaturalLightApi = yes,
hasWifiToggle = yes,
hasWifiManager = yes,
-- Not really, Device:reboot & Device:powerOff are not implemented, so we just exit ;).
canPowerOff = yes,
canReboot = yes,
@ -367,6 +366,28 @@ function Device:setEventHandlers(UIManager)
end
end
function Device:initNetworkManager(NetworkMgr)
function NetworkMgr:isWifiOn() return true end
function NetworkMgr:isConnected()
-- Pull the default gateway first, so we don't even try to ping anything if there isn't one...
local default_gw, std_out
if isCommand("ip") then
std_out = io.popen([[ip r | grep default | tail -n 1 | cut -d ' ' -f 3]], "r")
else
std_out = io.popen([[route -n | awk '$4 == "UG" {print $2}' | tail -n 1]], "r")
end
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
return 0 == os.execute("ping -c1 -w2 " .. default_gw)
end
end
function Emulator:supportsScreensaver() return true end
function Emulator:simulateSuspend()
@ -401,6 +422,7 @@ function Emulator:initNetworkManager(NetworkMgr)
function NetworkMgr:isWifiOn()
return G_reader_settings:nilOrTrue("emulator_fake_wifi_connected")
end
NetworkMgr.isConnected = NetworkMgr.isWifiOn
end
io.write("Starting SDL in " .. SDL.getBasePath() .. "\n")

@ -172,9 +172,13 @@ function SonyPRSTUX:initNetworkManager(NetworkMgr)
-- os.execute("./restore-wifi-async.sh")
end
--[[
function NetworkMgr:isWifiOn()
return 0 == os.execute("wmiconfig -i wlan0 --wlan query | grep -q enabled")
end
--]]
NetworkMgr.isWifiOn = NetworkMgr.sysfsWifiOn
NetworkMgr.isConnected = NetworkMgr.sysfsCarrierConnected
end

@ -9,6 +9,7 @@ local MultiConfirmBox = require("ui/widget/multiconfirmbox")
local UIManager = require("ui/uimanager")
local ffiutil = require("ffi/util")
local logger = require("logger")
local util = require("util")
local _ = require("gettext")
local T = ffiutil.template
@ -30,7 +31,7 @@ function NetworkMgr:connectivityCheck(iter, callback, widget)
self.wifi_was_on = false
G_reader_settings:makeFalse("wifi_was_on")
-- If we abort, murder Wi-Fi and the async script first...
if Device:hasWifiManager() and not Device:isEmulator() then
if Device:hasWifiManager() then
os.execute("pkill -TERM restore-wifi-async.sh 2>/dev/null")
end
self:turnOffWifi()
@ -105,7 +106,9 @@ end
-- NetworkMgr:setWirelessBackend
function NetworkMgr:turnOnWifi() end
function NetworkMgr:turnOffWifi() end
-- This function returns status of the WiFi radio
function NetworkMgr:isWifiOn() end
function NetworkMgr:isConnected() end
function NetworkMgr:getNetworkInterfaceName() end
function NetworkMgr:getNetworkList() end
function NetworkMgr:getCurrentNetwork() end
@ -117,6 +120,30 @@ function NetworkMgr:releaseIP() end
function NetworkMgr:restoreWifiAsync() end
-- End of device specific methods
--Helper fuctions for devices that use the sysfs entry to check connectivity.
function NetworkMgr:sysfsWifiOn()
-- Network interface directory exists while the Wi-Fi module is loaded.
local net_if = self:getNetworkInterfaceName()
return util.pathExists("/sys/class/net/".. net_if)
end
function NetworkMgr:sysfsCarrierConnected()
-- Read carrier state from sysfs.
-- NOTE: We can afford to use CLOEXEC, as devices too old for it don't support Wi-Fi anyway ;)
local out
local net_if = self:getNetworkInterfaceName()
local file = io.open("/sys/class/net/" .. net_if .. "/carrier", "re")
-- File only exists while Wi-Fi module is loaded.
if file then
-- 0 means not connected, 1 connected
out = file:read("*number")
file:close()
end
return out == 1
end
function NetworkMgr:toggleWifiOn(complete_callback, long_press)
local toggle_im = InfoMessage:new{
text = _("Turning on Wi-Fi…"),
@ -245,34 +272,6 @@ function NetworkMgr:afterWifiAction(callback)
end
end
function NetworkMgr:isConnected()
if Device:isAndroid() or Device:isCervantes() or Device:isPocketBook() or Device:isEmulator() then
return self:isWifiOn()
elseif Device:isKindle() then
local on, connected = self:isWifiOn()
return on and connected
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 " .. default_gw)
else
return 0 == os.execute("ping -c1 -w2 " .. default_gw)
end
end
end
function NetworkMgr:isOnline()
local socket = require("socket")
-- Microsoft uses `dns.msftncsi.com` for Windows, see
@ -308,8 +307,7 @@ function NetworkMgr:isNetworkInfoAvailable()
-- always available
return true
else
--- @todo also show network info when device is authenticated to router but offline
return self:isWifiOn()
return self:isConnected()
end
end
@ -499,7 +497,7 @@ function NetworkMgr:getPowersaveMenuTable()
text = _("Disable Wi-Fi connection when inactive"),
help_text = _([[This will automatically turn Wi-Fi off after a generous period of network inactivity, without disrupting workflows that require a network connection, so you can just keep reading without worrying about battery drain.]]),
checked_func = function() return G_reader_settings:isTrue("auto_disable_wifi") end,
enabled_func = function() return Device:hasWifiManager() and not Device:isEmulator() end,
enabled_func = function() return Device:hasWifiManager() end,
callback = function()
G_reader_settings:flipNilOrFalse("auto_disable_wifi")
-- NOTE: Well, not exactly, but the activity check wouldn't be (un)scheduled until the next Network(Dis)Connected event...
@ -513,7 +511,7 @@ function NetworkMgr:getRestoreMenuTable()
text = _("Restore Wi-Fi connection on resume"),
help_text = _([[This will attempt to automatically and silently re-connect to Wi-Fi on startup or on resume if Wi-Fi used to be enabled the last time you used KOReader.]]),
checked_func = function() return G_reader_settings:isTrue("auto_restore_wifi") end,
enabled_func = function() return Device:hasWifiManager() and not Device:isEmulator() end,
enabled_func = function() return Device:hasWifiManager() end,
callback = function() G_reader_settings:flipNilOrFalse("auto_restore_wifi") end,
}
end
@ -610,7 +608,7 @@ function NetworkMgr:getMenuTable(common_settings)
common_settings.network_proxy = self:getProxyMenuTable()
common_settings.network_info = self:getInfoMenuTable()
if Device:hasWifiManager() then
if Device:hasWifiManager() or Device:isEmulator() then
common_settings.network_powersave = self:getPowersaveMenuTable()
common_settings.network_restore = self:getRestoreMenuTable()
common_settings.network_dismiss_scan = self:getDismissScanMenuTable()

@ -115,7 +115,7 @@ local network_activity_noise_margin = 12 -- unscaled_size_check: ignore
-- Read the statistics/tx_packets sysfs entry for the current network interface.
-- It *should* be the least noisy entry on an idle network...
-- The fact that auto_disable_wifi is only available on (Device:hasWifiManager() and not Device:isEmulator())
-- The fact that auto_disable_wifi is only available on Device:hasWifiManager()
-- allows us to get away with a Linux-only solution.
function NetworkListener:_getTxPackets()
-- read tx_packets stats from sysfs (for the right network if)
@ -198,7 +198,7 @@ end
function NetworkListener:onNetworkConnected()
logger.dbg("NetworkListener: onNetworkConnected")
if not (Device:hasWifiManager() and not Device:isEmulator()) then
if not Device:hasWifiManager() then
return
end
@ -218,7 +218,7 @@ end
function NetworkListener:onNetworkDisconnected()
logger.dbg("NetworkListener: onNetworkDisconnected")
if not (Device:hasWifiManager() and not Device:isEmulator()) then
if not Device:hasWifiManager() then
return
end

Loading…
Cancel
Save