gluon-geolocator: request wifi interface once per radio and via ubus
This commit is contained in:
parent
5ffb482705
commit
7d2689c0e5
@ -2,7 +2,8 @@
|
|||||||
|
|
||||||
local uci = require('simple-uci').cursor()
|
local uci = require('simple-uci').cursor()
|
||||||
local json = require ("luci.jsonc")
|
local json = require ("luci.jsonc")
|
||||||
require("iwinfo")
|
local ubus = require 'ubus'
|
||||||
|
local iwinfo = require("iwinfo")
|
||||||
|
|
||||||
local LOC="gluon-node-info"
|
local LOC="gluon-node-info"
|
||||||
local GLC="geolocator"
|
local GLC="geolocator"
|
||||||
@ -36,64 +37,68 @@ local function exit(exc)
|
|||||||
os.exit(exc)
|
os.exit(exc)
|
||||||
end
|
end
|
||||||
|
|
||||||
local function getWifiifnames()
|
-- Iterates over all active WLAN interfaces
|
||||||
local ifnames = {}
|
-- Returning true from the callback function will skip all remaining
|
||||||
uci:foreach('wireless', 'wifi-iface',
|
-- interfaces of the same radio
|
||||||
function(s)
|
local function foreach_radio(f)
|
||||||
local ifname = uci:get('wireless', s['.name'], 'ifname')
|
local uconn = assert(ubus.connect(), 'failed to connect to ubus')
|
||||||
if (ifname ~= nil) then
|
local status = uconn:call('network.wireless', 'status', {})
|
||||||
table.insert(ifnames, ifname)
|
ubus.close(uconn)
|
||||||
|
|
||||||
|
for _, radio in pairs(status) do
|
||||||
|
for _, iface in ipairs(radio.interfaces) do
|
||||||
|
if f(iface.ifname) then
|
||||||
|
break
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
)
|
end
|
||||||
return ifnames
|
end
|
||||||
|
|
||||||
|
local function receive_json(request)
|
||||||
|
local f = assert(io.popen(string.format("exec wget -T 15 -q -O- '%s'", request)), 'failed to run wget')
|
||||||
|
local data = f:read('*a')
|
||||||
|
f:close()
|
||||||
|
|
||||||
|
return json.parse(data)
|
||||||
end
|
end
|
||||||
|
|
||||||
-- Get position
|
-- Get position
|
||||||
local function Get_geolocation_info()
|
local function locate()
|
||||||
|
local done_bssids = {}
|
||||||
|
local found_bssids = {}
|
||||||
|
foreach_radio(function(ifname)
|
||||||
|
local iw = iwinfo[iwinfo.type(ifname)]
|
||||||
|
if not iw then
|
||||||
|
-- Skip other ifaces of this radio, as they
|
||||||
|
-- will have the same type
|
||||||
|
return true
|
||||||
|
end
|
||||||
|
|
||||||
local scaned_bssid = ""
|
local scanlist = iw.scanlist(ifname)
|
||||||
local uniq = { }
|
if not scanlist then
|
||||||
for _, ifname in ipairs(getWifiifnames()) do
|
return false
|
||||||
local api = iwinfo.type(ifname)
|
end
|
||||||
if api then
|
|
||||||
local iw = iwinfo[api]
|
|
||||||
|
|
||||||
-- Get list of BSSID without redundancy entrys.
|
for _, entry in ipairs(scanlist) do
|
||||||
for _, net in ipairs(iw.scanlist(ifname) or { }) do
|
if entry.mode:match("Master") then
|
||||||
--only alowe Master mode driven wifis
|
local bssid = string.upper(entry.bssid:gsub(":", ""))
|
||||||
if net.mode:match("Master") then
|
if not done_bssids[bssid] then
|
||||||
-- Ensure rm colons and uppercase
|
table.insert(found_bssids, bssid)
|
||||||
net.bssid = string.upper(net.bssid:gsub(":", ""))
|
done_bssids[bssid] = true
|
||||||
if not uniq[net.bssid] then
|
|
||||||
scaned_bssid = scaned_bssid .. "," .. net.bssid
|
|
||||||
uniq[net.bssid] = true
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
if #scaned_bssid < 12 then -- because one BSSID contains 12 characters
|
|
||||||
io.stdout:write("No surrounded BSSIDs found.\n")
|
|
||||||
return { }
|
|
||||||
end
|
|
||||||
scaned_bssid = scaned_bssid:gsub("^,(.-),*", "%1")
|
|
||||||
end
|
end
|
||||||
end
|
|
||||||
-- Request position
|
|
||||||
local req = io.popen("wget -T 15 -q -O - http://openwifi.su/api/v1/bssids/" .. scaned_bssid)
|
|
||||||
if not req then
|
|
||||||
io.stdout:write("connection failed.\n")
|
|
||||||
return { }
|
|
||||||
end
|
|
||||||
|
|
||||||
local jreq, _, err = json.parse(req:read("*a"), 1, nil)
|
return true
|
||||||
req:close()
|
end)
|
||||||
if err or jreq == nil or jreq.lon == nil or jreq.lat == nil then
|
|
||||||
io.stdout:write("openwifi.su doesn't gif a location.\n")
|
|
||||||
return { }
|
|
||||||
end
|
|
||||||
|
|
||||||
return jreq
|
assert(#found_bssids >= 12, 'insufficient BSSIDs found')
|
||||||
end -- end Get_geolocation_info()
|
|
||||||
|
local data = receive_json('http://openwifi.su/api/v1/bssids/' .. table.concat(found_bssids, ','))
|
||||||
|
assert(type(data) == 'table' and data.lon and data.lat, 'location not available')
|
||||||
|
|
||||||
|
return data
|
||||||
|
end
|
||||||
|
|
||||||
-- Check if interval over or not exist
|
-- Check if interval over or not exist
|
||||||
if file_exsist(TIME_STAMP) then
|
if file_exsist(TIME_STAMP) then
|
||||||
@ -102,7 +107,7 @@ if file_exsist(TIME_STAMP) then
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
local pos = Get_geolocation_info()
|
local pos = locate()
|
||||||
if not next(pos) then
|
if not next(pos) then
|
||||||
exit(1)
|
exit(1)
|
||||||
end
|
end
|
||||||
|
Loading…
Reference in New Issue
Block a user