mirror of
https://github.com/Telecominfraproject/wlan-ap.git
synced 2025-11-02 03:17:48 +00:00
154 lines
4.7 KiB
Diff
154 lines
4.7 KiB
Diff
--- a/hostapd/config_file.c
|
|
+++ b/hostapd/config_file.c
|
|
@@ -2460,6 +2460,8 @@ static int hostapd_config_fill(struct ho
|
|
conf->ieee80211d = atoi(pos);
|
|
} else if (os_strcmp(buf, "ieee80211h") == 0) {
|
|
conf->ieee80211h = atoi(pos);
|
|
+ } else if (os_strcmp(buf, "dfs_test_mode") == 0) {
|
|
+ conf->dfs_test_mode = atoi(pos);
|
|
} else if (os_strcmp(buf, "ieee8021x") == 0) {
|
|
bss->ieee802_1x = atoi(pos);
|
|
} else if (os_strcmp(buf, "eapol_version") == 0) {
|
|
--- a/src/ap/ap_config.h
|
|
+++ b/src/ap/ap_config.h
|
|
@@ -979,6 +979,7 @@ struct hostapd_config {
|
|
int ieee80211d;
|
|
|
|
int ieee80211h; /* DFS */
|
|
+ int dfs_test_mode;
|
|
|
|
/*
|
|
* Local power constraint is an octet encoded as an unsigned integer in
|
|
--- a/src/ap/dfs.c
|
|
+++ b/src/ap/dfs.c
|
|
@@ -18,6 +18,8 @@
|
|
#include "drivers/driver.h"
|
|
#include "dfs.h"
|
|
#include "crypto/crypto.h"
|
|
+#include "beacon.h"
|
|
+#include "eloop.h"
|
|
|
|
|
|
static int dfs_get_used_n_chans(struct hostapd_iface *iface, int *seg1)
|
|
@@ -1036,6 +1038,73 @@ static int hostapd_dfs_start_channel_swi
|
|
return err;
|
|
}
|
|
|
|
+void hostapd_dfs_test_mode_csa_timeout(void *eloop_data, void *user_data)
|
|
+{
|
|
+ struct hostapd_data *hapd = eloop_data;
|
|
+
|
|
+ wpa_printf(MSG_INFO, "Stopping CSA in dfs test mode");
|
|
+ hostapd_cleanup_cs_params(hapd);
|
|
+ ieee802_11_set_beacon(hapd);
|
|
+}
|
|
+
|
|
+static int hostapd_dfs_testmode_set_beacon_csa(struct hostapd_iface *iface)
|
|
+{
|
|
+ struct hostapd_data *hapd = iface->bss[0];
|
|
+ struct csa_settings csa_settings;
|
|
+ int secondary_channel;
|
|
+ u8 vht_oper_centr_freq_seg0_idx;
|
|
+ u8 vht_oper_centr_freq_seg1_idx;
|
|
+ int err = 0;
|
|
+
|
|
+ eloop_cancel_timeout(hostapd_dfs_test_mode_csa_timeout, hapd, NULL);
|
|
+ secondary_channel = iface->conf->secondary_channel;
|
|
+ vht_oper_centr_freq_seg0_idx =
|
|
+ iface->conf->vht_oper_centr_freq_seg0_idx;
|
|
+ vht_oper_centr_freq_seg1_idx =
|
|
+ iface->conf->vht_oper_centr_freq_seg1_idx;
|
|
+
|
|
+ /* Setup CSA request */
|
|
+ os_memset(&csa_settings, 0, sizeof(csa_settings));
|
|
+ err = hostapd_set_freq_params(&csa_settings.freq_params,
|
|
+ iface->conf->hw_mode,
|
|
+ iface->freq,
|
|
+ iface->conf->channel,
|
|
+ iface->conf->ieee80211n,
|
|
+ iface->conf->ieee80211ac,
|
|
+ secondary_channel,
|
|
+ iface->conf->vht_oper_chwidth,
|
|
+ vht_oper_centr_freq_seg0_idx,
|
|
+ vht_oper_centr_freq_seg1_idx,
|
|
+ iface->current_mode->vht_capab);
|
|
+
|
|
+ if (err) {
|
|
+ wpa_printf(MSG_ERROR, "DFS failed to calculate CSA freq params");
|
|
+ goto fail;
|
|
+ }
|
|
+
|
|
+ if (!(hapd->iface->drv_flags & WPA_DRIVER_FLAGS_AP_CSA)) {
|
|
+ wpa_printf(MSG_INFO, "CSA is not supported");
|
|
+ hostapd_disable_iface(iface);
|
|
+ return -1;
|
|
+ }
|
|
+
|
|
+ hapd->cs_freq_params = csa_settings.freq_params;
|
|
+ hapd->cs_count = 3;
|
|
+ hapd->cs_block_tx = 1;
|
|
+ err = ieee802_11_set_beacon(hapd);
|
|
+ if (err)
|
|
+ goto fail;
|
|
+ wpa_printf(MSG_DEBUG, "CSA beacon configured for dfs mode, count %d",
|
|
+ hapd->cs_count);
|
|
+ hapd->csa_in_progress = 1;
|
|
+ eloop_register_timeout(HOSTAPD_DFS_TEST_MODE_CSA_DUR, 0,
|
|
+ hostapd_dfs_test_mode_csa_timeout, hapd, NULL);
|
|
+ return 0;
|
|
+
|
|
+fail:
|
|
+ hostapd_disable_iface(iface);
|
|
+ return err;
|
|
+}
|
|
|
|
static int hostapd_dfs_start_channel_switch(struct hostapd_iface *iface)
|
|
{
|
|
@@ -1071,6 +1140,9 @@ static int hostapd_dfs_start_channel_swi
|
|
if (iface->dfs_domain == HOSTAPD_DFS_REGION_ETSI)
|
|
skip_radar = 0;
|
|
|
|
+ if (iface->conf->dfs_test_mode)
|
|
+ return hostapd_dfs_testmode_set_beacon_csa(iface);
|
|
+
|
|
/* Perform channel switch/CSA */
|
|
channel = dfs_get_valid_channel(iface, &secondary_channel,
|
|
&oper_centr_freq_seg0_idx,
|
|
@@ -1206,6 +1278,12 @@ int hostapd_dfs_radar_detected(struct ho
|
|
if (!res)
|
|
return 0;
|
|
|
|
+ if (iface->conf->dfs_test_mode) {
|
|
+ set_dfs_state(iface, freq, ht_enabled, chan_offset,
|
|
+ chan_width, cf1, cf2,
|
|
+ HOSTAPD_CHAN_DFS_AVAILABLE);
|
|
+ }
|
|
+
|
|
/* Skip if reported radar event not overlapped our channels */
|
|
res = dfs_are_channels_overlapped(iface, freq, chan_width, cf1, cf2);
|
|
if (!res)
|
|
--- a/src/ap/dfs.h
|
|
+++ b/src/ap/dfs.h
|
|
@@ -9,6 +9,11 @@
|
|
#ifndef DFS_H
|
|
#define DFS_H
|
|
|
|
+/* CSA beacon duration in seconds for dfs testing mode */
|
|
+#define HOSTAPD_DFS_TEST_MODE_CSA_DUR 1
|
|
+
|
|
+void hostapd_dfs_test_mode_csa_timeout(void *eloop_data, void *user_data);
|
|
+
|
|
int hostapd_handle_dfs(struct hostapd_iface *iface);
|
|
|
|
int hostapd_dfs_complete_cac(struct hostapd_iface *iface, int success, int freq,
|
|
--- a/src/ap/hostapd.c
|
|
+++ b/src/ap/hostapd.c
|
|
@@ -2836,6 +2836,7 @@ int hostapd_disable_iface(struct hostapd
|
|
hostapd_cleanup_cs_params(hapd_iface->bss[j]);
|
|
#endif /* NEED_AP_MLME */
|
|
|
|
+ eloop_cancel_timeout(hostapd_dfs_test_mode_csa_timeout, hapd_iface, NULL);
|
|
/* same as hostapd_interface_deinit without deinitializing ctrl-iface */
|
|
for (j = 0; j < hapd_iface->num_bss; j++) {
|
|
struct hostapd_data *hapd = hapd_iface->bss[j];
|