/** * gas_query_req - Request a GAS query * @gas: GAS query data from gas_query_init() * @dst: Destination MAC address for the query * @freq: Frequency (in MHz) for the channel on which to send the query * @req: GAS query payload (to be freed by gas_query module in case of success * return) * @cb: Callback function for reporting GAS query result and response * @ctx: Context pointer to use with the @cb call * Returns: dialog token (>= 0) on success or -1 on failure */ 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; static int next_start = 0; if (wpabuf_len(req) < 3) return -1; for (dialog_token = 0; dialog_token < 256; dialog_token++) { if (gas_query_dialog_token_available( gas, dst, (next_start + dialog_token) % 256)) break; } if (dialog_token == 256) return -1; /* Too many pending queries */ dialog_token = (next_start + dialog_token) % 256; next_start = (dialog_token + 1) % 256; query = os_zalloc(sizeof(*query)); if (query == NULL) return -1; query->gas = gas; os_memcpy(query->addr, dst, ETH_ALEN); query->dialog_token = dialog_token; query->freq = freq; query->cb = cb; query->ctx = ctx; query->req = req; dl_list_add(&gas->pending, &query->list); *(wpabuf_mhead_u8(req) + 2) = dialog_token; wpa_msg(gas->wpa_s, MSG_INFO, GAS_QUERY_START "addr=" MACSTR " dialog_token=%u freq=%d", MAC2STR(query->addr), query->dialog_token, query->freq); 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; }
/** * gas_query_req - Request a GAS query * @gas: GAS query data from gas_query_init() * @dst: Destination MAC address for the query * @freq: Frequency (in MHz) for the channel on which to send the query * @req: GAS query payload (to be freed by gas_query module in case of success * return) * @cb: Callback function for reporting GAS query result and response * @ctx: Context pointer to use with the @cb call * Returns: dialog token (>= 0) on success or -1 on failure */ 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; dialog_token = gas_query_new_dialog_token(gas, dst); if (dialog_token < 0) return -1; query = os_zalloc(sizeof(*query)); if (query == NULL) return -1; query->gas = gas; os_memcpy(query->addr, dst, ETH_ALEN); query->dialog_token = dialog_token; query->freq = freq; query->cb = cb; query->ctx = ctx; query->req = req; dl_list_add(&gas->pending, &query->list); *(wpabuf_mhead_u8(req) + 2) = dialog_token; wpa_msg(gas->wpa_s, MSG_INFO, GAS_QUERY_START "addr=" MACSTR " dialog_token=%u freq=%d", MAC2STR(query->addr), query->dialog_token, query->freq); if (radio_add_work(gas->wpa_s, freq, "gas-query", 0, gas_query_start_cb, query) < 0) { query->req = NULL; /* caller will free this in error case */ gas_query_free(query, 1); return -1; } return dialog_token; }
void sme_authenticate(struct wpa_supplicant *wpa_s, struct wpa_bss *bss, struct wpa_ssid *ssid) { struct wpa_connect_work *cwork; if (bss == NULL || ssid == NULL) return; if (wpa_s->connect_work) { wpa_dbg(wpa_s, MSG_DEBUG, "SME: Reject sme_authenticate() call since connect_work exist"); return; } if (radio_work_pending(wpa_s, "sme-connect")) { /* * The previous sme-connect work might no longer be valid due to * the fact that the BSS list was updated. In addition, it makes * sense to adhere to the 'newer' decision. */ wpa_dbg(wpa_s, MSG_DEBUG, "SME: Remove previous pending sme-connect"); radio_remove_works(wpa_s, "sme-connect", 0, 1); } cwork = os_zalloc(sizeof(*cwork)); if (cwork == NULL) return; cwork->bss = bss; cwork->ssid = ssid; cwork->sme = 1; #ifdef CONFIG_SAE wpa_s->sme.sae.state = SAE_NOTHING; wpa_s->sme.sae.send_confirm = 0; wpa_s->sme.sae_group_index = 0; #endif /* CONFIG_SAE */ if (radio_add_work(wpa_s, bss->freq, "sme-connect", 1, sme_auth_start_cb, cwork) < 0) wpas_connect_work_free(cwork); }
/** * wpa_supplicant_trigger_scan - Request driver to start a scan * @wpa_s: Pointer to wpa_supplicant data * @params: Scan parameters * Returns: 0 on success, -1 on failure */ int wpa_supplicant_trigger_scan(struct wpa_supplicant *wpa_s, struct wpa_driver_scan_params *params) { struct wpa_driver_scan_params *ctx; if (wpa_s->scan_work) { wpa_dbg(wpa_s, MSG_INFO, "Reject scan trigger since one is already pending"); return -1; } ctx = wpa_scan_clone_params(params); if (ctx == NULL) return -1; if (radio_add_work(wpa_s, 0, "scan", 0, wpas_trigger_scan_cb, ctx) < 0) { wpa_scan_free_params(ctx); return -1; } return 0; }