Browse Source

GAS: Delay GAS query Tx while scanning/connecting

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>
Kyeyoon Park 11 years ago
parent
commit
c377514337

+ 9 - 3
wpa_supplicant/gas_query.c

@@ -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,

+ 1 - 1
wpa_supplicant/scan.c

@@ -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) {

+ 22 - 6
wpa_supplicant/wpa_supplicant.c

@@ -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;
 		}
 	}

+ 1 - 1
wpa_supplicant/wpa_supplicant_i.h

@@ -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