[RFC PATCH 4/5] hostapd: add support for DFS channels in hostapd_cli chan_switch

Sergey Matyukevich <[email protected]>
Newsgroups gmane.linux.drivers.hostap
Message-ID <[email protected]>
Enable support for DFS channels in hostapd_cli chan_switch command.
Perform CAC instead of CSA if DFS channel is selected. Then restart
normal AP operations.

Note that current implementation provides a simplified approach. It
does not check if selected DFS channel block is already in
HOSTAPD_CHAN_DFS_AVAILABLE state. CAC procedure is restarted anyway.

Signed-off-by: Sergey Matyukevich <[email protected]>
---
 hostapd/ctrl_iface.c | 60 +++++++++++++++++++++++++++++++++++++++++++++++++++-
 1 file changed, 59 insertions(+), 1 deletion(-)

diff --git a/hostapd/ctrl_iface.c b/hostapd/ctrl_iface.c
index 4ea22e3d2..5b36755cb 100644
--- a/hostapd/ctrl_iface.c
+++ b/hostapd/ctrl_iface.c
@@ -59,6 +59,7 @@
 #include "ap/neighbor_db.h"
 #include "ap/rrm.h"
 #include "ap/dpp_hostapd.h"
+#include "ap/dfs.h"
 #include "wps/wps_defs.h"
 #include "wps/wps.h"
 #include "fst/fst_ctrl_iface.h"
@@ -2503,8 +2504,11 @@ static int hostapd_ctrl_iface_chan_switch(struct hostapd_iface *iface,
 {
 #ifdef NEED_AP_MLME
 	struct csa_settings settings;
-	int ret;
+	int dfs_range = 0;
 	unsigned int i;
+	int bandwidth;
+	int ret;
+	u8 chan;
 
 	ret = hostapd_parse_csa_settings(pos, &settings);
 	if (ret)
@@ -2516,6 +2520,60 @@ static int hostapd_ctrl_iface_chan_switch(struct hostapd_iface *iface,
 		return ret;
 	}
 
+	switch (settings.freq_params.bandwidth) {
+	case 40:
+		bandwidth = CHAN_WIDTH_40;
+		break;
+	case 80:
+		if (settings.freq_params.center_freq2)
+			bandwidth = CHAN_WIDTH_80P80;
+		else
+			bandwidth = CHAN_WIDTH_80;
+		break;
+	case 160:
+		bandwidth = CHAN_WIDTH_160;
+		break;
+	default:
+		bandwidth = CHAN_WIDTH_20;
+		break;
+	}
+
+	if (settings.freq_params.center_freq1)
+		dfs_range += hostapd_is_dfs_overlap(iface, bandwidth,
+						    settings.freq_params.center_freq1);
+	else
+		dfs_range += hostapd_is_dfs_overlap(iface, bandwidth,
+						    settings.freq_params.freq);
+
+	if (settings.freq_params.center_freq2)
+		dfs_range += hostapd_is_dfs_overlap(iface, bandwidth,
+						    settings.freq_params.center_freq2);
+
+	if (dfs_range) {
+		ret = ieee80211_freq_to_chan(settings.freq_params.freq, &chan);
+		if (ret == NUM_HOSTAPD_MODES) {
+			wpa_printf(MSG_ERROR, "failed to get channel for (freq=%d, sec_channel_offset=%d, bw=%d)",
+				   settings.freq_params.freq,
+				   settings.freq_params.sec_channel_offset,
+				   settings.freq_params.bandwidth);
+			return -1;
+		}
+
+		settings.freq_params.channel = chan;
+
+		wpa_printf(MSG_DEBUG,
+				"DFS/CAC to (channel=%u, freq=%d, sec_channel_offset=%d, bw=%d, center_freq1=%d)",
+				settings.freq_params.channel,
+				settings.freq_params.freq,
+				settings.freq_params.sec_channel_offset,
+				settings.freq_params.bandwidth,
+				settings.freq_params.center_freq1);
+
+		/* perform CAC and switch channel */
+		hostapd_switch_channel_fallback(iface, &settings.freq_params);
+		return 0;
+	}
+
 	for (i = 0; i < iface->num_bss; i++) {
 
 		/* Save CHAN_SWITCH VHT config */
-- 
2.11.0
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.