aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSimon Polack <spolack+git@mailbox.org>2021-08-03 12:59:44 +0200
committerPolynomdivision <vincent@systemli.org>2021-08-23 11:40:33 +0200
commite36e8a6a3ba5b5fe103b19f6aab9dc1af9a224fa (patch)
treecd0bfa1014d2875d99339dc4ff1df0a0fce3338e
parent3a29ecfcc900ed6f123d0e2bc966df7eda06f57b (diff)
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>
-rw-r--r--utils/airos-dfs-reset/Makefile46
-rw-r--r--utils/airos-dfs-reset/files/airos-dfs-reset114
-rw-r--r--utils/airos-dfs-reset/files/airos-dfs-reset.config15
-rw-r--r--utils/airos-dfs-reset/files/airos-dfs-reset.init18
4 files changed, 193 insertions, 0 deletions
diff --git a/utils/airos-dfs-reset/Makefile b/utils/airos-dfs-reset/Makefile
new file mode 100644
index 000000000..353795f82
--- /dev/null
+++ b/utils/airos-dfs-reset/Makefile
@@ -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))
diff --git a/utils/airos-dfs-reset/files/airos-dfs-reset b/utils/airos-dfs-reset/files/airos-dfs-reset
new file mode 100644
index 000000000..1d15c9140
--- /dev/null
+++ b/utils/airos-dfs-reset/files/airos-dfs-reset
@@ -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
diff --git a/utils/airos-dfs-reset/files/airos-dfs-reset.config b/utils/airos-dfs-reset/files/airos-dfs-reset.config
new file mode 100644
index 000000000..c718a525f
--- /dev/null
+++ b/utils/airos-dfs-reset/files/airos-dfs-reset.config
@@ -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'
diff --git a/utils/airos-dfs-reset/files/airos-dfs-reset.init b/utils/airos-dfs-reset/files/airos-dfs-reset.init
new file mode 100644
index 000000000..d75c5b95a
--- /dev/null
+++ b/utils/airos-dfs-reset/files/airos-dfs-reset.init
@@ -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!"
+}