0
0
mirror of https://github.com/Doodle3D/doodle3d-firmware.git synced 2024-11-16 18:47:57 +01:00
doodle3d-firmware/src/wifihelper.lua

205 lines
5.8 KiB
Lua
Raw Normal View History

local util = require("util")
local uci = require("uci").cursor()
local iwinfo = require("iwinfo")
local M = {}
M.DFL_DEVICE = "radio0" -- was wlan0
M.AP_SSID = "d3d-ap"
M.AP_ADDRESS = "192.168.10.1"
M.AP_NETMASK = "255.255.255.0"
M.NET = "wlan"
local dev, dev_api
--- Map device mode as reported by iwinfo to device mode as required by UCI
-- Note that this function is quite naive.
-- @param mode mode text as reported by iwinfo
-- @param masterIsAp set to true to map 'Master' to 'ap' instead of 'sta' (optional)
function M.mapDeviceMode(mode, masterIsAp)
local modeMap = {
["Master"] = masterIsAp and "ap" or "sta",
["Client"] = "sta",
["Ad-Hoc"] = "adhoc"
}
return modeMap[mode] or mode
end
--- Initialize WiFi helper library
-- @param device wireless device to operate on (optional, defaults to DFL_DEVICE)
-- @return true on success or false+error on failure
function M.init(device)
-- iwinfo = pcall(require, "iwinfo")
dev = device or M.DFL_DEVICE
dev_api = iwinfo.type(dev)
if not dev_api then
return false, "No such wireless device: '"..dev.."'"
end
return true
end
function M.getDeviceState()
local iw = iwinfo[dev_api]
local result = {
["mode"] = M.mapDeviceMode(iw.mode(dev), true),
["ssid"] = iw.ssid(dev),
["bssid"] = iw.bssid(dev)
}
return result
end
--- Return one or all available wifi networks resulting from an iwinfo scan
-- @param ssid return data for given SSID or for all networks if SSID not given
-- @return data for all or requested network; false+error on failure or nil when requested network not found
function M.getScanInfo(ssid)
local iw = iwinfo[dev_api]
local sr = iw.scanlist(dev)
local si, se
if ssid == nil then
return sr
else
if sr and #sr > 0 then
for _, se in ipairs(sr) do
if se.ssid == ssid then
return se
end
end
else
return false, "No scan results or scanning not possible"
end
end
return nil
end
--- Return all wireless networks configured in UCI
function M.getConfigs()
local l = {}
uci.foreach("wireless", "wifi-iface", function(s) table.insert(l, s) end)
return l
end
--- Remove UCI config for network with given SSID
-- @return true if successfully removed, false if no such config exists
function M.removeConfig(ssid)
local rv = false
uci:foreach("wireless", "wifi-iface", function(s)
if s.ssid == ssid then
uci:delete("wireless", s[".name"])
rv = true
return false
end
end)
uci:commit("wireless")
return rv
end
--- Activate wireless section for given SSID and disable all others
-- @param ssid SSID of config to enable, or nil to disable all network configs
function M.activateConfig(ssid)
uci:foreach("wireless", "wifi-iface", function(s)
local disabled = s.ssid ~= ssid and "1" or "0"
uci:set("wireless", s[".name"], "disabled", disabled)
end)
uci:commit("wireless")
end
--- Create a new UCI network from the given iwinfo data
-- http://luci.subsignal.org/trac/browser/luci/trunk/libs/iwinfo/src/iwinfo_wext.c?rev=5645 (outdated?)
-- TODO: configure encryption correctly (how?)
-- @param info iwinfo data to create a network from
-- @param passphrase passphrase to use (optional)
-- @param disabled immediately disable the network (optional)
function M.createConfigFromScanInfo(info, passphrase, disabled)
local mode = M.mapDeviceMode(info.mode)
local apconfig = {
network = M.NET,
device = "radio0",
ssid = info.ssid,
bssid = info.bssid,
--encryption = "none",
mode = mode,
}
if passphrase ~= nil then apconfig.key = passphrase end
apconfig.disabled = disabled ~= nil and disabled and 1 or 0
local sname = uci:add("wireless", "wifi-iface");
for k, v in pairs(apconfig) do
uci:set("wireless", sname, k, v)
end
uci:commit("wireless")
end
--- Ensure a suitable config section for the access point network exists
-- @param disabled flag the network as disabled (optional)
function M.createOrReplaceApConfig(disabled)
local sname = nil
uci:foreach("wireless", "wifi-iface", function(s)
if s.ssid == M.AP_SSID then
sname = s[".name"]
return false
end
end)
if sname == nil then sname = uci:add("wireless", "wifi-iface") end
local apconfig = {
network = M.NET,
ssid = M.AP_SSID,
encryption = "none",
device = "radio0",
mode = "ap",
}
apconfig.disabled = disabled ~= nil and disabled and 1 or 0
for k, v in pairs(apconfig) do
uci:set("wireless", sname, k, v)
end
uci:commit("wireless")
end
--- Reload network config to reflect contents of config
-- @see http://wiki.openwrt.org/doc/techref/netifd)
-- * Network reload only restarts interfaces which need to be restarted so no
-- unneccesary interruptions there.
-- * ubus does not seem to work -- local c=ubus.connect();
-- c:call("network.interface.wlan", "down"); c:call("network.interface.wlan", "up"); c:close()
-- @param dhcpToo also reload dnsmasq if true
function M.restart(dhcpToo)
os.execute("/etc/init.d/network reload") --always seems to return 0
if dhcpToo ~= nil and dhcpToo then os.execute("/etc/init.d/dnsmasq reload") end
return 0
end
--- Add or remove DHCP section for wlan network
-- @param addCfg add section if true or nil, remove it if false
function M.configureDhcp(addCfg)
if addCfg == nil or addCfg == true then
uci:set("dhcp", M.NET, "dhcp")
uci:set("dhcp", M.NET, "interface", M.NET)
uci:set("dhcp", M.NET, "start", "100")
uci:set("dhcp", M.NET, "limit", "150")
uci:set("dhcp", M.NET, "leasetime", "12h")
uci:set("network", M.NET, "proto", "static")
uci:set("network", M.NET, "ipaddr", M.AP_ADDRESS)
uci:set("network", M.NET, "netmask", M.AP_NETMASK)
uci:set("network", M.NET, "type", "bridge")
else
uci:delete("dhcp", M.NET)
uci:set("network", M.NET, "proto", "dhcp")
uci:delete("network", M.NET, "ipaddr")
uci:delete("network", M.NET, "netmask")
-- uci:delete("network", M.NET, "bridge")
end
uci:commit("dhcp")
uci:commit("network")
--TODO: is network reload enough here?
end
return M