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>
207 lines
5.6 KiB
Lua
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
|