gluon/package/gluon-web-wifi-config/luasrc/lib/gluon/config-mode/model/admin/wifi-config.lua
David Bauer 963bcfd3ee site: disallow usage of outdoor mode in case outdoor_chanlist is missing
The documentation states the outdoor mode is only enabled in case
outdoor_chanlist is defined in the sites wifi5 configurationsection:

 > If enabled, by setting ``wifi5.outdoor_chanlist``, a number of
 > devices that are commonly installed outdoors will have outdoor
 > mode automatically enabled during their initial setup

This currently does not hold true, as Outdoor mode is always activated
for these devices on first setup, even in case the site does not specify
an outdoor chanlist.

Furthermore, it also does not make sense to show the option neither in
setup-modes basic nor advences configuration view in case the site is
lacking an out door chanlist.

This patch will disable outdoor mode on new installs in case the outdoor
chanlist is missing. It will also not show the respective configuration
options in this case.

Signed-off-by: David Bauer <mail@david-bauer.net>
2021-06-27 13:50:26 +02:00

207 lines
5.6 KiB
Lua

local iwinfo = require 'iwinfo'
local uci = require("simple-uci").cursor()
local site = require 'gluon.site'
local wireless = require 'gluon.wireless'
local function txpower_list(phy)
local list = iwinfo.nl80211.txpwrlist(phy) or { }
local off = tonumber(iwinfo.nl80211.txpower_offset(phy)) or 0
local new = { }
local prev = -1
for _, val in ipairs(list) do
local dbm = val.dbm + off
local mw = math.floor(10 ^ (dbm / 10))
if mw ~= prev then
prev = mw
table.insert(new, {
display_dbm = dbm,
display_mw = mw,
driver_dbm = val.dbm,
})
end
end
return new
end
local function has_5ghz_radio()
local result = false
uci:foreach('wireless', 'wifi-device', function(config)
local radio = config['.name']
local hwmode = uci:get('wireless', radio, 'hwmode')
result = result or (hwmode == '11a' or hwmode == '11na')
end)
return result
end
local f = Form(translate("WLAN"))
f:section(Section, nil, translate(
"You can enable or disable your node's client and mesh network "
.. "SSIDs here. Please don't disable the mesh network without "
.. "a good reason, so other nodes can mesh with yours.<br /><br />"
.. "It is also possible to configure the WLAN adapters transmission power "
.. "here. Please note that the transmission power values include the antenna gain "
.. "where available, but there are many devices for which the gain is unavailable or inaccurate."
))
local mesh_vifs_5ghz = {}
uci:foreach('wireless', 'wifi-device', function(config)
local radio = config['.name']
local is_5ghz = false
local title
if config.hwmode == '11g' or config.hwmode == '11ng' then
title = translate("2.4GHz WLAN")
elseif config.hwmode == '11a' or config.hwmode == '11na' then
is_5ghz = true
title = translate("5GHz WLAN")
else
return
end
local p = f:section(Section, title)
local function filter_existing_interfaces(interfaces)
local out = {}
for _, interface in ipairs(interfaces) do
if uci:get('wireless', interface .. '_' .. radio) then
table.insert(out, interface)
end
end
return out
end
local function has_active_interfaces(interfaces)
for _, interface in ipairs(interfaces) do
if not uci:get_bool('wireless', interface .. '_' .. radio, 'disabled') then
return true
end
end
return false
end
local function vif_option(name, interfaces, msg)
local existing_interfaces = filter_existing_interfaces(interfaces)
if #existing_interfaces == 0 then
return
end
local o = p:option(Flag, radio .. '_' .. name .. '_enabled', msg)
o.default = has_active_interfaces(existing_interfaces)
function o:write(data)
for _, interface in ipairs(existing_interfaces) do
uci:set('wireless', interface .. '_' .. radio, 'disabled', not data)
end
end
return o
end
vif_option('client', {'client', 'owe'}, translate('Enable client network (access point)'))
local mesh_vif = vif_option('mesh', {'mesh'}, translate("Enable mesh network (802.11s)"))
if is_5ghz then
table.insert(mesh_vifs_5ghz, mesh_vif)
end
local phy = wireless.find_phy(config)
if not phy then
return
end
local txpowers = txpower_list(phy)
if #txpowers <= 1 then
return
end
local tp = p:option(ListValue, radio .. '_txpower', translate("Transmission power"))
tp.default = uci:get('wireless', radio, 'txpower') or 'default'
tp:value('default', translate("(default)"))
table.sort(txpowers, function(a, b) return a.driver_dbm > b.driver_dbm end)
for _, entry in ipairs(txpowers) do
tp:value(entry.driver_dbm, string.format("%i dBm (%i mW)", entry.display_dbm, entry.display_mw))
end
function tp:write(data)
if data == 'default' then
data = nil
end
uci:set('wireless', radio, 'txpower', data)
end
end)
if has_5ghz_radio() and not wireless.preserve_channels(uci) and wireless.site_supports_outdoor_mode() then
local r = f:section(Section, translate("Outdoor Installation"), translate(
"Configuring the node for outdoor use tunes the 5 GHz radio to a frequency "
.. "and transmission power that conforms with the local regulatory requirements. "
.. "It also enables dynamic frequency selection (DFS; radar detection). At the "
.. "same time, mesh functionality is disabled as it requires neighbouring nodes "
.. "to stay on the same channel permanently."
))
local outdoor = r:option(Flag, 'outdoor', translate("Node will be installed outdoors"))
outdoor.default = uci:get_bool('gluon', 'wireless', 'outdoor')
for _, mesh_vif in ipairs(mesh_vifs_5ghz) do
mesh_vif:depends(outdoor, false)
if outdoor.default then
mesh_vif.default = not site.wifi5.mesh.disabled(false)
end
end
function outdoor:write(data)
uci:set('gluon', 'wireless', 'outdoor', data)
end
uci:foreach('wireless', 'wifi-device', function(config)
local radio = config['.name']
local hwmode = uci:get('wireless', radio, 'hwmode')
if hwmode ~= '11a' and hwmode ~= '11na' then
return
end
local phy = wireless.find_phy(uci:get_all('wireless', radio))
local ht = r:option(ListValue, 'outdoor_htmode', translate('HT Mode') .. ' (' .. radio .. ')')
ht:depends(outdoor, true)
ht.default = uci:get('gluon', 'wireless', 'outdoor_' .. radio .. '_htmode') or 'default'
ht:value('default', translate("(default)"))
for mode, available in pairs(iwinfo.nl80211.htmodelist(phy)) do
if available then
ht:value(mode, mode)
end
end
function ht:write(data)
if data == 'default' then
data = nil
end
uci:set('gluon', 'wireless', 'outdoor_' .. radio .. '_htmode', data)
end
end)
end
function f:write()
uci:commit('gluon')
os.execute('/lib/gluon/upgrade/200-wireless')
uci:commit('network')
uci:commit('wireless')
end
return f