fix(esp_wifi): Fixed some issues in esp_supplicant code

This commit is contained in:
Kapil Gupta
2026-05-01 12:38:53 +05:30
parent 3368b271f5
commit a6f5c15aca
3 changed files with 194 additions and 37 deletions
@@ -1,5 +1,5 @@
/*
* SPDX-FileCopyrightText: 2020-2025 Espressif Systems (Shanghai) CO LTD
* SPDX-FileCopyrightText: 2020-2026 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
@@ -37,6 +37,7 @@ static void *s_dpp_event_group = NULL;
#define DPP_ROC_EVENT_HANDLED BIT0
static atomic_bool roc_in_progress;
static atomic_bool dpp_shutting_down;
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;
@@ -46,6 +47,8 @@ static void tx_status_handler(void *arg, esp_event_base_t event_base,
static void roc_status_handler(void *arg, esp_event_base_t event_base,
int32_t event_id, void *event_data);
static void dpp_listen_next_channel(void *data, void *user_ctx);
static void esp_dpp_cancel_timeouts(void);
static esp_err_t dpp_api_lock(void)
{
if (!s_dpp_api_lock) {
@@ -211,6 +214,11 @@ static esp_err_t esp_dpp_rx_auth_req(struct action_rx_param *rx_param, uint8_t *
wpa_hexdump(MSG_MSGDUMP, "DPP: Initiator Bootstrapping Key Hash", i_bootstrap, i_bootstrap_len);
own_bi = dpp_bootstrap_get_id(s_dpp_ctx.dpp_global, s_dpp_ctx.id);
if (!own_bi) {
wpa_printf(MSG_ERROR, "DPP: Failed to find responder bootstrap information");
rc = ESP_ERR_DPP_FAILURE;
return rc;
}
/* Try to find own and peer bootstrapping key matches based on the
* received hash values */
if (os_memcmp(own_bi->pubkey_hash, r_bootstrap, SHA256_MAC_LEN)) {
@@ -225,6 +233,15 @@ static esp_err_t esp_dpp_rx_auth_req(struct action_rx_param *rx_param, uint8_t *
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);
if (!s_dpp_ctx.dpp_auth || !s_dpp_ctx.dpp_auth->resp_msg) {
wpa_printf(MSG_ERROR, "DPP: Failed to allocate authentication response");
if (s_dpp_ctx.dpp_auth) {
dpp_auth_deinit(s_dpp_ctx.dpp_auth);
s_dpp_ctx.dpp_auth = NULL;
}
rc = ESP_ERR_DPP_FAILURE;
return rc;
}
os_memcpy(s_dpp_ctx.dpp_auth->peer_mac_addr, rx_param->sa, ETH_ALEN);
wpa_printf(MSG_INFO, "DPP: Sending authentication response chan(%d)", rx_param->channel);
@@ -569,8 +586,14 @@ static void esp_dpp_rx_action(void *data, void *user_ctx)
return;
}
if (atomic_load(&dpp_shutting_down) || !s_dpp_ctx.dpp_init_done) {
os_free(rx_param);
return;
}
/* we don't cater other action frames except public here */
if (rx_param->action_frm->category != WLAN_ACTION_PUBLIC) {
os_free(rx_param);
return;
}
@@ -621,7 +644,7 @@ static void dpp_listen_next_channel(void *data, void *user_ctx)
esp_err_t ret = 0;
wifi_roc_req_t req = {0};
if (!s_dpp_ctx.dpp_listen_ongoing) {
if (atomic_load(&dpp_shutting_down) || !s_dpp_ctx.dpp_listen_ongoing) {
return;
}
if (p->num_chan <= 0) {
@@ -644,7 +667,9 @@ static void dpp_listen_next_channel(void *data, void *user_ctx)
return;
}
atomic_store(&roc_in_progress, true);
os_event_group_clear_bits(s_dpp_event_group, DPP_ROC_EVENT_HANDLED);
if (s_dpp_event_group) {
os_event_group_clear_bits(s_dpp_event_group, DPP_ROC_EVENT_HANDLED);
}
}
static void esp_dpp_bootstrap_gen(void *data, void *user_ctx)
@@ -652,6 +677,16 @@ static void esp_dpp_bootstrap_gen(void *data, void *user_ctx)
char *command = data;
const char *uri;
uint32_t len;
bool success = false;
wifi_event_dpp_uri_ready_t *event = NULL;
dpp_api_lock();
s_dpp_ctx.bootstrap_done = false;
dpp_api_unlock();
if (atomic_load(&dpp_shutting_down) || !command || !s_dpp_ctx.dpp_global) {
goto out;
}
s_dpp_ctx.id = dpp_bootstrap_gen(s_dpp_ctx.dpp_global, command);
@@ -661,23 +696,40 @@ static void esp_dpp_bootstrap_gen(void *data, void *user_ctx)
os_free(params->info);
params->info = NULL;
}
goto fail;
}
uri = dpp_bootstrap_get_uri(s_dpp_ctx.dpp_global, s_dpp_ctx.id);
if (!uri) {
goto fail;
}
wifi_event_dpp_uri_ready_t *event;
len = sizeof(*event) + os_strlen(uri) + 1;
event = os_malloc(len);
if (!event) {
return;
goto fail;
}
event->uri_data_len = os_strlen(uri);
os_memcpy(event->uri, uri, event->uri_data_len);
event->uri[event->uri_data_len++] = '\0';
esp_event_post(WIFI_EVENT, WIFI_EVENT_DPP_URI_READY, event, len, OS_BLOCK);
success = true;
fail:
if (!success && !atomic_load(&dpp_shutting_down)) {
wifi_event_dpp_failed_t fail_event = {
.failure_reason = ESP_ERR_DPP_FAILURE,
};
s_dpp_ctx.id = -1;
esp_event_post(WIFI_EVENT, WIFI_EVENT_DPP_FAILED,
&fail_event, sizeof(fail_event), OS_BLOCK);
}
out:
os_free(event);
os_free(command);
dpp_api_lock();
s_dpp_ctx.bootstrap_done = true;
s_dpp_ctx.bootstrap_done = success;
dpp_api_unlock();
}
@@ -686,8 +738,8 @@ 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);
atomic_store(&dpp_shutting_down, true);
esp_dpp_cancel_timeouts();
esp_event_handler_unregister(WIFI_EVENT, WIFI_EVENT_ACTION_TX_STATUS,
&tx_status_handler);
@@ -707,6 +759,7 @@ static int esp_dpp_deinit(void *data, void *user_ctx)
dpp_auth_deinit(s_dpp_ctx.dpp_auth);
s_dpp_ctx.dpp_auth = NULL;
}
atomic_store(&roc_in_progress, false);
s_dpp_ctx.dpp_init_done = false;
s_dpp_ctx.bootstrap_done = false;
if (s_dpp_event_group) {
@@ -779,6 +832,10 @@ static void tx_status_eloop_handler(void *eloop_ctx, void *event_data)
if (!evt) {
return;
}
if (atomic_load(&dpp_shutting_down)) {
os_free(evt);
return;
}
wpa_printf(MSG_DEBUG, "Mgmt Tx Status - %d, Cookie - 0x%x",
evt->status, (uint32_t)evt->context);
@@ -814,6 +871,10 @@ static void tx_status_eloop_handler(void *eloop_ctx, void *event_data)
static void tx_status_handler(void *arg, esp_event_base_t event_base,
int32_t event_id, void *event_data)
{
if (atomic_load(&dpp_shutting_down)) {
return;
}
wifi_event_action_tx_status_t *evt_c = os_malloc(sizeof(*evt_c));
if (evt_c) {
os_memcpy(evt_c, event_data, sizeof(*evt_c));
@@ -829,6 +890,14 @@ static void roc_status_eloop_handler(void *eloop_ctx, void *event_data)
{
wifi_event_roc_done_t *evt = (wifi_event_roc_done_t *)event_data;
if (atomic_load(&dpp_shutting_down)) {
if (evt) {
os_free(evt);
}
atomic_store(&roc_in_progress, false);
return;
}
if (evt) {
if (evt->context == (uint32_t)s_action_rx_cb) {
eloop_cancel_timeout(dpp_listen_next_channel, NULL, NULL);
@@ -838,12 +907,18 @@ static void roc_status_eloop_handler(void *eloop_ctx, void *event_data)
}
atomic_store(&roc_in_progress, false);
os_event_group_set_bits(s_dpp_event_group, DPP_ROC_EVENT_HANDLED);
if (s_dpp_event_group) {
os_event_group_set_bits(s_dpp_event_group, DPP_ROC_EVENT_HANDLED);
}
}
static void roc_status_handler(void *arg, esp_event_base_t event_base,
int32_t event_id, void *event_data)
{
if (atomic_load(&dpp_shutting_down)) {
return;
}
wifi_event_roc_done_t *evt_c = os_malloc(sizeof(*evt_c));
if (evt_c) {
os_memcpy(evt_c, event_data, sizeof(*evt_c));
@@ -1031,6 +1106,16 @@ static void dpp_listen_start(void *ctx, void *data)
dpp_listen_next_channel(NULL, NULL);
}
static void esp_dpp_cancel_timeouts(void)
{
eloop_cancel_timeout(dpp_listen_next_channel, NULL, NULL);
eloop_cancel_timeout(esp_dpp_auth_conf_wait_timeout, NULL, NULL);
eloop_cancel_timeout(esp_dpp_auth_resp_retry_timeout, NULL, NULL);
eloop_cancel_timeout(esp_dpp_auth_resp_retry, NULL, NULL);
eloop_cancel_timeout(gas_query_timeout, ELOOP_ALL_CTX, ELOOP_ALL_CTX);
eloop_cancel_timeout(dpp_listen_start, NULL, NULL);
}
esp_err_t esp_supp_dpp_start_listen(void)
{
int ret = dpp_api_lock();
@@ -1053,7 +1138,11 @@ esp_err_t esp_supp_dpp_start_listen(void)
esp_supp_dpp_stop_listen();
/* Give ample time to set the bit, timeout is necessary when ROC is not running previously */
os_event_group_wait_bits(s_dpp_event_group, DPP_ROC_EVENT_HANDLED, 0, 0, os_task_ms_to_tick(100));
if (!s_dpp_event_group) {
return ESP_ERR_INVALID_STATE;
}
os_event_group_wait_bits(s_dpp_event_group, DPP_ROC_EVENT_HANDLED, 0, 0,
os_task_ms_to_tick(100));
wpa_printf(MSG_DEBUG, "DPP: Starting ROC");
eloop_register_timeout(0, 0, dpp_listen_start, NULL, NULL);
return 0;
@@ -1092,6 +1181,9 @@ static int esp_dpp_init(void *eloop_data, void *user_ctx)
cfg.cb_ctx = &s_dpp_ctx;
cfg.msg_ctx = &s_dpp_ctx;
os_bzero(&s_dpp_ctx, sizeof(s_dpp_ctx));
atomic_store(&dpp_shutting_down, false);
atomic_store(&roc_in_progress, false);
s_current_tx_op_id = 0;
s_dpp_ctx.dpp_global = dpp_global_init(&cfg);
if (!s_dpp_ctx.dpp_global) {
@@ -1106,11 +1198,19 @@ static int esp_dpp_init(void *eloop_data, void *user_ctx)
&roc_status_handler, NULL);
s_dpp_event_group = os_event_group_create();
if (!s_dpp_event_group) {
ret = ESP_ERR_NO_MEM;
goto init_fail;
}
wpa_printf(MSG_INFO, "DPP: dpp init done");
s_dpp_ctx.dpp_init_done = true;
return ESP_OK;
init_fail:
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 (s_dpp_ctx.dpp_global) {
dpp_global_deinit(s_dpp_ctx.dpp_global);
s_dpp_ctx.dpp_global = NULL;
@@ -1185,7 +1285,7 @@ esp_err_t esp_supp_dpp_deinit(void)
return ESP_OK;
}
dpp_api_unlock();
eloop_register_timeout_blocking(esp_dpp_deinit, NULL, NULL);
return ESP_OK;
return eloop_register_timeout_blocking(esp_dpp_deinit, NULL, NULL) == 0 ?
ESP_OK : ESP_FAIL;
}
#endif
@@ -1,5 +1,5 @@
/*
* SPDX-FileCopyrightText: 2019-2025 Espressif Systems (Shanghai) CO LTD
* SPDX-FileCopyrightText: 2019-2026 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
@@ -189,6 +189,25 @@ static struct wpa2_rx_param * wpa2_rxq_dequeue(void)
return param;
}
static bool wpa2_rxq_remove(struct wpa2_rx_param *target)
{
struct wpa2_rx_param *param;
bool removed = false;
DATA_MUTEX_TAKE();
STAILQ_FOREACH(param, &s_wpa2_rxq, bqentry) {
if (param == target) {
STAILQ_REMOVE(&s_wpa2_rxq, param, wpa2_rx_param, bqentry);
STAILQ_NEXT(param, bqentry) = NULL;
removed = true;
break;
}
}
DATA_MUTEX_GIVE();
return removed;
}
static void wpa2_rxq_deinit(void)
{
struct wpa2_rx_param *param = NULL;
@@ -289,6 +308,11 @@ int wpa2_post(uint32_t sig, uint32_t par)
evt.sig = sig;
evt.par = par;
if (os_queue_send(s_wpa2_queue, &evt, os_task_ms_to_tick(10)) != TRUE) {
DATA_MUTEX_TAKE();
if (sm->wpa2_sig_cnt[sig]) {
sm->wpa2_sig_cnt[sig]--;
}
DATA_MUTEX_GIVE();
wpa_printf(MSG_ERROR, "EAP: Q S E");
return ESP_FAIL;
}
@@ -484,7 +508,12 @@ static int eap_sm_rx_eapol(u8 *src_addr, u8 *buf, u32 len, uint8_t *bssid)
memcpy(param->sa, src_addr, WPA_ADDR_LEN);
wpa2_rxq_enqueue(param);
return wpa2_post(SIG_WPA2_RX, 0);
int ret = wpa2_post(SIG_WPA2_RX, 0);
if (ret != ESP_OK && wpa2_rxq_remove(param)) {
os_free(param->buf);
os_free(param);
}
return ret;
}
#else
@@ -1167,7 +1196,7 @@ esp_err_t esp_eap_client_set_new_password(const unsigned char *new_password, int
}
os_memcpy(g_wpa_new_password, new_password, len);
g_wpa_password_len = len;
g_wpa_new_password_len = len;
eloop_register_timeout(0, 0, config_changed_handler, NULL, NULL);
return ESP_OK;
@@ -1,5 +1,5 @@
/*
* SPDX-FileCopyrightText: 2025 Espressif Systems (Shanghai) CO LTD
* SPDX-FileCopyrightText: 2025-2026 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
@@ -19,6 +19,22 @@ static void *s_nan_usd_data_lock = NULL;
#define NAN_USD_DATA_LOCK() os_mutex_lock(s_nan_usd_data_lock)
#define NAN_USD_DATA_UNLOCK() os_mutex_unlock(s_nan_usd_data_lock)
static bool nan_usd_try_lock_active(struct nan_de **nan_de)
{
if (!s_nan_usd_data_lock) {
return false;
}
NAN_USD_DATA_LOCK();
if (!g_nan_de) {
NAN_USD_DATA_UNLOCK();
return false;
}
*nan_de = g_nan_de;
return true;
}
#ifdef DEBUG_PRINT
static const char *nan_reason_txt(enum nan_de_reason reason)
{
@@ -86,6 +102,8 @@ static int esp_nan_freq_to_chan(int freq)
static void nan_de_tx_event_handler(void *arg, esp_event_base_t event_base,
int32_t event_id, void *event_data)
{
struct nan_de *nan_de = NULL;
if (event_id == WIFI_EVENT_ACTION_TX_STATUS) {
wifi_event_action_tx_status_t *evt = (wifi_event_action_tx_status_t *)event_data;
if (evt->status == WIFI_ACTION_TX_DONE) {
@@ -94,12 +112,16 @@ static void nan_de_tx_event_handler(void *arg, esp_event_base_t event_base,
wpa_printf(MSG_ERROR, "Invalid channel received from Action Tx handler");
return;
}
NAN_USD_DATA_LOCK();
nan_de_tx_status(g_nan_de, freq, NULL);
if (!nan_usd_try_lock_active(&nan_de)) {
return;
}
nan_de_tx_status(nan_de, freq, NULL);
NAN_USD_DATA_UNLOCK();
} else if (evt->status == WIFI_ACTION_TX_DURATION_COMPLETED) {
NAN_USD_DATA_LOCK();
nan_de_tx_wait_ended(g_nan_de);
if (!nan_usd_try_lock_active(&nan_de)) {
return;
}
nan_de_tx_wait_ended(nan_de);
NAN_USD_DATA_UNLOCK();
}
} else if (event_id == WIFI_EVENT_ROC_DONE) {
@@ -107,9 +129,12 @@ static void nan_de_tx_event_handler(void *arg, esp_event_base_t event_base,
int freq = esp_nan_chan_to_freq(evt->channel);
if (freq == -1) {
wpa_printf(MSG_ERROR, "Invalid channel received from ROC done handler");
return;
}
NAN_USD_DATA_LOCK();
nan_de_listen_ended(g_nan_de, freq);
if (!nan_usd_try_lock_active(&nan_de)) {
return;
}
nan_de_listen_ended(nan_de, freq);
NAN_USD_DATA_UNLOCK();
}
}
@@ -117,6 +142,7 @@ static void nan_de_tx_event_handler(void *arg, esp_event_base_t event_base,
int esp_nan_de_rx_action(uint8_t *hdr, uint8_t *payload, size_t len, uint8_t channel)
{
struct ieee80211_hdr *rx_hdr = (struct ieee80211_hdr *)hdr;
struct nan_de *nan_de = NULL;
int freq;
if (len < 6) {
@@ -152,8 +178,10 @@ int esp_nan_de_rx_action(uint8_t *hdr, uint8_t *payload, size_t len, uint8_t cha
return ESP_FAIL;
}
NAN_USD_DATA_LOCK();
nan_de_rx_sdf(g_nan_de, rx_hdr->addr2, rx_hdr->addr3, freq, payload, len - 6);
if (!nan_usd_try_lock_active(&nan_de)) {
return ESP_FAIL;
}
nan_de_rx_sdf(nan_de, rx_hdr->addr2, rx_hdr->addr3, freq, payload, len - 6);
NAN_USD_DATA_UNLOCK();
return ESP_OK;
}
@@ -315,6 +343,14 @@ static void esp_nan_de_receive(void *ctx, int id, int peer_instance_id,
esp_err_t esp_nan_usd_deinit()
{
esp_event_handler_unregister(WIFI_EVENT, WIFI_EVENT_ACTION_TX_STATUS, &nan_de_tx_event_handler);
esp_event_handler_unregister(WIFI_EVENT, WIFI_EVENT_ROC_DONE, &nan_de_tx_event_handler);
esp_event_handler_unregister(WIFI_EVENT, WIFI_EVENT_STA_STOP,
&nan_sta_stop_handler);
if (!s_nan_usd_data_lock) {
return ESP_FAIL;
}
NAN_USD_DATA_LOCK();
if (!g_nan_de) {
@@ -326,16 +362,6 @@ esp_err_t esp_nan_usd_deinit()
g_nan_de = NULL;
NAN_USD_DATA_UNLOCK();
if (s_nan_usd_data_lock) {
os_mutex_delete(s_nan_usd_data_lock);
s_nan_usd_data_lock = NULL;
}
esp_event_handler_unregister(WIFI_EVENT, WIFI_EVENT_ACTION_TX_STATUS, &nan_de_tx_event_handler);
esp_event_handler_unregister(WIFI_EVENT, WIFI_EVENT_ROC_DONE, &nan_de_tx_event_handler);
esp_event_handler_unregister(WIFI_EVENT, WIFI_EVENT_STA_STOP,
&nan_sta_stop_handler);
return ESP_OK;
}
@@ -360,10 +386,12 @@ esp_err_t esp_nan_usd_init(void)
cb.subscribe_terminated = esp_nan_de_subscribe_terminated;
cb.receive = esp_nan_de_receive;
s_nan_usd_data_lock = os_recursive_mutex_create();
if (!s_nan_usd_data_lock) {
ESP_LOGE("NAN-USD", "Failed to create NAN-USD data lock");
return ESP_FAIL;
s_nan_usd_data_lock = os_recursive_mutex_create();
if (!s_nan_usd_data_lock) {
ESP_LOGE("NAN-USD", "Failed to create NAN-USD data lock");
return ESP_FAIL;
}
}
ESP_RETURN_ON_ERROR(esp_wifi_get_mac(WIFI_IF_STA, mac), "NAN-USD", "Fetching MAC of STA ifx failed");