mirror of
https://github.com/openwrt/packages.git
synced 2025-12-10 12:41:22 +00:00
wifischedule: completely overhaul the script
Squashed using these commits: - wifischedule: use `service` instead of direct path - wifischedule: use `sort -u` instead of `uniq` - wifischedule: restart cron only at the end of batch instead of after every change - wifischedule: remove `[[` bash-isms - wifischedule: trim trailing ws - wifischedule: reduce `if` blocks - wifischedule: quote variables and remove some more bash-isms - wifischedule: simplify _get_uci_value` - wifischedule: don't exit whole script just because `uci get somekey` fails somewhere - wifischedule: revamp `_should_enable_wifi()` - wifischedule: revamp `_format_daysofweek_list()` - wifischedule: revamp `_enable_wifi_schedule()` - wifischedule: minor refactoring - wifischedule: mega revamp - wifischedule: fixes - wifischedule: touch-ups - wifischedule: use only `awk` in `_cfg_list_entries()` to filter `uci` - wifischedule: improve code docs - wifischedule: inline `_crontab_format_dow_field()` - wifischedule: refactor `_crontab_append_line()` - wifischedule: add `_uci_bool()` and refactor `_arith_bool()` - wifischedule: rename some functions - wifischedule: refactor using shellcheck - wifischedule: refactor `_wifi_get_interfaces()` - wifischedule: refactor `_wifi_get_devices()` - wifischedule: shellcheck fixes - wifischedule: use logger instead of a logfile - wifischedule: refactor global consts - wifischedule: introduce main() func - wifischedule: bump version Signed-off-by: Jan Chren ~rindeal <dev.rindeal@gmail.com>
This commit is contained in:
committed by
Rosen Penev
parent
25c197c9ea
commit
fa9a6f7cd2
@@ -15,8 +15,8 @@
|
||||
include $(TOPDIR)/rules.mk
|
||||
|
||||
PKG_NAME:=wifischedule
|
||||
PKG_VERSION:=1.0.5
|
||||
PKG_RELEASE:=2
|
||||
PKG_VERSION:=1.1.0
|
||||
PKG_RELEASE:=0
|
||||
PKG_LICENSE:=PRPL
|
||||
|
||||
PKG_MAINTAINER:=Nils Koenig <openwrt@newk.it>
|
||||
|
||||
@@ -1,11 +1,13 @@
|
||||
#!/bin/sh
|
||||
#!/bin/ash
|
||||
# shellcheck shell=dash
|
||||
|
||||
# Copyright (c) 2016, prpl Foundation
|
||||
# Copyright ANNO DOMINI 2024 Jan Chren ~rindeal <dev.rindeal{a}gmail.com>
|
||||
#
|
||||
# Permission to use, copy, modify, and/or distribute this software for any purpose with or without
|
||||
# fee is hereby granted, provided that the above copyright notice and this permission notice appear
|
||||
# in all copies.
|
||||
#
|
||||
#
|
||||
# THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE
|
||||
# INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE
|
||||
# FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
|
||||
@@ -16,368 +18,411 @@
|
||||
|
||||
set -o pipefail
|
||||
|
||||
SCRIPT=$0
|
||||
LOCKFILE=/tmp/wifi_schedule.lock
|
||||
LOGFILE=/tmp/log/wifi_schedule.log
|
||||
LOGGING=0 #default is off
|
||||
PACKAGE=wifi_schedule
|
||||
GLOBAL=${PACKAGE}.@global[0]
|
||||
|
||||
SCRIPT="$0"
|
||||
PACKAGE="wifi_schedule"
|
||||
GLOBAL="${PACKAGE}.@global[0]"
|
||||
LOCKFILE="/tmp/${PACKAGE}.lock"
|
||||
LOGGING=0 #default is off
|
||||
|
||||
|
||||
# Converts the result of arithmetic expansion to a normal command return code
|
||||
# Usage: if _arith_bool $(( 3*4 > 12 && foo <= bar )) ...
|
||||
_arith_bool() { [ "$1" -ne 0 ] ;}
|
||||
|
||||
# Usage: if _uci_bool $(_uci_get_value "foo.bar") ...
|
||||
_uci_bool() { [ "$1" -eq 1 ] ;}
|
||||
|
||||
# Usage: _join_by_char , foo bar baz
|
||||
# Prints: `foo.bar,baz`
|
||||
_join_by_char()
|
||||
{
|
||||
local IFS
|
||||
IFS="$1"
|
||||
shift
|
||||
printf "%s" "$*"
|
||||
}
|
||||
|
||||
## Usage: _log [emerg, alert, crit, err, warning, notice, info, debug] "Message ..."
|
||||
_log()
|
||||
{
|
||||
if [ ${LOGGING} -eq 1 ]; then
|
||||
local ts=$(date)
|
||||
echo "$ts $@" >> ${LOGFILE}
|
||||
fi
|
||||
local severity="$1"
|
||||
shift
|
||||
_uci_bool "${LOGGING}" || return
|
||||
logger -t "${PACKAGE}" -p "user.${severity}" "$@"
|
||||
}
|
||||
|
||||
_exit()
|
||||
{
|
||||
local rc=$1
|
||||
lock -u ${LOCKFILE}
|
||||
exit ${rc}
|
||||
lock -u "${LOCKFILE}"
|
||||
exit "$1"
|
||||
}
|
||||
|
||||
_cron_restart()
|
||||
{
|
||||
/etc/init.d/cron restart > /dev/null
|
||||
}
|
||||
_uci_get_value_raw() { uci get "$1" 2> /dev/null ;}
|
||||
|
||||
_add_cron_script()
|
||||
_uci_get_value()
|
||||
{
|
||||
(crontab -l ; echo "$1") | sort | uniq | crontab -
|
||||
_cron_restart
|
||||
}
|
||||
|
||||
_rm_cron_script()
|
||||
{
|
||||
crontab -l | grep -v "$1" | sort | uniq | crontab -
|
||||
_cron_restart
|
||||
}
|
||||
|
||||
_get_uci_value_raw()
|
||||
{
|
||||
local value
|
||||
value=$(uci get $1 2> /dev/null)
|
||||
_uci_get_value_raw "$1"
|
||||
local rc=$?
|
||||
echo ${value}
|
||||
return ${rc}
|
||||
}
|
||||
|
||||
_get_uci_value()
|
||||
{
|
||||
local value
|
||||
value=$(_get_uci_value_raw $1)
|
||||
local rc=$?
|
||||
if [ ${rc} -ne 0 ]; then
|
||||
_log "Could not determine UCI value $1"
|
||||
return 1
|
||||
if [ "${rc}" -ne 0 ]; then
|
||||
_log "notice" "Could not determine UCI value '$1'"
|
||||
fi
|
||||
echo ${value}
|
||||
return "${rc}"
|
||||
}
|
||||
|
||||
_format_dow_list()
|
||||
_cfg_global_is_enabled() {
|
||||
local value
|
||||
value="$(_uci_get_value "${GLOBAL}.enabled")"
|
||||
_uci_bool "${value}"
|
||||
}
|
||||
|
||||
_cfg_global_is_unload_modules_enabled()
|
||||
{
|
||||
local dow=$1
|
||||
local flist=""
|
||||
local day
|
||||
for day in ${dow}
|
||||
local unload_modules
|
||||
unload_modules="$(_uci_get_value_raw "${GLOBAL}.unload_modules")" || return 1
|
||||
_uci_bool "${unload_modules}"
|
||||
}
|
||||
|
||||
# Prints: `entry1_name$'\n'entry2_name$'\n'...`
|
||||
_cfg_list_entries()
|
||||
{
|
||||
uci show "${PACKAGE}" | awk -F= '$2 == "entry" { n = split($1, a, "."); print a[n] }'
|
||||
}
|
||||
|
||||
_cfg_entry_is_enabled() {
|
||||
local value
|
||||
value="$(_uci_get_value "${PACKAGE}.${entry}.enabled")"
|
||||
_uci_bool "${value}"
|
||||
}
|
||||
|
||||
_cfg_entry_is_now_within_timewindow()
|
||||
{
|
||||
local entry="$1"
|
||||
local starttime stoptime daysofweek
|
||||
local nowdow nowhhmm nowts startts stopts
|
||||
starttime=$( _uci_get_value "${PACKAGE}.${entry}.starttime" ) || return 1
|
||||
stoptime=$( _uci_get_value "${PACKAGE}.${entry}.stoptime" ) || return 1
|
||||
daysofweek=$(_uci_get_value "${PACKAGE}.${entry}.daysofweek") || return 1
|
||||
|
||||
# check if day of week matches today
|
||||
nowdow="$(date +%A)"
|
||||
echo "${daysofweek}" | grep -q "${nowdow}" || return 1
|
||||
|
||||
nowhhmm="$(date "+%H:%M")"
|
||||
nowts=$( date -u +%s -d "${nowhhmm}")
|
||||
startts=$(date -u +%s -d "${starttime}")
|
||||
stopts=$( date -u +%s -d "${stoptime}")
|
||||
# add a day if stopts goes past midnight
|
||||
stopts=$(( stopts < startts ? stopts + 86400 : stopts ))
|
||||
|
||||
_arith_bool $(( nowts >= startts && nowts < stopts ))
|
||||
}
|
||||
|
||||
_cfg_can_wifi_run_now()
|
||||
{
|
||||
local entry
|
||||
for entry in $(_cfg_list_entries)
|
||||
do
|
||||
if [ ! -z ${flist} ]; then
|
||||
flist="${flist},"
|
||||
fi
|
||||
flist="${flist}${day:0:3}"
|
||||
test -n "${entry}" || continue
|
||||
_cfg_entry_is_enabled "${entry}" || continue
|
||||
_cfg_entry_is_now_within_timewindow "${entry}" && return 0
|
||||
done
|
||||
echo ${flist}
|
||||
return 1
|
||||
}
|
||||
|
||||
_cron_restart() { service cron restart > /dev/null ;}
|
||||
|
||||
_enable_wifi_schedule()
|
||||
# shellcheck disable=SC2312
|
||||
_crontab_append_line() { (crontab -l ; printf "%s\n" "$(_join_by_char ' ' "$@")") | crontab - ;}
|
||||
|
||||
## Usage: _crontab_rm_script_entries_by_arg # this removes all script entries
|
||||
## Usage: _crontab_rm_script_entries_by_arg recheck # this removes just entries with recheck argument
|
||||
_crontab_rm_script_entries_by_arg()
|
||||
{
|
||||
local entry=$1
|
||||
local starttime
|
||||
local stoptime
|
||||
starttime=$(_get_uci_value ${PACKAGE}.${entry}.starttime) || _exit 1
|
||||
stoptime=$(_get_uci_value ${PACKAGE}.${entry}.stoptime) || _exit 1
|
||||
# this loop will create regexp that looks like this:
|
||||
#
|
||||
# ^\b${SCRIPT}\b\s+\b${@}\b
|
||||
#
|
||||
local regex="(:?^|[[:space:]])${SCRIPT}"
|
||||
local arg
|
||||
for arg in "$@"
|
||||
do
|
||||
regex="${regex}[[:space:]]+${arg}"
|
||||
done
|
||||
regex="${regex}(:?$|[[:space:]])"
|
||||
|
||||
local dow
|
||||
dow=$(_get_uci_value_raw ${PACKAGE}.${entry}.daysofweek) || _exit 1
|
||||
crontab -l | awk -v cmd_col_pos=6 -v regex="${regex}" '
|
||||
{
|
||||
is_blank_or_comment = $0 ~ /^[[:space:]]*(:?#.*)?$/
|
||||
is_env_var = $0 ~ /^[[:space:]]*[a-zA-Z_][a-zA-Z0-9_]*[[:space:]]*=.*$/
|
||||
|
||||
# find index of the cmdline cell start
|
||||
match($0, "[[:space:]]*([^[:space:]]+[[:space:]]+){" cmd_col_pos - 1 "}")
|
||||
# get the cmdline cell
|
||||
cmdline = substr($0, RLENGTH + 1)
|
||||
|
||||
if ( is_blank_or_comment || is_env_var || cmdline !~ regex )
|
||||
print
|
||||
}' | crontab -
|
||||
}
|
||||
|
||||
_crontab_add_from_cfg_entry()
|
||||
{
|
||||
local entry="$1"
|
||||
local starttime stoptime daysofweek forcewifidown
|
||||
starttime=$( _uci_get_value "${PACKAGE}.${entry}.starttime" ) || return 1
|
||||
stoptime=$( _uci_get_value "${PACKAGE}.${entry}.stoptime" ) || return 1
|
||||
daysofweek=$( _uci_get_value "${PACKAGE}.${entry}.daysofweek") || return 1
|
||||
forcewifidown=$(_uci_get_value "${PACKAGE}.${entry}.forcewifidown")
|
||||
|
||||
local fdow=$(_format_dow_list "$dow")
|
||||
local forcewifidown
|
||||
forcewifidown=$(_get_uci_value ${PACKAGE}.${entry}.forcewifidown)
|
||||
# parse `HH:MM` to `Xhh` and `Xmm` variables
|
||||
local starthh stophh startmm stopmm
|
||||
starthh=$(echo "${starttime}" | cut -c 1-2) startmm=$(echo "${starttime}" | cut -c 4-5) || true
|
||||
stophh=$( echo "${stoptime}" | cut -c 1-2) stopmm=$( echo "${stoptime}" | cut -c 4-5) || true
|
||||
|
||||
local fdow
|
||||
# shellcheck disable=SC2046,SC2086
|
||||
fdow=$(_join_by_char "," $(printf "%.3s\n" ${daysofweek}))
|
||||
|
||||
if [ "${starttime}" != "${stoptime}" ]
|
||||
then
|
||||
_crontab_append_line "${startmm} ${starthh} * * ${fdow} ${SCRIPT} start ${entry}"
|
||||
fi
|
||||
|
||||
local stopmode="stop"
|
||||
if [ $forcewifidown -eq 1 ]; then
|
||||
if _uci_bool "${forcewifidown}" ; then
|
||||
stopmode="forcestop"
|
||||
fi
|
||||
|
||||
|
||||
local stop_cron_entry="$(echo ${stoptime} | awk -F':' '{print $2, $1}') * * ${fdow} ${SCRIPT} ${stopmode}" # ${entry}"
|
||||
_add_cron_script "${stop_cron_entry}"
|
||||
|
||||
if [[ $starttime != $stoptime ]]
|
||||
then
|
||||
local start_cron_entry="$(echo ${starttime} | awk -F':' '{print $2, $1}') * * ${fdow} ${SCRIPT} start" # ${entry}"
|
||||
_add_cron_script "${start_cron_entry}"
|
||||
fi
|
||||
_crontab_append_line "${stopmm} ${stophh} * * ${fdow} ${SCRIPT} ${stopmode} ${entry}"
|
||||
|
||||
return 0
|
||||
}
|
||||
|
||||
_is_earlier()
|
||||
_crontab_reset_from_cfg()
|
||||
{
|
||||
local hhmm=$1
|
||||
local ret=1
|
||||
if [[ $(date +%H) -lt ${hhmm:0:2} ]]
|
||||
then
|
||||
ret=0
|
||||
fi
|
||||
if [[ $(date +%H) -eq ${hhmm:0:2} && $(date +%M) -lt ${hhmm:3:4} ]]
|
||||
then
|
||||
ret=0
|
||||
fi
|
||||
echo $ret
|
||||
}
|
||||
|
||||
# returns 0 if now() is in $entry
|
||||
_check_startup_timewindow()
|
||||
{
|
||||
local entry=$1
|
||||
local starttime
|
||||
local stoptime
|
||||
local dow
|
||||
starttime=$(_get_uci_value ${PACKAGE}.${entry}.starttime) || _exit 1
|
||||
stoptime=$(_get_uci_value ${PACKAGE}.${entry}.stoptime) || _exit 1
|
||||
dow=$(_get_uci_value_raw ${PACKAGE}.${entry}.daysofweek) || _exit 1
|
||||
|
||||
echo $dow | grep $(date +%A) > /dev/null 2>&1
|
||||
rc=$?
|
||||
|
||||
if [[ $rc -eq 0 && $(date +%H) -ge ${starttime:0:2} && $(date +%M) -ge ${starttime:3:4} && $(_is_earlier $stoptime) -eq 0 ]]
|
||||
then
|
||||
echo 0
|
||||
else
|
||||
echo 1
|
||||
fi
|
||||
}
|
||||
|
||||
_get_wireless_interfaces()
|
||||
{
|
||||
iwinfo | grep ESSID | cut -f 1 -s -d" "
|
||||
_crontab_rm_script_entries_by_arg
|
||||
|
||||
_cfg_global_is_enabled || return
|
||||
|
||||
local entry
|
||||
for entry in $(_cfg_list_entries)
|
||||
do
|
||||
test -n "${entry}" || continue
|
||||
_cfg_entry_is_enabled "${entry}" || continue
|
||||
_crontab_add_from_cfg_entry "${entry}"
|
||||
done
|
||||
}
|
||||
|
||||
# region: kernel module unload feature
|
||||
|
||||
get_module_list()
|
||||
{
|
||||
local mod_list
|
||||
local _if
|
||||
for _if in $(_get_wireless_interfaces)
|
||||
for _if in $(_wifi_get_interfaces)
|
||||
do
|
||||
local mod=$(basename $(readlink -f /sys/class/net/${_if}/device/driver))
|
||||
local mod_dep=$(modinfo ${mod} | awk '{if ($1 ~ /depends/) print $2}')
|
||||
mod_list=$(echo -e "${mod_list}\n${mod},${mod_dep}" | sort | uniq)
|
||||
local mod mod_dep
|
||||
# trunk-ignore(shellcheck/SC2312)
|
||||
mod=$(basename "$(readlink -f "/sys/class/net/${_if}/device/driver")")
|
||||
mod_dep=$(modinfo "${mod}" | awk '$1 ~ /^depends:/ { print $2 }')
|
||||
mod_list=$(printf "%s\n%s,%s" "${mod_list}" "${mod}" "${mod_dep}" | sort -u)
|
||||
done
|
||||
echo $mod_list | tr ',' ' '
|
||||
# trunk-ignore(shellcheck/SC2250)
|
||||
echo "$mod_list" | tr ',' ' '
|
||||
}
|
||||
|
||||
save_module_list_uci()
|
||||
{
|
||||
local list=$(get_module_list)
|
||||
uci set ${GLOBAL}.modules="${list}"
|
||||
uci commit ${PACKAGE}
|
||||
local list
|
||||
list=$(get_module_list)
|
||||
uci set "${GLOBAL}.modules=${list}"
|
||||
uci commit "${PACKAGE}"
|
||||
}
|
||||
|
||||
_unload_modules()
|
||||
{
|
||||
local list=$(_get_uci_value ${GLOBAL}.modules)
|
||||
local retries
|
||||
retries=$(_get_uci_value ${GLOBAL}.modules_retries) || _exit 1
|
||||
_log "unload_modules ${list} (retries: ${retries})"
|
||||
local list retries
|
||||
list=$(_uci_get_value "${GLOBAL}.modules")
|
||||
retries=$(_uci_get_value "${GLOBAL}.modules_retries") || return 1
|
||||
_log "info" "unload_modules ${list} (retries: ${retries})"
|
||||
local i=0
|
||||
while [[ ${i} -lt ${retries} && "${list}" != "" ]]
|
||||
do
|
||||
i=$(($i+1))
|
||||
# trunk-ignore(shellcheck/SC2250)
|
||||
while _arith_bool $(( i < retries )) && test -n "$list"
|
||||
do
|
||||
: $(( i += 1 ))
|
||||
local mod
|
||||
local first=0
|
||||
for mod in ${list}
|
||||
do
|
||||
if [ $first -eq 0 ]; then
|
||||
if [ "${first}" -eq 0 ]; then
|
||||
list=""
|
||||
first=1
|
||||
fi
|
||||
rmmod ${mod} > /dev/null 2>&1
|
||||
if [ $? -ne 0 ]; then
|
||||
|
||||
if ! rmmod "${mod}" >/dev/null 2>&1 ; then
|
||||
# trunk-ignore(shellcheck/SC2250)
|
||||
list="$list $mod"
|
||||
fi
|
||||
done
|
||||
done
|
||||
}
|
||||
|
||||
|
||||
_load_modules()
|
||||
{
|
||||
local list=$(_get_uci_value ${GLOBAL}.modules)
|
||||
local retries
|
||||
retries=$(_get_uci_value ${GLOBAL}.modules_retries) || _exit 1
|
||||
_log "load_modules ${list} (retries: ${retries})"
|
||||
local list retries
|
||||
list=$( _uci_get_value "${GLOBAL}.modules") || return 1
|
||||
retries=$(_uci_get_value "${GLOBAL}.modules_retries") || return 1
|
||||
_log "info" "load_modules ${list} (retries: ${retries})"
|
||||
local i=0
|
||||
while [[ ${i} -lt ${retries} && "${list}" != "" ]]
|
||||
do
|
||||
i=$(($i+1))
|
||||
# trunk-ignore(shellcheck/SC2250)
|
||||
while _arith_bool $(( i < retries )) && test -n "$list"
|
||||
do
|
||||
: $(( i += 1 ))
|
||||
local mod
|
||||
local first=0
|
||||
for mod in ${list}
|
||||
do
|
||||
if [ $first -eq 0 ]; then
|
||||
if [ "${first}" -eq 0 ]; then
|
||||
list=""
|
||||
first=1
|
||||
fi
|
||||
modprobe ${mod} > /dev/null 2>&1
|
||||
rc=$?
|
||||
if [ $rc -ne 255 ]; then
|
||||
modprobe "${mod}" > /dev/null 2>&1
|
||||
rc=$?
|
||||
if [ "${rc}" -ne 255 ]; then
|
||||
# trunk-ignore(shellcheck/SC2250)
|
||||
list="$list $mod"
|
||||
fi
|
||||
done
|
||||
done
|
||||
}
|
||||
|
||||
_create_cron_entries()
|
||||
{
|
||||
local entries=$(uci show ${PACKAGE} 2> /dev/null | awk -F'.' '{print $2}' | grep -v '=' | grep -v '@global\[0\]' | uniq | sort)
|
||||
local _entry
|
||||
for entry in ${entries}
|
||||
do
|
||||
local status
|
||||
status=$(_get_uci_value ${PACKAGE}.${entry}.enabled) || _exit 1
|
||||
if [ ${status} -eq 1 ]
|
||||
then
|
||||
_enable_wifi_schedule ${entry}
|
||||
fi
|
||||
done
|
||||
}
|
||||
# endregion: kernel module unload feature
|
||||
|
||||
_should_wifi_enabled()
|
||||
{
|
||||
# Prints: `phy0-ap0$'\n'phy0-ap1$'\n'`
|
||||
_wifi_get_interfaces() { iwinfo | awk '/[^[:alnum:]]ESSID[^[:alnum:]]/ { print $1 }' ;}
|
||||
|
||||
local enable_wifi=0
|
||||
local entries=$(uci show ${PACKAGE} 2> /dev/null | awk -F'.' '{print $2}' | grep -v '=' | grep -v '@global\[0\]' | uniq | sort)
|
||||
local _entry
|
||||
for _entry in ${entries}
|
||||
# Prints: `radio0$'\n'radio1$'\n'`
|
||||
_wifi_get_devices() { uci show "wireless" | awk -F= '$2 == "wifi-device" { n = split($1, a, "."); print a[n] }' ;}
|
||||
|
||||
_wifi_rfkill_set_all_to()
|
||||
{
|
||||
local status="$1"
|
||||
_arith_bool $(( status == 0 || status == 1 )) || return 1
|
||||
for radio in $(_wifi_get_devices)
|
||||
do
|
||||
local status
|
||||
status=$(_get_uci_value ${PACKAGE}.${_entry}.enabled) || _exit 1
|
||||
if [ ${status} -eq 1 ]
|
||||
then
|
||||
enable_wifi=$(_check_startup_timewindow $_entry)
|
||||
fi
|
||||
uci set "wireless.${radio}.disabled=${status}"
|
||||
done
|
||||
echo ${enable_wifi}
|
||||
uci commit
|
||||
/sbin/wifi
|
||||
}
|
||||
|
||||
startup()
|
||||
{
|
||||
_log "startup"
|
||||
local global_enabled=$(_get_uci_value ${GLOBAL}.enabled) || _exit 1
|
||||
if [ ${global_enabled} -eq 1 ]; then
|
||||
local _enable_wifi=$(_should_wifi_enabled)
|
||||
if [ ${_enable_wifi} -eq 0 ]; then
|
||||
_log "enable wifi"
|
||||
enable_wifi
|
||||
else
|
||||
_log "disable wifi"
|
||||
disable_wifi
|
||||
fi
|
||||
fi
|
||||
}
|
||||
_wifi_rfkill_unblock_all() { _wifi_rfkill_set_all_to 0 ;}
|
||||
_wifi_rfkill_block_all() { _wifi_rfkill_set_all_to 1 ;}
|
||||
|
||||
check_cron_status()
|
||||
wifi_disable()
|
||||
{
|
||||
local global_enabled
|
||||
global_enabled=$(_get_uci_value ${GLOBAL}.enabled) || _exit 1
|
||||
_rm_cron_script "${SCRIPT}"
|
||||
if [ ${global_enabled} -eq 1 ]; then
|
||||
_create_cron_entries
|
||||
fi
|
||||
}
|
||||
|
||||
disable_wifi()
|
||||
{
|
||||
_rm_cron_script "${SCRIPT} recheck"
|
||||
_set_status_wifi_uci 1
|
||||
local unload_modules
|
||||
unload_modules=$(_get_uci_value_raw ${GLOBAL}.unload_modules) || _exit 1
|
||||
if [[ "${unload_modules}" == "1" ]]; then
|
||||
_crontab_rm_script_entries_by_arg "recheck"
|
||||
_cron_restart
|
||||
_wifi_rfkill_block_all
|
||||
if _cfg_global_is_unload_modules_enabled
|
||||
then
|
||||
_unload_modules
|
||||
fi
|
||||
fi
|
||||
}
|
||||
|
||||
soft_disable_wifi()
|
||||
wifi_soft_disable()
|
||||
{
|
||||
local _disable_wifi=0 #0: disable wifi, 1: do not disable wifi
|
||||
local iwinfo=/usr/bin/iwinfo
|
||||
if [ ! -e ${iwinfo} ]; then
|
||||
_log "${iwinfo} not available, skipping"
|
||||
if ! command -v iwinfo >/dev/null 2>&1 ; then
|
||||
_log "info" "iwinfo not available, skipping"
|
||||
return 1
|
||||
fi
|
||||
|
||||
local ignore_stations=$(_get_uci_value_raw ${GLOBAL}.ignore_stations)
|
||||
[ -n "${ignore_stations}" ] && _log "Ignoring station(s) ${ignore_stations}"
|
||||
local has_assoc=false
|
||||
local mac_filter='([[:xdigit:]]{1,2}:){5}[[:xdigit:]]{1,2}'
|
||||
|
||||
local ignore_stations ignore_stations_filter
|
||||
ignore_stations=$(_uci_get_value_raw "${GLOBAL}.ignore_stations")
|
||||
# shellcheck disable=SC2086
|
||||
ignore_stations_filter=$(_join_by_char "|" ${ignore_stations})
|
||||
|
||||
# check if no stations are associated
|
||||
local _if
|
||||
for _if in $(_get_wireless_interfaces)
|
||||
for _if in $(_wifi_get_interfaces)
|
||||
do
|
||||
local stations=$(${iwinfo} ${_if} assoclist | grep -o -E '([[:xdigit:]]{1,2}:){5}[[:xdigit:]]{1,2}')
|
||||
local stations ignored_stations
|
||||
stations=$(iwinfo "${_if}" assoclist | grep -o -E "${mac_filter}")
|
||||
if [ -n "${ignore_stations}" ]; then
|
||||
stations=$(echo "${stations}" | grep -vwi -E "${ignore_stations// /|}")
|
||||
local all_stations="${stations}"
|
||||
# shellcheck disable=SC2086
|
||||
stations=$(printf "%s\n" ${stations} | grep -vwi -E "${ignore_stations_filter}")
|
||||
# shellcheck disable=SC2086
|
||||
ignored_stations="$(printf "%s\n" ${all_stations} ${stations} | sort | uniq -u)"
|
||||
fi
|
||||
|
||||
if [ -n "${stations}" ]; then
|
||||
_disable_wifi=1
|
||||
_log "Station(s) $(echo ${stations}) associated on ${_if}"
|
||||
test -n "${stations}" || continue
|
||||
|
||||
has_assoc=true
|
||||
|
||||
# shellcheck disable=SC2086
|
||||
_log "info" "Clients connected on '${_if}': $(_join_by_char ' ' ${stations})" || true
|
||||
if test -n "${ignored_stations}"
|
||||
then
|
||||
# shellcheck disable=SC2086
|
||||
_log "info" "Clients ignored on '${_if}': $(_join_by_char ' ' ${ignored_stations})" || true
|
||||
fi
|
||||
done
|
||||
|
||||
local _wifi_enabled=$(_should_wifi_enabled)
|
||||
if [[ ${_disable_wifi} -eq 0 && ${_wifi_enabled} -eq 1 ]]; then
|
||||
_log "No stations associated, disable wifi."
|
||||
disable_wifi
|
||||
elif [[ ${_disable_wifi} -eq 0 && ${_wifi_enabled} -eq 0 ]]; then
|
||||
_log "Do not disable wifi since there is an allow timeframe, skip rechecking."
|
||||
_rm_cron_script "${SCRIPT} recheck"
|
||||
_crontab_rm_script_entries_by_arg "recheck"
|
||||
|
||||
if [ "${has_assoc}" = "false" ]
|
||||
then
|
||||
if _cfg_can_wifi_run_now
|
||||
then
|
||||
_log "info" "Do not disable wifi since there is an allow timewindow, skip rechecking."
|
||||
else
|
||||
_log "notice" "No stations associated, disable wifi."
|
||||
wifi_disable
|
||||
fi
|
||||
else
|
||||
_log "Could not disable wifi due to associated stations, retrying..."
|
||||
local recheck_interval=$(_get_uci_value ${GLOBAL}.recheck_interval)
|
||||
_add_cron_script "*/${recheck_interval} * * * * ${SCRIPT} recheck"
|
||||
_log "notice" "Could not disable wifi due to associated stations, retrying..."
|
||||
local recheck_interval
|
||||
recheck_interval=$(_uci_get_value "${GLOBAL}.recheck_interval")
|
||||
if test -n "${recheck_interval}" && _arith_bool $(( recheck_interval > 0 )) ; then
|
||||
_crontab_append_line "*/${recheck_interval} * * * * /bin/nice -n 19 ${SCRIPT} recheck"
|
||||
fi
|
||||
fi
|
||||
|
||||
_cron_restart
|
||||
}
|
||||
|
||||
_set_status_wifi_uci()
|
||||
wifi_enable()
|
||||
{
|
||||
local status=$1
|
||||
local radios=$(uci show wireless | grep radio | awk -F'.' '{print $2}' | grep -v '[=|@]' | sort | uniq)
|
||||
for radio in ${radios}
|
||||
do
|
||||
uci set wireless.${radio}.disabled=${status}
|
||||
done
|
||||
uci commit
|
||||
}
|
||||
|
||||
enable_wifi()
|
||||
{
|
||||
_rm_cron_script "${SCRIPT} recheck"
|
||||
local unload_modules
|
||||
unload_modules=$(_get_uci_value_raw ${GLOBAL}.unload_modules) || _exit 1
|
||||
if [[ "${unload_modules}" == "1" ]]; then
|
||||
_crontab_rm_script_entries_by_arg "recheck"
|
||||
_cron_restart
|
||||
if _cfg_global_is_unload_modules_enabled
|
||||
then
|
||||
_load_modules
|
||||
fi
|
||||
_set_status_wifi_uci 0
|
||||
/sbin/wifi
|
||||
_wifi_rfkill_unblock_all
|
||||
}
|
||||
|
||||
wifi_startup()
|
||||
{
|
||||
_cfg_global_is_enabled || return
|
||||
|
||||
if _cfg_can_wifi_run_now
|
||||
then
|
||||
_log "notice" "enable wifi"
|
||||
wifi_enable
|
||||
else
|
||||
_log "notice" "disable wifi"
|
||||
wifi_disable
|
||||
fi
|
||||
}
|
||||
|
||||
usage()
|
||||
{
|
||||
echo ""
|
||||
echo "$0 cron|start|startup|stop|forcestop|recheck|getmodules|savemodules|help"
|
||||
echo ""
|
||||
echo " UCI Config File: /etc/config/${PACKAGE}"
|
||||
@@ -394,34 +439,40 @@ usage()
|
||||
echo ""
|
||||
}
|
||||
|
||||
# shellcheck disable=SC2317
|
||||
_cleanup()
|
||||
{
|
||||
lock -u ${LOCKFILE}
|
||||
rm ${LOCKFILE}
|
||||
lock -u "${LOCKFILE}"
|
||||
rm "${LOCKFILE}"
|
||||
}
|
||||
|
||||
###############################################################################
|
||||
# MAIN
|
||||
###############################################################################
|
||||
trap _cleanup EXIT
|
||||
main() {
|
||||
trap _cleanup EXIT
|
||||
|
||||
LOGGING=$(_get_uci_value ${GLOBAL}.logging) || _exit 1
|
||||
_log ${SCRIPT} $1 $2
|
||||
lock ${LOCKFILE}
|
||||
LOGGING=$(_uci_get_value "${GLOBAL}.logging") || _exit 1
|
||||
_log "info" "${SCRIPT}" "$@"
|
||||
lock "${LOCKFILE}"
|
||||
|
||||
case "$1" in
|
||||
cron)
|
||||
check_cron_status
|
||||
startup
|
||||
;;
|
||||
start) enable_wifi ;;
|
||||
startup) startup ;;
|
||||
forcestop) disable_wifi ;;
|
||||
stop) soft_disable_wifi ;;
|
||||
recheck) soft_disable_wifi ;;
|
||||
getmodules) get_module_list ;;
|
||||
savemodules) save_module_list_uci ;;
|
||||
help|--help|-h|*) usage ;;
|
||||
esac
|
||||
case "$1" in
|
||||
cron)
|
||||
_crontab_reset_from_cfg
|
||||
_cron_restart
|
||||
wifi_startup
|
||||
;;
|
||||
start) wifi_enable ;;
|
||||
startup) wifi_startup ;;
|
||||
forcestop) wifi_disable ;;
|
||||
stop) wifi_soft_disable ;;
|
||||
recheck) wifi_soft_disable ;;
|
||||
getmodules) get_module_list ;;
|
||||
savemodules) save_module_list_uci ;;
|
||||
help|--help|-h|*) usage ;;
|
||||
esac
|
||||
|
||||
_exit 0
|
||||
_exit 0
|
||||
}
|
||||
|
||||
main "${@}"
|
||||
|
||||
Reference in New Issue
Block a user