Skip to content

Commit

Permalink
ffh-wifi-offline-ssid: initial commit
Browse files Browse the repository at this point in the history
This commit adds a package to change the SSID if no internet connection is
available. It depends on ffh-check-connection.

This is based on freifunk-gluon/gluon#1649
  • Loading branch information
CodeFetch committed Jun 8, 2021
1 parent 25b56f9 commit a8b554f
Show file tree
Hide file tree
Showing 5 changed files with 183 additions and 0 deletions.
22 changes: 22 additions & 0 deletions ffh-wifi-offline-ssid/Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
include $(TOPDIR)/rules.mk

PKG_NAME:=ffh-wifi-offline-ssid
PKG_VERSION:=1
PKG_RELEASE:=1

include $(TOPDIR)/../package/gluon.mk

define Package/$(PKG_NAME)
TITLE:=Changes the SSID to an Offline-SSID on disrupted internet connection
DEPENDS:=+gluon-core +ffh-check-connection
endef

define Package/$(PKG_NAME)/description
Script to change the SSID to an Offline-SSID when there is no connection to
the internet. This SSID can be generated from the node's hostname with the
first and last part of the node's name or from the MAC address.
The script is being triggered by ffh-check-connection on connection status
changes.
endef

$(eval $(call BuildPackageGluon,$(PKG_NAME)))
5 changes: 5 additions & 0 deletions ffh-wifi-offline-ssid/check_site.lua
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
need_boolean({'ffh_wifi_offline_ssid', 'disabled'}, false)
need_string({'ffh_wifi_offline_ssid', 'target_group'}, true)
need_number({'ffh_wifi_offline_ssid', 'threshold'}, false)
need_string({'ffh_wifi_offline_ssid', 'prefix'}, false)
need_one_of({'ffh_wifi_offline_ssid', 'suffix'}, {'hostname', 'mac', 'none'}, false)
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
config settings 'settings'
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
#!/usr/bin/lua

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

if site.ffh_wifi_offline_ssid then
local site_disabled = site.ffh_wifi_offline_ssid.disabled() or '0'

uci:section('ffh-wifi-offline-ssid', 'settings', 'settings', {
disabled = uci:get('ffh-wifi-offline-ssid', 'settings', 'disabled') or site_disabled,
threshold = site.ffh_wifi_offline_ssid.threshold() or 5,
prefix = site.ffh_wifi_offline_ssid.prefix() or 'Offline_',
suffix = site.ffh_wifi_offline_ssid.suffix() or 'hostname',
})

uci:save('ffh-wifi-offline-ssid')

uci:section('ffh-check-connection', 'script', 'ffh_wifi_offline', {
enabled = true,
interval = 1,
command = 'ffh-wifi-offline-ssid offline',
groups = {site.ffh_wifi_offline_ssid.target_group(),},
trigger = 'offline',
})

uci:section('ffh-check-connection', 'script', 'ffh_wifi_online', {
enabled = true,
interval = 1,
command = 'ffh-wifi-offline-ssid online',
groups = {site.ffh_wifi_offline_ssid.target_group(),},
onchange = true,
trigger = 'online',
})

uci:save('ffh-check-connection')
end
119 changes: 119 additions & 0 deletions ffh-wifi-offline-ssid/luasrc/usr/sbin/ffh-wifi-offline-ssid
Original file line number Diff line number Diff line change
@@ -0,0 +1,119 @@
#!/usr/bin/lua

local uci = require('simple-uci').cursor()
local unistd = require 'posix.unistd'
local util = require 'gluon.util'

local prog_name = 'ffh-wifi-offline-ssid'
local offline_file = '/tmp/ffh-offline-ffh_wifi_offline'

local disabled = uci:get('ffh-wifi-offline-ssid', 'settings', 'disabled') == '1' or false
if disabled then
print(prog_name .. " is disabled. Exiting...")
os.exit(0)
end

local threshold_mins = uci:get(prog_name, 'settings', 'threshold') or 0

local uptime_mins = math.floor(util.get_uptime() / 60)
local offline_mins = uptime
if unistd.access(offline_file) then
offline_mins = uptime - (tonumber(util.readfile(offline_file)) or 0)
end

if arg[1] == "offline" and offline_mins < switch_time then
print((threshold_mins - offline_mins) .. ' minutes remaining until the node is considered offline. Exiting...')
os.exit(0)
end

local phys = {count = 0}
uci:foreach('wireless', 'wifi-device', function(config)
local phy = util.find_phy(config)
if phy then
phys[config['.name']] = phy
phys['count'] = phys['count'] + 1
end
end)

if phys['count'] == 0 then
print('No radios detected. Exiting...')
os.exit(0)
end

local ssids = {}
uci:foreach('wireless', 'wifi-iface', function(config)
if config['mode'] == 'ap' and config['network'] == 'client' then
local ssid = config['ssid']
if ssid then
table.insert(ssids, {ssid = ssid, phy = phys[config['device']]})
end
end
end)

if #ssids == 0 then
print('No client networks active. Exiting...')
os.exit(0)
end

-- Use something short to leave space for the hostname
-- (no '~' allowed!)
local prefix = uci:get(prog_name, 'settings', 'prefix') or 'Offline_'

-- Generate the SSID either with 'hostname', 'mac' or only using the prefix
local settings_suffix = uci:get(prog_name, 'settings', 'suffix') or 'hostname'

local suffix = ''
if settings_suffix == 'hostname' then
local pretty_hostname = require 'pretty_hostname'
suffix = pretty_hostname.get(uci)
-- 32 would be possible as well
if (string.len(suffix) > 30 - string.len(prefix)) then
-- Calculate the length of the first part of the node identifier in the offline-ssid
local half = math.floor((28 - string.len(prefix)) / 2)
-- Jump to this character for the last part of the name
local skip = string.len(suffix) - half
-- Use the first and last part of the nodename for nodes with long name
suffix = string.sub(suffix, 0, half) .. '...' .. string.sub(suffix, skip)
end
elseif settings_suffix == 'mac' then
local sysconfig = require 'gluon.sysconfig'
suffix = sysconfig.primary_mac
end

local offline_ssid = prefix .. suffix

local hup_needed = 0
local ssid_grep = 'grep "^ssid='
for _, ssid in ipairs(ssids) do
local hostapd = '/var/run/hostapd-' .. ssid.phy .. '.conf'

if arg[1] == "offline" then
old_ssid = ssid.ssid
new_ssid = offline_ssid
else
old_ssid = offline_ssid
new_ssid = ssid.ssid
end

if os.execute(ssid_grep .. new_ssid .. '" ' .. hostapd) == 0 then
print('Current SSID "' .. new_ssid .. '" for ' .. ssid.phy .. ' is already correct. Skipping...')
break
end

-- Confirm that old SSID was set
if os.execute(ssid_grep .. old_ssid .. '" ' .. hostapd) ~= 0 then
util.log(prog_name .. ': Warning: Neither found SSID "' .. ssid.ssid .. '" nor "' .. offline_ssid .. '" on ' .. ssid.phy .. '.')
end

local current_ssid = util.trim(util.exec(ssid_grep .. '" ' .. hostapd .. ' | cut -d"=" -f2'))

util.log(prog_name .. ': Current SSID is "' .. current_ssid .. '". Changing it to "' .. new_ssid .. '"...')
os.execute('sed -i "s~^ssid=' .. current_ssid .. '~ssid=' .. new_ssid .. '~" ' .. hostapd)
hup_needed = 1
end

-- Send hup to all hostapd instances to apply the new SSID
if hup_needed == 1 then
print("Applying new SSIDs...")
os.execute('killall -hup hostapd')
end

0 comments on commit a8b554f

Please sign in to comment.