]> git.ipfire.org Git - thirdparty/hostap.git/blobdiff - wpa_supplicant/bgscan_simple.c
bgscan: Allow simple bgscan to do BTM queries
[thirdparty/hostap.git] / wpa_supplicant / bgscan_simple.c
index f398b8507760a5044493eb5f321c647f61dc4b5c..cac3049e3e67b23f914a2fdb3eda38529b076e8d 100644 (file)
 #include "wpa_supplicant_i.h"
 #include "driver_i.h"
 #include "scan.h"
+#include "config.h"
+#include "wnm_sta.h"
+#include "bss.h"
 #include "bgscan.h"
 
 struct bgscan_simple_data {
        struct wpa_supplicant *wpa_s;
        const struct wpa_ssid *ssid;
+       unsigned int use_btm_query;
+       unsigned int scan_action_count;
        int scan_interval;
        int signal_threshold;
        int short_scan_count; /* counter for scans using short scan interval */
@@ -30,12 +35,54 @@ struct bgscan_simple_data {
 };
 
 
+static void bgscan_simple_timeout(void *eloop_ctx, void *timeout_ctx);
+
+
+static bool bgscan_simple_btm_query(struct wpa_supplicant *wpa_s,
+                                   struct bgscan_simple_data *data)
+{
+       unsigned int mod;
+
+       if (!data->use_btm_query || wpa_s->conf->disable_btm ||
+           !wpa_s->current_bss ||
+           !wpa_bss_ext_capab(wpa_s->current_bss,
+                              WLAN_EXT_CAPAB_BSS_TRANSITION))
+               return false;
+
+       /* Try BTM x times, scan on x + 1 */
+       data->scan_action_count++;
+       mod = data->scan_action_count % (data->use_btm_query + 1);
+       if (mod >= data->use_btm_query)
+               return false;
+
+       wpa_printf(MSG_DEBUG,
+                  "bgscan simple: Send BSS transition management query %d/%d",
+                  mod, data->use_btm_query);
+       if (wnm_send_bss_transition_mgmt_query(
+                   wpa_s, WNM_TRANSITION_REASON_BETTER_AP_FOUND, NULL, 0)) {
+               wpa_printf(MSG_DEBUG,
+                          "bgscan simple: Failed to send BSS transition management query");
+               /* Fall through and do regular scan */
+               return false;
+       }
+
+       /* Start a new timeout for the next one. We don't have scan callback to
+        * otherwise trigger future progress when using BTM path. */
+       eloop_register_timeout(data->scan_interval, 0,
+                              bgscan_simple_timeout, data, NULL);
+       return true;
+}
+
+
 static void bgscan_simple_timeout(void *eloop_ctx, void *timeout_ctx)
 {
        struct bgscan_simple_data *data = eloop_ctx;
        struct wpa_supplicant *wpa_s = data->wpa_s;
        struct wpa_driver_scan_params params;
 
+       if (bgscan_simple_btm_query(wpa_s, data))
+               goto scan_ok;
+
        os_memset(&params, 0, sizeof(params));
        params.num_ssids = 1;
        params.ssids[0].ssid = data->ssid->ssid;
@@ -54,6 +101,7 @@ static void bgscan_simple_timeout(void *eloop_ctx, void *timeout_ctx)
                eloop_register_timeout(data->scan_interval, 0,
                                       bgscan_simple_timeout, data, NULL);
        } else {
+       scan_ok:
                if (data->scan_interval == data->short_interval) {
                        data->short_scan_count++;
                        if (data->short_scan_count >= data->max_short_scans) {
@@ -80,6 +128,8 @@ static int bgscan_simple_get_params(struct bgscan_simple_data *data,
 {
        const char *pos;
 
+       data->use_btm_query = 0;
+
        data->short_interval = atoi(params);
 
        pos = os_strchr(params, ':');
@@ -95,6 +145,11 @@ static int bgscan_simple_get_params(struct bgscan_simple_data *data,
        }
        pos++;
        data->long_interval = atoi(pos);
+       pos = os_strchr(pos, ':');
+       if (pos) {
+               pos++;
+               data->use_btm_query = atoi(pos);
+       }
 
        return 0;
 }