You could use a hotplug.d script on the network interface (/etc/hotplug.d/net), but for something like this I think a procd service script makes more sense as it should give you more control of the process. In particular you’ll want to make sure the service has appropriate triggers to restart when the AP is reconfigured.
For information on procd service scripts please take a look at:
[OpenWrt Wiki] procd init scripts - for general information on procd scripts
[OpenWrt Wiki] Create a sample procd init script - for a sample procd script
I have written a procd script in the past which watches the wireless configuration and runs a program if the desired interface is configured as an AP. I’ve modified this script to call the hostapd_cli program with your action script. Install this script as /etc/init.d/hostap-leds on the device. It should start on boot, and whenever a change is made to /etc/config/wireless or uci wireless any subsequent reload will stop and restart the service.
Note that we do not need to pass in the -B parameter to hostapd_cli_s1g here as procd scripts expect programs to run in the foreground (procd daemonises them for you). This allows redirection of stdout and stderr to the syslog, which you will be able to query with logread -e hostap-leds.
Note that I haven’t strictly tested this script as is. It is very lightly modified from a script which I know works. So I’m fairly confident it should get you most of the way forward.
#!/bin/sh /etc/rc.common
. /lib/netifd/netifd-wireless.sh
START=99
STOP=10
USE_PROCD=1
PROG=/sbin/hostapd_cli_s1g
ACTION_SCRIPT=/lib/functions/clientconnected.sh
SERVICE=hostap-leds
get_first_ifname() {
[ -n "$ifname" ] && return
json_get_vars ifname
json_select config
json_get_values networks "network"
json_select ..
}
wait_for_ifname() {
local radio=$1
local delay=${2-5}
local timeout=60
local start_time="$(date -u +%s)"
local end_time=
local elapsed=
while true; do
json_load "$(wifi status $radio)"
json_select $radio
for_each_interface "ap" get_first_ifname
[ -n "$ifname" ] && return 0;
end_time="$(date -u +%s)"
elapsed="$(($end_time-$start_time))"
if [ "$elapsed" -gt "$timeout" ]; then
return 1
fi
sleep $delay
done
}
start_cli() {
local cfg="$1"
local radio=$cfg
config_get_bool enabled "$cfg" 'dcs' 0
[ $enabled -ne 1 ] && return
config_get type "$cfg" 'type'
if [ "$type" != "morse" ]; then
logger -t $SERVICE -p daemon.crit "wireless.${cfg} not a morse device!"
return 1
fi
radiojs=$(wifi status $radio 2>/dev/null)
if [ $? -ne 0 ]; then
logger -t $SERVICE -p daemon.crit "Selected radio $radio does not exist!"
return 1
fi
json_load "$radiojs"
json_select $radio
json_get_vars disabled
set_default disabled 1
if [ "$disabled" -ne 0 ]; then
logger -t $SERVICE -p daemon.crit "$radio disabled"
return 1
fi
ifname=
networks=
if ! wait_for_ifname $radio; then
logger -t $SERVICE -p daemon.crit "Couldn't get ifname for ap on $radio"
return 1
fi
procd_open_instance $cfg.$ifname
procd_set_param command $PROG -i "$ifname" -a $ACTION_SCRIPT
procd_set_param file $ACTION_SCRIPT
procd_set_param netdev "$ifname"
procd_set_param stdout 1
procd_set_param stderr 1
procd_set_param respawn
procd_close_instance
}
start_service() {
config_load wireless
config_foreach start_cli wifi-device
}
service_triggers() {
procd_add_reload_trigger wireless
procd_add_reload_interface_trigger $networks
}