Merge branch 'bugfix/dpp_listen_bugs_v4.3' into 'release/v4.3'

fix(esp_wifi): Backport DPP related bug fixes (v4.3)

See merge request espressif/esp-idf!27350
This commit is contained in:
Jiang Jiang Jian 2023-12-04 23:40:44 +08:00
commit b99bade548
4 changed files with 93 additions and 42 deletions

View File

@ -375,6 +375,9 @@ static const esp_err_msg_t esp_err_msg_table[] = {
# endif
# ifdef ESP_ERR_WIFI_DISCARD
ERR_TBL_IT(ESP_ERR_WIFI_DISCARD), /* 12311 0x3017 Discard frame */
# endif
# ifdef ESP_ERR_WIFI_ROC_IN_PROGRESS
ERR_TBL_IT(ESP_ERR_WIFI_ROC_IN_PROGRESS), /* 12312 0x3018 ROC op is in progress */
# endif
// components/wpa_supplicant/include/esp_supplicant/esp_wps.h
# ifdef ESP_ERR_WIFI_REGISTRAR

View File

@ -82,6 +82,7 @@ extern "C" {
#define ESP_ERR_WIFI_NOT_ASSOC (ESP_ERR_WIFI_BASE + 21) /*!< The WiFi connection is not associated */
#define ESP_ERR_WIFI_TX_DISALLOW (ESP_ERR_WIFI_BASE + 22) /*!< The WiFi TX is disallowed */
#define ESP_ERR_WIFI_DISCARD (ESP_ERR_WIFI_BASE + 23) /*!< Discard frame */
#define ESP_ERR_WIFI_ROC_IN_PROGRESS (ESP_ERR_WIFI_BASE + 24) /*!< ROC op is in progress */
/**
* @brief WiFi stack configuration parameters passed to esp_wifi_init call.

@ -1 +1 @@
Subproject commit 5b0b541f3a831d51e58f73aced93a3c092c79ba1
Subproject commit f888cc43d4c8842aeeecf16a8a6c19949eb62d42

View File

@ -17,8 +17,7 @@ static TaskHandle_t s_dpp_task_hdl = NULL;
static void *s_dpp_evt_queue = NULL;
static void *s_dpp_api_lock = NULL;
static bool s_dpp_stop_listening;
static int s_dpp_auth_retries;
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;
@ -70,6 +69,10 @@ end:
static void esp_dpp_call_cb(esp_supp_dpp_event_t evt, void *data)
{
if (evt == ESP_SUPP_DPP_FAIL && s_dpp_ctx.dpp_auth) {
dpp_auth_deinit(s_dpp_ctx.dpp_auth);
s_dpp_ctx.dpp_auth = NULL;
}
s_dpp_ctx.dpp_event_cb(evt, data);
}
@ -138,12 +141,14 @@ static void esp_dpp_rx_auth_req(struct action_rx_param *rx_param, uint8_t *dpp_d
rc = ESP_ERR_DPP_INVALID_ATTR;
goto fail;
}
if (s_dpp_ctx.dpp_auth) {
wpa_printf(MSG_DEBUG, "DPP: Already in DPP authentication exchange - ignore new one");
return;
}
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);
esp_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);
@ -200,7 +205,7 @@ static int esp_dpp_handle_config_obj(struct dpp_authentication *auth,
wpa_printf(MSG_INFO, DPP_EVENT_CONNECTOR "%s",
conf->connector);
}
s_dpp_stop_listening = false;
s_dpp_listen_in_progress = true;
esp_wifi_action_tx_req(WIFI_OFFCHAN_TX_CANCEL, 0, 0, NULL);
esp_dpp_call_cb(ESP_SUPP_DPP_CFG_RECVD, wifi_cfg);
@ -280,7 +285,7 @@ static void gas_query_resp_rx(struct action_rx_param *rx_param)
int i, res;
if (pos[1] == WLAN_EID_VENDOR_SPECIFIC && pos[2] == 5 &&
WPA_GET_BE24(&pos[3]) == OUI_WFA && pos[6] == 0x1a && pos[7] == 1) {
WPA_GET_BE24(&pos[3]) == OUI_WFA && pos[6] == 0x1a && pos[7] == 1 && auth) {
if (dpp_conf_resp_rx(auth, resp, rx_param->vendor_data_len - 2) < 0) {
wpa_printf(MSG_DEBUG, "DPP: Configuration attempt failed");
goto fail;
@ -316,7 +321,7 @@ static void esp_dpp_rx_action(struct action_rx_param *rx_param)
(size_t)(public_action->v.pa_vendor_spec.vendor_data -
(u8 *)rx_param->action_frm);
if (!s_dpp_stop_listening) {
if (s_dpp_listen_in_progress) {
esp_supp_dpp_stop_listen();
}
@ -354,9 +359,27 @@ static void esp_dpp_task(void *pvParameters )
}
switch (evt->id) {
case SIG_DPP_DEL_TASK:
case SIG_DPP_DEL_TASK: {
struct dpp_bootstrap_params_t *params = &s_dpp_ctx.bootstrap_params;
if (params->info) {
os_free(params->info);
params->info = NULL;
}
if (params->key) {
os_free(params->key);
params->key = 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;
}
break;
case SIG_DPP_BOOTSTRAP_GEN: {
char *command = (char *)evt->data;
@ -379,14 +402,20 @@ static void esp_dpp_task(void *pvParameters )
struct dpp_bootstrap_params_t *p = &s_dpp_ctx.bootstrap_params;
static int counter;
int channel;
esp_err_t ret = 0;
if (p->num_chan <= 0) {
wpa_printf(MSG_ERROR, "Listen channel not set");
break;
}
channel = p->chan_list[counter++ % p->num_chan];
esp_wifi_remain_on_channel(ESP_IF_WIFI_STA, WIFI_ROC_REQ, channel,
ret = esp_wifi_remain_on_channel(ESP_IF_WIFI_STA, WIFI_ROC_REQ, channel,
BOOTSTRAP_ROC_WAIT_TIME, s_action_rx_cb);
if (ret != ESP_OK) {
wpa_printf(MSG_ERROR, "Failed ROC. error : 0x%x", ret);
break;
}
s_dpp_listen_in_progress = true;
}
break;
@ -466,7 +495,7 @@ static void offchan_event_handler(void *arg, esp_event_base_t event_base,
} else if (event_id == WIFI_EVENT_ROC_DONE) {
wifi_event_roc_done_t *evt = (wifi_event_roc_done_t *)event_data;
if (!s_dpp_stop_listening && evt->context == (uint32_t)s_action_rx_cb) {
if (s_dpp_listen_in_progress && evt->context == (uint32_t)s_action_rx_cb) {
esp_dpp_post_evt(SIG_DPP_LISTEN_NEXT_CHANNEL, 0);
}
}
@ -613,6 +642,11 @@ 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;
}
if (!s_dpp_ctx.dpp_global || s_dpp_ctx.id < 1) {
wpa_printf(MSG_ERROR, "DPP: failed to start listen as dpp not initialized or bootstrapped.");
return ESP_FAIL;
@ -623,13 +657,12 @@ esp_err_t esp_supp_dpp_start_listen(void)
return ESP_ERR_INVALID_STATE;
}
s_dpp_stop_listening = false;
return esp_dpp_post_evt(SIG_DPP_LISTEN_NEXT_CHANNEL, 0);
}
void esp_supp_dpp_stop_listen(void)
{
s_dpp_stop_listening = true;
s_dpp_listen_in_progress = false;
esp_wifi_remain_on_channel(ESP_IF_WIFI_STA, WIFI_ROC_CANCEL, 0, 0, NULL);
}
@ -642,6 +675,7 @@ bool is_dpp_enabled(void)
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.");
@ -656,31 +690,42 @@ esp_err_t esp_supp_dpp_init(esp_supp_dpp_event_cb_t cb)
wpa_printf(MSG_ERROR, "DPP: failed to init as init already done.");
return ESP_FAIL;
}
struct dpp_global_config cfg = {0};
int ret;
os_bzero(&s_dpp_ctx, sizeof(s_dpp_ctx));
s_dpp_ctx.dpp_event_cb = cb;
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);
s_dpp_stop_listening = false;
s_dpp_evt_queue = xQueueCreate(3, sizeof(dpp_event_t));
ret = xTaskCreate(esp_dpp_task, "dppT", DPP_TASK_STACK_SIZE, NULL, 2, &s_dpp_task_hdl);
if (ret != pdPASS) {
wpa_printf(MSG_ERROR, "DPP: failed to create task");
return ESP_FAIL;
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 = xSemaphoreCreateRecursiveMutex();
if (!s_dpp_api_lock) {
esp_supp_dpp_deinit();
wpa_printf(MSG_ERROR, "DPP: dpp_init: failed to create DPP API lock");
return ESP_ERR_NO_MEM;
ret = ESP_ERR_NO_MEM;
goto init_fail;
}
s_dpp_evt_queue = xQueueCreate(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 = xTaskCreate(esp_dpp_task, "dppT", DPP_TASK_STACK_SIZE, NULL, 2, &s_dpp_task_hdl);
if (ret != pdPASS) {
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,
@ -689,29 +734,31 @@ esp_err_t esp_supp_dpp_init(esp_supp_dpp_event_cb_t cb)
wpa_printf(MSG_INFO, "esp_dpp_task prio:%d, stack:%d\n", 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) {
vSemaphoreDelete(s_dpp_api_lock);
s_dpp_api_lock = NULL;
}
if (s_dpp_evt_queue) {
vQueueDelete(s_dpp_evt_queue);
s_dpp_evt_queue = NULL;
}
return ret;
}
void esp_supp_dpp_deinit(void)
{
struct dpp_bootstrap_params_t *params = &s_dpp_ctx.bootstrap_params;
if (params->info) {
os_free(params->info);
params->info = NULL;
}
if (params->key) {
os_free(params->key);
params->key = NULL;
}
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);
s_dpp_auth_retries = 0;
if (s_dpp_ctx.dpp_global) {
dpp_global_deinit(s_dpp_ctx.dpp_global);
s_dpp_ctx.dpp_global = NULL;
esp_dpp_post_evt(SIG_DPP_DEL_TASK, 0);
if (esp_dpp_post_evt(SIG_DPP_DEL_TASK, 0)) {
wpa_printf(MSG_ERROR, "DPP Deinit Failed");
}
}
}
#endif