Skip to content

Commit 7739b79

Browse files
committed
gluon-offline-ssid: restructure original gluon-ssid-changer code
- transcoded ssid_changer.sh into Lua - remove gluonShellDiet - change defualt prefix to just "Offline_" - extract gluon-web-offline-ssid
1 parent 434efea commit 7739b79

File tree

20 files changed

+317
-285
lines changed

20 files changed

+317
-285
lines changed

docs/package/gluon-ssid-changer.rst docs/package/gluon-offline-ssid.rst

+9-9
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
1-
gluon-ssid-changer
1+
gluon-offline-ssid
22
==================
33

44
This package adds a script to change the SSID when there is no connection to any
55
gateway. This Offline-SSID can be generated from the node's hostname with the
66
first and last part of the node name or the MAC address allowing observers to
77
recognize which node does not have a connection to a gateway. This script is
8-
called once every minute by ``micron.d`` and check gateway-connectivity. It will
8+
called once every minute by ``micrond`` and check gateway-connectivity. It will
99
change the SSID to the Offline-SSID after the node lost gateway connectivity for
1010
several consecutive checks. As soon as the gateway-connectivity is back it
1111
toggles back to the original SSID.
@@ -41,14 +41,14 @@ Adapt and add this block to your ``site.conf``:
4141

4242
::
4343

44-
ssid_changer = {
45-
enabled = true,
44+
offline_ssid = {
45+
disabled = false,
4646
switch_timeframe = 30, -- only once every timeframe (in minutes) the SSID will change to the Offline-SSID
4747
-- set to 1440 to change once a day
4848
-- set to 1 minute to change every time the router gets offline
4949
first = 5, -- the first few minutes directly after reboot within which an Offline-SSID may be
5050
-- activated every minute (must be <= switch_timeframe)
51-
prefix = 'FF_Offline_', -- use something short to leave space for the nodename (no '~' allowed!)
51+
prefix = 'Offline_', -- use something short to leave space for the nodename (no '~' allowed!)
5252
suffix = 'nodename', -- generate the SSID with either 'nodename', 'mac' or to use only the prefix: 'none'
5353
5454
tq_limit_enabled = false, -- if false, the offline SSID will only be set if there is no gateway reacheable
@@ -62,16 +62,16 @@ Adapt and add this block to your ``site.conf``:
6262
Commandline options
6363
===================
6464

65-
You can configure the ssid-changer on the commandline with ``uci``, for example
65+
You can configure the offline-ssid on the commandline with ``uci``, for example
6666
disable it with:
6767

6868
::
6969

70-
uci set ssid-changer.settings.enabled='0'
70+
uci set gluon-offline-ssid.settings.disabled='1'
7171

7272
Or set the timeframe to every three minutes with
7373

7474
::
7575

76-
uci set ssid-changer.settings.switch_timeframe='3'
77-
uci set ssid-changer.settings.first='3'
76+
uci set gluon-offline-ssid.settings.switch_timeframe='3'
77+
uci set gluon-offline-ssid.settings.first='3'
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
11
include $(TOPDIR)/rules.mk
22

3-
PKG_NAME:=gluon-ssid-changer
4-
PKG_VERSION:=5
3+
PKG_NAME:=gluon-offline-ssid
4+
PKG_VERSION:=7
55

6-
include $(TOPDIR)/../package/gluon.mk
6+
include ../gluon.mk
77

88
define Package/$(PKG_NAME)
99
TITLE:=changes the SSID to an Offline-SSID so clients don't connect to an offline WiFi
@@ -19,18 +19,4 @@ define Package/$(PKG_NAME)/description
1919
most.
2020
endef
2121

22-
23-
define Build/Compile
24-
$(call Gluon/Build/Compile)
25-
./gluonShellDiet.sh shsrc/ssid-changer.sh > $(PKG_BUILD_DIR)/ssid-changer.sh
26-
endef
27-
28-
define Package/$(PKG_NAME)/install
29-
$(Gluon/Build/Install)
30-
31-
$(INSTALL_DIR) $(1)/lib/gluon/ssid-changer
32-
$(INSTALL_BIN) $(PKG_BUILD_DIR)/ssid-changer.sh $(1)/lib/gluon/ssid-changer/
33-
endef
34-
35-
3622
$(eval $(call BuildPackageGluon,$(PKG_NAME)))
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
need_boolean({'offline_ssid', 'disabled'}, false)
2+
need_number({'offline_ssid', 'switch_timeframe'}, false)
3+
need_number({'offline_ssid', 'first'}, false)
4+
need_string({'offline_ssid', 'prefix'}, false)
5+
need_one_of({'offline_ssid', 'suffix'}, {'nodename', 'mac', 'none'}, false)
6+
if need_boolean({'offline_ssid','tq_limit_enabled'}, false) then
7+
need_number({'offline_ssid', 'tq_limit_max'}, false)
8+
need_number({'offline_ssid', 'tq_limit_min'}, false)
9+
end
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
* * * * * /usr/bin/gluon-offline-ssid.lua
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
#!/usr/bin/lua
2+
3+
local site = require 'gluon.site'
4+
5+
local uci = require('simple-uci').cursor()
6+
7+
if site.offline_ssid ~= nil then
8+
local site_disabled = site.offline_ssid.disabled() or '0'
9+
10+
uci:section('gluon-offline-ssid', 'settings', 'settings', {
11+
disabled = uci:get('gluon-offline-ssid', 'settings', 'disabled') or site_disabled,
12+
switch_timeframe = site.offline_ssid.switch_timeframe() or '30',
13+
first = site.offline_ssid.first() or '5',
14+
prefix = site.offline_ssid.prefix() or 'Offline_',
15+
suffix = site.offline_ssid.suffix() or 'nodename',
16+
tq_limit_enabled = site.offline_ssid.tq_limit_enabled() or false,
17+
tq_limit_max = site.offline_ssid.tq_limit_max() or 45,
18+
tq_limit_min = site.offline_ssid.tq_limit_min() or 35,
19+
})
20+
uci:save('gluon-offline-ssid')
21+
end
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,219 @@
1+
#!/usr/bin/lua
2+
3+
local uci = require("simple-uci").cursor()
4+
local util = require 'gluon.util'
5+
6+
function safety_exit(t)
7+
io.write(t .. ", exiting with error code 2")
8+
os.exit(2)
9+
end
10+
11+
function logger(m)
12+
os.execute('logger -s -t "gluon-offline-ssid" -p 5 "' .. m .. '"')
13+
end
14+
15+
function file_exists(name)
16+
local f = io.open(name, "r")
17+
return f ~= nil and io.close(f)
18+
end
19+
20+
local ut = util.get_uptime()
21+
if ut < 60 then
22+
safety_exit('less than one minute')
23+
end
24+
25+
-- only once every timeframe minutes the ssid will change to the offline-ssid
26+
-- (set to 1 minute if you want to change immediately every time the router gets offline)
27+
local minutes = tonumber(uci:get('gluon-offline-ssid', 'settings', 'switch_timeframe') or '30')
28+
29+
-- the first few minutes directly after reboot within which an offline-ssid always may be activated
30+
-- (must be <= switch_timeframe)
31+
local first = tonumber(uci:get('gluon-offline-ssid', 'settings', 'first') or '5')
32+
33+
-- the offline-ssid will start with this prefix use something short to leave space for the nodename
34+
-- (no '~' allowed!)
35+
local prefix = uci:get('gluon-offline-ssid', 'settings', 'prefix') or 'Offline_'
36+
37+
local disabled = uci:get('gluon-offline-ssid', 'settings', 'disabled') == '1' or false
38+
if disabled then
39+
print("offline-ssid is disabled")
40+
end
41+
local phys = { length = 0 }
42+
uci:foreach('wireless', 'wifi-device', function(config)
43+
local phy = util.find_phy(config)
44+
if phy then
45+
phys[config['.name']] = phy
46+
phys['length'] = phys['length'] + 1
47+
end
48+
end)
49+
if phys['length'] == 0 then
50+
safety_exit('no hostapd-phys')
51+
end
52+
53+
local ssids = { }
54+
uci:foreach('wireless', 'wifi-iface', function(config)
55+
if config['mode'] == 'ap' and config['network'] == 'client' then
56+
local ssid = config['ssid']
57+
if ssid then
58+
table.insert(ssids, { ssid = ssid , phy = phys[config['device']] })
59+
end
60+
end
61+
end)
62+
if #ssids == 0 then
63+
safety_exit('no ssids')
64+
end
65+
66+
-- generate the ssid with either 'nodename', 'mac' or to use only the prefix set to 'none'
67+
local settings_suffix = uci:get('gluon-offline-ssid', 'settings', 'suffix') or 'nodename'
68+
69+
local suffix
70+
if settings_suffix == 'nodename' then
71+
local pretty_hostname = require 'pretty_hostname'
72+
suffix = pretty_hostname.get(uci)
73+
-- 32 would be possible as well
74+
if ( string.len(suffix) > 30 - string.len(prefix) ) then
75+
-- calculate the length of the first part of the node identifier in the offline-ssid
76+
local half = math.floor((28 - string.len(prefix) ) / 2)
77+
-- jump to this charakter for the last part of the name
78+
local skip = string.len(suffix) - half
79+
-- use the first and last part of the nodename for nodes with long name
80+
suffix = string.sub(suffix,0,half) .. '...' .. string.sub(suffix, skip)
81+
end
82+
elseif settings_suffix == 'mac' then
83+
local sysconfig = require 'gluon.sysconfig'
84+
suffix = sysconfig.primary_mac
85+
else
86+
-- 'none'
87+
suffix = ''
88+
end
89+
local offline_ssid = prefix .. suffix
90+
91+
-- temp file to count the offline incidents during switch_timeframe
92+
local tmp = '/tmp/offline-ssid-count'
93+
local off_count = '0'
94+
if not file_exists(tmp) then
95+
assert(io.open(tmp, 'w')):write('0')
96+
else
97+
off_count = tonumber(util.readfile(tmp))
98+
end
99+
100+
-- if tq_limit_enabled is true, the offline ssid will only be set if there is no gateway reacheable
101+
-- upper and lower limit to turn the offline_ssid on and off
102+
-- in-between these two values the ssid will never be changed to preven it from toggeling every minute.
103+
local tq_limit_enabled = tonumber(uci:get('gluon-offline-ssid', 'settings', 'tq_limit_enabled') or '0')
104+
105+
local check
106+
local msg
107+
if ( tq_limit_enabled == 1 ) then
108+
-- upper limit, above that the online ssid will be used
109+
local tq_limit_max = tonumber(uci:get('gluon-offline-ssid', 'settings', 'tq_limit_max') or '45')
110+
-- lower limit, below that the offline ssid will be used
111+
local tq_limit_min = tonumber(uci:get('gluon-offline-ssid', 'settings', 'tq_limit_min') or '35')
112+
-- grep the connection quality of the currently used gateway
113+
local gateway_tq = util.exec('batctl gwl | grep -e "^=>" -e "^\\*" | awk -F %'[()]%' %'{print $2}%' | tr -d " "')
114+
if ( gateway_tq == '' ) then
115+
-- there is no gateway
116+
local gateway_tq = 0
117+
end
118+
msg = "tq is " .. gateway_tq
119+
120+
if ( gateway_tq >= tq_limit_max ) then
121+
check = 1
122+
elseif ( gateway_tq < tq_limit_min ) then
123+
check = 0
124+
else
125+
-- get a clean run if we are in-between the grace period
126+
print(msg .. ", do nothing")
127+
os.exit(0)
128+
end
129+
else
130+
msg = ""
131+
check = os.execute('batctl gwl -H | grep -v "gateways in range"')
132+
end
133+
134+
local up = ut / 60
135+
local m = math.floor(up % minutes)
136+
137+
-- debug:
138+
print("uptime in minutes:"..up..", every "..minutes.." minutes, countdown:"..m)
139+
140+
local hup_needed = 0
141+
local ssid_grep = 'grep "^ssid='
142+
143+
-- debug:
144+
-- check=0 -- set this to set the node always offline
145+
146+
if check > 0 or disabled then
147+
print("node is online")
148+
-- check status for all physical devices
149+
for _, ssid in ipairs(ssids) do
150+
local hostapd = '/var/run/hostapd-' .. ssid.phy .. '.conf'
151+
152+
-- first grep for online-SSID in hostapd file
153+
if os.execute(ssid_grep .. ssid.ssid .. '" ' .. hostapd) == 0 then
154+
print("current ssid is correct")
155+
break
156+
else
157+
-- set online
158+
159+
-- debug: grep for offline_ssid in hostapd file
160+
if os.execute(ssid_grep .. offline_ssid .. '" ' .. hostapd) ~= 0 then
161+
logger('misconfiguration: did neither find ssid ' .. ssid.ssid .. ' nor ' .. offline_ssid .. '. please reboot')
162+
end
163+
164+
local current_ssid = util.trim(util.exec(ssid_grep .. '" ' .. hostapd .. ' | cut -d"=" -f2'))
165+
-- TODO: replace ~ in current_ssid and ssid.ssid
166+
167+
logger(msg .. ' - ssid is ' .. current_ssid .. ', change to ' .. ssid.ssid)
168+
os.execute('sed -i "s~^ssid=' .. current_ssid .. '~ssid=' .. ssid.ssid .. '~" ' .. hostapd)
169+
hup_needed = 1
170+
end
171+
end
172+
elseif check == 0 then
173+
print("node is considered offline")
174+
if up < first or m == 0 then
175+
-- set ssid offline, only if uptime is less than first or exactly a multiplicative of switch_timeframe
176+
local t = minutes
177+
if up < first then
178+
t = first
179+
end
180+
if off_count >= t / 2 then
181+
-- node was offline more times than half of switch_timeframe (or than first)
182+
for _, ssid in ipairs(ssids) do
183+
local hostapd = '/var/run/hostapd-' .. ssid.phy .. '.conf'
184+
local current_ssid = util.trim(util.exec(ssid_grep .. '" ' .. hostapd .. ' | cut -d"=" -f2'))
185+
186+
-- first grep for offline_ssid in hostapd file
187+
if os.execute(ssid_grep .. offline_ssid .. '" ' .. hostapd) == 0 then
188+
print('ssid ' .. current_ssid .. ' is correct')
189+
break
190+
else
191+
-- set offline
192+
193+
-- debug: grep for online-SSID in hostapd file
194+
if os.execute(ssid_grep .. ssid.ssid .. '" ' .. hostapd) == 0 then
195+
logger('misconfiguration: did neither find ssid ' .. ssid.ssid .. ' nor ' .. offline_ssid .. '. please reboot')
196+
end
197+
198+
logger(msg .. ' - ' off_count .. ' times offline, ssid is ' .. current_ssid .. ', change to ' .. offline_ssid)
199+
os.execute('sed -i "s~^ssid=' .. ssid.ssid .. '~ssid=' .. offline_ssid .. '~" ' .. hostapd)
200+
hup_needed = 1
201+
end
202+
end
203+
end
204+
-- else print("minute ' .. m .. ', just count ' .. off_count .. '")
205+
end
206+
207+
assert(io.open(tmp, 'w')):write(off_count + 1)
208+
end
209+
210+
if hup_needed == 1 then
211+
-- send hup to all hostapd to load the new ssid
212+
os.execute('killall -hup hostapd')
213+
print("hup!")
214+
end
215+
216+
if m == 0 then
217+
-- set counter to 0 if the timeframe is over
218+
assert(io.open(tmp, 'w')):write('0')
219+
end

package/gluon-ssid-changer/check_site.lua

-9
This file was deleted.

package/gluon-ssid-changer/files/usr/lib/micron.d/ssid-changer

-1
This file was deleted.

package/gluon-ssid-changer/gluonShellDiet.sh

-5
This file was deleted.

package/gluon-ssid-changer/i18n/gluon-ssid-changer.pot

-10
This file was deleted.

package/gluon-ssid-changer/luasrc/lib/gluon/config-mode/controller/admin/ssid-changer.lua

-1
This file was deleted.

package/gluon-ssid-changer/luasrc/lib/gluon/config-mode/model/admin/ssid-changer.lua

-28
This file was deleted.

0 commit comments

Comments
 (0)