aboutsummaryrefslogtreecommitdiffstats
path: root/wpa_supplicant
diff options
context:
space:
mode:
authorJouni Malinen <j@w1.fi>2014-01-03 13:09:50 (GMT)
committerJouni Malinen <j@w1.fi>2014-01-07 08:45:09 (GMT)
commitb9e6d7001d5408b3dd9c9e74df3f75732823d216 (patch)
treec064dffff210f4e681fc80e8ba454ecfaac1e226 /wpa_supplicant
parente05e130837c86a0d60d2f70bb03fcd468d79450d (diff)
downloadhostap-b9e6d7001d5408b3dd9c9e74df3f75732823d216.zip
hostap-b9e6d7001d5408b3dd9c9e74df3f75732823d216.tar.gz
hostap-b9e6d7001d5408b3dd9c9e74df3f75732823d216.tar.bz2
Use radio work for GAS requests
Avoid concurrent GAS operations with any other exclusive use of the radio by using the radio work queuing mechanism. This replaces some of the earlier constraints on concurrent operations with the more generic wpa_radio work concept. Signed-hostap: Jouni Malinen <j@w1.fi>
Diffstat (limited to 'wpa_supplicant')
-rw-r--r--wpa_supplicant/gas_query.c65
-rw-r--r--wpa_supplicant/gas_query.h1
-rw-r--r--wpa_supplicant/scan.c9
3 files changed, 46 insertions, 29 deletions
diff --git a/wpa_supplicant/gas_query.c b/wpa_supplicant/gas_query.c
index dd10a75..fda7c84 100644
--- a/wpa_supplicant/gas_query.c
+++ b/wpa_supplicant/gas_query.c
@@ -2,6 +2,7 @@
* Generic advertisement service (GAS) query
* Copyright (c) 2009, Atheros Communications
* Copyright (c) 2011-2013, Qualcomm Atheros, Inc.
+ * Copyright (c) 2011-2014, Jouni Malinen <j@w1.fi>
*
* This software may be distributed under the terms of the BSD license.
* See README for more details.
@@ -31,6 +32,7 @@
*/
struct gas_query_pending {
struct dl_list list;
+ struct gas_query *gas;
u8 addr[ETH_ALEN];
u8 dialog_token;
u8 next_frag_id;
@@ -55,6 +57,7 @@ struct gas_query {
struct wpa_supplicant *wpa_s;
struct dl_list pending; /* struct gas_query_pending */
struct gas_query_pending *current;
+ struct wpa_radio_work *work;
};
@@ -106,6 +109,25 @@ static const char * gas_result_txt(enum gas_query_result result)
}
+static void gas_query_free(struct gas_query_pending *query, int del_list)
+{
+ struct gas_query *gas = query->gas;
+
+ if (del_list)
+ dl_list_del(&query->list);
+
+ if (gas->work && gas->work->ctx == query) {
+ radio_work_done(gas->work);
+ gas->work = NULL;
+ }
+
+ wpabuf_free(query->req);
+ wpabuf_free(query->adv_proto);
+ wpabuf_free(query->resp);
+ os_free(query);
+}
+
+
static void gas_query_done(struct gas_query *gas,
struct gas_query_pending *query,
enum gas_query_result result)
@@ -124,10 +146,7 @@ static void gas_query_done(struct gas_query *gas,
dl_list_del(&query->list);
query->cb(query->ctx, query->addr, query->dialog_token, result,
query->adv_proto, query->resp, query->status_code);
- wpabuf_free(query->req);
- wpabuf_free(query->adv_proto);
- wpabuf_free(query->resp);
- os_free(query);
+ gas_query_free(query, 0);
}
@@ -516,11 +535,8 @@ static void gas_service_timeout(void *eloop_data, void *user_ctx)
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" : "");
+ if (conn) {
+ wpa_printf(MSG_DEBUG, "GAS: Delaying GAS query Tx while connection operation is in progress");
eloop_register_timeout(
GAS_SERVICE_RETRY_PERIOD_MS / 1000,
(GAS_SERVICE_RETRY_PERIOD_MS % 1000) * 1000,
@@ -531,9 +547,7 @@ static void gas_service_timeout(void *eloop_data, void *user_ctx)
if (gas_query_tx(gas, query, query->req) < 0) {
wpa_printf(MSG_DEBUG, "GAS: Failed to send Action frame to "
MACSTR, MAC2STR(query->addr));
- dl_list_del(&query->list);
- wpabuf_free(query->req);
- os_free(query);
+ gas_query_free(query, 1);
return;
}
gas->current = query;
@@ -559,6 +573,20 @@ static int gas_query_dialog_token_available(struct gas_query *gas,
}
+static void gas_query_start_cb(struct wpa_radio_work *work, int deinit)
+{
+ struct gas_query_pending *query = work->ctx;
+
+ if (deinit) {
+ gas_query_free(query, 1);
+ return;
+ }
+
+ query->gas->work = work;
+ gas_service_timeout(query->gas, query);
+}
+
+
/**
* gas_query_req - Request a GAS query
* @gas: GAS query data from gas_query_init()
@@ -599,6 +627,7 @@ int gas_query_req(struct gas_query *gas, const u8 *dst, int freq,
if (query == NULL)
return -1;
+ query->gas = gas;
os_memcpy(query->addr, dst, ETH_ALEN);
query->dialog_token = dialog_token;
query->freq = freq;
@@ -613,7 +642,11 @@ int gas_query_req(struct gas_query *gas, const u8 *dst, int freq,
" dialog_token=%u freq=%d",
MAC2STR(query->addr), query->dialog_token, query->freq);
- eloop_register_timeout(0, 0, gas_service_timeout, gas, query);
+ if (radio_add_work(gas->wpa_s, freq, "gas-query", 0, gas_query_start_cb,
+ query) < 0) {
+ gas_query_free(query, 1);
+ return -1;
+ }
return dialog_token;
}
@@ -634,9 +667,3 @@ void gas_query_cancel(struct gas_query *gas, const u8 *dst, u8 dialog_token)
gas_query_done(gas, query, GAS_QUERY_CANCELLED);
}
-
-
-int gas_query_in_progress(struct gas_query *gas)
-{
- return gas->current != NULL;
-}
diff --git a/wpa_supplicant/gas_query.h b/wpa_supplicant/gas_query.h
index 6b6c77c..5c3d161 100644
--- a/wpa_supplicant/gas_query.h
+++ b/wpa_supplicant/gas_query.h
@@ -18,7 +18,6 @@ struct gas_query * gas_query_init(struct wpa_supplicant *wpa_s);
void gas_query_deinit(struct gas_query *gas);
int gas_query_rx(struct gas_query *gas, const u8 *da, const u8 *sa,
const u8 *bssid, const u8 *data, size_t len, int freq);
-int gas_query_in_progress(struct gas_query *gas);
/**
* enum gas_query_result - GAS query result
diff --git a/wpa_supplicant/scan.c b/wpa_supplicant/scan.c
index b36c87c..b84d537 100644
--- a/wpa_supplicant/scan.c
+++ b/wpa_supplicant/scan.c
@@ -21,7 +21,6 @@
#include "hs20_supplicant.h"
#include "notify.h"
#include "bss.h"
-#include "gas_query.h"
#include "scan.h"
@@ -582,14 +581,6 @@ static void wpa_supplicant_scan(void *eloop_ctx, void *timeout_ctx)
}
#endif /* CONFIG_P2P */
-#ifdef CONFIG_GAS
- if (gas_query_in_progress(wpa_s->gas)) {
- wpa_dbg(wpa_s, MSG_DEBUG, "Delay scan while GAS query is in progress");
- wpa_supplicant_req_scan(wpa_s, 1, 0);
- return;
- }
-#endif /* CONFIG_GAS */
-
if (wpa_s->conf->ap_scan == 2)
max_ssids = 1;
else {