Toggling wifi over SSH

Looked over both uci and wifi and I'm confused as to how to programmatically toggle wifi. What I'm trying to do is enable/disable my 2.4GHz band on my R7800 through SSH. All configurations are set and I can enable and disable through LuCi. What I tried to do was:
uci set wireless.radio1.disabled=0 && uci commit wireless && wifi

Doesn't work. I am noticing that the wireless.radio1.disabled key is not there after I enable the radio through LuCi. Do I delete that key entirely to enable and then add it to disable? In theory shouldn't I just be able to do wifi up radio1 or wifi down radio1?

check https://openwrt.org/docs/guide-user/network/wifi/wifitoggle

Thanks, a little closer but I will have to modify this script.
device is hardcoded to wl0 which I can easily modify to take in an argument. Though I am still not understanding the sequence of how wifi is enabled/disabled in practice here as this will not work (at least on 19.07.2) -
When a wifi radio is enabled the wireless.radio*.disabled key is non-existent. When it is disabled that key is set to 1. The script checks if it's set to either 1 or 0 (which makes total logical sense). In actually it can only be 1 or non-existent. Have there been changes to the way wifi interfaces are brought up and down recently? I am thinking I will need to modify the script to delete the key instead of setting it to 0.

I recall being able to reload a single radio... Does that not work for you with the wifi command? It takes e.g. radio0 and radio1 as additional arguments.

The script does work. Check the wireless configuration guide here. Options not set in UCI will inherit the default value. So setting the wireless.device.disabled to 0 equals wireless.device.disabled='0' or removing the option.

Here's a quick and dirty toggle script using arguments. Call it using toggle-wifi.sh <device_name>.

#!/bin/sh

device=$(uci get wireless."$1" >/dev/null 2>&1)

if [ "$?" -ne 0 ]; then
    echo "Device not specified or does not exists" 1>&2
    exit 1
fi

disabled=$(uci get wireless."$1".disabled 2>/dev/null)

if [ "$?" -ne 0 ] || [ "$disabled" -eq 0 ]; then
    echo "Disabling ${1}"

    uci set wireless."$1".disabled='1'
    uci commit

    wifi down "$1" >/dev/null 2>$1
else
    echo "Enabling ${1}"

    uci set wireless."$1".disabled='0'
    uci commit

    wifi up "$1" >/dev/null 2>&1
fi

exit 0

It's working for me.

1 Like

As @vuhuy said, radio1.disabled=0 or radio1.disabled=1 are both valid and work as expected. LuCI will remove the disabled key entirely to enable a radio.

uci commit alone does not necessarily re-load the config to the radios though. Follow uci commit with wifi up radio1. The "up" command will read the uci config and turn the radio on or off as configured. It is not necessary to call wifi down. Running wifi without specifying a radio will restart both radios, which disrupts connections on radio0.

Just updated the script that I quickly wrote for @kam to reflect your input. Now it went from quick and dirty to legit.

Edit: nope, changed it back. Not calling wifi down did not turn of my WiFi. Well it's up to OP to test it further.

Thanks @mk24 and @vuhuy - script looks good, I was just about to write one. Though I am still not getting the result. It looks like there is an interface array that's not being filled. Here's the second half of the output of wifi status:

"radio1": {
		"up": true,
		"pending": false,
		"autostart": true,
		"disabled": false,
		"retry_setup_failed": false,
		"config": {
			"channel": "11",
			"hwmode": "11g",
			"path": "soc/1b700000.pci/pci0001:00/0001:00:00.0/0001:01:00.0",
			"htmode": "HT20",
			"disabled": false
		},
		"interfaces": [

		]
	}

I have a wireless.default_radio1.disabled=1 entry as well which looks like it contains the interface information. On radio0 (5Ghz) this interface array is properly filled:

"radio0": {
		"up": true,
		"pending": false,
		"autostart": true,
		"disabled": false,
		"retry_setup_failed": false,
		"config": {
			"hwmode": "11a",
			"path": "soc/1b500000.pci/pci0000:00/0000:00:00.0/0000:01:00.0",
			"htmode": "VHT80",
			"channel": "161"
		},
		"interfaces": [
			{
				"section": "default_radio0",
				"ifname": "wlan0",
				"config": {
                ...........
}

Should be wireless.radio1.disabled=1

Those are two different sections under my config for wireless. Looks like this:

wireless.radio1=wifi-device
wireless.radio1.type='mac80211'
wireless.radio1.channel='11'
wireless.radio1.hwmode='11g'
wireless.radio1.path='soc/1b700000.pci/pci0001:00/0001:00:00.0/0001:01:00.0'
wireless.radio1.htmode='HT20'
wireless.radio1.disabled='1'
wireless.default_radio1=wifi-iface
wireless.default_radio1.device='radio1'
wireless.default_radio1.network='lan'
wireless.default_radio1.mode='ap'
wireless.default_radio1.key='xyz'
wireless.default_radio1.ssid='xyz'
wireless.default_radio1.encryption='psk2'
wireless.default_radio1.disabled='1'

Weird indeed. Looks like your configuration is scrambled. Go to LuCI. Delete all SSIDs. There should be two device entries left (your two radios). One for 2.4 GHz, the other for 5 GHz. Add a network for both radios. Run my script using again, it should work. Execute toggle-wifi.sh radio0 or toggle-wifi.sh radio1. You might want to toggle both radios once first so that LuCI reflects the actual state (this was / is a bug when adding interfaces). If this does not work, post the output of uci show wireless and wifi status again.

Confirmed that the config was scrambled. I recreated both networks for both bands and now I have wireless.radio0 with wireless.wifinet0 and wireless.radio1 with wireless.wifinet1. I would like to trace why I had wireless.default_radioX sections instead - there's not many mentions across the site of it at all.

Confirmed that toggling works now! :sunglasses:

Please mark the answer that helped you as solution :slightly_smiling_face:.

As for default_radioX, those are just the standard names for wireless networks created upon flashing OpenWRT. Newly created networks are named wifinetX instead.

1 Like

This topic was automatically closed 10 days after the last reply. New replies are no longer allowed.