From bfc86f6094504f38f42b10eed02e7e099a26fdf3 Mon Sep 17 00:00:00 2001 From: Kapil Gupta Date: Mon, 7 Oct 2024 14:38:56 +0530 Subject: [PATCH] fix(esp_wifi): Removal of task posting code and use pptask instead --- components/esp_common/src/esp_err_to_name.c | 3 + .../esp_supplicant/include/esp_dpp.h | 3 +- .../src/crypto/crypto_mbedtls-ec.c | 16 +- .../esp_supplicant/src/esp_dpp.c | 761 +++++++++--------- .../esp_supplicant/src/esp_dpp_i.h | 26 +- .../esp_supplicant/src/esp_wpa_main.c | 2 +- components/wpa_supplicant/src/common/dpp.c | 2 +- 7 files changed, 384 insertions(+), 429 deletions(-) diff --git a/components/esp_common/src/esp_err_to_name.c b/components/esp_common/src/esp_err_to_name.c index 1c342e6b2a..606e78124f 100644 --- a/components/esp_common/src/esp_err_to_name.c +++ b/components/esp_common/src/esp_err_to_name.c @@ -474,6 +474,9 @@ static const esp_err_msg_t esp_err_msg_table[] = { ERR_TBL_IT(ESP_ERR_DPP_INVALID_LIST), /* 12443 0x309b Channel list given in esp_supp_dpp_bootstrap_gen() is not valid or too big */ +# endif +# ifdef ESP_ERR_DPP_CONF_TIMEOUT + ERR_TBL_IT(ESP_ERR_DPP_CONF_TIMEOUT), /* 12444 0x309c DPP Configuration was not received in time */ # endif // components/esp_common/include/esp_err.h # ifdef ESP_ERR_MESH_BASE diff --git a/components/wpa_supplicant/esp_supplicant/include/esp_dpp.h b/components/wpa_supplicant/esp_supplicant/include/esp_dpp.h index 909cea6f15..77c694f743 100644 --- a/components/wpa_supplicant/esp_supplicant/include/esp_dpp.h +++ b/components/wpa_supplicant/esp_supplicant/include/esp_dpp.h @@ -16,7 +16,6 @@ extern "C" { #endif -#define ESP_DPP_AUTH_TIMEOUT_SECS 2 #define ESP_DPP_MAX_CHAN_COUNT 5 #define ESP_ERR_DPP_FAILURE (ESP_ERR_WIFI_BASE + 151) /*!< Generic failure during DPP Operation */ @@ -24,7 +23,7 @@ extern "C" { #define ESP_ERR_DPP_INVALID_ATTR (ESP_ERR_WIFI_BASE + 153) /*!< Encountered invalid DPP Attribute */ #define ESP_ERR_DPP_AUTH_TIMEOUT (ESP_ERR_WIFI_BASE + 154) /*!< DPP Auth response was not received in time */ #define ESP_ERR_DPP_INVALID_LIST (ESP_ERR_WIFI_BASE + 155) /*!< Channel list given in esp_supp_dpp_bootstrap_gen() is not valid or too big */ -#define ESP_ERR_DPP_CONF_TIMEOUT (ESP_ERR_WIFI_BASE + 155) /*!< DPP Configuration was not recieved in time */ +#define ESP_ERR_DPP_CONF_TIMEOUT (ESP_ERR_WIFI_BASE + 156) /*!< DPP Configuration was not received in time */ /** @brief Types of Bootstrap Methods for DPP. */ typedef enum dpp_bootstrap_type { diff --git a/components/wpa_supplicant/esp_supplicant/src/crypto/crypto_mbedtls-ec.c b/components/wpa_supplicant/esp_supplicant/src/crypto/crypto_mbedtls-ec.c index 0a498e0664..6751d41b74 100644 --- a/components/wpa_supplicant/esp_supplicant/src/crypto/crypto_mbedtls-ec.c +++ b/components/wpa_supplicant/esp_supplicant/src/crypto/crypto_mbedtls-ec.c @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2015-2024 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2015-2025 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -844,21 +844,23 @@ int crypto_ec_key_verify_signature_r_s(struct crypto_ec_key *csign, void crypto_ec_key_debug_print(struct crypto_ec_key *key, const char *title) { -#ifdef DEBUG_PRINT +#if defined(CONFIG_LOG_DEFAULT_LEVEL_DEBUG) || defined(CONFIG_LOG_DEFAULT_LEVEL_VERBOSE) +#if defined(DEBUG_PRINT) mbedtls_pk_context *pkey = (mbedtls_pk_context *)key; mbedtls_ecp_keypair *ecp = mbedtls_pk_ec(*pkey); u8 x[32], y[32], d[32]; - wpa_printf(MSG_DEBUG, "curve: %s", + wpa_printf(MSG_EXCESSIVE, "curve: %s", mbedtls_ecp_curve_info_from_grp_id(ecp->MBEDTLS_PRIVATE(grp).id)->name); int len = mbedtls_mpi_size((mbedtls_mpi *)crypto_ec_get_prime((struct crypto_ec *)crypto_ec_get_group_from_key(key))); - wpa_printf(MSG_DEBUG, "prime len is %d", len); + wpa_printf(MSG_EXCESSIVE, "prime len is %d", len); crypto_ec_point_to_bin((struct crypto_ec *)crypto_ec_get_group_from_key(key), crypto_ec_key_get_public_key(key), x, y); crypto_bignum_to_bin(crypto_ec_key_get_private_key(key), d, len, len); - wpa_hexdump(MSG_DEBUG, "Q_x:", x, 32); - wpa_hexdump(MSG_DEBUG, "Q_y:", y, 32); - wpa_hexdump(MSG_DEBUG, "d: ", d, 32); + wpa_hexdump(MSG_EXCESSIVE, "Q_x:", x, 32); + wpa_hexdump(MSG_EXCESSIVE, "Q_y:", y, 32); + wpa_hexdump(MSG_EXCESSIVE, "d: ", d, 32); +#endif #endif } diff --git a/components/wpa_supplicant/esp_supplicant/src/esp_dpp.c b/components/wpa_supplicant/esp_supplicant/src/esp_dpp.c index 72b905f6d7..d984a49a07 100644 --- a/components/wpa_supplicant/esp_supplicant/src/esp_dpp.c +++ b/components/wpa_supplicant/esp_supplicant/src/esp_dpp.c @@ -21,68 +21,76 @@ #include "rsn_supp/pmksa_cache.h" #ifdef CONFIG_DPP -static void *s_dpp_task_hdl = NULL; -static void *s_dpp_evt_queue = NULL; -static void *s_dpp_api_lock = NULL; - -static bool s_dpp_listen_in_progress; -static struct esp_dpp_context_t s_dpp_ctx; -static wifi_action_rx_cb_t s_action_rx_cb = esp_supp_rx_action; -static uint8_t s_current_tx_op_id; -#define DPP_API_LOCK() os_mutex_lock(s_dpp_api_lock) -#define DPP_API_UNLOCK() os_mutex_unlock(s_dpp_api_lock) struct action_rx_param { u8 sa[ETH_ALEN]; u32 channel; u32 frm_len; u32 vendor_data_len; - struct ieee80211_action *action_frm; + struct ieee80211_action action_frm[]; }; -esp_err_t esp_dpp_post_evt(uint32_t evt_id, uint32_t data) +static void *s_dpp_api_lock = NULL; + +static bool s_dpp_listen_in_progress; +static struct esp_dpp_context_t s_dpp_ctx; +static int esp_supp_rx_action(uint8_t *hdr, uint8_t *payload, size_t len, uint8_t channel); +static wifi_action_rx_cb_t s_action_rx_cb = esp_supp_rx_action; +static uint8_t s_current_tx_op_id; +static void tx_status_handler(void *arg, esp_event_base_t event_base, + int32_t event_id, void *event_data); +static void roc_status_handler(void *arg, esp_event_base_t event_base, + int32_t event_id, void *event_data); +static esp_err_t dpp_api_lock(void) { - dpp_event_t evt; - esp_err_t ret = ESP_OK; + if (!s_dpp_api_lock) { + s_dpp_api_lock = os_recursive_mutex_create(); + } + if (!s_dpp_api_lock) { + wpa_printf(MSG_ERROR, "DPP: dpp_init: failed to create DPP API lock"); + return ESP_ERR_NO_MEM; + } - evt.id = evt_id; - evt.data = data; + os_mutex_lock(s_dpp_api_lock); + + return ESP_OK; +} + +static esp_err_t dpp_api_unlock(void) +{ if (s_dpp_api_lock) { - DPP_API_LOCK(); - } else { - ret = ESP_ERR_DPP_FAILURE; - goto end; + os_mutex_unlock(s_dpp_api_lock); } - if (os_queue_send(s_dpp_evt_queue, &evt, os_task_ms_to_tick(10)) != TRUE) { - DPP_API_UNLOCK(); - ret = ESP_ERR_DPP_FAILURE; - goto end; - } - if (evt_id != SIG_DPP_DEL_TASK) { - DPP_API_UNLOCK(); - } - wpa_printf(MSG_DEBUG, "DPP: Sent event %d to DPP task", evt_id); - return ret; -end: - wpa_printf(MSG_ERROR, "DPP: Failed to send event %d to DPP task", evt_id); - return ret; + return ESP_OK; } static uint8_t esp_dpp_deinit_auth(void) { - esp_err_t ret = esp_dpp_post_evt(SIG_DPP_DEINIT_AUTH, 0); - if (ESP_OK != ret) { - wpa_printf(MSG_ERROR, "Failed to post DPP auth deinit to DPP Task(status=%d)", ret); - return ret; + if (s_dpp_ctx.dpp_auth) { + dpp_auth_deinit(s_dpp_ctx.dpp_auth); + s_dpp_ctx.dpp_auth = NULL; } + return ESP_OK; } +static void listen_stop_handler(void *data, void *user_ctx) +{ + wifi_roc_req_t req = {0}; + + s_dpp_listen_in_progress = false; + req.ifx = WIFI_IF_STA; + req.type = WIFI_ROC_CANCEL; + + esp_wifi_remain_on_channel(&req); +} + static void esp_dpp_call_cb(esp_supp_dpp_event_t evt, void *data) { if (s_dpp_ctx.dpp_auth) { esp_dpp_deinit_auth(); + listen_stop_handler(NULL, NULL); } s_dpp_ctx.dpp_event_cb(evt, data); } @@ -93,7 +101,7 @@ static void esp_dpp_auth_conf_wait_timeout(void *eloop_ctx, void *timeout_ctx) return; } - wpa_printf(MSG_DEBUG, + wpa_printf(MSG_INFO, "DPP: Terminate authentication exchange due to Auth Confirm timeout"); esp_dpp_call_cb(ESP_SUPP_DPP_FAIL, (void *)ESP_ERR_DPP_AUTH_TIMEOUT); } @@ -107,14 +115,14 @@ esp_err_t esp_dpp_send_action_frame(uint8_t *dest_mac, const uint8_t *buf, uint3 } req->ifx = WIFI_IF_STA; - memcpy(req->dest_mac, dest_mac, ETH_ALEN); + os_memcpy(req->dest_mac, dest_mac, ETH_ALEN); req->no_ack = false; req->data_len = len; req->rx_cb = s_action_rx_cb; req->channel = channel; req->wait_time_ms = wait_time_ms; req->type = WIFI_OFFCHAN_TX_REQ; - memcpy(req->data, buf, req->data_len); + os_memcpy(req->data, buf, req->data_len); wpa_printf(MSG_DEBUG, "DPP: Mgmt Tx - MAC:" MACSTR ", Channel-%d, WaitT-%d", MAC2STR(dest_mac), channel, wait_time_ms); @@ -132,7 +140,28 @@ esp_err_t esp_dpp_send_action_frame(uint8_t *dest_mac, const uint8_t *buf, uint3 return ESP_OK; } -static void esp_dpp_rx_auth_req(struct action_rx_param *rx_param, uint8_t *dpp_data) +static void esp_dpp_auth_resp_retry_timeout(void *eloop_ctx, void *timeout_ctx) +{ + struct dpp_authentication *auth = s_dpp_ctx.dpp_auth; + + if (!auth || !auth->resp_msg) { + return; + } + + wpa_printf(MSG_DEBUG, + "DPP: Retry Authentication Response after timeout"); + wpa_msg(wpa_s, MSG_INFO, DPP_EVENT_TX "dst=" MACSTR + " chan=%u type=%d", + MAC2STR(auth->peer_mac_addr), auth->curr_chan, + DPP_PA_AUTHENTICATION_RESP); + + esp_dpp_send_action_frame(s_dpp_ctx.dpp_auth->peer_mac_addr, + wpabuf_head(s_dpp_ctx.dpp_auth->resp_msg), + wpabuf_len(s_dpp_ctx.dpp_auth->resp_msg), + auth->curr_chan, 1000 + OFFCHAN_TX_WAIT_TIME); +} + +static esp_err_t esp_dpp_rx_auth_req(struct action_rx_param *rx_param, uint8_t *dpp_data) { size_t len = rx_param->vendor_data_len - 2; const u8 *r_bootstrap, *i_bootstrap; @@ -140,14 +169,15 @@ static void esp_dpp_rx_auth_req(struct action_rx_param *rx_param, uint8_t *dpp_d struct dpp_bootstrap_info *own_bi; int rc; - wpa_printf(MSG_INFO, "DPP: Authentication Request from " MACSTR, MAC2STR(rx_param->sa)); + wpa_printf(MSG_INFO, "DPP: Authentication Request from " MACSTR " chan=%d", + MAC2STR(rx_param->sa), rx_param->channel); r_bootstrap = dpp_get_attr(dpp_data, len, DPP_ATTR_R_BOOTSTRAP_KEY_HASH, &r_bootstrap_len); if (!r_bootstrap || r_bootstrap_len != SHA256_MAC_LEN) { wpa_printf(MSG_INFO, "DPP: Missing or invalid Responder Bootstrapping Key Hash attribute"); rc = ESP_ERR_DPP_INVALID_ATTR; - goto fail; + return rc; } wpa_hexdump(MSG_MSGDUMP, "DPP: Responder Bootstrapping Key Hash", r_bootstrap, r_bootstrap_len); @@ -156,7 +186,7 @@ static void esp_dpp_rx_auth_req(struct action_rx_param *rx_param, uint8_t *dpp_d if (!i_bootstrap || i_bootstrap_len != SHA256_MAC_LEN) { wpa_printf(MSG_INFO, "DPP: Missing or invalid Initiator Bootstrapping Key Hash attribute"); rc = ESP_ERR_DPP_INVALID_ATTR; - goto fail; + return rc; } wpa_hexdump(MSG_MSGDUMP, "DPP: Initiator Bootstrapping Key Hash", i_bootstrap, i_bootstrap_len); @@ -166,25 +196,25 @@ static void esp_dpp_rx_auth_req(struct action_rx_param *rx_param, uint8_t *dpp_d if (os_memcmp(own_bi->pubkey_hash, r_bootstrap, SHA256_MAC_LEN)) { wpa_printf(MSG_INFO, "DPP: No matching own bootstrapping key found as responder - ignore message"); rc = ESP_ERR_DPP_INVALID_ATTR; - goto fail; + return ESP_ERR_DPP_INVALID_ATTR; } if (s_dpp_ctx.dpp_auth) { wpa_printf(MSG_DEBUG, "DPP: Already in DPP authentication exchange - ignore new one"); - return; + return ESP_OK; } s_dpp_ctx.dpp_auth = dpp_auth_req_rx(NULL, DPP_CAPAB_ENROLLEE, 0, NULL, own_bi, rx_param->channel, (const u8 *)&rx_param->action_frm->u.public_action.v, dpp_data, len); os_memcpy(s_dpp_ctx.dpp_auth->peer_mac_addr, rx_param->sa, ETH_ALEN); - wpa_printf(MSG_INFO, "DPP: Sending authentication response."); + wpa_printf(MSG_INFO, "DPP: Sending authentication response chan(%d)", rx_param->channel); + eloop_cancel_timeout(esp_dpp_auth_resp_retry_timeout, NULL, NULL); + eloop_register_timeout(0, 200000, esp_dpp_auth_resp_retry_timeout, NULL, NULL); esp_dpp_send_action_frame(rx_param->sa, wpabuf_head(s_dpp_ctx.dpp_auth->resp_msg), wpabuf_len(s_dpp_ctx.dpp_auth->resp_msg), - rx_param->channel, OFFCHAN_TX_WAIT_TIME); + rx_param->channel, 1000 + OFFCHAN_TX_WAIT_TIME); - return; -fail: - esp_dpp_call_cb(ESP_SUPP_DPP_FAIL, (void *)rc); + return ESP_OK; } static void gas_query_timeout(void *eloop_data, void *user_ctx) @@ -192,6 +222,7 @@ static void gas_query_timeout(void *eloop_data, void *user_ctx) struct dpp_authentication *auth = user_ctx; if (!auth || !auth->auth_success) { + wpa_printf(MSG_INFO, "DPP-GAS: Auth %p state not correct", auth); return; } @@ -212,7 +243,7 @@ static int gas_query_req_tx(struct dpp_authentication *auth) buf = dpp_build_conf_req_helper(auth, NULL, 0, NULL, supp_op_classes); if (!buf) { - wpa_printf(MSG_DEBUG, "DPP: No configuration request data available"); + wpa_printf(MSG_ERROR, "DPP: No configuration request data available"); esp_dpp_call_cb(ESP_SUPP_DPP_FAIL, (void *)ESP_ERR_DPP_FAILURE); return ESP_FAIL; } @@ -221,9 +252,10 @@ static int gas_query_req_tx(struct dpp_authentication *auth) MAC2STR(auth->peer_mac_addr), auth->curr_chan); ret = esp_dpp_send_action_frame(auth->peer_mac_addr, wpabuf_head(buf), wpabuf_len(buf), - auth->curr_chan, OFFCHAN_TX_WAIT_TIME); + auth->curr_chan, 1000 + OFFCHAN_TX_WAIT_TIME); if (ret != ESP_OK) { wpabuf_free(buf); + return ret; } auth->conf_req = buf; @@ -261,14 +293,14 @@ static int esp_dpp_handle_config_obj(struct dpp_authentication *auth, conf->connector); } if (s_dpp_listen_in_progress) { - esp_supp_dpp_stop_listen(); + listen_stop_handler(NULL, NULL); } esp_dpp_call_cb(ESP_SUPP_DPP_CFG_RECVD, wifi_cfg); return 0; } -static void esp_dpp_rx_auth_conf(struct action_rx_param *rx_param, uint8_t *dpp_data) +static int esp_dpp_rx_auth_conf(struct action_rx_param *rx_param, uint8_t *dpp_data) { struct dpp_authentication *auth = s_dpp_ctx.dpp_auth; struct ieee80211_public_action *public_action = @@ -281,35 +313,31 @@ static void esp_dpp_rx_auth_conf(struct action_rx_param *rx_param, uint8_t *dpp_ if (!auth) { wpa_printf(MSG_DEBUG, "DPP: No DPP Authentication in progress - drop"); - rc = ESP_ERR_DPP_FAILURE; - goto fail; + return ESP_ERR_DPP_FAILURE; } if (os_memcmp(rx_param->sa, auth->peer_mac_addr, ETH_ALEN) != 0) { wpa_printf(MSG_DEBUG, "DPP: MAC address mismatch (expected " MACSTR ") - drop", MAC2STR(auth->peer_mac_addr)); - rc = ESP_ERR_DPP_FAILURE; - goto fail; + return ESP_ERR_DPP_FAILURE; } eloop_cancel_timeout(esp_dpp_auth_conf_wait_timeout, NULL, NULL); if (dpp_auth_conf_rx(auth, (const u8 *)&public_action->v, dpp_data, len) < 0) { - wpa_printf(MSG_DEBUG, "DPP: Authentication failed"); - rc = ESP_ERR_DPP_FAILURE; - goto fail; + wpa_printf(MSG_ERROR, "DPP: Authentication failed"); + return ESP_ERR_DPP_FAILURE; } /* Send GAS Query Req */ - if (gas_query_req_tx(auth) != ESP_OK) { - goto fail; + rc = gas_query_req_tx(auth); + if (rc != ESP_OK) { + wpa_printf(MSG_ERROR, "DPP: GAS query Tx failed"); + return rc; } - return; - -fail: - esp_dpp_call_cb(ESP_SUPP_DPP_FAIL, (void *)rc); + return rc; } static esp_err_t esp_dpp_rx_peer_disc_resp(struct action_rx_param *rx_param) @@ -328,7 +356,7 @@ static esp_err_t esp_dpp_rx_peer_disc_resp(struct action_rx_param *rx_param) struct rsn_pmksa_cache_entry *entry = NULL; int i = 0; - if (!rx_param || !rx_param->action_frm) { + if (!rx_param) { return ESP_ERR_INVALID_ARG; } @@ -444,26 +472,25 @@ static esp_err_t esp_dpp_rx_frm(struct action_rx_param *rx_param) if (crypto_suit != 1) { wpa_printf(MSG_ERROR, "DPP: Unsupported crypto suit"); - esp_dpp_call_cb(ESP_SUPP_DPP_FAIL, (void *)ESP_ERR_NOT_SUPPORTED); - ret = ESP_FAIL; - } else { - switch (type) { - case DPP_PA_AUTHENTICATION_REQ: - esp_dpp_rx_auth_req(rx_param, &tmp[2]); - break; - case DPP_PA_AUTHENTICATION_CONF: - esp_dpp_rx_auth_conf(rx_param, &tmp[2]); - break; - case DPP_PA_PEER_DISCOVERY_RESP: - ret = esp_dpp_rx_peer_disc_resp(rx_param); - break; - } + return ESP_FAIL; + } + + switch (type) { + case DPP_PA_AUTHENTICATION_REQ: + ret = esp_dpp_rx_auth_req(rx_param, &tmp[2]); + break; + case DPP_PA_AUTHENTICATION_CONF: + ret = esp_dpp_rx_auth_conf(rx_param, &tmp[2]); + break; + case DPP_PA_PEER_DISCOVERY_RESP: + ret = esp_dpp_rx_peer_disc_resp(rx_param); + break; } return ret; } -static void gas_query_resp_rx(struct action_rx_param *rx_param) +static esp_err_t gas_query_resp_rx(struct action_rx_param *rx_param) { struct dpp_authentication *auth = s_dpp_ctx.dpp_auth; uint8_t *pos = rx_param->action_frm->u.public_action.v.pa_gas_resp.data; @@ -472,77 +499,79 @@ static void gas_query_resp_rx(struct action_rx_param *rx_param) if (pos[1] == WLAN_EID_VENDOR_SPECIFIC && pos[2] == 5 && WPA_GET_BE24(&pos[3]) == OUI_WFA && pos[6] == 0x1a && pos[7] == 1 && auth) { + eloop_cancel_timeout(gas_query_timeout, NULL, auth); if (dpp_conf_resp_rx(auth, resp, rx_param->vendor_data_len - 2) < 0) { - wpa_printf(MSG_DEBUG, "DPP: Configuration attempt failed"); + wpa_printf(MSG_INFO, "DPP: Configuration attempt failed"); goto fail; } for (i = 0; i < auth->num_conf_obj; i++) { res = esp_dpp_handle_config_obj(auth, &auth->conf_obj[i]); if (res < 0) { + wpa_printf(MSG_INFO, "DPP: Configuration parsing failed"); goto fail; } } } - return; + return ESP_OK; fail: - esp_dpp_call_cb(ESP_SUPP_DPP_FAIL, (void *)ESP_ERR_DPP_FAILURE); + return ESP_FAIL; } -static esp_err_t esp_dpp_rx_action(struct action_rx_param *rx_param) +static void esp_dpp_rx_action(void *data, void *user_ctx) { - + struct action_rx_param *rx_param = data; + struct ieee80211_public_action *public_action; int ret = ESP_OK; if (!rx_param) { - return ESP_ERR_INVALID_ARG; + return; } - if (rx_param->action_frm->category == WLAN_ACTION_PUBLIC) { - struct ieee80211_public_action *public_action = - &rx_param->action_frm->u.public_action; + /* we don't cater other action frames except public here */ + if (rx_param->action_frm->category != WLAN_ACTION_PUBLIC) { + return; + } - wpa_printf(MSG_DEBUG, "DPP: Rx Public Action frame: action - %d", - public_action->action); + public_action = &rx_param->action_frm->u.public_action; - if (public_action->action == WLAN_PA_VENDOR_SPECIFIC && - WPA_GET_BE24(public_action->v.pa_vendor_spec.oui) == OUI_WFA && - public_action->v.pa_vendor_spec.wfa_stype == DPP_OUI_TYPE) { + wpa_printf(MSG_DEBUG, "DPP: Rx Public Action frame: action - %d", + public_action->action); - rx_param->vendor_data_len = rx_param->frm_len - - (size_t)(public_action->v.pa_vendor_spec.vendor_data - - (u8 *)rx_param->action_frm); + if (public_action->action == WLAN_PA_VENDOR_SPECIFIC && + WPA_GET_BE24(public_action->v.pa_vendor_spec.oui) == OUI_WFA && + public_action->v.pa_vendor_spec.wfa_stype == DPP_OUI_TYPE) { - if (s_dpp_listen_in_progress) { - esp_supp_dpp_stop_listen(); - } + rx_param->vendor_data_len = rx_param->frm_len - + (size_t)(public_action->v.pa_vendor_spec.vendor_data - + (u8 *)rx_param->action_frm); - ret = esp_dpp_rx_frm(rx_param); - } else if (public_action->action == WLAN_PA_GAS_INITIAL_RESP && - public_action->v.pa_gas_resp.type == WLAN_EID_ADV_PROTO && - public_action->v.pa_gas_resp.length == 8 && - public_action->v.pa_gas_resp.status_code == 0) { - - rx_param->vendor_data_len = rx_param->frm_len - - (size_t)(public_action->v.pa_gas_resp.data + - public_action->v.pa_gas_resp.length - - (u8 *)rx_param->action_frm); - - wpa_printf(MSG_DEBUG, "DPP: Gas response received"); - gas_query_resp_rx(rx_param); + if (s_dpp_listen_in_progress) { + listen_stop_handler(NULL, NULL); } + + ret = esp_dpp_rx_frm(rx_param); + } else if (public_action->action == WLAN_PA_GAS_INITIAL_RESP && + public_action->v.pa_gas_resp.type == WLAN_EID_ADV_PROTO && + public_action->v.pa_gas_resp.length == 8 && + public_action->v.pa_gas_resp.status_code == 0) { + + rx_param->vendor_data_len = rx_param->frm_len - + (size_t)(public_action->v.pa_gas_resp.data + + public_action->v.pa_gas_resp.length - + (u8 *)rx_param->action_frm); + + wpa_printf(MSG_DEBUG, "DPP: Gas response received"); + ret = gas_query_resp_rx(rx_param); } - os_free(rx_param->action_frm); os_free(rx_param); - return ret; -} -void esp_dpp_rx_action_eloop(void *data, void *user_ctx) -{ - esp_dpp_rx_action(data); + if (ret != ESP_OK) { + esp_dpp_call_cb(ESP_SUPP_DPP_FAIL, (void *)ESP_ERR_DPP_FAILURE); + } } void esp_dpp_listen_next_channel(void *data, void *user_ctx) @@ -551,187 +580,116 @@ void esp_dpp_listen_next_channel(void *data, void *user_ctx) static int counter; int channel; esp_err_t ret = 0; + wifi_roc_req_t req = {0}; if (p->num_chan <= 0) { wpa_printf(MSG_ERROR, "Listen channel not set"); return; } channel = p->chan_list[counter++ % p->num_chan]; - ret = esp_wifi_remain_on_channel(WIFI_IF_STA, WIFI_ROC_REQ, channel, - BOOTSTRAP_ROC_WAIT_TIME, s_action_rx_cb); + + wpa_printf(MSG_DEBUG, "DPP: Starting ROC on channel %d", channel); + + req.ifx = WIFI_IF_STA; + req.type = WIFI_ROC_REQ; + req.channel = channel; + req.wait_time_ms = BOOTSTRAP_ROC_WAIT_TIME; + req.rx_cb = s_action_rx_cb; + ret = esp_wifi_remain_on_channel(&req); if (ret != ESP_OK) { wpa_printf(MSG_ERROR, "Failed ROC. error : 0x%x", ret); return; } - s_dpp_listen_in_progress = true; } -static void esp_dpp_task(void *pvParameters) +static void esp_dpp_bootstrap_gen(void *data, void *user_ctx) { - dpp_event_t evt; - bool task_del = false; + char *command = data; + const char *uri; - for (;;) { - if (os_queue_recv(s_dpp_evt_queue, &evt, OS_BLOCK) == TRUE) { - if (evt.id >= SIG_DPP_MAX) { - continue; - } + s_dpp_ctx.id = dpp_bootstrap_gen(s_dpp_ctx.dpp_global, command); - switch (evt.id) { - case SIG_DPP_DEL_TASK: - struct dpp_bootstrap_params_t *params = &s_dpp_ctx.bootstrap_params; - eloop_cancel_timeout(esp_dpp_auth_conf_wait_timeout, NULL, NULL); - if (params->info) { - os_free(params->info); - params->info = NULL; - } - - if (s_dpp_ctx.dpp_global) { - dpp_global_deinit(s_dpp_ctx.dpp_global); - s_dpp_ctx.dpp_global = NULL; - } - if (s_dpp_ctx.dpp_auth) { - dpp_auth_deinit(s_dpp_ctx.dpp_auth); - s_dpp_ctx.dpp_auth = NULL; - } - task_del = true; - break; - - case SIG_DPP_BOOTSTRAP_GEN: { - char *command = (char *)evt.data; - const char *uri; - - s_dpp_ctx.id = dpp_bootstrap_gen(s_dpp_ctx.dpp_global, command); - uri = dpp_bootstrap_get_uri(s_dpp_ctx.dpp_global, s_dpp_ctx.id); - - esp_dpp_call_cb(ESP_SUPP_DPP_URI_READY, (void *)uri); - os_free(command); - } - break; - - case SIG_DPP_RX_ACTION: { - esp_dpp_rx_action((struct action_rx_param *)evt.data); - } - break; - - case SIG_DPP_LISTEN_NEXT_CHANNEL: { - struct dpp_bootstrap_params_t *p = &s_dpp_ctx.bootstrap_params; - static int counter; - esp_err_t ret = 0; - - if (p->num_chan <= 0) { - wpa_printf(MSG_ERROR, "Listen channel not set"); - break; - } - - wifi_roc_req_t req = {0}; - req.ifx = WIFI_IF_STA; - req.type = WIFI_ROC_REQ; - req.channel = p->chan_list[counter++ % p->num_chan]; - req.wait_time_ms = BOOTSTRAP_ROC_WAIT_TIME; - req.rx_cb = s_action_rx_cb; - req.done_cb = NULL; - wpa_printf(MSG_DEBUG, "Listening on channel=%d", req.channel); - ret = esp_wifi_remain_on_channel(&req); - if (ret != ESP_OK) { - wpa_printf(MSG_ERROR, "Failed ROC. error : 0x%x", ret); - break; - } - wpa_printf(MSG_DEBUG, "Started DPP listen operation %d", req.op_id); - s_dpp_listen_in_progress = true; - } - break; - - case SIG_DPP_START_NET_INTRO: { - esp_dpp_start_net_intro_protocol((uint8_t*)evt.data); - } - break; - - case SIG_DPP_DEINIT_AUTH: { - if (s_dpp_ctx.dpp_auth) { - dpp_auth_deinit(s_dpp_ctx.dpp_auth); - s_dpp_ctx.dpp_auth = NULL; - } - wpa_printf(MSG_DEBUG, "DPP auth deinintialized"); - } - break; - - default: - break; - } - - if (task_del) { - break; - } + if (s_dpp_ctx.id < 0) { + struct dpp_bootstrap_params_t *params = &s_dpp_ctx.bootstrap_params; + if (params->info) { + os_free(params->info); + params->info = NULL; } } + uri = dpp_bootstrap_get_uri(s_dpp_ctx.dpp_global, s_dpp_ctx.id); - os_queue_delete(s_dpp_evt_queue); - s_dpp_evt_queue = NULL; - - if (s_dpp_api_lock) { - os_mutex_delete(s_dpp_api_lock); - s_dpp_api_lock = NULL; - } - - /* At this point, we completed */ - os_task_delete(NULL); + esp_dpp_call_cb(ESP_SUPP_DPP_URI_READY, (void *)uri); + os_free(command); + dpp_api_lock(); + s_dpp_ctx.bootstrap_done = true; + dpp_api_unlock(); } -int esp_supp_rx_action(uint8_t *hdr, uint8_t *payload, size_t len, uint8_t channel) +static int esp_dpp_deinit(void *data, void *user_ctx) +{ + struct dpp_bootstrap_params_t *params = &s_dpp_ctx.bootstrap_params; + + wpa_printf(MSG_DEBUG, "DPP: Deinitializing DPP"); + /* Cancel all registered timeouts */ + eloop_cancel_timeout(esp_dpp_auth_conf_wait_timeout, NULL, NULL); + + esp_event_handler_unregister(WIFI_EVENT, WIFI_EVENT_ACTION_TX_STATUS, + &tx_status_handler); + esp_event_handler_unregister(WIFI_EVENT, WIFI_EVENT_ROC_DONE, + &roc_status_handler); + + if (params->info) { + os_free(params->info); + params->info = NULL; + } + + if (s_dpp_ctx.dpp_global) { + dpp_global_deinit(s_dpp_ctx.dpp_global); + s_dpp_ctx.dpp_global = NULL; + } + if (s_dpp_ctx.dpp_auth) { + dpp_auth_deinit(s_dpp_ctx.dpp_auth); + s_dpp_ctx.dpp_auth = NULL; + } + s_dpp_ctx.dpp_init_done = false; + s_dpp_ctx.bootstrap_done = false; + + return 0; +} + +static int esp_supp_rx_action(uint8_t *hdr, uint8_t *payload, size_t len, uint8_t channel) { struct ieee80211_hdr *rx_hdr = (struct ieee80211_hdr *)hdr; struct action_rx_param *rx_param; int ret = ESP_ERR_NOT_SUPPORTED; + struct ieee80211_action *frm = (struct ieee80211_action *)payload; if (WLAN_FC_GET_STYPE(rx_hdr->frame_control) == WLAN_FC_STYPE_ACTION) { - rx_param = os_zalloc(sizeof(struct action_rx_param)); + if (frm->category != WLAN_ACTION_PUBLIC) { + wpa_printf(MSG_DEBUG, "Not public action frame"); + return -1; + } + + rx_param = os_zalloc(sizeof(struct action_rx_param) + len); if (!rx_param) { wpa_printf(MSG_ERROR, "Failed to allocate memory for Rx Action"); return ESP_ERR_NO_MEM; } os_memcpy(rx_param->sa, rx_hdr->addr2, ETH_ALEN); rx_param->channel = channel; - rx_param->action_frm = os_zalloc(len); - if (!rx_param->action_frm) { - wpa_printf(MSG_ERROR, "Failed to allocate memory for Rx Action"); - os_free(rx_param); - return ESP_ERR_NO_MEM; - } rx_param->frm_len = len; os_memcpy(rx_param->action_frm, payload, len); - eloop_register_timeout(0, 0, esp_dpp_rx_action_eloop, rx_param, NULL); + eloop_register_timeout(0, 0, esp_dpp_rx_action, rx_param, NULL); } return ret; } -static void esp_dpp_auth_resp_retry_timeout(void *eloop_ctx, void *timeout_ctx) +static void esp_dpp_auth_resp_retry(void *eloop_ctx, void *timeout_ctx) { struct dpp_authentication *auth = s_dpp_ctx.dpp_auth; - - if (!auth || !auth->resp_msg) { - return; - } - - wpa_printf(MSG_DEBUG, - "DPP: Retry Authentication Response after timeout"); - wpa_msg(wpa_s, MSG_INFO, DPP_EVENT_TX "dst=" MACSTR - " chan=%u type=%d", - MAC2STR(auth->peer_mac_addr), auth->curr_chan, - DPP_PA_AUTHENTICATION_RESP); - - esp_dpp_send_action_frame(s_dpp_ctx.dpp_auth->peer_mac_addr, - wpabuf_head(s_dpp_ctx.dpp_auth->resp_msg), - wpabuf_len(s_dpp_ctx.dpp_auth->resp_msg), - auth->curr_chan, OFFCHAN_TX_WAIT_TIME); -} - -static void esp_dpp_auth_resp_retry(void) -{ - struct dpp_authentication *auth = s_dpp_ctx.dpp_auth; - unsigned int wait_time, max_tries = 5; + unsigned int max_tries = 5; if (!auth || !auth->resp_msg) { return; @@ -744,52 +702,60 @@ static void esp_dpp_auth_resp_retry(void) return; } - wait_time = 1; wpa_printf(MSG_INFO, - "DPP: Schedule retransmission %d of Authentication Response frame in %u s", auth->auth_resp_tries, - wait_time); + "DPP: Retransmiting Authentication Response frame"); eloop_cancel_timeout(esp_dpp_auth_resp_retry_timeout, NULL, NULL); - eloop_register_timeout(wait_time, 0, esp_dpp_auth_resp_retry_timeout, NULL, NULL); + esp_dpp_auth_resp_retry_timeout(NULL, NULL); } -static void offchan_event_handler(void *arg, esp_event_base_t event_base, - int32_t event_id, void *event_data) +static void tx_status_handler(void *arg, esp_event_base_t event_base, + int32_t event_id, void *event_data) { struct dpp_authentication *auth = s_dpp_ctx.dpp_auth; - if (event_id == WIFI_EVENT_ACTION_TX_STATUS) { - wifi_event_action_tx_status_t *evt = event_data; + wifi_event_action_tx_status_t *evt = event_data; - wpa_printf(MSG_DEBUG, "Mgmt Tx Status - %d, Cookie - 0x%x", - evt->status, (uint32_t)evt->context); - if (!auth) { + wpa_printf(MSG_DEBUG, "Mgmt Tx Status - %d, Cookie - 0x%x", + evt->status, (uint32_t)evt->context); + + if (evt->op_id != s_current_tx_op_id) { + wpa_printf(MSG_DEBUG, "DPP: status not for recent frame op_id=%u, s_current_tx_op_id=%u", + evt->op_id, s_current_tx_op_id); + return; + } + if (!auth) { + esp_dpp_call_cb(ESP_SUPP_DPP_FAIL, (void *)ESP_ERR_DPP_FAILURE); + return; + } + if (auth->waiting_auth_conf) { + eloop_cancel_timeout(esp_dpp_auth_resp_retry_timeout, NULL, NULL); + if (evt->status) { + /* failed to send auth response frame */ + eloop_cancel_timeout(esp_dpp_auth_conf_wait_timeout, NULL, NULL); + eloop_register_timeout(1, 0, esp_dpp_auth_resp_retry, NULL, NULL); + } else { + eloop_cancel_timeout(esp_dpp_auth_conf_wait_timeout, NULL, NULL); + eloop_register_timeout(ESP_DPP_AUTH_TIMEOUT_SECS, 0, esp_dpp_auth_conf_wait_timeout, NULL, NULL); + } + } else if (auth->auth_success) { + if (evt->status) { + /* failed to send gas query frame, retry logic needed? */ + wpa_printf(MSG_WARNING, "DPP: failed to send GAS query frame"); esp_dpp_call_cb(ESP_SUPP_DPP_FAIL, (void *)ESP_ERR_DPP_TX_FAILURE); - return; + } else { + eloop_cancel_timeout(gas_query_timeout, NULL, auth); + eloop_register_timeout(ESP_GAS_TIMEOUT_SECS, 0, gas_query_timeout, NULL, auth); } - if (auth->waiting_auth_conf) { - if (evt->status) { - /* failed to send auth response frame */ - eloop_cancel_timeout(esp_dpp_auth_conf_wait_timeout, NULL, NULL); - esp_dpp_auth_resp_retry(); - } else { - eloop_cancel_timeout(esp_dpp_auth_conf_wait_timeout, NULL, NULL); - eloop_register_timeout(ESP_DPP_AUTH_TIMEOUT_SECS, 0, esp_dpp_auth_conf_wait_timeout, NULL, NULL); - } - } else if (auth->auth_success) { - if (evt->status) { - /* failed to send gas query frame, retry logic needed? */ - esp_dpp_call_cb(ESP_SUPP_DPP_FAIL, (void *)ESP_ERR_DPP_TX_FAILURE); - } else { - eloop_cancel_timeout(gas_query_timeout, NULL, auth); - eloop_register_timeout(2, 0, gas_query_timeout, NULL, auth); - } - } - } else if (event_id == WIFI_EVENT_ROC_DONE) { - wifi_event_roc_done_t *evt = (wifi_event_roc_done_t *)event_data; + } +} - if (s_dpp_listen_in_progress && evt->context == (uint32_t)s_action_rx_cb) { - eloop_register_timeout(0, 0, esp_dpp_listen_next_channel, NULL, NULL); - } +static void roc_status_handler(void *arg, esp_event_base_t event_base, + int32_t event_id, void *event_data) +{ + wifi_event_roc_done_t *evt = (wifi_event_roc_done_t *)event_data; + + if (s_dpp_listen_in_progress && evt->context == (uint32_t)s_action_rx_cb) { + eloop_register_timeout(0, 0, esp_dpp_listen_next_channel, NULL, NULL); } } @@ -879,20 +845,28 @@ esp_err_t esp_supp_dpp_bootstrap_gen(const char *chan_list, enum dpp_bootstrap_type type, const char *key, const char *uri_info) { - if (!s_dpp_ctx.dpp_global) { + int ret = dpp_api_lock(); + if (ret != ESP_OK) { + return ret; + } + if (!s_dpp_ctx.dpp_init_done) { + dpp_api_unlock(); wpa_printf(MSG_ERROR, "DPP: failed to bootstrap as dpp not initialized."); return ESP_FAIL; } + dpp_api_unlock(); + struct dpp_bootstrap_params_t *params = &s_dpp_ctx.bootstrap_params; char *uri_chan_list = esp_dpp_parse_chan_list(chan_list); + wpa_printf(MSG_DEBUG, "DPP: Starting bootstrap genration"); if (params->num_chan > ESP_DPP_MAX_CHAN_COUNT) { os_free(uri_chan_list); + wpa_printf(MSG_ERROR, "DPP: Invalid channel list"); return ESP_ERR_DPP_INVALID_LIST; } char *command = os_zalloc(1200); - int ret; if (!uri_chan_list || !command || params->num_chan > ESP_DPP_MAX_CHAN_COUNT || params->num_chan == 0) { wpa_printf(MSG_ERROR, "Invalid Channel list - %s", chan_list); @@ -931,15 +905,7 @@ esp_supp_dpp_bootstrap_gen(const char *chan_list, enum dpp_bootstrap_type type, params->info_len ? " info=" : "", params->info_len ? params->info : ""); - ret = esp_dpp_post_evt(SIG_DPP_BOOTSTRAP_GEN, (u32)command); - if (ret != ESP_OK) { - os_free(command); - if (params->info) { - os_free(params->info); - params->info = NULL; - } - goto fail; - } + eloop_register_timeout(0, 0, esp_dpp_bootstrap_gen, command, NULL); ret = ESP_OK; fail: @@ -952,49 +918,93 @@ fail: esp_err_t esp_supp_dpp_start_listen(void) { - if (s_dpp_listen_in_progress) { - wpa_printf(MSG_ERROR, "DPP: Failed to start listen as listen is already in progress."); - return ESP_FAIL; + int ret = dpp_api_lock(); + if (ret != ESP_OK) { + return ret; } - - if (!s_dpp_ctx.dpp_global || s_dpp_ctx.id < 1) { + if (!s_dpp_ctx.dpp_init_done || !s_dpp_ctx.bootstrap_done) { wpa_printf(MSG_ERROR, "DPP: failed to start listen as dpp not initialized or bootstrapped."); + dpp_api_unlock(); return ESP_FAIL; } + dpp_api_unlock(); if (esp_wifi_get_user_init_flag_internal() == 0) { wpa_printf(MSG_ERROR, "DPP: ROC not possible before wifi is started"); return ESP_ERR_INVALID_STATE; } + wpa_printf(MSG_DEBUG, "DPP: Starting ROC"); /* cancel previous ROC if ongoing */ esp_supp_dpp_stop_listen(); - + s_dpp_listen_in_progress = true; eloop_register_timeout(0, 0, esp_dpp_listen_next_channel, NULL, NULL); return 0; } esp_err_t esp_supp_dpp_stop_listen(void) { - s_dpp_listen_in_progress = false; - wifi_roc_req_t req = {0}; - req.ifx = WIFI_IF_STA; - req.type = WIFI_ROC_CANCEL; - esp_err_t ret = esp_wifi_remain_on_channel(&req); + eloop_register_timeout(0, 0, listen_stop_handler, NULL, NULL); + return ESP_OK; +} + +/* this is called from public API, need protection */ +bool is_dpp_enabled(void) +{ + int ret; + ret = dpp_api_lock(); if (ret != ESP_OK) { - wpa_printf(MSG_ERROR, "DPP: ROC cancel failed"); + return false; } + ret = s_dpp_ctx.dpp_init_done; + dpp_api_unlock(); + return ret; } -bool is_dpp_enabled(void) +/* Caller supposed to have dpp_api_lock() before calling this in blocking context */ +static int esp_dpp_init(void *eloop_data, void *user_ctx) { - return (s_dpp_ctx.dpp_global ? true : false); + struct dpp_global_config cfg = {0}; + int ret; + esp_supp_dpp_event_cb_t cb = user_ctx; + + cfg.cb_ctx = &s_dpp_ctx; + cfg.msg_ctx = &s_dpp_ctx; + os_bzero(&s_dpp_ctx, sizeof(s_dpp_ctx)); + + s_dpp_ctx.dpp_global = dpp_global_init(&cfg); + if (!s_dpp_ctx.dpp_global) { + wpa_printf(MSG_ERROR, "DPP: failed to allocate memory for dpp_global"); + ret = ESP_ERR_NO_MEM; + goto init_fail; + } + + s_dpp_listen_in_progress = false; + s_dpp_ctx.dpp_event_cb = cb; + + esp_event_handler_register(WIFI_EVENT, WIFI_EVENT_ACTION_TX_STATUS, + &tx_status_handler, NULL); + esp_event_handler_register(WIFI_EVENT, WIFI_EVENT_ROC_DONE, + &roc_status_handler, NULL); + + wpa_printf(MSG_INFO, "DPP: dpp init done"); + s_dpp_ctx.dpp_init_done = true; + + return ESP_OK; +init_fail: + if (s_dpp_ctx.dpp_global) { + dpp_global_deinit(s_dpp_ctx.dpp_global); + s_dpp_ctx.dpp_global = NULL; + } + return ret; + } esp_err_t esp_supp_dpp_init(esp_supp_dpp_event_cb_t cb) { esp_err_t ret = ESP_OK; + wifi_mode_t mode = 0; if (esp_wifi_get_mode(&mode) || ((mode != WIFI_MODE_STA) && (mode != WIFI_MODE_APSTA))) { wpa_printf(MSG_ERROR, "DPP: failed to init as not in station mode."); @@ -1005,102 +1015,59 @@ esp_err_t esp_supp_dpp_init(esp_supp_dpp_event_cb_t cb) wpa_printf(MSG_ERROR, "DPP: failed to init since WPS is enabled"); return ESP_FAIL; } - if (s_dpp_ctx.dpp_global) { + + ret = dpp_api_lock(); + if (ret != ESP_OK) { + return ret; + } + if (s_dpp_ctx.dpp_init_done) { wpa_printf(MSG_ERROR, "DPP: failed to init as init already done. Please deinit first and retry."); + dpp_api_unlock(); return ESP_FAIL; } - - os_bzero(&s_dpp_ctx, sizeof(s_dpp_ctx)); - struct dpp_global_config cfg = {0}; - cfg.cb_ctx = &s_dpp_ctx; - cfg.msg_ctx = &s_dpp_ctx; - s_dpp_ctx.dpp_global = dpp_global_init(&cfg); - if (!s_dpp_ctx.dpp_global) { - wpa_printf(MSG_ERROR, "DPP: failed to allocate memory for dpp_global"); - ret = ESP_ERR_NO_MEM; - goto init_fail; - } - - s_dpp_api_lock = os_recursive_mutex_create(); - if (!s_dpp_api_lock) { - wpa_printf(MSG_ERROR, "DPP: dpp_init: failed to create DPP API lock"); - ret = ESP_ERR_NO_MEM; - goto init_fail; - } - - s_dpp_evt_queue = os_queue_create(3, sizeof(dpp_event_t)); - if (!s_dpp_evt_queue) { - wpa_printf(MSG_ERROR, "DPP: dpp_init: failed to create DPP API queue"); - ret = ESP_ERR_NO_MEM; - goto init_fail; - } - - ret = os_task_create(esp_dpp_task, "dppT", DPP_TASK_STACK_SIZE, NULL, 15, &s_dpp_task_hdl); - if (ret != TRUE) { - wpa_printf(MSG_ERROR, "DPP: failed to create task"); - ret = ESP_ERR_NO_MEM; - goto init_fail; - } - - s_dpp_listen_in_progress = false; - s_dpp_ctx.dpp_event_cb = cb; - - esp_event_handler_register(WIFI_EVENT, WIFI_EVENT_ACTION_TX_STATUS, - &offchan_event_handler, NULL); - esp_event_handler_register(WIFI_EVENT, WIFI_EVENT_ROC_DONE, - &offchan_event_handler, NULL); - - wpa_printf(MSG_INFO, "esp_dpp_task prio:%d, stack:%d", 2, DPP_TASK_STACK_SIZE); - - return ESP_OK; -init_fail: - if (s_dpp_ctx.dpp_global) { - dpp_global_deinit(s_dpp_ctx.dpp_global); - s_dpp_ctx.dpp_global = NULL; - } - if (s_dpp_api_lock) { - os_mutex_delete(s_dpp_api_lock); - s_dpp_api_lock = NULL; - } - if (s_dpp_evt_queue) { - os_queue_delete(s_dpp_evt_queue); - s_dpp_evt_queue = NULL; - } + ret = eloop_register_timeout_blocking(esp_dpp_init, NULL, cb); + dpp_api_unlock(); return ret; } esp_err_t esp_dpp_start_net_intro_protocol(uint8_t *bssid) { struct dpp_authentication *auth = s_dpp_ctx.dpp_auth; - struct wpabuf *buf; + struct wpabuf *buf = NULL; + int ret = ESP_OK; + for (int i = 0; i < auth->num_conf_obj; i++) { os_memcpy(auth->peer_mac_addr, bssid, ETH_ALEN); buf = dpp_build_peer_disc_req(auth, &auth->conf_obj[i]); - if (buf) { - if (esp_dpp_send_action_frame(bssid, wpabuf_head(buf), wpabuf_len(buf), auth->curr_chan, OFFCHAN_TX_WAIT_TIME) != ESP_OK) { - wpabuf_free(buf); - return ESP_FAIL; - } - } else { + if (!buf) { return ESP_ERR_NO_MEM; } + + if (esp_dpp_send_action_frame(bssid, wpabuf_head(buf), wpabuf_len(buf), + auth->curr_chan, OFFCHAN_TX_WAIT_TIME) != ESP_OK) { + ret = ESP_FAIL; + } + + wpabuf_free(buf); } - return ESP_OK; + + return ret; } esp_err_t esp_supp_dpp_deinit(void) { - - esp_event_handler_unregister(WIFI_EVENT, WIFI_EVENT_ACTION_TX_STATUS, - &offchan_event_handler); - esp_event_handler_unregister(WIFI_EVENT, WIFI_EVENT_ROC_DONE, - &offchan_event_handler); - if (s_dpp_ctx.dpp_global) { - if (esp_dpp_post_evt(SIG_DPP_DEL_TASK, 0)) { - wpa_printf(MSG_ERROR, "DPP Deinit Failed"); - } + int ret = dpp_api_lock(); + if (ret != ESP_OK) { + return ret; } + if (!s_dpp_ctx.dpp_init_done) { + wpa_printf(MSG_DEBUG, "DPP: Already disabled"); + dpp_api_unlock(); + return ESP_OK; + } + dpp_api_unlock(); + eloop_register_timeout_blocking(esp_dpp_deinit, NULL, NULL); return ESP_OK; } #endif diff --git a/components/wpa_supplicant/esp_supplicant/src/esp_dpp_i.h b/components/wpa_supplicant/esp_supplicant/src/esp_dpp_i.h index f7f8f1e6d9..651dfdbcc3 100644 --- a/components/wpa_supplicant/esp_supplicant/src/esp_dpp_i.h +++ b/components/wpa_supplicant/esp_supplicant/src/esp_dpp_i.h @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2020-2024 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2020-2025 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -14,25 +14,10 @@ #include "esp_dpp.h" #include "esp_wifi_driver.h" -#define DPP_TASK_STACK_SIZE (6144 + TASK_STACK_SIZE_ADD) +#define ESP_DPP_AUTH_TIMEOUT_SECS 2 +#define ESP_GAS_TIMEOUT_SECS 2 #define ESP_DPP_PMK_CACHE_DEFAULT_TIMEOUT 86400 * 7 /*!< 7 days */ -enum SIG_DPP { - SIG_DPP_RESET = 0, - SIG_DPP_BOOTSTRAP_GEN, - SIG_DPP_RX_ACTION, - SIG_DPP_LISTEN_NEXT_CHANNEL, - SIG_DPP_DEL_TASK, - SIG_DPP_START_NET_INTRO, - SIG_DPP_DEINIT_AUTH, - SIG_DPP_MAX, -}; - -typedef struct { - uint32_t id; - uint32_t data; -} dpp_event_t; - #define BOOTSTRAP_ROC_WAIT_TIME 500 #define OFFCHAN_TX_WAIT_TIME 600 @@ -53,11 +38,10 @@ struct esp_dpp_context_t { struct dpp_global *dpp_global; wifi_config_t wifi_cfg; int id; + bool dpp_init_done; + bool bootstrap_done; }; -int esp_supp_rx_action(uint8_t *hdr, uint8_t *payload, size_t len, uint8_t channel); -esp_err_t esp_dpp_post_evt(uint32_t evt_id, uint32_t data); - #ifdef CONFIG_TESTING_OPTIONS int dpp_test_gen_invalid_key(struct wpabuf *msg, const struct dpp_curve_params *curve); char * dpp_corrupt_connector_signature(const char *connector); diff --git a/components/wpa_supplicant/esp_supplicant/src/esp_wpa_main.c b/components/wpa_supplicant/esp_supplicant/src/esp_wpa_main.c index 24cbc34a21..80f48cb824 100644 --- a/components/wpa_supplicant/esp_supplicant/src/esp_wpa_main.c +++ b/components/wpa_supplicant/esp_supplicant/src/esp_wpa_main.c @@ -213,7 +213,7 @@ int dpp_connect(uint8_t *bssid, bool pdr_done) int res = 0; if (!pdr_done) { if (esp_wifi_sta_get_prof_authmode_internal() == WPA3_AUTH_DPP) { - esp_dpp_post_evt(SIG_DPP_START_NET_INTRO, (u32)bssid); + esp_dpp_start_net_intro_protocol(bssid); } } else { res = wpa_config_bss(bssid); diff --git a/components/wpa_supplicant/src/common/dpp.c b/components/wpa_supplicant/src/common/dpp.c index 7fa67d10fa..fd7a1f9848 100644 --- a/components/wpa_supplicant/src/common/dpp.c +++ b/components/wpa_supplicant/src/common/dpp.c @@ -84,7 +84,7 @@ void dpp_debug_print_point(const char *title, struct crypto_ec *e, static void dpp_auth_fail(struct dpp_authentication *auth, const char *txt) { - wpa_msg(auth->msg_ctx, MSG_INFO, DPP_EVENT_FAIL "%s", txt); + wpa_printf(MSG_INFO, "%s", txt); } struct wpabuf * dpp_alloc_msg(enum dpp_public_action_frame_type type,