From 76723c063a34246484310a5fad69a87196347197 Mon Sep 17 00:00:00 2001 From: Kapil Gupta Date: Thu, 24 Apr 2025 13:07:54 +0530 Subject: [PATCH 1/5] fix(esp_wifi): Fixed DPP concurrency issue --- .../esp_supplicant/src/esp_dpp.c | 25 ++++++++++++------- 1 file changed, 16 insertions(+), 9 deletions(-) diff --git a/components/wpa_supplicant/esp_supplicant/src/esp_dpp.c b/components/wpa_supplicant/esp_supplicant/src/esp_dpp.c index d984a49a07..bc66a3ba6b 100644 --- a/components/wpa_supplicant/esp_supplicant/src/esp_dpp.c +++ b/components/wpa_supplicant/esp_supplicant/src/esp_dpp.c @@ -19,6 +19,7 @@ #include "esp_wps_i.h" #include "rsn_supp/wpa.h" #include "rsn_supp/pmksa_cache.h" +#include #ifdef CONFIG_DPP @@ -32,7 +33,7 @@ struct action_rx_param { static void *s_dpp_api_lock = NULL; -static bool s_dpp_listen_in_progress; +static atomic_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; @@ -75,15 +76,17 @@ static uint8_t esp_dpp_deinit_auth(void) return ESP_OK; } -static void listen_stop_handler(void *data, void *user_ctx) +static int listen_stop_handler(void *data, void *user_ctx) { wifi_roc_req_t req = {0}; - s_dpp_listen_in_progress = false; + atomic_store(&s_dpp_listen_in_progress, false); req.ifx = WIFI_IF_STA; req.type = WIFI_ROC_CANCEL; esp_wifi_remain_on_channel(&req); + + return 0; } static void esp_dpp_call_cb(esp_supp_dpp_event_t evt, void *data) @@ -292,7 +295,7 @@ static int esp_dpp_handle_config_obj(struct dpp_authentication *auth, wpa_printf(MSG_INFO, DPP_EVENT_CONNECTOR "%s", conf->connector); } - if (s_dpp_listen_in_progress) { + if (atomic_load(&s_dpp_listen_in_progress)) { listen_stop_handler(NULL, NULL); } esp_dpp_call_cb(ESP_SUPP_DPP_CFG_RECVD, wifi_cfg); @@ -548,7 +551,7 @@ static void esp_dpp_rx_action(void *data, void *user_ctx) (size_t)(public_action->v.pa_vendor_spec.vendor_data - (u8 *)rx_param->action_frm); - if (s_dpp_listen_in_progress) { + if (atomic_load(&s_dpp_listen_in_progress)) { listen_stop_handler(NULL, NULL); } @@ -754,7 +757,7 @@ static void roc_status_handler(void *arg, esp_event_base_t event_base, { 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) { + if (atomic_load(&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); } } @@ -937,14 +940,18 @@ esp_err_t esp_supp_dpp_start_listen(void) /* cancel previous ROC if ongoing */ esp_supp_dpp_stop_listen(); - s_dpp_listen_in_progress = true; + atomic_store(&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) { - eloop_register_timeout(0, 0, listen_stop_handler, NULL, NULL); + int ret = eloop_register_timeout_blocking(listen_stop_handler, NULL, NULL); + + if (ret) { + return ESP_FAIL; + } return ESP_OK; } @@ -980,7 +987,7 @@ static int esp_dpp_init(void *eloop_data, void *user_ctx) goto init_fail; } - s_dpp_listen_in_progress = false; + atomic_store(&s_dpp_listen_in_progress, false); s_dpp_ctx.dpp_event_cb = cb; esp_event_handler_register(WIFI_EVENT, WIFI_EVENT_ACTION_TX_STATUS, From 15c336bf493f900c7e48f1a0bb401cf73e8f2824 Mon Sep 17 00:00:00 2001 From: Kapil Gupta Date: Mon, 5 May 2025 15:43:07 +0530 Subject: [PATCH 2/5] fix(esp_wifi): Update dpp code to send events in freeRTOS context --- .../esp_wifi/include/esp_wifi_types_generic.h | 19 ++++ .../esp_supplicant/include/esp_dpp.h | 7 +- .../esp_supplicant/src/esp_dpp.c | 94 ++++++++++++++++--- 3 files changed, 104 insertions(+), 16 deletions(-) diff --git a/components/esp_wifi/include/esp_wifi_types_generic.h b/components/esp_wifi/include/esp_wifi_types_generic.h index cabb434a39..04898f247e 100644 --- a/components/esp_wifi/include/esp_wifi_types_generic.h +++ b/components/esp_wifi/include/esp_wifi_types_generic.h @@ -1116,6 +1116,9 @@ typedef enum { WIFI_EVENT_AP_WRONG_PASSWORD, /**< a station tried to connect with wrong password */ WIFI_EVENT_STA_BEACON_OFFSET_UNSTABLE, /**< Station sampled beacon offset unstable */ + WIFI_EVENT_DPP_URI_READY, /**< DPP URI is ready through Bootstrapping */ + WIFI_EVENT_DPP_CFG_RECVD, /**< Config received via DPP Authentication */ + WIFI_EVENT_DPP_FAILED, /**< DPP failed */ WIFI_EVENT_MAX, /**< Invalid Wi-Fi event ID */ } wifi_event_t; @@ -1520,6 +1523,22 @@ typedef struct { float beacon_success_rate; /**< Received beacon success rate */ } wifi_event_sta_beacon_offset_unstable_t; +/** Argument structure for WIFI_EVENT_DPP_URI_READY event */ +typedef struct { + uint32_t uri_len; /**< URI length */ + char uri[]; /**< URI data */ +} wifi_event_dpp_uri_ready_t; + +/** Argument structure for WIFI_EVENT_DPP_CFG_RECVD event */ +typedef struct { + wifi_config_t wifi_cfg; /**< Received WIFI config in DPP */ +} wifi_event_dpp_config_received_t; + +/** Argument structure for WIFI_EVENT_DPP_FAIL event */ +typedef struct { + int failure_reason; /**< Failure reason */ +} wifi_event_dpp_failed_t; + #ifdef __cplusplus } #endif diff --git a/components/wpa_supplicant/esp_supplicant/include/esp_dpp.h b/components/wpa_supplicant/esp_supplicant/include/esp_dpp.h index 5330c5dbe8..0346ee71f5 100644 --- a/components/wpa_supplicant/esp_supplicant/include/esp_dpp.h +++ b/components/wpa_supplicant/esp_supplicant/include/esp_dpp.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 */ @@ -55,7 +55,10 @@ typedef void (*esp_supp_dpp_event_cb_t)(esp_supp_dpp_event_t evt, void *data); * * Starts DPP Supplicant and initializes related Data Structures. * - * @param evt_cb Callback function to receive DPP related events + * @note The `evt_cb` parameter is deprecated and will be ignored in future IDF versions. + * Directly register for WiFi events to get DPP events. + * + * @param evt_cb (Deprecated) Callback function to receive DPP related events * * return * - ESP_OK: Success diff --git a/components/wpa_supplicant/esp_supplicant/src/esp_dpp.c b/components/wpa_supplicant/esp_supplicant/src/esp_dpp.c index bc66a3ba6b..bc34a7fe16 100644 --- a/components/wpa_supplicant/esp_supplicant/src/esp_dpp.c +++ b/components/wpa_supplicant/esp_supplicant/src/esp_dpp.c @@ -66,7 +66,30 @@ static esp_err_t dpp_api_unlock(void) return ESP_OK; } -static uint8_t esp_dpp_deinit_auth(void) +static void dpp_event_handler(void *arg, esp_event_base_t event_base, + int32_t event_id, void *event_data) +{ + if (!s_dpp_ctx.dpp_event_cb) { + return; + } + switch (event_id) { + case WIFI_EVENT_DPP_URI_READY: + wifi_event_dpp_uri_ready_t *event = (wifi_event_dpp_uri_ready_t *) event_data; + s_dpp_ctx.dpp_event_cb(ESP_SUPP_DPP_URI_READY, (void *)(event->uri)); + break; + case WIFI_EVENT_DPP_CFG_RECVD: + s_dpp_ctx.dpp_event_cb(ESP_SUPP_DPP_CFG_RECVD, (wifi_config_t *)event_data); + break; + case WIFI_EVENT_DPP_FAILED: + s_dpp_ctx.dpp_event_cb(ESP_SUPP_DPP_FAIL, (void *)event_data); + break; + default: + break; + } + return; +} + +static uint8_t dpp_deinit_auth(void) { if (s_dpp_ctx.dpp_auth) { dpp_auth_deinit(s_dpp_ctx.dpp_auth); @@ -89,13 +112,23 @@ static int listen_stop_handler(void *data, void *user_ctx) return 0; } -static void esp_dpp_call_cb(esp_supp_dpp_event_t evt, void *data) +static void dpp_stop(void) { if (s_dpp_ctx.dpp_auth) { - esp_dpp_deinit_auth(); + dpp_deinit_auth(); listen_stop_handler(NULL, NULL); } - s_dpp_ctx.dpp_event_cb(evt, data); +} + +static void dpp_abort_with_failure(uint32_t failure_reason) +{ + /* Stop DPP*/ + dpp_stop(); + + /* Send event to APP */ + wifi_event_dpp_failed_t event = {0}; + event.failure_reason = failure_reason; + esp_event_post(WIFI_EVENT, WIFI_EVENT_DPP_FAILED, &event, sizeof(event), OS_BLOCK); } static void esp_dpp_auth_conf_wait_timeout(void *eloop_ctx, void *timeout_ctx) @@ -106,7 +139,7 @@ static void esp_dpp_auth_conf_wait_timeout(void *eloop_ctx, void *timeout_ctx) 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); + dpp_abort_with_failure(ESP_ERR_DPP_AUTH_TIMEOUT); } esp_err_t esp_dpp_send_action_frame(uint8_t *dest_mac, const uint8_t *buf, uint32_t len, @@ -132,7 +165,7 @@ esp_err_t esp_dpp_send_action_frame(uint8_t *dest_mac, const uint8_t *buf, uint3 if (ESP_OK != esp_wifi_action_tx_req(req)) { wpa_printf(MSG_ERROR, "DPP: Failed to perform offchannel operation"); - esp_dpp_call_cb(ESP_SUPP_DPP_FAIL, (void *)ESP_ERR_DPP_TX_FAILURE); + dpp_abort_with_failure(ESP_ERR_DPP_TX_FAILURE); os_free(req); return ESP_FAIL; } @@ -234,7 +267,7 @@ static void gas_query_timeout(void *eloop_data, void *user_ctx) wpabuf_free(auth->conf_req); auth->conf_req = NULL; } - esp_dpp_call_cb(ESP_SUPP_DPP_FAIL, (void *)ESP_ERR_DPP_CONF_TIMEOUT); + dpp_abort_with_failure(ESP_ERR_DPP_CONF_TIMEOUT); } static int gas_query_req_tx(struct dpp_authentication *auth) @@ -247,7 +280,7 @@ static int gas_query_req_tx(struct dpp_authentication *auth) supp_op_classes); if (!buf) { wpa_printf(MSG_ERROR, "DPP: No configuration request data available"); - esp_dpp_call_cb(ESP_SUPP_DPP_FAIL, (void *)ESP_ERR_DPP_FAILURE); + dpp_abort_with_failure(ESP_ERR_DPP_FAILURE); return ESP_FAIL; } @@ -298,7 +331,12 @@ static int esp_dpp_handle_config_obj(struct dpp_authentication *auth, if (atomic_load(&s_dpp_listen_in_progress)) { listen_stop_handler(NULL, NULL); } - esp_dpp_call_cb(ESP_SUPP_DPP_CFG_RECVD, wifi_cfg); + /* deinit AUTH since authentication is done */ + dpp_deinit_auth(); + + wifi_event_dpp_config_received_t event = {0}; + event.wifi_cfg = s_dpp_ctx.wifi_cfg; + esp_event_post(WIFI_EVENT, WIFI_EVENT_DPP_CFG_RECVD, &event, sizeof(event), OS_BLOCK); return 0; } @@ -573,7 +611,7 @@ static void esp_dpp_rx_action(void *data, void *user_ctx) os_free(rx_param); if (ret != ESP_OK) { - esp_dpp_call_cb(ESP_SUPP_DPP_FAIL, (void *)ESP_ERR_DPP_FAILURE); + dpp_abort_with_failure(ESP_ERR_DPP_FAILURE); } } @@ -609,6 +647,7 @@ static void esp_dpp_bootstrap_gen(void *data, void *user_ctx) { char *command = data; const char *uri; + uint32_t len; s_dpp_ctx.id = dpp_bootstrap_gen(s_dpp_ctx.dpp_global, command); @@ -621,7 +660,17 @@ static void esp_dpp_bootstrap_gen(void *data, void *user_ctx) } 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); + wifi_event_dpp_uri_ready_t *event; + len = sizeof(*event) + os_strlen(uri) + 1; + event = os_malloc(len); + if (!event) { + return; + } + event->uri_len = os_strlen(uri); + os_memcpy(event->uri, uri, event->uri_len); + event->uri[event->uri_len++] = '\0'; + esp_event_post(WIFI_EVENT, WIFI_EVENT_DPP_URI_READY, event, len, OS_BLOCK); + os_free(event); os_free(command); dpp_api_lock(); s_dpp_ctx.bootstrap_done = true; @@ -641,6 +690,14 @@ static int esp_dpp_deinit(void *data, void *user_ctx) esp_event_handler_unregister(WIFI_EVENT, WIFI_EVENT_ROC_DONE, &roc_status_handler); + if (s_dpp_ctx.dpp_event_cb) { + esp_event_handler_unregister(WIFI_EVENT, WIFI_EVENT_DPP_URI_READY, + &dpp_event_handler); + esp_event_handler_unregister(WIFI_EVENT, WIFI_EVENT_DPP_CFG_RECVD, + &dpp_event_handler); + esp_event_handler_unregister(WIFI_EVENT, WIFI_EVENT_DPP_FAILED, + &dpp_event_handler); + } if (params->info) { os_free(params->info); params->info = NULL; @@ -656,6 +713,7 @@ static int esp_dpp_deinit(void *data, void *user_ctx) } s_dpp_ctx.dpp_init_done = false; s_dpp_ctx.bootstrap_done = false; + s_dpp_ctx.dpp_event_cb = NULL; return 0; } @@ -701,7 +759,7 @@ static void esp_dpp_auth_resp_retry(void *eloop_ctx, void *timeout_ctx) auth->auth_resp_tries++; if (auth->auth_resp_tries >= max_tries) { wpa_printf(MSG_INFO, "DPP: No confirm received from initiator - stopping exchange"); - esp_dpp_call_cb(ESP_SUPP_DPP_FAIL, (void *)ESP_ERR_DPP_TX_FAILURE); + dpp_abort_with_failure(ESP_ERR_DPP_TX_FAILURE); return; } @@ -727,7 +785,7 @@ static void tx_status_handler(void *arg, esp_event_base_t event_base, return; } if (!auth) { - esp_dpp_call_cb(ESP_SUPP_DPP_FAIL, (void *)ESP_ERR_DPP_FAILURE); + dpp_abort_with_failure(ESP_ERR_DPP_FAILURE); return; } if (auth->waiting_auth_conf) { @@ -744,7 +802,7 @@ static void tx_status_handler(void *arg, esp_event_base_t event_base, 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); + dpp_abort_with_failure(ESP_ERR_DPP_TX_FAILURE); } else { eloop_cancel_timeout(gas_query_timeout, NULL, auth); eloop_register_timeout(ESP_GAS_TIMEOUT_SECS, 0, gas_query_timeout, NULL, auth); @@ -990,6 +1048,14 @@ static int esp_dpp_init(void *eloop_data, void *user_ctx) atomic_store(&s_dpp_listen_in_progress, false); s_dpp_ctx.dpp_event_cb = cb; + if (cb) { + esp_event_handler_register(WIFI_EVENT, WIFI_EVENT_DPP_URI_READY, + &dpp_event_handler, NULL); + esp_event_handler_register(WIFI_EVENT, WIFI_EVENT_DPP_CFG_RECVD, + &dpp_event_handler, NULL); + esp_event_handler_register(WIFI_EVENT, WIFI_EVENT_DPP_FAILED, + &dpp_event_handler, NULL); + } 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, From a929aae33f71f84db270bc6e31d96c7081a5ff46 Mon Sep 17 00:00:00 2001 From: Kapil Gupta Date: Wed, 7 May 2025 16:00:21 +0530 Subject: [PATCH 3/5] change(esp_wifi): Update dpp enrollee example to use updated events --- .../dpp-enrollee/main/dpp_enrollee_main.c | 101 +++++++++--------- 1 file changed, 51 insertions(+), 50 deletions(-) diff --git a/examples/wifi/wifi_easy_connect/dpp-enrollee/main/dpp_enrollee_main.c b/examples/wifi/wifi_easy_connect/dpp-enrollee/main/dpp_enrollee_main.c index a5af57587a..65bb9c6a4e 100644 --- a/examples/wifi/wifi_easy_connect/dpp-enrollee/main/dpp_enrollee_main.c +++ b/examples/wifi/wifi_easy_connect/dpp-enrollee/main/dpp_enrollee_main.c @@ -54,21 +54,56 @@ static EventGroupHandle_t s_dpp_event_group; static void event_handler(void *arg, esp_event_base_t event_base, int32_t event_id, void *event_data) { - if (event_base == WIFI_EVENT && event_id == WIFI_EVENT_STA_START) { - ESP_ERROR_CHECK(esp_supp_dpp_start_listen()); - ESP_LOGI(TAG, "Started listening for DPP Authentication"); - } else if (event_base == WIFI_EVENT && event_id == WIFI_EVENT_STA_DISCONNECTED) { - if (s_retry_num < WIFI_MAX_RETRY_NUM) { - esp_wifi_connect(); - s_retry_num++; - ESP_LOGI(TAG, "retry to connect to the AP"); - } else { - xEventGroupSetBits(s_dpp_event_group, DPP_CONNECT_FAIL_BIT); - } - ESP_LOGI(TAG, "connect to the AP fail"); - } else if (event_base == WIFI_EVENT && event_id == WIFI_EVENT_STA_CONNECTED) { + if (event_base == WIFI_EVENT) { + switch (event_id) { + case WIFI_EVENT_STA_START: + ESP_ERROR_CHECK(esp_supp_dpp_start_listen()); + ESP_LOGI(TAG, "Started listening for DPP Authentication"); + break; + case WIFI_EVENT_STA_DISCONNECTED: + if (s_retry_num < WIFI_MAX_RETRY_NUM) { + esp_wifi_connect(); + s_retry_num++; + ESP_LOGI(TAG, "Disconnect event, retry to connect to the AP"); + } else { + xEventGroupSetBits(s_dpp_event_group, DPP_CONNECT_FAIL_BIT); + } + break; + case WIFI_EVENT_STA_CONNECTED: ESP_LOGI(TAG, "Successfully connected to the AP ssid : %s ", s_dpp_wifi_config.sta.ssid); - } else if (event_base == IP_EVENT && event_id == IP_EVENT_STA_GOT_IP) { + break; + case WIFI_EVENT_DPP_URI_READY: + wifi_event_dpp_uri_ready_t *uri_data = event_data; + if (uri_data != NULL) { + esp_qrcode_config_t cfg = ESP_QRCODE_CONFIG_DEFAULT(); + + ESP_LOGI(TAG, "Scan below QR Code to configure the enrollee:"); + esp_qrcode_generate(&cfg, (const char *)uri_data->uri); + } + break; + case WIFI_EVENT_DPP_CFG_RECVD: + wifi_event_dpp_config_received_t *config = event_data; + memcpy(&s_dpp_wifi_config, &config->wifi_cfg, sizeof(s_dpp_wifi_config)); + s_retry_num = 0; + esp_wifi_set_config(ESP_IF_WIFI_STA, &s_dpp_wifi_config); + esp_wifi_connect(); + break; + case WIFI_EVENT_DPP_FAILED: + wifi_event_dpp_failed_t *dpp_failure = event_data; + if (s_retry_num < 5) { + ESP_LOGI(TAG, "DPP Auth failed (Reason: %s), retry...", esp_err_to_name((int)dpp_failure->failure_reason)); + ESP_ERROR_CHECK(esp_supp_dpp_start_listen()); + s_retry_num++; + } else { + xEventGroupSetBits(s_dpp_event_group, DPP_AUTH_FAIL_BIT); + } + + break; + default: + break; + } + } + if (event_base == IP_EVENT && event_id == IP_EVENT_STA_GOT_IP) { ip_event_got_ip_t *event = (ip_event_got_ip_t *) event_data; ESP_LOGI(TAG, "got ip:" IPSTR, IP2STR(&event->ip_info.ip)); s_retry_num = 0; @@ -76,37 +111,6 @@ static void event_handler(void *arg, esp_event_base_t event_base, } } -void dpp_enrollee_event_cb(esp_supp_dpp_event_t event, void *data) -{ - switch (event) { - case ESP_SUPP_DPP_URI_READY: - if (data != NULL) { - esp_qrcode_config_t cfg = ESP_QRCODE_CONFIG_DEFAULT(); - - ESP_LOGI(TAG, "Scan below QR Code to configure the enrollee:"); - esp_qrcode_generate(&cfg, (const char *)data); - } - break; - case ESP_SUPP_DPP_CFG_RECVD: - memcpy(&s_dpp_wifi_config, data, sizeof(s_dpp_wifi_config)); - s_retry_num = 0; - esp_wifi_set_config(ESP_IF_WIFI_STA, &s_dpp_wifi_config); - esp_wifi_connect(); - break; - case ESP_SUPP_DPP_FAIL: - if (s_retry_num < 5) { - ESP_LOGI(TAG, "DPP Auth failed (Reason: %s), retry...", esp_err_to_name((int)data)); - ESP_ERROR_CHECK(esp_supp_dpp_start_listen()); - s_retry_num++; - } else { - xEventGroupSetBits(s_dpp_event_group, DPP_AUTH_FAIL_BIT); - } - break; - default: - break; - } -} - esp_err_t dpp_enrollee_bootstrap(void) { esp_err_t ret; @@ -157,7 +161,7 @@ void dpp_enrollee_init(void) ESP_ERROR_CHECK(esp_wifi_init(&cfg)); ESP_ERROR_CHECK(esp_wifi_set_mode(WIFI_MODE_STA)); - ESP_ERROR_CHECK(esp_supp_dpp_init(dpp_enrollee_event_cb)); + ESP_ERROR_CHECK(esp_supp_dpp_init(NULL)); ESP_ERROR_CHECK(dpp_enrollee_bootstrap()); ESP_ERROR_CHECK(esp_wifi_start()); @@ -171,10 +175,7 @@ void dpp_enrollee_init(void) /* xEventGroupWaitBits() returns the bits before the call returned, hence we can test which event actually * happened. */ - if (bits & DPP_CONNECTED_BIT) { - ESP_LOGI(TAG, "connected to ap SSID:%s password:%s", - s_dpp_wifi_config.sta.ssid, s_dpp_wifi_config.sta.password); - } else if (bits & DPP_CONNECT_FAIL_BIT) { + if (bits & DPP_CONNECT_FAIL_BIT) { ESP_LOGI(TAG, "Failed to connect to SSID:%s, password:%s", s_dpp_wifi_config.sta.ssid, s_dpp_wifi_config.sta.password); } else if (bits & DPP_AUTH_FAIL_BIT) { From ab9304d3b7673e9948f51fa0dedde93be34c1f99 Mon Sep 17 00:00:00 2001 From: Kapil Gupta Date: Fri, 23 May 2025 12:59:54 +0530 Subject: [PATCH 4/5] fix(esp_wifi): Modify check for dpp event handlers --- components/esp_wifi/lib | 2 +- components/wpa_supplicant/esp_supplicant/src/esp_dpp.c | 10 +++++----- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/components/esp_wifi/lib b/components/esp_wifi/lib index ddc2cd5f6a..a854d20ea4 160000 --- a/components/esp_wifi/lib +++ b/components/esp_wifi/lib @@ -1 +1 @@ -Subproject commit ddc2cd5f6adf0c1503e0bb6843ea1b2ee1c4fd09 +Subproject commit a854d20ea4e7d7c818387aa22436ce3d5c52ae2f diff --git a/components/wpa_supplicant/esp_supplicant/src/esp_dpp.c b/components/wpa_supplicant/esp_supplicant/src/esp_dpp.c index bc34a7fe16..dee5e78efa 100644 --- a/components/wpa_supplicant/esp_supplicant/src/esp_dpp.c +++ b/components/wpa_supplicant/esp_supplicant/src/esp_dpp.c @@ -785,25 +785,25 @@ static void tx_status_handler(void *arg, esp_event_base_t event_base, return; } if (!auth) { - dpp_abort_with_failure(ESP_ERR_DPP_FAILURE); + wpa_printf(MSG_DEBUG, "Auth already deinitialized, return"); return; } if (auth->waiting_auth_conf) { eloop_cancel_timeout(esp_dpp_auth_resp_retry_timeout, NULL, NULL); - if (evt->status) { + if (evt->status == WIFI_ACTION_TX_FAILED) { /* 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 { + } else if (evt->status == WIFI_ACTION_TX_DONE) { 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) { + if (evt->status == WIFI_ACTION_TX_FAILED) { /* failed to send gas query frame, retry logic needed? */ wpa_printf(MSG_WARNING, "DPP: failed to send GAS query frame"); dpp_abort_with_failure(ESP_ERR_DPP_TX_FAILURE); - } else { + } else if (evt->status == WIFI_ACTION_TX_DONE) { eloop_cancel_timeout(gas_query_timeout, NULL, auth); eloop_register_timeout(ESP_GAS_TIMEOUT_SECS, 0, gas_query_timeout, NULL, auth); } From 3c84fd7b4d024502d201968c7a936b70719f5a5d Mon Sep 17 00:00:00 2001 From: Kapil Gupta Date: Tue, 3 Jun 2025 12:05:03 +0530 Subject: [PATCH 5/5] fix(esp_wifi): Make sure old DPP listen is cancelled --- .../esp_wifi/include/esp_wifi_types_generic.h | 2 +- components/esp_wifi/lib | 2 +- .../esp_supplicant/src/esp_dpp.c | 56 ++++++++++++++----- .../esp_supplicant/src/esp_dpp_i.h | 1 + components/wpa_supplicant/port/include/os.h | 2 +- .../dpp-enrollee/main/dpp_enrollee_main.c | 3 +- 6 files changed, 48 insertions(+), 18 deletions(-) diff --git a/components/esp_wifi/include/esp_wifi_types_generic.h b/components/esp_wifi/include/esp_wifi_types_generic.h index 04898f247e..dd1ab1a4bd 100644 --- a/components/esp_wifi/include/esp_wifi_types_generic.h +++ b/components/esp_wifi/include/esp_wifi_types_generic.h @@ -1525,7 +1525,7 @@ typedef struct { /** Argument structure for WIFI_EVENT_DPP_URI_READY event */ typedef struct { - uint32_t uri_len; /**< URI length */ + uint32_t uri_data_len; /**< URI data length including null termination */ char uri[]; /**< URI data */ } wifi_event_dpp_uri_ready_t; diff --git a/components/esp_wifi/lib b/components/esp_wifi/lib index a854d20ea4..bef6a32b6d 160000 --- a/components/esp_wifi/lib +++ b/components/esp_wifi/lib @@ -1 +1 @@ -Subproject commit a854d20ea4e7d7c818387aa22436ce3d5c52ae2f +Subproject commit bef6a32b6d1c862b5023ba1cf767d810ca1c3fa8 diff --git a/components/wpa_supplicant/esp_supplicant/src/esp_dpp.c b/components/wpa_supplicant/esp_supplicant/src/esp_dpp.c index dee5e78efa..17ce5408ea 100644 --- a/components/wpa_supplicant/esp_supplicant/src/esp_dpp.c +++ b/components/wpa_supplicant/esp_supplicant/src/esp_dpp.c @@ -32,8 +32,11 @@ struct action_rx_param { }; static void *s_dpp_api_lock = NULL; +static void *s_dpp_event_group = NULL; -static atomic_bool s_dpp_listen_in_progress; +#define DPP_ROC_EVENT_HANDLED BIT0 + +static atomic_bool roc_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; @@ -42,6 +45,7 @@ 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 void dpp_listen_next_channel(void *data, void *user_ctx); static esp_err_t dpp_api_lock(void) { if (!s_dpp_api_lock) { @@ -103,9 +107,11 @@ static int listen_stop_handler(void *data, void *user_ctx) { wifi_roc_req_t req = {0}; - atomic_store(&s_dpp_listen_in_progress, false); + wpa_printf(MSG_DEBUG, "DPP: Stoping ROC"); req.ifx = WIFI_IF_STA; req.type = WIFI_ROC_CANCEL; + eloop_cancel_timeout(dpp_listen_next_channel, NULL, NULL); + s_dpp_ctx.dpp_listen_ongoing = false; esp_wifi_remain_on_channel(&req); @@ -328,7 +334,7 @@ static int esp_dpp_handle_config_obj(struct dpp_authentication *auth, wpa_printf(MSG_INFO, DPP_EVENT_CONNECTOR "%s", conf->connector); } - if (atomic_load(&s_dpp_listen_in_progress)) { + if (atomic_load(&roc_in_progress)) { listen_stop_handler(NULL, NULL); } /* deinit AUTH since authentication is done */ @@ -589,7 +595,7 @@ static void esp_dpp_rx_action(void *data, void *user_ctx) (size_t)(public_action->v.pa_vendor_spec.vendor_data - (u8 *)rx_param->action_frm); - if (atomic_load(&s_dpp_listen_in_progress)) { + if (atomic_load(&roc_in_progress)) { listen_stop_handler(NULL, NULL); } @@ -615,7 +621,7 @@ static void esp_dpp_rx_action(void *data, void *user_ctx) } } -void esp_dpp_listen_next_channel(void *data, void *user_ctx) +static void dpp_listen_next_channel(void *data, void *user_ctx) { struct dpp_bootstrap_params_t *p = &s_dpp_ctx.bootstrap_params; static int counter; @@ -623,10 +629,14 @@ void esp_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) { + return; + } if (p->num_chan <= 0) { wpa_printf(MSG_ERROR, "Listen channel not set"); return; } + channel = p->chan_list[counter++ % p->num_chan]; wpa_printf(MSG_DEBUG, "DPP: Starting ROC on channel %d", channel); @@ -641,6 +651,7 @@ void esp_dpp_listen_next_channel(void *data, void *user_ctx) wpa_printf(MSG_ERROR, "Failed ROC. error : 0x%x", ret); return; } + os_event_group_clear_bits(s_dpp_event_group, DPP_ROC_EVENT_HANDLED); } static void esp_dpp_bootstrap_gen(void *data, void *user_ctx) @@ -666,9 +677,9 @@ static void esp_dpp_bootstrap_gen(void *data, void *user_ctx) if (!event) { return; } - event->uri_len = os_strlen(uri); - os_memcpy(event->uri, uri, event->uri_len); - event->uri[event->uri_len++] = '\0'; + 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); os_free(event); os_free(command); @@ -714,6 +725,10 @@ static int esp_dpp_deinit(void *data, void *user_ctx) s_dpp_ctx.dpp_init_done = false; s_dpp_ctx.bootstrap_done = false; s_dpp_ctx.dpp_event_cb = NULL; + if (s_dpp_event_group) { + os_event_group_delete(s_dpp_event_group); + s_dpp_event_group = NULL; + } return 0; } @@ -808,6 +823,7 @@ static void tx_status_handler(void *arg, esp_event_base_t event_base, eloop_register_timeout(ESP_GAS_TIMEOUT_SECS, 0, gas_query_timeout, NULL, auth); } } + atomic_store(&roc_in_progress, true); } static void roc_status_handler(void *arg, esp_event_base_t event_base, @@ -815,9 +831,13 @@ static void roc_status_handler(void *arg, esp_event_base_t event_base, { wifi_event_roc_done_t *evt = (wifi_event_roc_done_t *)event_data; - if (atomic_load(&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); + if (evt->context == (uint32_t)s_action_rx_cb) { + eloop_cancel_timeout(dpp_listen_next_channel, NULL, NULL); + eloop_register_timeout(0, 0, dpp_listen_next_channel, NULL, NULL); } + + atomic_store(&roc_in_progress, false); + os_event_group_set_bits(s_dpp_event_group, DPP_ROC_EVENT_HANDLED); } static char *esp_dpp_parse_chan_list(const char *chan_list) @@ -977,6 +997,12 @@ fail: return ret; } +static void dpp_listen_start(void *ctx, void *data) +{ + s_dpp_ctx.dpp_listen_ongoing = true; + dpp_listen_next_channel(NULL, NULL); +} + esp_err_t esp_supp_dpp_start_listen(void) { int ret = dpp_api_lock(); @@ -994,12 +1020,14 @@ esp_err_t esp_supp_dpp_start_listen(void) 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(); - atomic_store(&s_dpp_listen_in_progress, true); - eloop_register_timeout(0, 0, esp_dpp_listen_next_channel, NULL, NULL); + + /* 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)); + wpa_printf(MSG_DEBUG, "DPP: Starting ROC"); + eloop_register_timeout(0, 0, dpp_listen_start, NULL, NULL); return 0; } @@ -1045,7 +1073,6 @@ static int esp_dpp_init(void *eloop_data, void *user_ctx) goto init_fail; } - atomic_store(&s_dpp_listen_in_progress, false); s_dpp_ctx.dpp_event_cb = cb; if (cb) { @@ -1061,6 +1088,7 @@ static int esp_dpp_init(void *eloop_data, void *user_ctx) esp_event_handler_register(WIFI_EVENT, WIFI_EVENT_ROC_DONE, &roc_status_handler, NULL); + s_dpp_event_group = os_event_group_create(); wpa_printf(MSG_INFO, "DPP: dpp init done"); s_dpp_ctx.dpp_init_done = true; 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 651dfdbcc3..a0c6c9a475 100644 --- a/components/wpa_supplicant/esp_supplicant/src/esp_dpp_i.h +++ b/components/wpa_supplicant/esp_supplicant/src/esp_dpp_i.h @@ -40,6 +40,7 @@ struct esp_dpp_context_t { int id; bool dpp_init_done; bool bootstrap_done; + bool dpp_listen_ongoing; }; #ifdef CONFIG_TESTING_OPTIONS diff --git a/components/wpa_supplicant/port/include/os.h b/components/wpa_supplicant/port/include/os.h index af4677cae6..a2de76d46d 100644 --- a/components/wpa_supplicant/port/include/os.h +++ b/components/wpa_supplicant/port/include/os.h @@ -376,7 +376,7 @@ extern const wifi_osi_funcs_t *wifi_funcs; #define os_timer_get_time(void) wifi_funcs->_esp_timer_get_time(void) #define os_event_group_create(void) wifi_funcs->_event_group_create(void) -#define os_event_group_delete(void) wifi_funcs->_event_group_delete(void) +#define os_event_group_delete(a) wifi_funcs->_event_group_delete((a)) #define os_event_group_wait_bits(a, b, c, d, e) wifi_funcs->_event_group_wait_bits((a), (b), (c), (d), (e)) #define os_event_group_clear_bits(a, b) wifi_funcs->_event_group_clear_bits((a), (b)) #define os_event_group_set_bits(a, b) wifi_funcs->_event_group_set_bits((a), (b)) diff --git a/examples/wifi/wifi_easy_connect/dpp-enrollee/main/dpp_enrollee_main.c b/examples/wifi/wifi_easy_connect/dpp-enrollee/main/dpp_enrollee_main.c index 65bb9c6a4e..b2bac9e24c 100644 --- a/examples/wifi/wifi_easy_connect/dpp-enrollee/main/dpp_enrollee_main.c +++ b/examples/wifi/wifi_easy_connect/dpp-enrollee/main/dpp_enrollee_main.c @@ -175,7 +175,8 @@ void dpp_enrollee_init(void) /* xEventGroupWaitBits() returns the bits before the call returned, hence we can test which event actually * happened. */ - if (bits & DPP_CONNECT_FAIL_BIT) { + if (bits & DPP_CONNECTED_BIT) { + } else if (bits & DPP_CONNECT_FAIL_BIT) { ESP_LOGI(TAG, "Failed to connect to SSID:%s, password:%s", s_dpp_wifi_config.sta.ssid, s_dpp_wifi_config.sta.password); } else if (bits & DPP_AUTH_FAIL_BIT) {