GAS: Delay GAS query Tx while scanning/connecting
authorKyeyoon Park <kyeyoonp@qca.qualcomm.com>
Mon, 21 Oct 2013 10:15:45 +0000 (13:15 +0300)
committerJouni Malinen <j@w1.fi>
Mon, 21 Oct 2013 10:15:45 +0000 (13:15 +0300)
Offchannel operations needed for a GAS query can conflict with ongoing
scan/connection progress, so delay GAS queries if such an operation is
in progress on the current interface or any virtual interface sharing
the same radio.

Signed-hostap: Jouni Malinen <jouni@qca.qualcomm.com>

wpa_supplicant/gas_query.c
wpa_supplicant/scan.c
wpa_supplicant/wpa_supplicant.c
wpa_supplicant/wpa_supplicant_i.h

index a4e675d..00f730e 100644 (file)
@@ -478,10 +478,16 @@ static void gas_query_timeout(void *eloop_data, void *user_ctx)
 static void gas_service_timeout(void *eloop_data, void *user_ctx)
 {
        struct gas_query *gas = eloop_data;
+       struct wpa_supplicant *wpa_s = gas->wpa_s;
        struct gas_query_pending *query = user_ctx;
-
-       if (gas->current) {
-               wpa_printf(MSG_DEBUG, "GAS: Delaying GAS query Tx while another operation is in progress");
+       int conn;
+
+       conn = wpas_wpa_is_in_progress(wpa_s, 1);
+       if (conn || wpa_s->scanning || gas->current) {
+               wpa_printf(MSG_DEBUG, "GAS: Delaying GAS query Tx while another operation is in progress:%s%s%s",
+                          conn ? " connection" : "",
+                          wpa_s->scanning ? " scanning" : "",
+                          gas->current ? " gas_query" : "");
                eloop_register_timeout(
                        GAS_SERVICE_RETRY_PERIOD_MS / 1000,
                        (GAS_SERVICE_RETRY_PERIOD_MS % 1000) * 1000,
index be826db..f1f858e 100644 (file)
@@ -588,7 +588,7 @@ static void wpa_supplicant_scan(void *eloop_ctx, void *timeout_ctx)
        }
 
 #ifdef CONFIG_P2P
-       if (wpas_p2p_in_progress(wpa_s) || wpas_wpa_is_in_progress(wpa_s)) {
+       if (wpas_p2p_in_progress(wpa_s) || wpas_wpa_is_in_progress(wpa_s, 0)) {
                if (wpa_s->sta_scan_pending &&
                    wpas_p2p_in_progress(wpa_s) == 2 &&
                    wpa_s->global->p2p_cb_on_scan_complete) {
index ec938fe..bd0773f 100644 (file)
@@ -3945,37 +3945,53 @@ void wpas_request_connection(struct wpa_supplicant *wpa_s)
 }
 
 
+static int wpas_conn_in_progress(struct wpa_supplicant *wpa_s)
+{
+       return wpa_s->wpa_state >= WPA_AUTHENTICATING &&
+               wpa_s->wpa_state != WPA_COMPLETED;
+}
+
+
 /**
  * wpas_wpa_is_in_progress - Check whether a connection is in progress
  * @wpa_s: Pointer to wpa_supplicant data
+ * @include_current: Whether to consider specified interface
  *
  * This function is to check if the wpa state is in beginning of the connection
  * during 4-way handshake or group key handshake with WPA on any shared
  * interface.
  */
-int wpas_wpa_is_in_progress(struct wpa_supplicant *wpa_s)
+int wpas_wpa_is_in_progress(struct wpa_supplicant *wpa_s, int include_current)
 {
        const char *rn, *rn2;
        struct wpa_supplicant *ifs;
 
-       if (!wpa_s->driver->get_radio_name)
+       if (!wpa_s->driver->get_radio_name) {
+               if (include_current && wpas_conn_in_progress(wpa_s)) {
+                       wpa_dbg(wpa_s, MSG_DEBUG, "Connection is in progress on interface %s - defer",
+                               wpa_s->ifname);
+                       return 1;
+               }
+
                 return 0;
+       }
 
        rn = wpa_s->driver->get_radio_name(wpa_s->drv_priv);
        if (rn == NULL || rn[0] == '\0')
                return 0;
 
        for (ifs = wpa_s->global->ifaces; ifs; ifs = ifs->next) {
-               if (ifs == wpa_s || !ifs->driver->get_radio_name)
+               if (!include_current && ifs == wpa_s)
+                       continue;
+               if (!ifs->driver->get_radio_name)
                        continue;
 
                rn2 = ifs->driver->get_radio_name(ifs->drv_priv);
                if (!rn2 || os_strcmp(rn, rn2) != 0)
                        continue;
-               if (ifs->wpa_state >= WPA_AUTHENTICATING &&
-                   ifs->wpa_state != WPA_COMPLETED) {
+               if (wpas_conn_in_progress(ifs)) {
                        wpa_dbg(wpa_s, MSG_DEBUG, "Connection is in progress "
-                               "on interface %s - defer scan", ifs->ifname);
+                               "on interface %s - defer", ifs->ifname);
                        return 1;
                }
        }
index be493cf..d44f0a2 100644 (file)
@@ -823,7 +823,7 @@ int disallowed_ssid(struct wpa_supplicant *wpa_s, const u8 *ssid,
                    size_t ssid_len);
 void wpas_request_connection(struct wpa_supplicant *wpa_s);
 int wpas_build_ext_capab(struct wpa_supplicant *wpa_s, u8 *buf);
-int wpas_wpa_is_in_progress(struct wpa_supplicant *wpa_s);
+int wpas_wpa_is_in_progress(struct wpa_supplicant *wpa_s, int include_current);
 
 /**
  * wpa_supplicant_ctrl_iface_ctrl_rsp_handle - Handle a control response