Table of Contents
Introduction
ChannelSelectionRequest is a TR-181 command that allows relying individual channel preferences from the Controller to any Agent in the network. It's located in the Device.DataElements.Network.Device.{i}.ChannelSelectionRequest path. This can be used to orchestrate different topology and channel arrangement across the Wi-Fi mesh.
Disabling Dynamic Channel Selection
The Controller is already in charge of dynamic channel selection. Changes made by operator's call to ChannelSelectionRequest will eventually get overridden. To prevent that the operator is adviced to disable the dynamic channel selection. This can be done, eg.
ba-cli 'X_PRPLWARE-COM_Controller.Configuration.DynamicChannelSelectionTaskEnabled=0'
Setting a specific channel
Using ChannelSelectionRequest to simply direct an Agent's radio onto a specific channel is not straightforward. EasyMesh Channel Preference logic makes it such that one needs to demote all unwanted channels leaving only the most preferred one.
The operator needs to know what the available channel set is, and re-arrange preferenes in that set in a specific manner. The attached script serves as an example how Device.WiFi.DataElements.Network.Device.{i}.Radio.{i}.OpClassPreference.{i}. can be used to arrange preference to make an Agent perform a "go to channel" operation for a given radio. It is made to rely on recommendation of EasyMesh R6 Appendix 3.5 on how to signal beacon channel preference for bandwidths >= 80MHz.
#!/bin/sh
self=$0
device=$1
radio=$2
target=$3
beacon=$4
err_usage=1
err_notfound=2
err_target=3
err_beacon=4
non_oper=0
bcn_pref=7
max_pref=14
path=Device.WiFi.DataElements.Network.Device.$device.Radio.$radio.OpClassPreference.
usage() {
echo "usage: $self <device indice> <radio indice> <channel> [beacon channel]"
echo
echo "device indice - matching Device.WiFi.DataElements.Device.X"
echo "radio indice - matching Device.WiFi.DataElements.Device._.Radio.X"
echo "channel - represented as opclass-channel, eg. 81-1 is OpClass: 81, Channel: 1"
echo "beacon channel - optional, for wider than 40MHz channels"
echo
echo "examples:"
echo " - channel 1, 20Mhz on 2.4GHz"
echo " $self 1 1 81-1"
echo " - channel 1, 40Mhz on 2.4GHz"
echo " $self 1 1 83-1"
echo " - channel 36 (center 42), 80Mhz on 5GHz"
echo " $self 1 1 128-42 115-36"
echo " - channel 5 (center 15), 160MHz on 6GHz"
echo " $self 1 1 134-15 131-5"
exit $err_usage
}
test -z "$device" && usage
test -z "$radio" && usage
test -z "$target" && usage
# shellcheck disable=SC1091
. /usr/share/libubox/jshn.sh
# wrapped with {} because jshn doesn't support ingesting top-level arrays
instances="{ \"output\": $(ba-cli -laj "${path}?") }"
json_load "$instances"
json_select output
if test $? -ne 0
then
# Failing to parse means the device+radio likely does not exist
echo "$path: not found"
exit $err_notfound
fi
keys=
json_select 1
json_get_keys keys
channels=$(
for key in $keys
do
OpClass=
ChannelList=
Preference=
json_select "$key"
json_get_vars OpClass ChannelList Preference
for channel in $(echo "$ChannelList" | tr ',' ' ')
do
test "$Preference" -ne 0 && echo "$OpClass-$channel"
done
json_select ..
done
)
if ! echo "$channels" | grep -qxF "$target"
then
echo "channel $target is unavailable, refusing to continue"
echo "channels available:"
echo "$channels"
exit $err_target
fi
if test -n "$beacon" && ! echo "$channels" | grep -qxF "$beacon"
then
echo "beacon channel $beacon is unavailable, refusing to continue"
echo "channels available:"
echo "$channels"
exit $err_beacon
fi
prefs=$(
echo "$channels" \
| grep -xFv "$target" \
| grep -xFv "$beacon" \
| sed "s/$/:$non_oper/"
test -n "$target" && echo "$target:$max_pref"
test -n "$beacon" && echo "$beacon:$bcn_pref"
)
arg=$(
indice=1
for pref in $prefs
do
opclass=$(echo "$pref" | cut -d- -f1)
channel=$(echo "$pref" | cut -d- -f2 | cut -d: -f1)
preference=$(echo "$pref" | cut -d- -f2 | cut -d: -f2)
echo "$indice={OpClass=$opclass,Channel={1={Channel=$channel,Preference=$preference}}}"
indice=$((indice + 1))
done | tr '\n' ','
)
exec ba-cli "Device.WiFi.DataElements.Network.Device.$device.Radio.$radio.ChannelSelectionRequest(Class={$arg})"