Skip to content

Commit

Permalink
Merge pull request #1329 from mweinelt/outdoor_mode
Browse files Browse the repository at this point in the history
gluon-core: add outdoor channel support for 5 ghz radios
  • Loading branch information
neocturne authored Apr 28, 2019
2 parents 4f60f6d + 501c3b3 commit ddb11dd
Show file tree
Hide file tree
Showing 16 changed files with 347 additions and 30 deletions.
1 change: 1 addition & 0 deletions docs/site-example/site.conf
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,7 @@
-- for channel.
wifi5 = {
channel = 44,
outdoor_chanlist = '100-140',
ap = {
ssid = 'alpha-centauri.freifunk.net',
},
Expand Down
19 changes: 19 additions & 0 deletions docs/user/site.rst
Original file line number Diff line number Diff line change
Expand Up @@ -166,6 +166,25 @@ wifi24 \: optional
wifi5 \: optional
Same as `wifi24` but for the 5Ghz radio.

Additionally a range of channels that are safe to use outsides on the 5 GHz band can
be set up through ``outdoor_chanlist``, which allows for a space-seperated list of
channels and channel ranges, seperated by a hyphen.
When set this offers the outdoor mode flag for 5 GHz radios in the config mode which
reconfigures the AP to select its channel from outdoor chanlist, while respecting
regulatory specifications, and disables mesh on that radio.
The ``outdoors`` option in turn allows to configure when outdoor mode will be enabled.
When set to ``true`` all 5 GHz radios will use outdoor channels, while on ``false``
the outdoor mode will be completely disabled. The default setting is ``'preset'``,
which will enable outdoor mode automatically on outdoor-capable devices.
::

wifi5 = {
channel = 44,
outdoor_chanlist = "100-140",

[...]
},

next_node \: package
Configuration of the local node feature of Gluon
::
Expand Down
3 changes: 2 additions & 1 deletion package/features
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,8 @@ nodefault 'web-wizard'
packages 'web-wizard' \
'gluon-config-mode-hostname' \
'gluon-config-mode-geo-location' \
'gluon-config-mode-contact-info'
'gluon-config-mode-contact-info' \
'gluon-config-mode-outdoor'

packages 'web-wizard & autoupdater' \
'gluon-config-mode-autoupdater'
Expand Down
13 changes: 13 additions & 0 deletions package/gluon-config-mode-outdoor/Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
include $(TOPDIR)/rules.mk

PKG_NAME:=gluon-config-mode-outdoor
PKG_VERSION:=1

include ../gluon.mk

define Package/gluon-config-mode-outdoor
TITLE:=UI for displaying & changing the outdoor mode flag in the wizard
DEPENDS:=+gluon-config-mode-core
endef

$(eval $(call BuildPackageGluon,gluon-config-mode-outdoor))
9 changes: 9 additions & 0 deletions package/gluon-config-mode-outdoor/i18n/de.po
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
msgid ""
"Please enable this option in case the node is to be installed outdoors "
"to comply with local frequency regulations."
msgstr ""
"Wenn der Knoten im Freien aufgestellt werden soll, dann aktiviere bitte "
"diese Option um den örtlichen Frequenzbestimmungen zu entsprechen."

msgid "Node will be installed outdoors"
msgstr "Knoten wird im Außenbereich betrieben"
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
msgid ""
"Please enable this option in case the node is to be installed outdoors "
"to comply with local frequency regulations."
msgstr ""

msgid "Node will be installed outdoors"
msgstr ""
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
return function(form, uci)
local platform_info = require 'platform_info'

if not platform_info.is_outdoor_device() then
-- only visible on wizard for outdoor devices
return
end

local pkg_i18n = i18n 'gluon-config-mode-outdoor'

local section = form:section(Section, nil, pkg_i18n.translate(
"Please enable this option in case the node is to be installed outdoors "
.. "to comply with local frequency regulations."
))

local outdoor = section:option(Flag, 'outdoor', pkg_i18n.translate("Node will be installed outdoors"))
outdoor.default = outdoor_mode

function outdoor:write(data)
if data ~= outdoor_mode then
uci:set('gluon', 'wireless', 'outdoor', data)
uci:save('gluon')
os.execute('/lib/gluon/upgrade/200-wireless')
end
end

return {'gluon', 'wireless'}
end
14 changes: 13 additions & 1 deletion package/gluon-core/check_site.lua
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,19 @@ for _, config in ipairs({'wifi24', 'wifi5'}) do
if need_table({config}, nil, false) then
need_string(in_site({'regdom'})) -- regdom is only required when wifi24 or wifi5 is configured

need_number({config, 'channel'})
if config == "wifi24" then
local channels = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14}
need_one_of({config, 'channel'}, channels)
elseif config == 'wifi5' then
local channels = {
34, 36, 38, 40, 42, 44, 46, 48, 50, 52, 54, 56, 58, 60, 62,
64, 96, 100, 102, 104, 106, 108, 110, 112, 114, 116, 118,
120, 122, 124, 126, 128, 132, 134, 136, 138, 140, 142, 144,
149, 151, 153, 155, 157, 159, 161, 165, 169, 173 }
need_one_of({config, 'channel'}, channels)
need_chanlist({config, 'outdoor_chanlist'}, channels, false)
need_one_of({config, 'outdoors'}, {true, false, 'preset'}, false)
end

obsolete({config, 'supported_rates'}, '802.11b rates are disabled by default.')
obsolete({config, 'basic_rate'}, '802.11b rates are disabled by default.')
Expand Down
35 changes: 35 additions & 0 deletions package/gluon-core/luasrc/lib/gluon/upgrade/180-outdoors
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
#!/usr/bin/lua

-- This script needs to be sorted before 200-wireless as it affects
-- wireless channel selection and wireless mesh configuration.

local uci = require('simple-uci').cursor()
local site = require 'gluon.site'

if uci:get('gluon', 'wireless', 'outdoor') ~= nil then
-- don't overwrite existing configuration
os.exit(0)
end

local sysconfig = require 'gluon.sysconfig'
local platform_info = require 'platform_info'

local config = site.wifi5.outdoor_preset('preset')
local outdoor = false

if sysconfig.gluon_version then
-- don't enable the outdoor mode after an upgrade
outdoor = false
elseif config == 'preset' then
-- enable outdoor mode through presets on new installs
outdoor = platform_info.is_outdoor_device()
else
-- enable/disable outdoor mode unconditionally on new installs
outdoor = config
end

uci:section('gluon', 'wireless', 'wireless', {
outdoor = outdoor
})

uci:save('gluon')
87 changes: 60 additions & 27 deletions package/gluon-core/luasrc/lib/gluon/upgrade/200-wireless
Original file line number Diff line number Diff line change
Expand Up @@ -49,22 +49,37 @@ if not sysconfig.gluon_version then
end)
end

local function is_outdoor()
return uci:get_bool('gluon', 'wireless', 'outdoor')
end

local function get_channel(radio, config)
local channel
if uci:get_first('gluon-core', 'wireless', 'preserve_channels') then
-- preserved channel always wins
channel = radio.channel
elseif (radio.hwmode == '11a' or radio.hwmode == '11na') and is_outdoor() then
-- actual channel will be picked and probed from chanlist
channel = 'auto'
end

return channel or config.channel()
end

local function get_htmode(radio)
local phy = util.find_phy(radio)
if iwinfo.nl80211.hwmodelist(phy).ac then
return 'VHT20'
else
return 'HT20'
end
if (radio.hwmode == '11a' or radio.hwmode == '11na') and is_outdoor() then
local outdoor_htmode = uci:get('gluon', 'wireless', 'outdoor_' .. radio['.name'] .. '_htmode')
if outdoor_htmode ~= nil then
return outdoor_htmode
end
end

local phy = util.find_phy(radio)
if iwinfo.nl80211.hwmodelist(phy).ac then
return 'VHT20'
end

return 'HT20'
end

local function is_disabled(name)
Expand Down Expand Up @@ -207,32 +222,50 @@ util.foreach_radio(uci, function(radio, index, config)
uci:set('wireless', radio_name, 'htmode', htmode)
uci:set('wireless', radio_name, 'country', site.regdom())

uci:delete('wireless', radio_name, 'supported_rates')
uci:delete('wireless', radio_name, 'basic_rate')

local hwmode = radio.hwmode
if hwmode == '11g' or hwmode == '11ng' then
uci:set('wireless', radio_name, 'legacy_rates', false)
elseif (hwmode == '11a' or hwmode == '11na') then
if is_outdoor() then
uci:set('wireless', radio_name, 'channels', config.outdoor_chanlist())

-- enforce outdoor channels by filtering the regdom for outdoor channels
local hostapd_options = uci:get_list('wireless', radio_name, 'hostapd_options')
util.add_to_set(hostapd_options, 'country3=0x4f')
uci:set_list('wireless', radio_name, 'hostapd_options', hostapd_options)

uci:delete('wireless', 'ibss_' .. radio_name)
uci:delete('wireless', 'mesh_' .. radio_name)
else
uci:delete('wireless', radio_name, 'channels')

local hostapd_options = uci:get_list('wireless', radio_name, 'hostapd_options')
util.remove_from_set(hostapd_options, 'country3=0x4f')
uci:set_list('wireless', radio_name, 'hostapd_options', hostapd_options)

local ibss_disabled = is_disabled('ibss_' .. radio_name)
local mesh_disabled = is_disabled('mesh_' .. radio_name)

configure_ibss(config.ibss(), radio, index, suffix,
first_non_nil(
ibss_disabled,
mesh_disabled,
config.ibss.disabled(false)
)
)
configure_mesh(config.mesh(), radio, index, suffix,
first_non_nil(
mesh_disabled,
ibss_disabled,
config.mesh.disabled(false)
)
)
end
end

uci:delete('wireless', radio_name, 'supported_rates')
uci:delete('wireless', radio_name, 'basic_rate')

local ibss_disabled = is_disabled('ibss_' .. radio_name)
local mesh_disabled = is_disabled('mesh_' .. radio_name)

configure_ibss(config.ibss(), radio, index, suffix,
first_non_nil(
ibss_disabled,
mesh_disabled,
config.ibss.disabled(false)
)
)
configure_mesh(config.mesh(), radio, index, suffix,
first_non_nil(
mesh_disabled,
ibss_disabled,
config.mesh.disabled(false)
)
)

fixup_wan(radio, index)
end)

Expand Down
20 changes: 20 additions & 0 deletions package/gluon-core/luasrc/usr/lib/lua/gluon/platform.lua
Original file line number Diff line number Diff line change
Expand Up @@ -27,3 +27,23 @@ function match(target, subtarget, boards)

return true
end

function is_outdoor_device()
if match('ar71xx', 'generic', {
'cpe510-520-v1',
'ubnt-nano-m',
'ubnt-nano-m-xw',
}) then
return true

elseif match('ar71xx', 'generic', {'unifiac-lite'}) and
get_model() == 'Ubiquiti UniFi-AC-MESH' then
return true

elseif match('ar71xx', 'generic', {'unifiac-pro'}) and
get_model() == 'Ubiquiti UniFi-AC-MESH-PRO' then
return true
end

return false
end
22 changes: 22 additions & 0 deletions package/gluon-web-wifi-config/i18n/de.po
Original file line number Diff line number Diff line change
Expand Up @@ -49,3 +49,25 @@ msgstr ""
"werden. Wenn möglich, ist in den Werten der Sendeleistung der Antennengewinn "
"enthalten; diese Werte sind allerdings für viele Geräte nicht verfügbar oder "
"fehlerhaft."

msgid "Outdoor installation"
msgstr "Outdoor-Installation"

msgid "Node will be installed outdoors"
msgstr "Knoten wird im Außenbereich betrieben"

msgid ""
"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."
msgstr ""
"Ist der Knoten für den Einsatz im Freien konfiguriert, wird ein WLAN-Kanal auf "
"dem 5-GHz-Band sowie eine Sendeleistung entsprechend den gesetzlichen "
"Frequenzregulatorien gewählt. Gleichzeitig wird die dynamische Frequenzwahl "
"(DFS; Radarerkennung) aktiviert und die Mesh-Funktionalität deaktiviert, da "
"sich Nachbarknoten dauerhaft auf demselben Kanal befinden müssen."

msgid "HT Mode"
msgstr "HT-Modus"
6 changes: 6 additions & 0 deletions package/gluon-web-wifi-config/i18n/fr.po
Original file line number Diff line number Diff line change
Expand Up @@ -46,3 +46,9 @@ msgstr ""
"<br /><br />Ici vous pouvez aussi configurer la puissance d'émmission se votre Wi-Fi. "
"Prenez note que les valeurs fournies pour la puissance de transmission prennent "
"en compte les gains fournis par l'antenne, et que ces valeurs ne sont pas toujours disponibles ou exactes."

msgid "Outdoor installation"
msgstr "Installation extérieure"

msgid "HT Mode"
msgstr "Mode HT"
17 changes: 17 additions & 0 deletions package/gluon-web-wifi-config/i18n/gluon-web-wifi-config.pot
Original file line number Diff line number Diff line change
Expand Up @@ -33,3 +33,20 @@ msgid ""
"values include the antenna gain where available, but there are many devices "
"for which the gain is unavailable or inaccurate."
msgstr ""

msgid "Outdoor installation"
msgstr ""

msgid "Node will be installed outdoors"
msgstr ""

msgid ""
"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."
msgstr ""

msgid "HT Mode"
msgstr ""
Loading

0 comments on commit ddb11dd

Please sign in to comment.