Home | History | Annotate | Download | only in wpa_supplicant

Lines Matching refs:gas

2  * Generic advertisement service (GAS) query
16 #include "common/gas.h"
26 /** GAS query timeout in seconds */
29 /* GAS query wait-time / duration in ms */
36 * struct gas_query_pending - Pending GAS query
40 struct gas_query *gas;
64 * struct gas_query - Internal GAS query data
80 static void gas_query_tx_initial_req(struct gas_query *gas,
82 static int gas_query_new_dialog_token(struct gas_query *gas, const u8 *dst);
96 * gas_query_init - Initialize GAS query component
98 * Returns: Pointer to GAS query data or %NULL on failure
102 struct gas_query *gas;
104 gas = os_zalloc(sizeof(*gas));
105 if (gas == NULL)
108 gas->wpa_s = wpa_s;
109 dl_list_init(&gas->pending);
111 return gas;
140 struct gas_query *gas = query->gas;
145 if (gas->work && gas->work->ctx == query) {
146 radio_work_done(gas->work);
147 gas->work = NULL;
157 static void gas_query_done(struct gas_query *gas,
161 wpa_msg(gas->wpa_s, MSG_INFO, GAS_QUERY_DONE "addr=" MACSTR
165 if (gas->current == query)
166 gas->current = NULL;
168 offchannel_send_action_done(gas->wpa_s);
169 eloop_cancel_timeout(gas_query_tx_comeback_timeout, gas, query);
170 eloop_cancel_timeout(gas_query_timeout, gas, query);
171 eloop_cancel_timeout(gas_query_rx_comeback_timeout, gas, query);
180 * gas_query_deinit - Deinitialize GAS query component
181 * @gas: GAS query data from gas_query_init()
183 void gas_query_deinit(struct gas_query *gas)
187 if (gas == NULL)
190 dl_list_for_each_safe(query, next, &gas->pending,
192 gas_query_done(gas, query, GAS_QUERY_DELETED_AT_DEINIT);
194 os_free(gas);
199 gas_query_get_pending(struct gas_query *gas, const u8 *addr, u8 dialog_token)
202 struct wpa_supplicant *wpa_s = gas->wpa_s;
204 dl_list_for_each(q, &gas->pending, struct gas_query_pending, list) {
221 wpa_printf(MSG_DEBUG, "GAS: No memory to store the response");
236 struct gas_query *gas = wpa_s->gas;
239 if (gas->current == NULL) {
240 wpa_printf(MSG_DEBUG, "GAS: Unexpected TX status: freq=%u dst="
246 query = gas->current;
249 wpa_printf(MSG_DEBUG, "GAS: TX status: freq=%u dst=" MACSTR
253 wpa_printf(MSG_DEBUG, "GAS: TX status for unexpected destination");
260 eloop_cancel_timeout(gas_query_timeout, gas, query);
262 wpa_printf(MSG_DEBUG, "GAS: No ACK to GAS request");
264 gas_query_timeout, gas, query);
267 gas_query_timeout, gas, query);
271 gas, query);
274 gas_query_rx_comeback_timeout, gas, query);
278 eloop_cancel_timeout(gas_query_timeout, gas, query);
279 eloop_register_timeout(0, 0, gas_query_timeout, gas, query);
284 static int gas_query_tx(struct gas_query *gas, struct gas_query_pending *query,
287 int res, prot = pmf_in_use(gas->wpa_s, query->addr);
293 wpa_printf(MSG_DEBUG, "GAS: Send action frame to " MACSTR " len=%u "
302 if (gas->wpa_s->max_remain_on_chan &&
303 wait_time > gas->wpa_s->max_remain_on_chan)
304 wait_time = gas->wpa_s->max_remain_on_chan;
306 (!gas->wpa_s->conf->gas_address3 ||
307 (gas->wpa_s->current_ssid &&
308 gas->wpa_s->wpa_state >= WPA_ASSOCIATED &&
309 ether_addr_equal(query->addr, gas->wpa_s->bssid))))
314 res = offchannel_send_action(gas->wpa_s, query->freq, query->addr,
325 static void gas_query_tx_comeback_req(struct gas_query *gas,
333 gas_query_done(gas, query, GAS_QUERY_INTERNAL_ERROR);
340 if (gas_query_tx(gas, query, req, wait_time) < 0) {
341 wpa_printf(MSG_DEBUG, "GAS: Failed to send Action frame to "
343 gas_query_done(gas, query, GAS_QUERY_INTERNAL_ERROR);
352 struct gas_query *gas = eloop_data;
357 "GAS: No response to comeback request received (retry=%u)",
359 if (gas->current != query || query->retry)
361 dialog_token = gas_query_new_dialog_token(gas, query->addr);
365 "GAS: Retry GAS query due to comeback response timeout");
373 eloop_cancel_timeout(gas_query_tx_comeback_timeout, gas, query);
374 eloop_cancel_timeout(gas_query_timeout, gas, query);
375 gas_query_tx_initial_req(gas, query);
381 struct gas_query *gas = eloop_data;
384 wpa_printf(MSG_DEBUG, "GAS: Comeback timeout for request to " MACSTR,
386 gas_query_tx_comeback_req(gas, query);
390 static void gas_query_tx_comeback_req_delay(struct gas_query *gas,
397 offchannel_send_action_done(gas->wpa_s);
403 wpa_printf(MSG_DEBUG, "GAS: Send comeback request to " MACSTR
405 eloop_cancel_timeout(gas_query_tx_comeback_timeout, gas, query);
407 gas, query);
411 static void gas_query_rx_initial(struct gas_query *gas,
416 wpa_printf(MSG_DEBUG, "GAS: Received initial response from "
422 gas_query_done(gas, query, GAS_QUERY_INTERNAL_ERROR);
427 eloop_cancel_timeout(gas_query_timeout, gas, query);
429 gas_query_tx_comeback_req_delay(gas, query, comeback_delay);
435 gas_query_done(gas, query, GAS_QUERY_INTERNAL_ERROR);
439 gas_query_done(gas, query, GAS_QUERY_SUCCESS);
443 static void gas_query_rx_comeback(struct gas_query *gas,
449 wpa_printf(MSG_DEBUG, "GAS: Received comeback response from "
454 eloop_cancel_timeout(gas_query_rx_comeback_timeout, gas, query);
459 wpa_printf(MSG_DEBUG, "GAS: Advertisement Protocol changed "
462 gas_query_done(gas, query, GAS_QUERY_PEER_ERROR);
468 wpa_printf(MSG_DEBUG, "GAS: Invalid comeback response "
471 gas_query_done(gas, query, GAS_QUERY_PEER_ERROR);
474 gas_query_tx_comeback_req_delay(gas, query, comeback_delay);
479 wpa_printf(MSG_DEBUG, "GAS: Unexpected frag_id in response "
482 wpa_printf(MSG_DEBUG, "GAS: Drop frame as possible "
486 gas_query_done(gas, query, GAS_QUERY_PEER_ERROR);
492 gas_query_done(gas, query, GAS_QUERY_INTERNAL_ERROR);
497 gas_query_tx_comeback_req(gas, query);
501 gas_query_done(gas, query, GAS_QUERY_SUCCESS);
507 * @gas: GAS query data from gas_query_init()
515 * Returns: 0 if the Public Action frame was a GAS frame or -1 if not
517 int gas_query_rx(struct gas_query *gas, const u8 *da, const u8 *sa,
529 if (gas == NULL || len < 4)
538 return -1; /* Not a GAS response */
541 pmf = pmf_in_use(gas->wpa_s, sa);
543 wpa_printf(MSG_DEBUG, "GAS: Drop unexpected protected GAS frame when PMF is disabled");
547 wpa_printf(MSG_DEBUG, "GAS: Drop unexpected unprotected GAS frame when PMF is enabled");
551 query = gas_query_get_pending(gas, sa, dialog_token);
553 wpa_printf(MSG_DEBUG, "GAS: No pending query found for " MACSTR
558 wpa_printf(MSG_DEBUG, "GAS: Response in %d ms from " MACSTR,
562 wpa_printf(MSG_DEBUG, "GAS: Unexpected initial response from "
569 wpa_printf(MSG_DEBUG, "GAS: Unexpected comeback response from "
580 wpa_printf(MSG_DEBUG, "GAS: Allow non-zero status for outstanding comeback response");
582 wpa_printf(MSG_DEBUG, "GAS: Query to " MACSTR " dialog token "
585 gas_query_done(gas, query, GAS_QUERY_FAILURE);
609 wpa_printf(MSG_DEBUG, "GAS: No room for Advertisement "
616 wpa_printf(MSG_DEBUG, "GAS: Unexpected Advertisement "
629 wpa_printf(MSG_DEBUG, "GAS: No room for GAS Response Length");
637 wpa_printf(MSG_DEBUG, "GAS: Truncated Query Response in "
643 wpa_printf(MSG_DEBUG, "GAS: Ignore %u octets of extra data "
649 gas_query_rx_comeback(gas, query, adv_proto, adv_proto_len,
653 gas_query_rx_initial(gas, query, adv_proto, adv_proto_len,
662 struct gas_query *gas = eloop_data;
665 wpa_printf(MSG_DEBUG, "GAS: No response received for query to " MACSTR
668 gas_query_done(gas, query, GAS_QUERY_TIMEOUT);
672 static int gas_query_dialog_token_available(struct gas_query *gas,
676 dl_list_for_each(q, &gas->pending, struct gas_query_pending, list) {
689 struct gas_query *gas = query->gas;
690 struct wpa_supplicant *wpa_s = gas->wpa_s;
694 gas->work = NULL;
695 gas_query_done(gas, query, GAS_QUERY_DELETED_AT_DEINIT);
706 "Failed to assign random MAC address for GAS");
714 gas->work = work;
715 gas_query_tx_initial_req(gas, query);
719 static void gas_query_tx_initial_req(struct gas_query *gas,
722 if (gas_query_tx(gas, query, query->req,
724 wpa_printf(MSG_DEBUG, "GAS: Failed to send Action frame to "
726 gas_query_done(gas, query, GAS_QUERY_INTERNAL_ERROR);
729 gas->current = query;
731 wpa_printf(MSG_DEBUG, "GAS: Starting query timeout for dialog token %u",
734 gas_query_timeout, gas, query);
738 static int gas_query_new_dialog_token(struct gas_query *gas, const u8 *dst)
743 /* There should never be more than couple active GAS queries in
752 if (gas_query_dialog_token_available(gas, dst, dialog_token))
761 static int gas_query_set_sa(struct gas_query *gas,
764 struct wpa_supplicant *wpa_s = gas->wpa_s;
775 "GAS: Use own MAC address as the transmitter address%s%s%s",
790 if (wpa_s->conf->gas_rand_mac_addr == gas->last_rand_sa_type &&
791 gas->last_mac_addr_rand.sec != 0 &&
792 !os_reltime_expired(&now, &gas->last_mac_addr_rand,
795 "GAS: Use the previously selected random transmitter address "
796 MACSTR, MAC2STR(gas->rand_addr));
797 os_memcpy(query->sa, gas->rand_addr, ETH_ALEN);
802 random_mac_addr(gas->rand_addr) < 0) {
803 wpa_printf(MSG_ERROR, "GAS: Failed to get random address");
808 random_mac_addr_keep_oui(gas->rand_addr) < 0) {
810 "GAS: Failed to get random address with same OUI");
814 wpa_printf(MSG_DEBUG, "GAS: Use a new random transmitter address "
815 MACSTR, MAC2STR(gas->rand_addr));
816 os_memcpy(query->sa, gas->rand_addr, ETH_ALEN);
817 os_get_reltime(&gas->last_mac_addr_rand);
818 gas->last_rand_sa_type = wpa_s->conf->gas_rand_mac_addr;
825 * gas_query_req - Request a GAS query
826 * @gas: GAS query data from gas_query_init()
832 * @req: GAS query payload (to be freed by gas_query module in case of success
834 * @cb: Callback function for reporting GAS query result and response
838 int gas_query_req(struct gas_query *gas, const u8 *dst, int freq,
852 dialog_token = gas_query_new_dialog_token(gas, dst);
860 query->gas = gas;
862 if (gas_query_set_sa(gas, query)) {
873 dl_list_add(&gas->pending, &query->list);
877 wpa_msg(gas->wpa_s, MSG_INFO, GAS_QUERY_START "addr=" MACSTR
881 if (radio_add_work(gas->wpa_s, freq, "gas-query", 0, gas_query_start_cb,
892 int gas_query_stop(struct gas_query *gas, u8 dialog_token)
896 dl_list_for_each(query, &gas->pending, struct gas_query_pending, list) {
898 if (!gas->work) {
905 radio_remove_pending_work(gas->wpa_s, query);
907 gas_query_done(gas, query, GAS_QUERY_STOPPED);