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

203 lines
5.9 KiB
Lua
Raw Normal View History

2013-07-08 13:43:59 +02:00
local util = require("util.utils")
local l = require("util.logger")
local uci = require("uci").cursor()
local iwinfo = require("iwinfo")
local M = {}
--NOTE: fallback device 'radio0' is required because sometimes the wlan0 device disappears
M.DFL_DEVICE = "wlan0"
M.DFL_DEVICE_FALLBACK = "radio0"
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
--[[
- TODO: several modes need to be tested (wep, psk2, mixed-psk)
- See: http://wiki.openwrt.org/doc/uci/wireless#wpa.modes
]]
function M.mapEncryptionType(scanEncrTbl)
local wpaModeMap = { [1] = "psk", [2] = "psk2", [3] = "mixed-psk" }
if scanEncrTbl.enabled == false then return "none" end
if scanEncrTbl.wep == true then return "wep" end
return wpaModeMap[scanEncrTbl.wpa] or scanEncrTbl.description
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
--TODO: warn about missing dev here?
local devInitial = dev
dev = M.DFL_DEVICE_FALLBACK
dev_api = iwinfo.type(dev)
if not dev_api then
return false, "No such wireless device: '" .. devInitial .. "' (and fallback '" .. dev .. "' does not exist either)"
end
end
return true
end
function M.getDeviceState()
local iw = iwinfo[dev_api]
local result = {
["ssid"] = iw.ssid(dev),
["bssid"] = iw.bssid(dev),
["channel"] = iw.channel(dev),
["mode"] = M.mapDeviceMode(iw.mode(dev), true),
["encryption"] = M.mapEncryptionType(iw.encryption(dev).description),
["quality"] = iw.quality(dev),
["quality_max"] = iw.quality_max(dev),
["txpower"] = iw.txpower(dev),
["signal"] = iw.signal(dev),
["noise"] = iw.noise(dev)
}
return result
end
--returns the wireless device's MAC address (as string, without colons)
--(lua numbers on openWrt seem to be 32bit so they cannot represent a MAC address as one number)
function M.getMacAddress()
local iw = iwinfo[dev_api]
local macText = iw.bssid(dev)
local out = ""
for i = 0, 5 do
local bt = string.sub(macText, i*3+1, i*3+2)
out = out .. bt
end
return out
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: delete previous network if exists (match on MAC-address)
-- @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 = M.mapEncryptionType(info.encryption),
mode = mode,
}
if passphrase ~= nil then apconfig.key = passphrase end
apconfig.disabled = disabled ~= nil and disabled and 1 or 0
uci:foreach("wireless", "wifi-iface", function(s)
if s.bssid == info.bssid then
l:debug("removing old wireless config for net '" .. s.ssid .. "(bssid: " .. s.bssid .. ")'")
uci:delete("wireless", s[".name"])
-- return false --keep looking, just in case multiple entries with this bssid exist
end
end)
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
--- 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
return M