Add support to switch channel when CAC is in progress

Prior to initiating communication on a DFS channel, channel availability
check needs to be performed. During this period, the AP does not beacon.
Hence, no channel switch was allowed during this period. However, if a
user wishes to switch to a non-DFS channel during the potentially long
CAC period and start transmission immediately, there is no provision to
do that currently.

Extend the existing CHAN_SWITCH control interface command to allow
channel switch even when the AP is in CAC state. To do this, first
disable the interface to abort the CAC in progress and then configure
the interface with the new parameters and finally re-enable the
interface.

Signed-off-by: Amith A <quic_amitajit@quicinc.com>
This commit is contained in:
Amith A 2024-08-07 11:34:07 +05:30 committed by Jouni Malinen
parent b7f08c28cd
commit 5cb6747f97
3 changed files with 44 additions and 0 deletions

View file

@ -2735,6 +2735,12 @@ static int hostapd_ctrl_iface_chan_switch(struct hostapd_iface *iface,
return 0; return 0;
} }
if (iface->cac_started) {
wpa_printf(MSG_DEBUG,
"CAC is in progress - switching channel without CSA");
return hostapd_force_channel_switch(iface, settings);
}
for (i = 0; i < iface->num_bss; i++) { for (i = 0; i < iface->num_bss; i++) {
/* Save CHAN_SWITCH VHT, HE, and EHT config */ /* Save CHAN_SWITCH VHT, HE, and EHT config */

View file

@ -4504,6 +4504,42 @@ int hostapd_switch_channel(struct hostapd_data *hapd,
} }
int hostapd_force_channel_switch(struct hostapd_iface *iface,
struct csa_settings settings)
{
int ret = 0;
if (!settings.freq_params.channel) {
/* Check if the new channel is supported */
settings.freq_params.channel = hostapd_hw_get_channel(
iface->bss[0], settings.freq_params.freq);
if (!settings.freq_params.channel)
return -1;
}
ret = hostapd_disable_iface(iface);
if (ret) {
wpa_printf(MSG_DEBUG, "Failed to disable the interface");
return ret;
}
hostapd_chan_switch_config(iface->bss[0], &settings.freq_params);
ret = hostapd_change_config_freq(iface->bss[0], iface->conf,
&settings.freq_params, NULL);
if (ret) {
wpa_printf(MSG_DEBUG,
"Failed to set the new channel in config");
return ret;
}
ret = hostapd_enable_iface(iface);
if (ret)
wpa_printf(MSG_DEBUG, "Failed to enable the interface");
return ret;
}
void void
hostapd_switch_channel_fallback(struct hostapd_iface *iface, hostapd_switch_channel_fallback(struct hostapd_iface *iface,
const struct hostapd_freq_params *freq_params) const struct hostapd_freq_params *freq_params)

View file

@ -753,6 +753,8 @@ void hostapd_chan_switch_config(struct hostapd_data *hapd,
struct hostapd_freq_params *freq_params); struct hostapd_freq_params *freq_params);
int hostapd_switch_channel(struct hostapd_data *hapd, int hostapd_switch_channel(struct hostapd_data *hapd,
struct csa_settings *settings); struct csa_settings *settings);
int hostapd_force_channel_switch(struct hostapd_iface *iface,
struct csa_settings settings);
void void
hostapd_switch_channel_fallback(struct hostapd_iface *iface, hostapd_switch_channel_fallback(struct hostapd_iface *iface,
const struct hostapd_freq_params *freq_params); const struct hostapd_freq_params *freq_params);