static void gas_query_start_cb(struct wpa_radio_work *work, int deinit) { struct gas_query_pending *query = work->ctx; struct gas_query *gas = query->gas; if (deinit) { if (work->started) { gas->work = NULL; gas_query_done(gas, query, GAS_QUERY_DELETED_AT_DEINIT); return; } gas_query_free(query, 1); return; } gas->work = work; if (gas_query_tx(gas, query, query->req) < 0) { wpa_printf(MSG_DEBUG, "GAS: Failed to send Action frame to " MACSTR, MAC2STR(query->addr)); gas_query_free(query, 1); return; } gas->current = query; wpa_printf(MSG_DEBUG, "GAS: Starting query timeout for dialog token %u", query->dialog_token); eloop_register_timeout(GAS_QUERY_TIMEOUT_PERIOD, 0, gas_query_timeout, gas, query); }
int gas_query_req(struct gas_query *gas, const u8 *dst, int freq, struct wpabuf *req, void (*cb)(void *ctx, const u8 *dst, u8 dialog_token, enum gas_query_result result, const struct wpabuf *adv_proto, const struct wpabuf *resp, u16 status_code), void *ctx) { struct gas_query_pending *query; int dialog_token; if (wpabuf_len(req) < 3) return -1; for (dialog_token = 0; dialog_token < 256; dialog_token++) { if (gas_query_dialog_token_available(gas, dst, dialog_token)) break; } if (dialog_token == 256) return -1; /* Too many pending queries */ query = os_zalloc(sizeof(*query)); if (query == NULL) return -1; os_memcpy(query->addr, dst, ETH_ALEN); query->dialog_token = dialog_token; query->freq = freq; query->cb = cb; query->ctx = ctx; dl_list_add(&gas->pending, &query->list); *(wpabuf_mhead_u8(req) + 2) = dialog_token; wpa_printf(MSG_DEBUG, "GAS: Starting request for " MACSTR " dialog_token %u", MAC2STR(dst), dialog_token); if (gas_query_tx(gas, query, req) < 0) { wpa_printf(MSG_DEBUG, "GAS: Failed to send Action frame to " MACSTR, MAC2STR(query->addr)); os_free(query); return -1; } eloop_register_timeout(GAS_QUERY_TIMEOUT, 0, gas_query_timeout, gas, query); return dialog_token; }
static void gas_query_tx_initial_req(struct gas_query *gas, struct gas_query_pending *query) { if (gas_query_tx(gas, query, query->req, GAS_QUERY_WAIT_TIME_INITIAL) < 0) { wpa_printf(MSG_DEBUG, "GAS: Failed to send Action frame to " MACSTR, MAC2STR(query->addr)); gas_query_done(gas, query, GAS_QUERY_INTERNAL_ERROR); return; } gas->current = query; wpa_printf(MSG_DEBUG, "GAS: Starting query timeout for dialog token %u", query->dialog_token); eloop_register_timeout(GAS_QUERY_TIMEOUT_PERIOD, 0, gas_query_timeout, gas, query); }
static void gas_query_tx_comeback_req(struct gas_query *gas, struct gas_query_pending *query) { struct wpabuf *req; req = gas_build_comeback_req(query->dialog_token); if (req == NULL) { gas_query_done(gas, query, GAS_QUERY_INTERNAL_ERROR); return; } if (gas_query_tx(gas, query, req) < 0) { wpa_printf(MSG_DEBUG, "GAS: Failed to send Action frame to " MACSTR, MAC2STR(query->addr)); gas_query_done(gas, query, GAS_QUERY_INTERNAL_ERROR); } wpabuf_free(req); }
static void gas_query_start_cb(struct wpa_radio_work *work, int deinit) { struct gas_query_pending *query = work->ctx; struct gas_query *gas = query->gas; struct wpa_supplicant *wpa_s = gas->wpa_s; if (deinit) { if (work->started) { gas->work = NULL; gas_query_done(gas, query, GAS_QUERY_DELETED_AT_DEINIT); return; } gas_query_free(query, 1); return; } if (wpas_update_random_addr_disassoc(wpa_s) < 0) { wpa_msg(wpa_s, MSG_INFO, "Failed to assign random MAC address for GAS"); gas_query_free(query, 1); radio_work_done(work); return; } gas->work = work; if (gas_query_tx(gas, query, query->req) < 0) { wpa_printf(MSG_DEBUG, "GAS: Failed to send Action frame to " MACSTR, MAC2STR(query->addr)); gas_query_free(query, 1); return; } gas->current = query; wpa_printf(MSG_DEBUG, "GAS: Starting query timeout for dialog token %u", query->dialog_token); eloop_register_timeout(GAS_QUERY_TIMEOUT_PERIOD, 0, gas_query_timeout, gas, query); }
static void gas_query_tx_comeback_req(struct gas_query *gas, struct gas_query_pending *query) { struct wpabuf *req; unsigned int wait_time; req = gas_build_comeback_req(query->dialog_token); if (req == NULL) { gas_query_done(gas, query, GAS_QUERY_INTERNAL_ERROR); return; } wait_time = (query->retry || !query->offchannel_tx_started) ? GAS_QUERY_WAIT_TIME_INITIAL : GAS_QUERY_WAIT_TIME_COMEBACK; if (gas_query_tx(gas, query, req, wait_time) < 0) { wpa_printf(MSG_DEBUG, "GAS: Failed to send Action frame to " MACSTR, MAC2STR(query->addr)); gas_query_done(gas, query, GAS_QUERY_INTERNAL_ERROR); } wpabuf_free(req); }