gluon-offline-ssid: add original gluon-ssid-changer package to automatically change the SSID when no Internet connection

This commit is contained in:
rubo77 2019-02-14 22:22:47 +01:00 committed by Ruben Barkow
parent 3a5fcbf09d
commit 6f3af9b4b6
No known key found for this signature in database
GPG Key ID: 8BCC811299DBC5DF
12 changed files with 395 additions and 0 deletions

View File

@ -0,0 +1,77 @@
gluon-ssid-changer
==================
This package adds a script to change the SSID when there is no connection to any
gateway. This Offline-SSID can be generated from the node's hostname with the
first and last part of the node name or the MAC address allowing observers to
recognize which node does not have a connection to a gateway. This script is
called once every minute by ``micron.d`` and check gateway-connectivity. It will
change the SSID to the Offline-SSID after the node lost gateway connectivity for
several consecutive checks. As soon as the gateway-connectivity is back it
toggles back to the original SSID.
You can enable/disable it in the config mode.
It checks if a gateway is reachable in an interval. Different algorithms can be
selected to determine whether a gateway is reachable:
- ``tq_limit_enabled=true``: (not working with BATMAN\_V) define an upper and
lower bound to toggle the SSID. As long as the TQ stays in-between those
bounds the SSID will not be changed.
- ``tq_limit_enabled=false``: there will be only checked, if the gateway is
reachable with:
::
batctl gwl -H
The SSID is always changed back to normal every minute as soon as the
gateway-connectivity is back, The parameter ``switch_timeframe`` defines how
long it will record the gateway-connectivity. **Only** if the gateway is not
reachable during at least half the checks within ``switch_timeframe`` minutes,
the SSID will be changed to "FF\_Offline\_$node\_hostname".
The parameter ``first`` defines a learning phase after reboot (in minutes)
during which the SSID may be changed to the Offline-SSID **every minute**.
site.conf
=========
Adapt and add this block to your ``site.conf``:
::
ssid_changer = {
enabled = true,
switch_timeframe = 30, -- only once every timeframe (in minutes) the SSID will change to the Offline-SSID
-- set to 1440 to change once a day
-- set to 1 minute to change every time the router gets offline
first = 5, -- the first few minutes directly after reboot within which an Offline-SSID may be
-- activated every minute (must be <= switch_timeframe)
prefix = 'FF_Offline_', -- use something short to leave space for the nodename (no '~' allowed!)
suffix = 'nodename', -- generate the SSID with either 'nodename', 'mac' or to use only the prefix: 'none'
tq_limit_enabled = false, -- if false, the offline SSID will only be set if there is no gateway reacheable
-- upper and lower limit to turn the offline_ssid on and off
-- in-between these two values the SSID will never be changed to prevent it from
-- toggeling every minute.
tq_limit_max = 45, -- upper limit, above that the online SSID will be used
tq_limit_min = 35 -- lower limit, below that the offline SSID will be used
},
Commandline options
===================
You can configure the ssid-changer on the commandline with ``uci``, for example
disable it with:
::
uci set ssid-changer.settings.enabled='0'
Or set the timeframe to every three minutes with
::
uci set ssid-changer.settings.switch_timeframe='3'
uci set ssid-changer.settings.first='3'

View File

@ -0,0 +1,36 @@
include $(TOPDIR)/rules.mk
PKG_NAME:=gluon-ssid-changer
PKG_VERSION:=5
include $(TOPDIR)/../package/gluon.mk
define Package/$(PKG_NAME)
TITLE:=changes the SSID to an Offline-SSID so clients don't connect to an offline WiFi
DEPENDS:=+gluon-core +micrond
endef
define Package/$(PKG_NAME)/description
Script to change the SSID to an Offline-SSID when there is no connection to
any gateway. This SSID can be generated from the node's hostname with the
first and last part of the nodename or the mac address, to allow observers to
recognise which node is down. The script is called once a minute by micrond
and it will change from online to Offline-SSID once per definable timeframe at
most.
endef
define Build/Compile
$(call Gluon/Build/Compile)
./gluonShellDiet.sh shsrc/ssid-changer.sh > $(PKG_BUILD_DIR)/ssid-changer.sh
endef
define Package/$(PKG_NAME)/install
$(Gluon/Build/Install)
$(INSTALL_DIR) $(1)/lib/gluon/ssid-changer
$(INSTALL_BIN) $(PKG_BUILD_DIR)/ssid-changer.sh $(1)/lib/gluon/ssid-changer/
endef
$(eval $(call BuildPackageGluon,$(PKG_NAME)))

View File

@ -0,0 +1,9 @@
need_boolean({'ssid_changer', 'enabled'}, false)
need_number({'ssid_changer', 'switch_timeframe'}, false)
need_number({'ssid_changer', 'first'}, false)
need_string({'ssid_changer', 'prefix'}, false)
need_one_of({'ssid_changer', 'suffix'}, {'nodename', 'mac', 'none'}, false)
if need_boolean({'ssid_changer','tq_limit_enabled'}, false) then
need_number({'ssid_changer', 'tq_limit_max'}, false)
need_number({'ssid_changer', 'tq_limit_min'}, false)
end

View File

@ -0,0 +1 @@
config settings 'settings'

View File

@ -0,0 +1 @@
* * * * * /lib/gluon/ssid-changer/ssid-changer.sh

View File

@ -0,0 +1,5 @@
#!/bin/sh
# This script requires a file as argument in which it will remove all comment lines that start with a hash '#'
sed '/^\s*\#[^!].*/d; /^\s*\#$/d' $1

View File

@ -0,0 +1,26 @@
msgid ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"PO-Revision-Date: 2018-07-29 15:26+0200\n"
"Last-Translator: <github@r.z11.de>\n"
"Language-Team: German\n"
"Language: de\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
msgid "Enabled"
msgstr "Aktiviert"
msgid ""
"Here you can enable to automatically change the SSID to the Offline-SSID "
"when the node has no connection to the selected Gateway."
msgstr ""
"Hier kannst du aktivieren, dass dein Knoten automatisch die SSID auf die "
"Offline-SSID ändert, wenn keine Verbindung zu Freifunk Servern besteht.<br /><br />"
"Das verhindert, dass Client-Geräte sich mit einem Knoten verbinden, an dem es "
"derzeit keine nutzbare Interverbindung gibt.<br />"
"Wenn in dieser Firmware der Suffix auf 'nodename' gestellt ist, dann kann man "
"leichter anhand der dann gesendeten Offline-SSID nach einem fehlerhaften Gerät "
"suchen."

View File

@ -0,0 +1,10 @@
msgid ""
msgstr "Content-Type: text/plain; charset=UTF-8"
msgid "Enabled"
msgstr ""
msgid ""
"Here you can enable to automatically change the SSID to the Offline-SSID "
"when the node has no connection to the selected Gateway."
msgstr ""

View File

@ -0,0 +1 @@
entry({"admin", "ssid-changer"}, model("admin/ssid-changer"), _("Offline-SSID"), 35)

View File

@ -0,0 +1,28 @@
local uci = require('simple-uci').cursor()
local util = require 'gluon.util'
local pkg_i18n = i18n 'gluon-ssid-changer'
local f = Form(pkg_i18n.translate('Offline-SSID'))
local s = f:section(Section, nil, pkg_i18n.translate(
'Here you can enable to automatically change the SSID to the Offline-SSID '
.. 'when the node has no connection to the selected Gateway.'
))
local enabled = s:option(Flag, 'enabled', pkg_i18n.translate('Enabled'))
enabled.default = uci:get_bool('ssid-changer', 'settings', 'enabled')
function f:write()
if enabled.data then
uci:section('ssid-changer', 'settings', 'settings', {
enabled = '1'
})
else
uci:set('ssid-changer', 'settings', 'enabled', '0')
end
uci:commit('ssid-changer')
end
return f

View File

@ -0,0 +1,21 @@
#!/usr/bin/lua
local site = require 'gluon.site'
local uci = require('simple-uci').cursor()
if site.ssid_changer ~= nil then
local site_enabled = site.ssid_changer.enabled() or '1'
uci:section('ssid-changer', 'settings', 'settings', {
enabled = uci:get('ssid-changer', 'settings', 'enabled') or site_enabled,
switch_timeframe = site.ssid_changer.switch_timeframe() or '30',
first = site.ssid_changer.first() or '5',
prefix = site.ssid_changer.prefix() or 'FF_Offline_',
suffix = site.ssid_changer.suffix() or 'nodename',
tq_limit_enabled = site.ssid_changer.tq_limit_enabled() or false,
tq_limit_max = site.ssid_changer.tq_limit_max() or 45,
tq_limit_min = site.ssid_changer.tq_limit_min() or 35,
})
uci:save('ssid-changer')
end

View File

@ -0,0 +1,180 @@
#!/bin/sh
#################
# safety checks #
#################
safety_exit() {
echo $1, exiting with error code 2
exit 2
}
pgrep -f autoupdater >/dev/null && safety_exit 'autoupdater running'
UT=$(sed 's/\..*//g' /proc/uptime)
[ $UT -gt 60 ] || safety_exit 'less than one minute'
[ $(find /var/run -name hostapd-phy* | wc -l) -gt 0 ] || safety_exit 'no hostapd-phy*'
# only once every timeframe minutes the SSID will change to the Offline-SSID
# (set to 1 minute to change immediately every time the router gets offline)
MINUTES="$(uci -q get ssid-changer.settings.switch_timeframe)"
: ${MINUTES:=30}
# the first few minutes directly after reboot within which an Offline-SSID always may be activated
# (must be <= switch_timeframe)
FIRST="$(uci -q get ssid-changer.settings.first)"
: ${FIRST:=5}
# the Offline-SSID will start with this prefix use something short to leave space for the nodename
# (no '~' allowed!)
PREFIX="$(uci -q get ssid-changer.settings.prefix)"
: ${PREFIX:='FF_Offline_'}
if [ "$(uci -q get ssid-changer.settings.enabled)" = '0' ]; then
DISABLED='1'
else
DISABLED='0'
fi
# generate the ssid with either 'nodename', 'mac' or to use only the prefix set to 'none'
SETTINGS_SUFFIX="$(uci -q get ssid-changer.settings.suffix)"
: ${SETTINGS_SUFFIX:='nodename'}
if [ $SETTINGS_SUFFIX = 'nodename' ]; then
SUFFIX="$(uname -n)"
# 32 would be possible as well
if [ ${#SUFFIX} -gt $((30 - ${#PREFIX})) ]; then
# calculate the length of the first part of the node identifier in the offline-ssid
HALF=$(( (28 - ${#PREFIX} ) / 2 ))
# jump to this charakter for the last part of the name
SKIP=$(( ${#SUFFIX} - $HALF ))
# use the first and last part of the nodename for nodes with long name
SUFFIX=${SUFFIX:0:$HALF}...${SUFFIX:$SKIP:${#SUFFIX}}
fi
elif [ $SETTINGS_SUFFIX = 'mac' ]; then
SUFFIX="$(uci -q get network.bat0.macaddr | /bin/sed 's/://g')"
else
# 'none'
SUFFIX=''
fi
OFFLINE_SSID="$PREFIX$SUFFIX"
# get all SSIDs (replace \' with TICX and back to keep a possible tic in an SSID)
ONLINE_SSIDs="$(uci show | grep wireless.client_radio[0-9]\. | grep ssid | awk -F '=' '{print $2}' | sed "s/\\\'/TICX/g" | tr \' \~ | sed "s/TICX/\\\'/g" ) "
# if for whatever reason ONLINE_SSIDs is NULL:
: ${ONLINE_SSIDs:="~FREIFUNK~"}
# temp file to count the offline incidents during switch_timeframe
TMP=/tmp/ssid-changer-count
if [ ! -f $TMP ]; then echo "0">$TMP; fi
OFF_COUNT=$(cat $TMP)
TQ_LIMIT_ENABLED="$(uci -q get ssid-changer.settings.tq_limit_enabled)"
# if true, the offline ssid will only be set if there is no gateway reacheable
# upper and lower limit to turn the offline_ssid on and off
# in-between these two values the SSID will never be changed to preven it from toggeling every Minute.
: ${TQ_LIMIT_ENABLED:='0'}
if [ $TQ_LIMIT_ENABLED = 1 ]; then
TQ_LIMIT_MAX="$(uci -q get ssid-changer.settings.tq_limit_max)"
# upper limit, above that the online SSID will be used
: ${TQ_LIMIT_MAX:='45'}
TQ_LIMIT_MIN="$(uci -q get ssid-changer.settings.tq_limit_min)"
# lower limit, below that the offline SSID will be used
: ${TQ_LIMIT_MIN:='35'}
# grep the connection quality of the currently used gateway
GATEWAY_TQ=$(batctl gwl | grep -e "^=>" -e "^\*" | awk -F '[('')]' '{print $2}' | tr -d " ")
if [ ! $GATEWAY_TQ ]; then
# there is no gateway
GATEWAY_TQ=0
fi
MSG="TQ is $GATEWAY_TQ, "
if [ $GATEWAY_TQ -ge $TQ_LIMIT_MAX ]; then
CHECK=1
elif [ $GATEWAY_TQ -lt $TQ_LIMIT_MIN ]; then
CHECK=0
else
# this is just get a clean run if we are in-between the grace periode
echo "TQ is $GATEWAY_TQ, do nothing"
exit 0
fi
else
MSG=""
CHECK="$(batctl gwl -H|grep -v "gateways in range"|wc -l)"
fi
UP=$(($UT / 60))
M=$(($UP % $MINUTES))
HUP_NEEDED=0
if [ "$CHECK" -gt 0 ] || [ "$DISABLED" = '1' ]; then
echo "node is online"
LOOP=1
# check status for all physical devices
for HOSTAPD in $(ls /var/run/hostapd-phy*); do
ONLINE_SSID="$(echo $ONLINE_SSIDs | awk -F '~' -v l=$((LOOP*2)) '{print $l}')"
LOOP=$((LOOP+1))
CURRENT_SSID="$(grep "^ssid=$ONLINE_SSID" $HOSTAPD | cut -d"=" -f2)"
if [ "$CURRENT_SSID" = "$ONLINE_SSID" ]; then
echo "SSID $CURRENT_SSID is correct, nothing to do"
break
fi
CURRENT_SSID="$(grep "^ssid=$OFFLINE_SSID" $HOSTAPD | cut -d"=" -f2)"
if [ "$CURRENT_SSID" = "$OFFLINE_SSID" ]; then
# set online
logger -s -t "gluon-ssid-changer" -p 5 $MSG"SSID is $CURRENT_SSID, change to $ONLINE_SSID"
sed -i "s~^ssid=$CURRENT_SSID~ssid=$ONLINE_SSID~" $HOSTAPD
# HUP here would be to early for dualband devices
HUP_NEEDED=1
else
logger -s -t "gluon-ssid-changer" -p 5 "could not set to online state: did neither find SSID '$ONLINE_SSID' nor '$OFFLINE_SSID'. Please reboot"
fi
done
elif [ "$CHECK" -eq 0 ]; then
echo "node is considered offline"
if [ $UP -lt $FIRST ] || [ $M -eq 0 ]; then
# set SSID offline, only if uptime is less than FIRST or exactly a multiplicative of switch_timeframe
if [ $UP -lt $FIRST ]; then
T=$FIRST
else
T=$MINUTES
fi
#echo minute $M, check if $OFF_COUNT is more than half of $T
if [ $OFF_COUNT -ge $(($T / 2)) ]; then
# node was offline more times than half of switch_timeframe (or than $FIRST)
LOOP=1
for HOSTAPD in $(ls /var/run/hostapd-phy*); do
ONLINE_SSID="$(echo $ONLINE_SSIDs | awk -F '~' -v l=$((LOOP*2)) '{print $l}')"
LOOP=$((LOOP+1))
CURRENT_SSID="$(grep "^ssid=$OFFLINE_SSID" $HOSTAPD | cut -d"=" -f2)"
if [ "$CURRENT_SSID" = "$OFFLINE_SSID" ]; then
echo "SSID $CURRENT_SSID is correct, nothing to do"
break
fi
CURRENT_SSID="$(grep "^ssid=$ONLINE_SSID" $HOSTAPD | cut -d"=" -f2)"
if [ "$CURRENT_SSID" = "$ONLINE_SSID" ]; then
# set offline
logger -s -t "gluon-ssid-changer" -p 5 $MSG"$OFF_COUNT times offline, SSID is $CURRENT_SSID, change to $OFFLINE_SSID"
sed -i "s~^ssid=$ONLINE_SSID~ssid=$OFFLINE_SSID~" $HOSTAPD
HUP_NEEDED=1
else
logger -s -t "gluon-ssid-changer" -p 5 "could not set to offline state: did neither find SSID '$ONLINE_SSID' nor '$OFFLINE_SSID'. Please reboot"
fi
done
fi
#else echo minute $M, just count $OFF_COUNT
fi
echo "$(($OFF_COUNT + 1))">$TMP
fi
if [ $HUP_NEEDED = 1 ]; then
# send HUP to all hostapd to load the new SSID
killall -HUP hostapd
HUP_NEEDED=0
echo "HUP!"
fi
if [ $M -eq 0 ]; then
# set counter to 0 if the timeframe is over
echo "0">$TMP
fi