GPIO LED control

using 2.5.3 sdk. Our board 7688/silex board has LEDs configured w/ red using gpio44, blue gpio18, green gpio19. Main question: How to capture a halow connection/disconnection to control the LEDs? We want green on/red off for halow connected, green off/red on for halow not connected.

I can use this in dts and I can see green when halow connects:

            led_green: green { 
                   label = "green:sys"; 
                   gpios = <&gpio 19 GPIO_ACTIVE_HIGH>; 
                   linux,default-trigger = "phy3assoc";
           }; 

Howeverā€¦this works only if the halow radio is using phy3. This doesnā€™t work because if we load the image, the green triggers have phy1 for phy1radio, phy1assoc, phy1rx, phy1tx, but right after running the wizard, the green triggers change from phy1 to phy3. So, yes, the green led will go on when halow connects as itā€™s associated with phy3 after running wizard the first time. BUTā€¦if we software reboot, then it boots as phy2 and, thus, even though luci shows connected halow, the green wonā€™t go on since its trigger is phy3. (this is the list of triggers after reboot: [none] switch0 timer heartbeat default-on netdev phy0rx phy0tx phy0assoc phy0radio phy0tpt usbport mmc0 phy2rx phy2tx phy2assoc phy2radio).

So, since this method seems unreliable, unless thereā€™s a way to control that, is there any other way to know when halow connects/disconnects so we can control the led ourselves through led on/off of any colors we want? Some file that handles events? A script that runs based on an event?

From the 2.5.3 sdk Iā€™ve been trying to figure out how morse does the led for ekh03-05 kit for changing the various colors of the led (including yellow, the combo of red & green). How are events captured? How do you control it? I only saw green led defined in the ekh0304 dts file and havenā€™t been able to find where other led controls are for your kit.

Hi Don,

As of the 2.5.3 Morse Micro SDK release, the EKH03 used the simple LED aliases as defined by OpenWrts /etc/diag.sh script. There are 4 LED aliases defined by default in OpenWrt: boot, failsafe, upgrade, and running. Youā€™ll see these aliases mapped in devicetree as

aliases {
	led-boot = &led_boot;
	led-failsafe = &led_failsafe;
	led-dpp = &led_failsafe;
	led-running = &led_boot;
	led-upgrade = &led_upgrade;
	label-mac-device = &wmac;
};

A very brief summary of the default states used by OpenWrt:

  • The boot state is set in /lib/preinit/10_indicate_preinit and configures led-boot to flash.
  • The failsafe state is set in /lib/preinit/10_indicate_failsafe and configures led-failsafe to flash.
  • The upgrade state is set in /lib/upgrade/common.sh and configures led-upgrade to flash
  • The done state is set in /etc/init.d/done (which is the last service started by procd), and configures led-running to the on state.

I would recommend reading through /etc/diag.sh and /lib/functions/leds.sh for further info on those default LED states.

There is a non-standard OpenWrt LED alias defined in that list, led-dpp, which was added by Morse Micro. Youā€™ll see this LED is used in a script wpa_s1g_dpp_action.sh deployed by the netifd-morse package. Through a few layers of application, this script is called in response to DPP events seen on the wpa_supplicant and hostapd control sockets. I donā€™t want to spend too much time in the details of this LED though, as it is a little application specific and we are changing how this LED is driven in later versions.


To finally answer your question as specific to your application. OpenWrt has a number of ways to configure LEDs of different functions. Normally, when phy interface numbers remain static, routers will set the intended functionality through UCI via a special board.d script which builds device configuration at first boot. See for example, target/linux/ramips/mt76x8/base-files/etc/board.d/01_leds which defines some netdev triggered LEDs.

However, given that the Morse Micro driver module is sometimes reinserted - the phy number does change. These reinsertions are sometimes necessary while we have to self-manage the 802.11ah regulatory domains.
To handle this, you may want to consider leveraging a hotplug script, instead of UCI, to set this LED state when the new phy is created. Unfortunately, ieee80211 hotplug events do not appear to be documented in the above link, but most ramips targets deploy one you could use as a starting reference - see target/linux/ramips/mt76x8/base-files/etc/hotplug.d/ieee80211/10_fix_wifi_mac.

With an ieee80211 hotplug script reacting to $ACTION == "add", you could then simply extract the phy number as done in 10_fix_wifi_mac, and set your led triggers directly using Linux sysfs. You may want to also look at how /lib/functions/leds.sh configures LEDs using sysfs.

I realise thatā€™s a very long response to your questions, but I hope it has helped! If you need more clarification, or assistance with the hotplug script and device tree configuration feel free to ask!

Hi, Arien. I appreciate the response and details. You mentioned it being a long response ā€“ long is GOOD. I appreciate every detail and this was helpful. And it was a prompt response, too, which I also appreciate. Just being frank here: itā€™s been a bit frustrating with the amount of time it takes to get support response from morse support staff. While there have been a few very useful tidbits, itā€™s (understand from my perspective) been very frustrating when there are no responses. Not dumping on you, just mentioning, and back to appreciating your timely response.

With this info, I was able to get an outside tip on how to identify which phyn is used based on the driver reinsertion (adding code in /lib/netifd/wireless/morse.sh, which it seems that script file is gone through when thereā€™s a halow connect or disconnect. That new code determined the other phyn besides 0 and did: echo ā€œ$led_trigā€ > /sys/class/leds/red:sys/trigger) and between that and defining the red led in the dts to be inverted from the green led, I can use the same phynassoc trigger on both leds for the client. Thus, the green led lights when halow connected, red when halow disconnected. This is a single led controlled by rgb on 3 gpio pins, so I need the proper coordination.

Related to this, and continuing this topic, the green led on the client device turns on when halow connects and I can see the events in the debug log using teraterm showing this process until it shows wlan0 associated, but nothing like that happens on the ap. Iā€™d like the ap to also have its led turn green when any clients are connected. That can be 1ā€¦n, is that right? The log in the debug output off the uart is the same log you see from ā€œdmesg logā€. On the AP, no events happen in this log during halow connect or disconnect. However, use ā€œlogreadā€ and you see these other messages that show AP-STA connected or disconnected. I donā€™t know where those are coming from.

The question is, on the AP, how can I know that there was a client connect or disconnect and how would I know how many clients are connected (if thatā€™s applicable)? Iā€™d like to be able to control the led from this.

Any idea?

Don

Happy to help Don!

/lib/netifd/wireless/morse.sh, which it seems that script file is gone through when thereā€™s a halow connect or disconnect.

If this script suits your needs, then modifying the script there should be sufficient! I would clarify by saying that this script is called by the netifd service daemon on OpenWrt which is typically re-triggered when the configuration changes.

I have a personal preference for hotplug.d scripts, as they can be then treated as separate packages - which may help with feature management. So would recommend you have a look at that avenue too! The events in these hotplug scripts wonā€™t necessarily correlate with the same events triggering functions in morse.sh. So can appreciate if they donā€™t suit your needs.

use ā€œlogreadā€ and you see these other messages that show AP-STA connected or disconnected. I donā€™t know where those are coming from.

These events will be coming from hostapd_s1g which is responsible for handling the HaLow AP functionality on the interface.

Iā€™d like the ap to also have its led turn green when any clients are connected. That can be 1ā€¦n, is that right?

There are going to be a few different ways to implement this, and I might refrain from pointing out a specific approach as ā€œidealā€, as they all will have their own tradeoffs.

Thereā€™s also an extra complexity here in that existing associated clients may leave the network without cleanly disassociating from the AP. So while you should be able to react quite quickly to association events, in some cases there may not be a clear disassociation event - and in some cases it may be simpler to periodically poll the list of associated stations.

Lots of words there without clear direction! For detecting association, the three options which come to mind immediately for me are:

  • write an application which listens to events on the hostapd control socket, then probably wrap this in a procd service so it runs on boot. You will need to check wpa_supplicant / hostapd: hostapd control interface for information on the events advertised on the control socket. Iā€™m not aware of any examples internally leveraging this directly. I will look!
  • You might be able to leverage ubus to capture some of these events as well. Unfortunately, because weā€™ve had to provide a modified hostapd for HaLow support, our hostapd_s1g is missing some of the helpful ubus hooks - ie those described on this page. So you may be limited to the iwinfo object.
  • Poll a utility like iwinfo wlan0 assoclist or itā€™s ubus equivalent to check associated stations. This is probably the wrong approach for detecting association, but it may be the most reliable for keeping track of a total list of associated stations, especially if they leave without sending an appropriate frame to disassociate - polling will capture those stations which time out. The iwinfo ubus endpoint does work fine for the HaLow interfaces.

Iā€™ll see if I can work up an example for a couple of the above for you. Not sure Iā€™ll be able to provide an example quickly though. Hopefully these pointers give a good place to start!

Thanks, Arien. Again, appreciate your details and responsiveness. This gives me some things to chew on. As you know, resources are somewhat limited regarding openwrt and especially when incorporating new tech like halow. Thus, itā€™s important to ask yā€™all for details to help understand.

And, yes, as you get some moments, examples are always excellent and sometimes vital. Sometimes you may understand what the problem is and know what you need to do but not know ā€œhowā€ to do it.

Regards,

Don

Arien, in a very related but slightly different issue on this topic weā€™re discussing, going to your first reply below for the morse.sh script, hereā€™s something thatā€™s happening when I turn the halow radio off then back on. In the morse.sh script, itā€™s able to set the led triggers based on the current phy[n]assoc when the halow radio comes up, authenticates and associates. Our led goes green when that assoc happens, red when it goes away (the red is active low, green active high so on the same trigger, they go opposite).

Hereā€™s the problem I found. Refer to the attached pic then continue after viewing that.

Then, click the enable button on that 2nd line to start the radio back up again. Debug log shows things starting back up, authenticating and associating. The led turns green then a few seconds later, the associated stations in luci shows the ap information.

The bad: usually the led stays green, but sometimes, after 3 seconds, the led turns red, but luci still shows the associated station.

I found something in the log using ā€˜logreadā€™ (which gives more info than the dmesg log which is simply the interactive output to the uart for teraterm). Right after the ā€œwlan0: link becomes readyā€ line, in the following log items, whenever the line that looks like ā€œThu Nov 14 01:29:20 2024 user.notice root: Prplmesh is disabledā€ is in the log at that spot below, the led goes from green to red 3 seconds after it turns green. Makes total sense when you look at the timestamps of the log items. When that line isnā€™t there, the led stays green.

The log:

(As reference, after this line happens, green led immediately goes on)

Thu Nov 14 01:29:17 2024 kern.info kernel: [10976.730262] IPv6: ADDRCONF(NETDEV_CHANGE): wlan0: link becomes ready

(Then, each of these next entries are in all logs, except the prplmesh disabled ā€“ thatā€™s only in the one where the led turned red. Thereā€™s some delay due to that because in the logs that green stayed on, the timestamp for all below are on the same second. Note how this happened 3 seconds after the led turned green, exactly what I counted when the led went re)

Thu Nov 14 01:29:17 2024 daemon.notice netifd: ahwlan (20405): udhcpc: started, v1.36.1
Thu Nov 14 01:29:17 2024 daemon.notice netifd: ahwlan (20405): udhcpc: broadcasting discover
Thu Nov 14 01:29:20 2024 user.notice root: Prplmesh is disabled
Thu Nov 14 01:29:20 2024 daemon.notice netifd: ahwlan (20405): udhcpc: broadcasting discover
Thu Nov 14 01:29:20 2024 daemon.notice netifd: ahwlan (20405): udhcpc: broadcasting select for 192.168.1.194, server 192.168.1.1
Thu Nov 14 01:29:20 2024 daemon.notice netifd: ahwlan (20405): udhcpc: lease of 192.168.1.194 obtained from 192.168.1.1, lease time 43200
Thu Nov 14 01:29:20 2024 daemon.notice netifd: Interface 'ahwlan' is now up

MORE INFO:

When I do ā€œuci showā€, it includes this in the output:

prplmesh.config.enable='0'

Was curious because when I did a grep for ā€œPrplmesh is disabledā€, the file ./feeds/prpl/prplmesh/files/etc/init.d/prplmesh came up and has the following routine:

start_service() {
    if [ "$(uci get prplmesh.config.enable 2>/dev/null)" = "1" ]; then
        start_agent_monitor
        procd_open_instance
        procd_set_param command /opt/prplmesh/scripts/prplmesh.init start
        procd_set_param stdout 1
        procd_set_param stderr 1
        procd_close_instance
    else
        logger "Prplmesh is disabled"
    fi
}

So, whatever is calling this start_service is then displaying that message. And it only calls this for whatever reason and because of that, turns the led red from green. And, both green and red are triggered by the phy[n]assoc itā€™s set to, as it shows when it just happened again:

root@ep-hilink-d94cda:/# cat /sys/devices/platform/leds/leds/green:sys/trigger
none switch0 timer heartbeat default-on netdev phy0rx phy0tx phy0assoc phy0radio phy0tpt usbport mmc0 phy32rx phy32tx [phy32assoc] phy32radio
root@ep-hilink-d94cda:/# cat /sys/devices/platform/leds/leds/red:sys/trigger
none switch0 timer heartbeat default-on netdev phy0rx phy0tx phy0assoc phy0radio phy0tpt usbport mmc0 phy32rx phy32tx [phy32assoc] phy32radio

I couldnā€™t find where start_service was called when I did a grep on the project.

So, what is it doing that makes the led go red but still shows in luci that halow is connected with the entry in the associated stations list?

Does all that make sense?

Don

(attachments)

Arien, I just sent a reply to below with some detailed specifics and your system bounced it back as being objectionable. There was nothing in there objectionable, abusive, or related. Iā€™ll try the short version; if you want more detail, let me know how to get it to you.

Itā€™s about an issue with the led going from green to red in 3 secs after I re-enable the halow radio after having disabled it. It doesnā€™t happen every time, though. Most of the time, the led goes and stays green right after we connect halow. Our led goes green when halow is associated, red when halow drops out. But, thereā€™s a line in the log that only appears when something turns the led red after it went green for 3 secs: ā€œThu Nov 14 06:11:55 2024 user.notice root: Prplmesh is disabledā€. Itā€™s not like the halow connection dropped, as luci still shows it connected to the ap.

If you need more details, I can provide but thatā€™s the short version. Just tell me how to provide so my note doesnā€™t get rejected by your system. But that line in the log is the one thing thatā€™s consistent as itā€™s only there whenever it turns the led red after 3 secs.

Regards,

Don

Don-
Weā€™re still tuning the content filters around here. Iā€™ve approved that post.
-Zandr

Hi Don,

I took the liberty of wrapping some bits of your reply in code blocks.

Answering some questions which Iā€™ve inferred from your post; feel free to clarify if Iā€™ve misunderstood anything youā€™ve asked.

What is calling start_service?

start_service is being called by procd which is OpenWrtā€™s service management daemon. Similar to systemd on some Linux desktop distributions. procd will trigger a service restart for many reasons:

  • A script has called service prplmesh start or service prplmesh restart
  • The service has a dependency on another service, and is re-triggering as a result of another service.
  • The service has a dependency on a configuration file which has changed eg /etc/config/wireless

In particular, for prplmesh, the following line in the service script tells procd it should trigger a reload on change to specific configuration files.

procd_add_reload_trigger "prplmesh" "network" "wireless"

See this link and this link for more about procd.

what is it doing that makes the led go red but still shows in luci that halow is connected with the entry in the associated stations list?

From the logs shown, I think we can safely say the device is associated. It has a DHCP lease so there is network activity. Iā€™m generally trustworthy of Linux sysfs functionality - like the phyNassoc LED trigger, as it is relatively simple and hooked directly into mac80211. So wonā€™t look for bugs in that area, yet.

I would take the prplmesh line in logread as a hint that procd has reloaded a number of services. If this line is not showing in other logs, then thereā€™s possibly more services reloading than expected.

Early versions of our morse.sh script did aggressively reinsert the driver which would trigger a phy number change. Iā€™m skeptical that this is actually the problem, as I would not expect the LED trigger file to show phy number selected if that phy did not exist.
Can you verify the phy number of the HaLow interface matches the phy specified in the trigger file?

Can share exactly where in the morse.sh file you added the lines to set the trigger?

Good morning, Arien. Good info, thanks.

As I was preparing to answer your questions this morning, I was double checking some stuff. That code you asked about that was added morse.sh? Well, I put it in morse.sh, but I realized I had put it in /lib/wifi/morse.sh and meant to put it in /lib/netifd/wireless/morse.sh. Itā€™s actually at the end of the file. So, I moved it to that one and thought Iā€™d try disabling/enabling the morse radio again as I described. For an hour Iā€™ve been disabling/enabling the halow radio, itā€™s up to phy37assoc and the green led has acted normally, meaning it came on when associated and didnā€™t turn red 3 secs after coming on. Plus, interestingly, that line ā€œuser.notice root: Prplmesh is disabledā€ is even in the log!

Is this all because /lib/wifi/morse.sh is launched before /lib/netifd/wireless/morse.sh and thereā€™s something in the latter thatā€™s run such that the trigger has to be set after that morse.sh runs?

Hereā€™s the code I added at the end of /lib/netifd/wireless/morse.sh after the last line ā€œadd_driver morseā€:

for item in `cat /sys/class/leds/green:sys/trigger`
do
    if [[ $item == "*assoc*" ]]; then
        if [[ $item != "phy0assoc*" ]]; then
            led_trig=$item
        fi
    fi
done

led_trig=`echo $led_trig | sed -e 's/\[//' | sed -e 's/\]//'`
echo "$led_trig" > /sys/class/leds/green:sys/trigger
echo "$led_trig" > /sys/class/leds/red:sys/trigger

(note: since red is active low, green active high, they get the same trigger)

So, thereā€™s a saying ā€œconfession is good for the soulā€. So, confession: I had put the code in the wrong file and if I hadnā€™t, I wouldnā€™t have seen that issue. Thereā€™s an end to that phrase few people useā€¦ā€confession is good for the soul, but bad for the reputationā€. At least this situation with the led appears to be working now. I figured an hour was a good amount of time to test since the bad condition would often appear about every few minutes of trying the dsbl/enbl cycle.

Thanks so much for your attention to this and the help youā€™ve been.

Finally: You asked: ā€œCan you verify the phy number of the HaLow interface matches the phy specified in the trigger file?ā€ I can get the phy trigger number from the list of ā€œcat /sys/class/leds/green:sys/triggerā€, but where do I find the phy number for the halow i/f?

Regards,

Don

Hi Don,

Glad youā€™ve resolved it!

but where do I find the phy number for the halow i/f?

There are many ways to find this. A simple one I would use for checking is
ls /sys/class/morse/morse_io/device/ieee80211

Is this all because /lib/wifi/morse.sh is launched before /lib/netifd/wireless/morse.sh

On insertion of a wireless driver module, and subsequent creation of the phy device, a hotplug script /etc/hotplug.d/ieee80211/10-wifi-detect executes. This hotplug scripts calls /sbin/wifi with the intention of adding configuration entries to /etc/config/wireless. It should be noted, however, that any time /sbin/wifi is executed, it ā€œincludesā€ every script in /lib/wifi/. This inclusion effectively executes every script in /lib/wifi/. Which will execute the lines you added.

When your addition is added to /lib/netifd/wireless/morse.sh then the LED configuration will be executed at anytime the netifd binary executes that handler (see this link for the line where netifd starts adding handlers to itā€™s internal registry). This will happen any time the network service is restarted, netifd detects a change to configuration, and possibly more.

Without further debugging, itā€™s still a little difficult to say conclusively why your LED configuration didnā€™t work correctly when in /lib/wifi/morse.sh. If I find the time to do further debug I definitely will.


If possible, I would recommend exploring a separate hotplug script so that you avoid the complexities of netifd, and maintain your changes separately from any updates we make to the netifd package.

I havenā€™t tested this, but you could add a new script to /etc/hotplug.d/ieee80211/ containing the following

#!/bin/sh

[ "${ACTION}" = "add" ] && {
	basename "$(readlink -f "/sys/${DEVPATH}/device/driver")" | grep '^morse_' || return;

	phy=${DEVPATH##*/}
	[ -n $phy ] || exit 0

	echo "${phy}assoc" > /sys/class/leds/green:sys/trigger
	echo "${phy}assoc" > /sys/class/leds/red:sys/trigger

}

This script will trigger whenever mac80211 registers a new phy. It will first check that phy is using a Morse Micro driver, then extract the phy name (eg, phy3), and then force your LEDs to the phyNassoc trigger.
If youā€™re feeling particularly fancy, you could leverage the functions in /lib/functions/leds.sh to get the leds by their device tree name.

Your note from reply 4 on 11/13 above was VERY helpful. The 3rd option ā€œiwinfo wlan0 assoclistā€ got me a list of clients on the AP. Using that in a script, I used cron to launch a script every minute to check the output of that command. That output helps me know to turn my LED if clients are attached.

I then turned off a client and after a while, it eventually disappeared from the list. I disabled another client halow radio and it pretty much immediately disappeared from the list.

Questions:

  1. In the script, is there a command I can use that will give me the halow mac? (also, the device or wifi mac). Since the script is going to be part of the image regardless of it being an AP or client, that way I can filter. If the mac in the list is the same as the device halow mac, Iā€™ll know Iā€™m on a client and wonā€™t mess with the LED, but if not itā€™s an AP and I should control the LED. Or, is there a better way to know and what other ways can you know if that device is an AP or client?

  2. What is the timeout when a client disappears without a proper disconnect before it disappears from that assoclist?

  3. is there a way to know on the AP when it gets a halow connection or disconnect (i.e. ā€œdaemon.notice hostapd_s1g: wlan0: AP-STA-CONNECTED ā€, ā€œdaemon.notice hostapd_s1g: wlan0: AP-STA-DISCONNECTED ā€)? I thought it would be preferrable to run the script at that time to have immediate reaction to the LED when the first client connects or the last client disconnects.

In the script, is there a command I can use that will give me the halow mac?

Do you mean the HaLow MAC of the device you intend to run the command on?
If you donā€™t want to parse the output of ifconfig or ip addr show, then perhaps using sysfs is sensible? Something like cat /sys/class/net/wlan0/address. This last command will return only the configured hardware address.


What is the timeout when a client disappears without a proper disconnect before it disappears from that assoclist?

This is actually a configurable parameter of hostapd! See these options available in uci [OpenWrt Wiki] Wi-Fi /etc/config/wireless
By default the max station inactivity is configured to be 5 minutes. A station may leave immediately if it sends a deauthentication frame. This will likely occur if the wpa_supplicant process is terminated cleanly, which rarely happens in reality. Typically a device goes out of range, or otherwise has its power pulled.


is there a way to know on the AP when it gets a halow connection or disconnec

There are a few ways to achieve this. I think the easiest approach is to use hostap_cli_s1g with an action script in daemon mode running in the background. For example, you could create a script named station_connected containing

#!/bin/sh

[ "$2" == "AP-STA-CONNECTED" ] && {
	echo "$@"
}

[ "$2" == "AP-STA-DISCONNECTED" ] && {
	echo "$@"
}
exit 0

and hook it into hostapd with
hostapd_cli_s1g -i wlan0 -a station_connected -B

When a station connects, the action script will run. If the event fired by hostapd is AP-STA-CONNECTED or AP-STA-DISCONNECTED this script will simply print the arguments of the event fired.


Alternatively, you could write a C application which uses the hostapd control interface to receive these events. We have an example application handling DPP push button events for wpa_supplicant available here. Youā€™ll need to point this to the hostapd control interface, that is #define CONFIG_CTRL_IFACE_DIR "/var/run/hostapd_s1g", and instead of listening for DPPPB events. Youā€™ll probably want to receive AP_STA_CONNECTED and AP_STA_DISCONNECTED events. The full list of events for hostapd can be found here.

Hostapd documentation for the control interface can be found here. It is unfortunately, a bit light on explaining the details.

Hi, Arien. I tried the script and hostapd_cli_s1g below but didnā€™t see any effect. I disabled then reenabled the radio on the client to disconnect/reconnect through luci network/wireless.

I put that sample you showed into a file /lib/functions/clientconnected.sh, then ran ā€œhostapd_cli_s1g -i wlan0 -a /lib/functions/clientconnected.sh -Bā€ from the command line. I even added an echo, as below. I also tried renaming without the ā€œ.shā€, too. Am I doing something wrong?

#!/bin/sh

[ "$2" == "AP-STA-CONNECTED" ] && {

echo "$@"

echo ā€œClient connectedā€ > /dev/console

}

[ "$2" == "AP-STA-DISCONNECTED" ] && {

echo "$@"

echo ā€œClient disconnectedā€ > /dev/console

}

exit 0

Hi @don.baker,

Of course, when itā€™s daemonised with -B, the output will be hidden.

If you run the hostapd script in the foreground (ie, without -B), are you seeing the following?

hostapd_cli_s1g -i wlan0 -a /lib/functions/clientconnected.sh
execv: Permission denied
execv: Permission denied

If so, your script may not be executable. Donā€™t forget to chmod +x /lib/functions/clientconnected.sh

Iā€™m testing via ssh to my AP, not a UART cable, so I canā€™t use /dev/console. But doing echo "$@" > /dev/kmsg pushes the output to logs I can output with dmesg.

[998304.611289] wlan0 AP-STA-CONNECTED 02:00:5e:f0:bb:f8

If that fails, try toggle an LED instead.

Arien ā€“ this is cool, itā€™s starting to work. When I type that hostapd_cli_s1g command on the console command line, with my clientconnected.sh script, I have it toggle the led accordingly and it works.

However, 1 more stepā€¦where do I put that line in a script to make it work programmatically? Not understanding the coordination of this stuff and where it really needs to be, I tried at the end of rc.local but no success. I had to manually type it then it worked.

Then, Iā€™m not aware of how that command works relative to other conditions that may happen. What if the AP this is running on reboots? What if its halow radio cycles dsbl/enbl?

Can you advise on a good place to put that command?

Don

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
}

Arien-appreciate the script. However, it doesnā€™t seem to do anything, unless I missed something. I put it in the file as you suggested. I put logger output commands in every function and at the topā€¦I get nothing output in logread. As a test, to verify that would work, I put logger commands in each function and the top of init.d/network and got a bunch of logger messages.

Ideas?

reading your note on checking out procd stuff, would the above need a way to start the service? If so, how?
I ask because of this in the link:
ā€œEnabling the service
To tell OpenWrt that we have a new service we would need to run
/etc/init.d/myservice enable
This will install a symlink for us in directory /etc/rc.d/ā€

You will need to install the script with service hostap-leds enable . Good spot.

You can then start it with service hostap-leds start or by rebooting the device.