Skip to content

Commit e313438

Browse files
committed
Merge branch 'bugfix/dpp_listen_bugs_v5.0' into 'release/v5.0'
fix(wpa_supplicant): Fix few bugs in dpp(v5.0) See merge request espressif/esp-idf!26794
2 parents 907638e + 6cb42e4 commit e313438

File tree

6 files changed

+140
-54
lines changed

6 files changed

+140
-54
lines changed

components/esp_common/src/esp_err_to_name.c

+6
Original file line numberDiff line numberDiff line change
@@ -392,6 +392,9 @@ static const esp_err_msg_t esp_err_msg_table[] = {
392392
# endif
393393
# ifdef ESP_ERR_WIFI_DISCARD
394394
ERR_TBL_IT(ESP_ERR_WIFI_DISCARD), /* 12311 0x3017 Discard frame */
395+
# endif
396+
# ifdef ESP_ERR_WIFI_ROC_IN_PROGRESS
397+
ERR_TBL_IT(ESP_ERR_WIFI_ROC_IN_PROGRESS), /* 12312 0x3018 ROC op is in progress */
395398
# endif
396399
// components/wpa_supplicant/esp_supplicant/include/esp_wps.h
397400
# ifdef ESP_ERR_WIFI_REGISTRAR
@@ -440,6 +443,9 @@ static const esp_err_msg_t esp_err_msg_table[] = {
440443
# endif
441444
# ifdef ESP_ERR_DPP_INVALID_ATTR
442445
ERR_TBL_IT(ESP_ERR_DPP_INVALID_ATTR), /* 12441 0x3099 Encountered invalid DPP Attribute */
446+
# endif
447+
# ifdef ESP_ERR_DPP_AUTH_TIMEOUT
448+
ERR_TBL_IT(ESP_ERR_DPP_AUTH_TIMEOUT), /* 12442 0x309a DPP Auth response was not recieved in time */
443449
# endif
444450
// components/esp_common/include/esp_err.h
445451
# ifdef ESP_ERR_MESH_BASE

components/esp_wifi/include/esp_wifi.h

+2
Original file line numberDiff line numberDiff line change
@@ -83,6 +83,8 @@ extern "C" {
8383
#define ESP_ERR_WIFI_NOT_ASSOC (ESP_ERR_WIFI_BASE + 21) /*!< The WiFi connection is not associated */
8484
#define ESP_ERR_WIFI_TX_DISALLOW (ESP_ERR_WIFI_BASE + 22) /*!< The WiFi TX is disallowed */
8585
#define ESP_ERR_WIFI_DISCARD (ESP_ERR_WIFI_BASE + 23) /*!< Discard frame */
86+
#define ESP_ERR_WIFI_ROC_IN_PROGRESS (ESP_ERR_WIFI_BASE + 24) /*!< ROC op is in progress */
87+
8688
/**
8789
* @brief WiFi stack configuration parameters passed to esp_wifi_init call.
8890
*/

components/wpa_supplicant/esp_supplicant/include/esp_dpp.h

+4-2
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* SPDX-FileCopyrightText: 2020-2022 Espressif Systems (Shanghai) CO LTD
2+
* SPDX-FileCopyrightText: 2020-2023 Espressif Systems (Shanghai) CO LTD
33
*
44
* SPDX-License-Identifier: Apache-2.0
55
*/
@@ -15,10 +15,12 @@
1515
extern "C" {
1616
#endif
1717

18+
#define ESP_DPP_AUTH_TIMEOUT_SECS 1
19+
1820
#define ESP_ERR_DPP_FAILURE (ESP_ERR_WIFI_BASE + 151) /*!< Generic failure during DPP Operation */
1921
#define ESP_ERR_DPP_TX_FAILURE (ESP_ERR_WIFI_BASE + 152) /*!< DPP Frame Tx failed OR not Acked */
2022
#define ESP_ERR_DPP_INVALID_ATTR (ESP_ERR_WIFI_BASE + 153) /*!< Encountered invalid DPP Attribute */
21-
23+
#define ESP_ERR_DPP_AUTH_TIMEOUT (ESP_ERR_WIFI_BASE + 154) /*!< DPP Auth response was not recieved in time */
2224
/** @brief Types of Bootstrap Methods for DPP. */
2325
typedef enum dpp_bootstrap_type {
2426
DPP_BOOTSTRAP_QR_CODE, /**< QR Code Method */

components/wpa_supplicant/esp_supplicant/src/esp_dpp.c

+104-33
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66

77
#include "utils/includes.h"
88
#include "utils/common.h"
9+
#include "utils/eloop.h"
910
#include "common/defs.h"
1011

1112
#include "esp_dpp_i.h"
@@ -21,8 +22,7 @@ static void *s_dpp_task_hdl = NULL;
2122
static void *s_dpp_evt_queue = NULL;
2223
static void *s_dpp_api_lock = NULL;
2324

24-
static bool s_dpp_stop_listening;
25-
static int s_dpp_auth_retries;
25+
static bool s_dpp_listen_in_progress;
2626
static struct esp_dpp_context_t s_dpp_ctx;
2727
static wifi_action_rx_cb_t s_action_rx_cb = esp_supp_rx_action;
2828

@@ -37,6 +37,7 @@ struct action_rx_param {
3737
struct ieee80211_action *action_frm;
3838
};
3939

40+
4041
static int esp_dpp_post_evt(uint32_t evt_id, uint32_t data)
4142
{
4243
dpp_event_t *evt = os_zalloc(sizeof(dpp_event_t));
@@ -73,9 +74,27 @@ static int esp_dpp_post_evt(uint32_t evt_id, uint32_t data)
7374

7475
static void esp_dpp_call_cb(esp_supp_dpp_event_t evt, void *data)
7576
{
77+
if ( evt == ESP_SUPP_DPP_FAIL && s_dpp_ctx.dpp_auth) {
78+
dpp_auth_deinit(s_dpp_ctx.dpp_auth);
79+
s_dpp_ctx.dpp_auth = NULL;
80+
}
7681
s_dpp_ctx.dpp_event_cb(evt, data);
7782
}
7883

84+
static void esp_dpp_auth_conf_wait_timeout(void *eloop_ctx, void *timeout_ctx)
85+
{
86+
if (!s_dpp_ctx.dpp_auth || !s_dpp_ctx.dpp_auth->waiting_auth_conf)
87+
return;
88+
89+
wpa_printf(MSG_DEBUG,
90+
"DPP: Terminate authentication exchange due to Auth Confirm timeout");
91+
if (s_dpp_ctx.dpp_auth) {
92+
dpp_auth_deinit(s_dpp_ctx.dpp_auth);
93+
s_dpp_ctx.dpp_auth = NULL;
94+
}
95+
esp_dpp_call_cb(ESP_SUPP_DPP_FAIL, (void *)ESP_ERR_DPP_AUTH_TIMEOUT);
96+
}
97+
7998
void esp_send_action_frame(uint8_t *dest_mac, const uint8_t *buf, uint32_t len,
8099
uint8_t channel, uint32_t wait_time_ms)
81100
{
@@ -141,15 +160,20 @@ static void esp_dpp_rx_auth_req(struct action_rx_param *rx_param, uint8_t *dpp_d
141160
rc = ESP_ERR_DPP_INVALID_ATTR;
142161
goto fail;
143162
}
144-
163+
if (s_dpp_ctx.dpp_auth) {
164+
wpa_printf(MSG_DEBUG, "DPP: Already in DPP authentication exchange - ignore new one");
165+
return;
166+
}
145167
s_dpp_ctx.dpp_auth = dpp_auth_req_rx(NULL, DPP_CAPAB_ENROLLEE, 0, NULL,
146168
own_bi, rx_param->channel,
147169
(const u8 *)&rx_param->action_frm->u.public_action.v, dpp_data, len);
148170
os_memcpy(s_dpp_ctx.dpp_auth->peer_mac_addr, rx_param->sa, ETH_ALEN);
149-
150171
esp_send_action_frame(rx_param->sa, wpabuf_head(s_dpp_ctx.dpp_auth->resp_msg),
151172
wpabuf_len(s_dpp_ctx.dpp_auth->resp_msg),
152173
rx_param->channel, OFFCHAN_TX_WAIT_TIME);
174+
eloop_cancel_timeout(esp_dpp_auth_conf_wait_timeout, NULL,NULL);
175+
eloop_register_timeout(ESP_DPP_AUTH_TIMEOUT_SECS, 0, esp_dpp_auth_conf_wait_timeout,NULL, NULL);
176+
153177
return;
154178
fail:
155179
esp_dpp_call_cb(ESP_SUPP_DPP_FAIL, (void *)rc);
@@ -203,7 +227,7 @@ static int esp_dpp_handle_config_obj(struct dpp_authentication *auth,
203227
wpa_printf(MSG_INFO, DPP_EVENT_CONNECTOR "%s",
204228
conf->connector);
205229
}
206-
s_dpp_stop_listening = false;
230+
s_dpp_listen_in_progress = true;
207231
esp_wifi_action_tx_req(WIFI_OFFCHAN_TX_CANCEL, 0, 0, NULL);
208232
esp_dpp_call_cb(ESP_SUPP_DPP_CFG_RECVD, wifi_cfg);
209233

@@ -234,6 +258,8 @@ static void esp_dpp_rx_auth_conf(struct action_rx_param *rx_param, uint8_t *dpp_
234258
goto fail;
235259
}
236260

261+
eloop_cancel_timeout(esp_dpp_auth_conf_wait_timeout, NULL, NULL);
262+
237263
if (dpp_auth_conf_rx(auth, (const u8 *)&public_action->v,
238264
dpp_data, len) < 0) {
239265
wpa_printf(MSG_DEBUG, "DPP: Authentication failed");
@@ -283,7 +309,7 @@ static void gas_query_resp_rx(struct action_rx_param *rx_param)
283309
int i, res;
284310

285311
if (pos[1] == WLAN_EID_VENDOR_SPECIFIC && pos[2] == 5 &&
286-
WPA_GET_BE24(&pos[3]) == OUI_WFA && pos[6] == 0x1a && pos[7] == 1) {
312+
WPA_GET_BE24(&pos[3]) == OUI_WFA && pos[6] == 0x1a && pos[7] == 1 && auth) {
287313
if (dpp_conf_resp_rx(auth, resp, rx_param->vendor_data_len - 2) < 0) {
288314
wpa_printf(MSG_DEBUG, "DPP: Configuration attempt failed");
289315
goto fail;
@@ -319,7 +345,7 @@ static void esp_dpp_rx_action(struct action_rx_param *rx_param)
319345
(size_t)(public_action->v.pa_vendor_spec.vendor_data -
320346
(u8 *)rx_param->action_frm);
321347

322-
if (!s_dpp_stop_listening) {
348+
if (s_dpp_listen_in_progress) {
323349
esp_supp_dpp_stop_listen();
324350
}
325351

@@ -356,6 +382,21 @@ static void esp_dpp_task(void *pvParameters )
356382

357383
switch (evt->id) {
358384
case SIG_DPP_DEL_TASK:
385+
struct dpp_bootstrap_params_t *params = &s_dpp_ctx.bootstrap_params;
386+
eloop_cancel_timeout(esp_dpp_auth_conf_wait_timeout, NULL, NULL);
387+
if (params->info) {
388+
os_free(params->info);
389+
params->info = NULL;
390+
}
391+
392+
if (s_dpp_ctx.dpp_global) {
393+
dpp_global_deinit(s_dpp_ctx.dpp_global);
394+
s_dpp_ctx.dpp_global = NULL;
395+
}
396+
if (s_dpp_ctx.dpp_auth) {
397+
dpp_auth_deinit(s_dpp_ctx.dpp_auth);
398+
s_dpp_ctx.dpp_auth = NULL;
399+
}
359400
task_del = true;
360401
break;
361402

@@ -380,14 +421,20 @@ static void esp_dpp_task(void *pvParameters )
380421
struct dpp_bootstrap_params_t *p = &s_dpp_ctx.bootstrap_params;
381422
static int counter;
382423
int channel;
424+
esp_err_t ret = 0;
383425

384426
if (p->num_chan <= 0) {
385427
wpa_printf(MSG_ERROR, "Listen channel not set");
386428
break;
387429
}
388430
channel = p->chan_list[counter++ % p->num_chan];
389-
esp_wifi_remain_on_channel(WIFI_IF_STA, WIFI_ROC_REQ, channel,
431+
ret = esp_wifi_remain_on_channel(WIFI_IF_STA, WIFI_ROC_REQ, channel,
390432
BOOTSTRAP_ROC_WAIT_TIME, s_action_rx_cb);
433+
if (ret != ESP_OK) {
434+
wpa_printf(MSG_ERROR, "Failed ROC. error : 0x%x", ret);
435+
break;
436+
}
437+
s_dpp_listen_in_progress = true;
391438
}
392439
break;
393440

@@ -460,13 +507,14 @@ static void offchan_event_handler(void *arg, esp_event_base_t event_base,
460507
evt->status, (uint32_t)evt->context);
461508

462509
if (evt->status) {
510+
eloop_cancel_timeout(esp_dpp_auth_conf_wait_timeout, NULL, NULL);
463511
esp_dpp_call_cb(ESP_SUPP_DPP_FAIL, (void *)ESP_ERR_DPP_TX_FAILURE);
464512
}
465513

466514
} else if (event_id == WIFI_EVENT_ROC_DONE) {
467515
wifi_event_roc_done_t *evt = (wifi_event_roc_done_t *)event_data;
468516

469-
if (!s_dpp_stop_listening && evt->context == (uint32_t)s_action_rx_cb) {
517+
if (s_dpp_listen_in_progress && evt->context == (uint32_t)s_action_rx_cb) {
470518
esp_dpp_post_evt(SIG_DPP_LISTEN_NEXT_CHANNEL, 0);
471519
}
472520
}
@@ -591,6 +639,11 @@ esp_supp_dpp_bootstrap_gen(const char *chan_list, enum dpp_bootstrap_type type,
591639

592640
esp_err_t esp_supp_dpp_start_listen(void)
593641
{
642+
if (s_dpp_listen_in_progress) {
643+
wpa_printf(MSG_ERROR, "DPP: Failed to start listen as listen is already in progress.");
644+
return ESP_FAIL;
645+
}
646+
594647
if (!s_dpp_ctx.dpp_global || s_dpp_ctx.id < 1) {
595648
wpa_printf(MSG_ERROR, "DPP: failed to start listen as dpp not initialized or bootstrapped.");
596649
return ESP_FAIL;
@@ -601,13 +654,12 @@ esp_err_t esp_supp_dpp_start_listen(void)
601654
return ESP_ERR_INVALID_STATE;
602655
}
603656

604-
s_dpp_stop_listening = false;
605657
return esp_dpp_post_evt(SIG_DPP_LISTEN_NEXT_CHANNEL, 0);
606658
}
607659

608660
void esp_supp_dpp_stop_listen(void)
609661
{
610-
s_dpp_stop_listening = true;
662+
s_dpp_listen_in_progress = false;
611663
esp_wifi_remain_on_channel(WIFI_IF_STA, WIFI_ROC_CANCEL, 0, 0, NULL);
612664
}
613665

@@ -618,6 +670,7 @@ bool is_dpp_enabled(void)
618670

619671
esp_err_t esp_supp_dpp_init(esp_supp_dpp_event_cb_t cb)
620672
{
673+
esp_err_t ret = ESP_OK;
621674
wifi_mode_t mode = 0;
622675
if (esp_wifi_get_mode(&mode) || ((mode != WIFI_MODE_STA) && (mode != WIFI_MODE_APSTA))) {
623676
wpa_printf(MSG_ERROR, "DPP: failed to init as not in station mode.");
@@ -632,30 +685,41 @@ esp_err_t esp_supp_dpp_init(esp_supp_dpp_event_cb_t cb)
632685
wpa_printf(MSG_ERROR, "DPP: failed to init as init already done.");
633686
return ESP_FAIL;
634687
}
635-
struct dpp_global_config cfg = {0};
636-
int ret;
637688

638689
os_bzero(&s_dpp_ctx, sizeof(s_dpp_ctx));
639-
s_dpp_ctx.dpp_event_cb = cb;
640-
690+
struct dpp_global_config cfg = {0};
641691
cfg.cb_ctx = &s_dpp_ctx;
642692
cfg.msg_ctx = &s_dpp_ctx;
643693
s_dpp_ctx.dpp_global = dpp_global_init(&cfg);
694+
if (!s_dpp_ctx.dpp_global) {
695+
wpa_printf(MSG_ERROR, "DPP: failed to allocate memory for dpp_global");
696+
ret = ESP_ERR_NO_MEM;
697+
goto init_fail;
698+
}
699+
700+
s_dpp_api_lock = os_recursive_mutex_create();
701+
if (!s_dpp_api_lock) {
702+
wpa_printf(MSG_ERROR, "DPP: dpp_init: failed to create DPP API lock");
703+
ret = ESP_ERR_NO_MEM;
704+
goto init_fail;
705+
}
644706

645-
s_dpp_stop_listening = false;
646707
s_dpp_evt_queue = os_queue_create(3, sizeof(dpp_event_t));
708+
if (!s_dpp_evt_queue) {
709+
wpa_printf(MSG_ERROR, "DPP: dpp_init: failed to create DPP API queue");
710+
ret = ESP_ERR_NO_MEM;
711+
goto init_fail;
712+
}
713+
647714
ret = os_task_create(esp_dpp_task, "dppT", DPP_TASK_STACK_SIZE, NULL, 2, &s_dpp_task_hdl);
648715
if (ret != TRUE) {
649716
wpa_printf(MSG_ERROR, "DPP: failed to create task");
650-
return ESP_FAIL;
717+
ret = ESP_ERR_NO_MEM;
718+
goto init_fail;
651719
}
652720

653-
s_dpp_api_lock = os_recursive_mutex_create();
654-
if (!s_dpp_api_lock) {
655-
esp_supp_dpp_deinit();
656-
wpa_printf(MSG_ERROR, "DPP: dpp_init: failed to create DPP API lock");
657-
return ESP_ERR_NO_MEM;
658-
}
721+
s_dpp_listen_in_progress = false;
722+
s_dpp_ctx.dpp_event_cb = cb;
659723

660724
esp_event_handler_register(WIFI_EVENT, WIFI_EVENT_ACTION_TX_STATUS,
661725
&offchan_event_handler, NULL);
@@ -665,25 +729,32 @@ esp_err_t esp_supp_dpp_init(esp_supp_dpp_event_cb_t cb)
665729
wpa_printf(MSG_INFO, "esp_dpp_task prio:%d, stack:%d\n", 2, DPP_TASK_STACK_SIZE);
666730

667731
return ESP_OK;
732+
init_fail:
733+
if (s_dpp_ctx.dpp_global) {
734+
dpp_global_deinit(s_dpp_ctx.dpp_global);
735+
s_dpp_ctx.dpp_global = NULL;
736+
}
737+
if (s_dpp_api_lock) {
738+
os_semphr_delete(s_dpp_api_lock);
739+
s_dpp_api_lock = NULL;
740+
}
741+
if (s_dpp_evt_queue) {
742+
os_queue_delete(s_dpp_evt_queue);
743+
s_dpp_evt_queue = NULL;
744+
}
745+
return ret;
668746
}
669-
670747
void esp_supp_dpp_deinit(void)
671748
{
672-
struct dpp_bootstrap_params_t *params = &s_dpp_ctx.bootstrap_params;
673-
if (params->info) {
674-
os_free(params->info);
675-
params->info = NULL;
676-
}
677749

678750
esp_event_handler_unregister(WIFI_EVENT, WIFI_EVENT_ACTION_TX_STATUS,
679751
&offchan_event_handler);
680752
esp_event_handler_unregister(WIFI_EVENT, WIFI_EVENT_ROC_DONE,
681753
&offchan_event_handler);
682-
s_dpp_auth_retries = 0;
683754
if (s_dpp_ctx.dpp_global) {
684-
dpp_global_deinit(s_dpp_ctx.dpp_global);
685-
s_dpp_ctx.dpp_global = NULL;
686-
esp_dpp_post_evt(SIG_DPP_DEL_TASK, 0);
755+
if (esp_dpp_post_evt(SIG_DPP_DEL_TASK, 0)) {
756+
wpa_printf(MSG_ERROR, "DPP Deinit Failed");
757+
}
687758
}
688759
}
689760
#endif

0 commit comments

Comments
 (0)