mirror of https://github.com/aredn/aredn.git
Scan cache (#1160)
* Cache the last wifi scan and update it when a re-scan is requested. This change was suggested as a way of handling Ubiquiti AC devices which disconnect while scanning and making retrieving the results problematic if that was your connection. Now we scan and store the results so they can be retrieved later. In fact we no longer scan when navigating to this page but require an explicity scan button push. This make the page generally more responsive when initially navigated to.
This commit is contained in:
parent
c25be28b97
commit
86271040a0
|
@ -36,6 +36,7 @@
|
|||
--]]
|
||||
|
||||
require("nixio")
|
||||
require("luci.jsonc")
|
||||
require("aredn.http")
|
||||
require("aredn.hardware")
|
||||
require("aredn.utils")
|
||||
|
@ -55,6 +56,19 @@ if board_type:match("^ubnt,") and board_type:match("ac") then
|
|||
ubnt_ac = true
|
||||
end
|
||||
|
||||
local rescan = string.find((nixio.getenv("QUERY_STRING") or ""):lower(),"rescan=1")
|
||||
|
||||
local scanlist = {}
|
||||
-- Show the last scan if we have one, it's not too old, and we're not rescanning
|
||||
if not rescan then
|
||||
local lscan = io.open("/tmp/last-scan.json")
|
||||
if lscan then
|
||||
scanlist = luci.jsonc.parse(lscan:read("*a") or "")
|
||||
lscan:close()
|
||||
end
|
||||
end
|
||||
|
||||
if rescan then
|
||||
local channels = aredn.hardware.get_rfchannels(wifiiface)
|
||||
local scan_list = ""
|
||||
for _, channel in ipairs(channels)
|
||||
|
@ -87,7 +101,7 @@ if f then
|
|||
end
|
||||
scan.mode = "Connected Ad-Hoc Station"
|
||||
scan.ssid = myssid
|
||||
scan.freq[myfreq] = true
|
||||
scan.freq[tostring(myfreq)] = true
|
||||
end
|
||||
m = line:match("signal avg:%s+([%d%-]+)")
|
||||
if m then
|
||||
|
@ -174,56 +188,13 @@ end
|
|||
|
||||
-- scan end
|
||||
|
||||
-- generate page
|
||||
http_header()
|
||||
html.header(node .. " WiFi scan", false)
|
||||
local autoscan = string.find((nixio.getenv("QUERY_STRING") or ""):lower(),"autoscan=1")
|
||||
if autoscan then
|
||||
html.print("<script>setTimeout(function(){ window.location.reload(); }, 10000);</script>")
|
||||
end
|
||||
html.print([[
|
||||
<script src="/js/sorttable-min.js"></script>
|
||||
<style>
|
||||
table {
|
||||
border-collapse:collapse;
|
||||
}
|
||||
table.sortable thead {
|
||||
background-color:#eee;
|
||||
color:#666666;
|
||||
font-weight: bold;
|
||||
cursor: default;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body><form method=post action=/cgi-bin/scan enctype='multipart/form-data'>
|
||||
<center>
|
||||
]])
|
||||
|
||||
html.alert_banner()
|
||||
html.print("<h1>" .. node .. " WiFi scan</h1><hr>")
|
||||
|
||||
if autoscan then
|
||||
html.print("<input type=button name=stop value=Stop title='Abort continuous scan' onclick='window.location = window.location.origin + window.location.pathname'>")
|
||||
else
|
||||
html.print("<input type=button name=refresh value=Refresh title='Refresh this page' onclick='window.location.reload();'>")
|
||||
html.print(" ")
|
||||
html.print([[<input type=button name=auto value=Auto title='Begin continuous scan' onclick='window.location = window.location.origin + window.location.pathname + "?autoscan=1"'>]])
|
||||
end
|
||||
|
||||
html.print(" ")
|
||||
html.print("<button type=button onClick='window.location=\"status\"' title='Return to status page'>Quit</button><br><br>")
|
||||
|
||||
-- display scan
|
||||
html.print("<table class=sortable border=1 cellpadding=5>")
|
||||
html.print("<tr><th>SNR</th><th>Signal</th><th>Chan</th><th>Enc</th><th>SSID</th><th>Hostname</th><th>MAC/BSSID</th><th>802.11 Mode</th></tr>")
|
||||
|
||||
-- load arp cache
|
||||
local arpcache = {}
|
||||
arptable(function(a)
|
||||
arpcache[a["HW address"]] = a["IP address"]
|
||||
end)
|
||||
|
||||
local scanlist = {}
|
||||
scanlist = {}
|
||||
for _, v in pairs(scanned)
|
||||
do
|
||||
if v.signal ~= 9999 or v.joined then
|
||||
|
@ -255,39 +226,120 @@ do
|
|||
end
|
||||
end
|
||||
table.sort(chan)
|
||||
chan = table.concat(chan, " ")
|
||||
scan.chan = table.concat(chan, " ")
|
||||
if scan.joined then
|
||||
hostname = node
|
||||
scan.hostname = node
|
||||
else
|
||||
-- ip lookup then host lookup
|
||||
local ip = arpcache[scan.mac]
|
||||
if ip then
|
||||
hostname = ip
|
||||
scan.hostname = ip
|
||||
local f = io.popen("nslookup " .. ip)
|
||||
if f then
|
||||
for line in f:lines()
|
||||
do
|
||||
local m = line:match("name = (.*)%.local%.mesh")
|
||||
if m then
|
||||
hostname = m:gsub("^mid[0-9]*%.",""):gsub("^dtdlink%.",""):gsub("%.local%.mesh$","")
|
||||
scan.hostname = m:gsub("^mid[0-9]*%.",""):gsub("^dtdlink%.",""):gsub("%.local%.mesh$","")
|
||||
break
|
||||
end
|
||||
end
|
||||
f:close()
|
||||
end
|
||||
else
|
||||
hostname = "-"
|
||||
scan.hostname = "-"
|
||||
end
|
||||
end
|
||||
end
|
||||
lscan = io.open("/tmp/last-scan.json", "w")
|
||||
if lscan then
|
||||
lscan:write(luci.jsonc.stringify(scanlist, true))
|
||||
lscan:close()
|
||||
end
|
||||
end
|
||||
|
||||
-- generate page
|
||||
http_header()
|
||||
html.header(node .. " WiFi scan", false)
|
||||
local autoscan = string.find((nixio.getenv("QUERY_STRING") or ""):lower(),"autoscan=1")
|
||||
if autoscan then
|
||||
html.print("<script>setTimeout(function(){ window.location.reload(); }, 10000);</script>")
|
||||
end
|
||||
if rescan then
|
||||
html.print([[
|
||||
<script>
|
||||
if (history.replaceState) {
|
||||
history.replaceState(null, "", window.location.origin + window.location.pathname)
|
||||
}
|
||||
</script>
|
||||
]])
|
||||
end
|
||||
html.print([[
|
||||
<script src="/js/sorttable-min.js"></script>
|
||||
<style>
|
||||
table {
|
||||
border-collapse:collapse;
|
||||
}
|
||||
table.sortable thead {
|
||||
background-color:#eee;
|
||||
color:#666666;
|
||||
font-weight: bold;
|
||||
cursor: default;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<center>
|
||||
]])
|
||||
|
||||
html.alert_banner()
|
||||
html.print("<h1>" .. node .. " WiFi scan</h1><hr>")
|
||||
|
||||
if autoscan then
|
||||
html.print("<input type=button name=stop value=Stop title='Abort continuous scan' onclick='window.location = window.location.origin + window.location.pathname'>")
|
||||
else
|
||||
html.print([[<input type=button name=refresh value=Rescan title='Run a new scan' onclick='window.location = window.location.origin + window.location.pathname + "?rescan=1"'>]])
|
||||
if not ubnt_ac then
|
||||
html.print(" ")
|
||||
html.print([[<input type=button name=auto value=Auto title='Begin continuous scan' onclick='window.location = window.location.origin + window.location.pathname + "?autoscan=1"'>]])
|
||||
end
|
||||
end
|
||||
|
||||
html.print(" ")
|
||||
html.print("<button type=button onClick='window.location=\"status\"' title='Return to status page'>Quit</button><br><br>")
|
||||
|
||||
-- display scan
|
||||
html.print("<table class=sortable border=1 cellpadding=5>")
|
||||
html.print("<tr><th>SNR</th><th>Signal</th><th>Chan</th><th>Enc</th><th>SSID</th><th>Hostname</th><th>MAC/BSSID</th><th>802.11 Mode</th></tr>")
|
||||
|
||||
for _, scan in ipairs(scanlist)
|
||||
do
|
||||
if scan.ssid:match("^AREDN-") then
|
||||
html.print("<tr class=\"wscan-row-node\">")
|
||||
else
|
||||
html.print("<tr>")
|
||||
end
|
||||
html.print("<td>" .. (scan.signal - nf) .. "</td><td>" .. scan.signal .. "</td><td>" .. chan .. "</td><td>" .. scan.key .. "</td><td>" .. scan.ssid .. "</td><td align=center>" .. hostname .. "</td><td>" .. scan.mac:upper() .. "</td><td>" .. scan.mode .. "</td>")
|
||||
html.print("<td>" .. (scan.signal - nf) .. "</td><td>" .. scan.signal .. "</td><td>" .. scan.chan .. "</td><td>" .. scan.key .. "</td><td>" .. scan.ssid .. "</td><td align=center>" .. scan.hostname .. "</td><td>" .. scan.mac:upper() .. "</td><td>" .. scan.mode .. "</td>")
|
||||
html.print("</tr>")
|
||||
end
|
||||
|
||||
html.print("</table><br></center>")
|
||||
html.print("</table><br>")
|
||||
local lastscan = nixio.fs.stat("/tmp/last-scan.json", "mtime")
|
||||
if lastscan then
|
||||
lastscan = os.time() - lastscan
|
||||
if lastscan == 1 then
|
||||
html.print("<div>Last scan: 1 second ago")
|
||||
elseif lastscan < 60 then
|
||||
html.print("<div>Last scan: " .. lastscan .. " seconds ago")
|
||||
elseif lastscan < 120 then
|
||||
html.print("<div>Last scan: 1 minute ago")
|
||||
elseif lastscan < 3600 then
|
||||
html.print("<div>Last scan: " .. math.floor(lastscan / 60) .. " minutes ago")
|
||||
else
|
||||
html.print("<div>Last scan: a long time ago")
|
||||
end
|
||||
else
|
||||
html.print("<div>Last scan: none")
|
||||
end
|
||||
html.footer()
|
||||
html.print("</body></html>")
|
||||
html.print("</center></body></html>")
|
||||
|
|
Loading…
Reference in New Issue