diff --git a/wpa_supplicant/gas_query.c b/wpa_supplicant/gas_query.c index dd10a75a9..fda7c849a 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 * * 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 6b6c77ce2..5c3d161ad 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 b36c87c6e..b84d537d8 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 {