airos-dfs-reset: add airos-dfs-reset

Ubiquitis airmax based gear does not fallback to original port after DFS
event is over. This tool triggers the fallback automatically by soft-restarting
unconditionally, whenever the configured freq differs from the running.

Signed-off-by: Simon Polack <spolack+git@mailbox.org>
This commit is contained in:
Simon Polack 2021-08-03 12:59:44 +02:00 committed by Polynomdivision
parent 3a29ecfcc9
commit e36e8a6a3b
4 changed files with 193 additions and 0 deletions

View File

@ -0,0 +1,46 @@
# SPDX-License-Identifier: GPL-2.0-only
#
# Copyright (C) 2021 Simon Polack <spolack+git@@mailbox.org>
#
include $(TOPDIR)/rules.mk
PKG_NAME:=airos-dfs-reset
PKG_VERSION:=1
PKG_RELEASE:=$(AUTORELEASE)
PKG_MAINTAINER:=Simon Polack <spolack+git@mailbox.org>
PKG_LICENSE:=GPL-2.0-only
include $(INCLUDE_DIR)/package.mk
define Package/airos-dfs-reset
SECTION:=utils
CATEGORY:=Utilities
TITLE:=Companion app for Ubiquity AirOS to help with DFS
PKGARCH:=all
EXTRA_DEPENDS:=dropbear
endef
define Package/airos-dfs-reset/description
Companion app for Ubiquity AirOS Gear to enforce fallback to original frequency after DFS event is over.
It works by soft-rebooting if running-frequency doesnt match the configured frequency.
endef
define Package/airos-dfs-reset/conffiles
/etc/config/airos-dfs-reset
endef
define Build/Compile
endef
define Package/airos-dfs-reset/install
$(INSTALL_DIR) $(1)/etc/init.d
$(INSTALL_BIN) ./files/airos-dfs-reset.init $(1)/etc/init.d/airos-dfs-reset
$(INSTALL_DIR) $(1)/usr/bin
$(INSTALL_BIN) ./files/airos-dfs-reset $(1)/usr/bin/airos-dfs-reset
$(INSTALL_DIR) $(1)/etc/config
$(INSTALL_DATA) ./files/airos-dfs-reset.config $(1)/etc/config/airos-dfs-reset
endef
$(eval $(call BuildPackage,airos-dfs-reset))

View File

@ -0,0 +1,114 @@
#!/bin/sh
. /lib/functions.sh
log() {
local msg="$1"
logger -t airos-dfs-reset -s "$msg"
}
rexec() {
local target="$1"
local username="$2"
local password="$3"
local cmd="$4"
raw=$(DROPBEAR_PASSWORD="$password" ssh -y $username@$target "$cmd")
ssh_result=$?
}
reset_dfs() {
local cmd="/usr/etc/rc.d/rc.softrestart force"
rexec $* "$cmd"
}
get_running_freq() {
local cmd="iwconfig ath0 | grep Frequency | awk -F ':' '{print \$3}' | awk '{print \$1}' | sed 's/\.//'"
rexec $* "$cmd"
# Append zeroes which are then cut to 4, we have to convert GHz into MHz
raw="$raw"000
running_freq=${raw:0:4}
}
get_target_freq() {
local cmd="grep 'radio.1.freq' /tmp/system.cfg | awk -F '=' '{ print \$2}'"
rexec $* "$cmd"
target_freq="$raw"
}
check_dfs() {
local target="$1"
local username="$2"
local password="$3"
get_running_freq $target $username $password
if [ "$ssh_result" != 0 ]; then
return
fi
get_target_freq $target $username $password
if [ "$ssh_result" != 0 ]; then
return
fi
log "Running freq: $running_freq - Target freq: $target_freq"
[ "$running_freq" == "$target_freq" ]
}
reset_allowed() {
local daytime_limit="$1"
local start="$(echo $daytime_limit | awk -F '-' '{print $1'})"
local end="$(echo $daytime_limit | awk -F '-' '{print $2'})"
local cur="$(date +%H)"
[ "$cur" -ge "$start" ] && [ "$cur" -le "$end" ]
}
handle_device() {
local device="$1"
config_get target "$device" target
config_get username "$device" username
config_get password "$device" password
config_get daytime_limit "$device" daytime_limit "0-23"
ssh_result=0
log "Checking Device $device"
check_dfs $target $username $password
freqmatch=$?
if [ "$ssh_result" != 0 ]; then
log "ssh exited non-zero - connect timeout?"
return
elif [ "$freqmatch" == 0 ]; then
log "Frequency is matching. No radar event fired"
else
log "Frequency doesnt match. Looks like DFS activity :("
if reset_allowed $daytime_limit; then
log "Initiating reset"
reset_dfs $target $username $password
log "Waiting $cfg_reset_sleep seconds after reset"
sleep $cfg_reset_sleep
else
log "Resetting is forbidden at this daytime"
fi
fi
}
main() {
log "started!"
config_load airos-dfs-reset
config_get cfg_interval general interval 600
config_get cfg_reset_sleep general reset_sleep 120
while :;
do
config_foreach handle_device device
sleep $cfg_interval
done
}
main

View File

@ -0,0 +1,15 @@
config airos-dfs-reset general
option interval '600' # Check every x seconds
option reset_sleep '120' # Sleep after reset to let routing protocols reconverge
config device 'sample_ap' # make sure to not use dashes in name
option target '192.168.1.20'
option username 'ubnt'
option password 'ubnt'
option daytime_limit '2-7' # .. from 2:xx to 7:xx reset is allowed
#config device 'sample_ap1'
# option target '10.31.81.21'
# option username 'ubnt'
# option password '...'
# option daytime_limit '0-23'

View File

@ -0,0 +1,18 @@
#!/bin/sh /etc/rc.common
USE_PROCD=1
START=95
STOP=01
start_service() {
procd_open_instance
procd_set_param command /usr/bin/airos-dfs-reset
procd_set_param stdout 0
procd_set_param stderr 0
procd_set_param user nobody
procd_close_instance
}
service_stopped() {
echo "airos-dfs-reset stopped!"
}