Merge branch 'bugfix/backport_supplicant_fixes_v5.1' into 'release/v5.1'

fix(wifi): Backport some fixes(v5.1)

See merge request espressif/esp-idf!33977
This commit is contained in:
Jiang Jiang Jian 2024-10-18 11:18:10 +08:00
commit 71ff7408a2
7 changed files with 59 additions and 47 deletions

View File

@ -19,6 +19,7 @@
#include "esp_wifi_types.h" #include "esp_wifi_types.h"
#include "esp_wpa3_i.h" #include "esp_wpa3_i.h"
#include "esp_wps.h" #include "esp_wps.h"
#include "esp_wps_i.h"
#define WIFI_PASSWORD_LEN_MAX 65 #define WIFI_PASSWORD_LEN_MAX 65
@ -238,6 +239,9 @@ bool hostap_deinit(void *data)
esp_wifi_unset_appie_internal(WIFI_APPIE_WPA); esp_wifi_unset_appie_internal(WIFI_APPIE_WPA);
esp_wifi_unset_appie_internal(WIFI_APPIE_ASSOC_RESP); esp_wifi_unset_appie_internal(WIFI_APPIE_ASSOC_RESP);
#ifdef CONFIG_WPS_REGISTRAR
wifi_ap_wps_disable_internal();
#endif
#ifdef CONFIG_SAE #ifdef CONFIG_SAE
wpa3_hostap_auth_deinit(); wpa3_hostap_auth_deinit();
/* Wait till lock is released by wpa3 task */ /* Wait till lock is released by wpa3 task */

View File

@ -358,16 +358,19 @@ int wpa3_hostap_post_evt(uint32_t evt_id, uint32_t data)
if (g_wpa3_hostap_evt_queue == NULL) { if (g_wpa3_hostap_evt_queue == NULL) {
WPA3_HOSTAP_AUTH_API_UNLOCK(); WPA3_HOSTAP_AUTH_API_UNLOCK();
os_free(evt); os_free(evt);
wpa_printf(MSG_DEBUG, "hostap evt queue NULL");
return ESP_FAIL; return ESP_FAIL;
} }
} else { } else {
os_free(evt); os_free(evt);
wpa_printf(MSG_DEBUG, "g_wpa3_hostap_auth_api_lock not found");
return ESP_FAIL; return ESP_FAIL;
} }
if (evt->id == SIG_WPA3_RX_CONFIRM || evt->id == SIG_TASK_DEL) { if (evt->id == SIG_WPA3_RX_CONFIRM || evt->id == SIG_TASK_DEL) {
/* prioritising confirm for completing handshake for committed sta */ /* prioritising confirm for completing handshake for committed sta */
if (os_queue_send_to_front(g_wpa3_hostap_evt_queue, &evt, 0) != pdPASS) { if (os_queue_send_to_front(g_wpa3_hostap_evt_queue, &evt, 0) != pdPASS) {
WPA3_HOSTAP_AUTH_API_UNLOCK(); WPA3_HOSTAP_AUTH_API_UNLOCK();
wpa_printf(MSG_DEBUG, "failed to add msg to queue front");
os_free(evt); os_free(evt);
return ESP_FAIL; return ESP_FAIL;
} }
@ -375,6 +378,7 @@ int wpa3_hostap_post_evt(uint32_t evt_id, uint32_t data)
if (os_queue_send(g_wpa3_hostap_evt_queue, &evt, 0) != pdPASS) { if (os_queue_send(g_wpa3_hostap_evt_queue, &evt, 0) != pdPASS) {
WPA3_HOSTAP_AUTH_API_UNLOCK(); WPA3_HOSTAP_AUTH_API_UNLOCK();
os_free(evt); os_free(evt);
wpa_printf(MSG_DEBUG, "failed to send msg to queue");
return ESP_FAIL; return ESP_FAIL;
} }
} }

View File

@ -72,6 +72,7 @@ void wifi_station_wps_msg_timeout(void *data, void *user_ctx);
void wifi_station_wps_eapol_start_handle(void *data, void *user_ctx); void wifi_station_wps_eapol_start_handle(void *data, void *user_ctx);
void wifi_station_wps_success(void *data, void *user_ctx); void wifi_station_wps_success(void *data, void *user_ctx);
void wifi_station_wps_timeout(void *data, void *user_ctx); void wifi_station_wps_timeout(void *data, void *user_ctx);
int wps_delete_timer(void);
struct wps_sm *gWpsSm = NULL; struct wps_sm *gWpsSm = NULL;
static wps_factory_information_t *s_factory_info = NULL; static wps_factory_information_t *s_factory_info = NULL;
@ -420,9 +421,9 @@ wps_parse_scan_result(struct wps_scan_ie *scan)
return false; return false;
} }
esp_wifi_enable_sta_privacy_internal(); esp_wifi_enable_sta_privacy_internal();
os_memset(sm->ssid[0], 0, SSID_MAX_LEN); os_memset(sm->creds[0].ssid, 0, SSID_MAX_LEN);
os_memcpy(sm->ssid[0], (char *)&scan->ssid[2], (int)scan->ssid[1]); os_memcpy(sm->creds[0].ssid, (char *)&scan->ssid[2], (int)scan->ssid[1]);
sm->ssid_len[0] = scan->ssid[1]; sm->creds[0].ssid_len = scan->ssid[1];
if (scan->bssid && memcmp(sm->bssid, scan->bssid, ETH_ALEN) != 0) { if (scan->bssid && memcmp(sm->bssid, scan->bssid, ETH_ALEN) != 0) {
wpa_printf(MSG_INFO, "sm BSSid: "MACSTR " scan BSSID " MACSTR, wpa_printf(MSG_INFO, "sm BSSid: "MACSTR " scan BSSID " MACSTR,
MAC2STR(sm->bssid), MAC2STR(scan->bssid)); MAC2STR(sm->bssid), MAC2STR(scan->bssid));
@ -436,7 +437,7 @@ wps_parse_scan_result(struct wps_scan_ie *scan)
wps_build_ic_appie_wps_ar(); wps_build_ic_appie_wps_ar();
} }
} }
wpa_printf(MSG_DEBUG, "wps discover [%s]", (char *)sm->ssid); wpa_printf(MSG_DEBUG, "wps discover [%s]", (char *)sm->creds[0].ssid);
sm->channel = scan->chan; sm->channel = scan->chan;
return true; return true;
@ -592,14 +593,14 @@ int wps_process_wps_mX_req(u8 *ubuf, int len, enum wps_process_res *res)
if (expd->opcode != WSC_Start) { if (expd->opcode != WSC_Start) {
wpa_printf(MSG_DEBUG, "EAP-WSC: Unexpected Op-Code %d " wpa_printf(MSG_DEBUG, "EAP-WSC: Unexpected Op-Code %d "
"in WAIT_START state", expd->opcode); "in WAIT_START state", expd->opcode);
return ESP_FAIL; return ESP_ERR_INVALID_STATE;
} }
wpa_printf(MSG_DEBUG, "EAP-WSC: Received start"); wpa_printf(MSG_DEBUG, "EAP-WSC: Received start");
sm->state = WPA_MESG; sm->state = WPA_MESG;
} else if (expd->opcode == WSC_Start){ } else if (expd->opcode == WSC_Start) {
wpa_printf(MSG_DEBUG, "EAP-WSC: Unexpected Op-Code %d", wpa_printf(MSG_DEBUG, "EAP-WSC: Unexpected Op-Code %d",
expd->opcode); expd->opcode);
return ESP_FAIL; return ESP_ERR_INVALID_STATE;
} }
flag = *(u8 *)(ubuf + sizeof(struct eap_expand)); flag = *(u8 *)(ubuf + sizeof(struct eap_expand));
@ -764,8 +765,7 @@ static int wps_sm_init(struct wps_sm *sm)
sm->scan_cnt = 0; sm->scan_cnt = 0;
sm->discover_ssid_cnt = 0; sm->discover_ssid_cnt = 0;
os_bzero(sm->bssid, ETH_ALEN); os_bzero(sm->bssid, ETH_ALEN);
os_bzero(sm->ssid, sizeof(sm->ssid)); os_bzero(sm->creds, sizeof(sm->creds));
os_bzero(sm->ssid_len, sizeof(sm->ssid_len));
sm->ap_cred_cnt = 0; sm->ap_cred_cnt = 0;
return 0; return 0;
@ -806,7 +806,8 @@ int wps_finish(void)
if (sm->wps->state == WPS_FINISHED) { if (sm->wps->state == WPS_FINISHED) {
wpa_printf(MSG_DEBUG, "wps finished------>"); wpa_printf(MSG_DEBUG, "wps finished------>");
wps_set_status(WPS_STATUS_SUCCESS); wps_set_status(WPS_STATUS_SUCCESS);
wps_stop_connection_timers(sm); /* WPS finished, dequeue all timers */
wps_delete_timer();
if (sm->ap_cred_cnt == 1) { if (sm->ap_cred_cnt == 1) {
wifi_config_t *config = os_zalloc(sizeof(wifi_config_t)); wifi_config_t *config = os_zalloc(sizeof(wifi_config_t));
@ -816,12 +817,21 @@ int wps_finish(void)
} }
esp_wifi_get_config(WIFI_IF_STA, config); esp_wifi_get_config(WIFI_IF_STA, config);
os_memcpy(config->sta.ssid, sm->ssid[0], sm->ssid_len[0]); esp_wifi_disconnect();
os_memcpy(config->sta.password, sm->key[0], sm->key_len[0]); os_memcpy(config->sta.ssid, sm->creds[0].ssid, sm->creds[0].ssid_len);
os_memcpy(config->sta.password, sm->creds[0].key, sm->creds[0].key_len);
os_memcpy(config->sta.bssid, sm->bssid, ETH_ALEN); os_memcpy(config->sta.bssid, sm->bssid, ETH_ALEN);
#ifndef CONFIG_WPS_STRICT
/* Some APs support AES in WPA IE, enable connection with them */
if (sm->creds[0].auth_type == WPS_AUTH_WPAPSK &&
(sm->creds[0].encr_type & WPS_ENCR_AES)) {
config->sta.threshold.authmode = WIFI_AUTH_WPA_PSK;
}
#endif
config->sta.bssid_set = 0; config->sta.bssid_set = 0;
config->sta.sae_pwe_h2e = 0; config->sta.sae_pwe_h2e = 0;
esp_wifi_set_config(WIFI_IF_STA, config); esp_wifi_set_config(WIFI_IF_STA, config);
esp_wifi_connect();
os_free(config); os_free(config);
} }
@ -834,8 +844,7 @@ int wps_finish(void)
if (sm->ignore_sel_reg) { if (sm->ignore_sel_reg) {
sm->discover_ssid_cnt = 0; sm->discover_ssid_cnt = 0;
esp_wifi_disconnect(); esp_wifi_disconnect();
os_bzero(sm->ssid, sizeof(sm->ssid)); os_bzero(sm->creds, sizeof(sm->creds));
os_bzero(sm->ssid_len, sizeof(sm->ssid_len));
wps_add_discard_ap(sm->bssid); wps_add_discard_ap(sm->bssid);
} else { } else {
ret = wps_stop_process(WPS_FAIL_REASON_NORMAL); ret = wps_stop_process(WPS_FAIL_REASON_NORMAL);
@ -1058,6 +1067,8 @@ int wps_sm_rx_eapol_internal(u8 *src_addr, u8 *buf, u32 len)
wpa_printf(MSG_DEBUG, "sm->wps->state = %d", sm->wps->state); wpa_printf(MSG_DEBUG, "sm->wps->state = %d", sm->wps->state);
wps_start_msg_timer(); wps_start_msg_timer();
} }
} else if (ret == ESP_ERR_INVALID_STATE) {
ret = ESP_OK;
} else { } else {
ret = ESP_FAIL; ret = ESP_FAIL;
} }
@ -1285,8 +1296,7 @@ wifi_station_wps_msg_timeout_internal(void)
if (sm->ignore_sel_reg) { if (sm->ignore_sel_reg) {
esp_wifi_disconnect(); esp_wifi_disconnect();
wps_add_discard_ap(sm->bssid); wps_add_discard_ap(sm->bssid);
os_bzero(sm->ssid, sizeof(sm->ssid)); os_bzero(sm->creds, sizeof(sm->creds));
os_bzero(sm->ssid_len, sizeof(sm->ssid_len));
os_bzero(sm->bssid, ETH_ALEN); os_bzero(sm->bssid, ETH_ALEN);
sm->discover_ssid_cnt = 0; sm->discover_ssid_cnt = 0;
wifi_wps_scan(NULL, NULL); wifi_wps_scan(NULL, NULL);
@ -1316,8 +1326,8 @@ void wifi_station_wps_success_internal(void)
if (sm->ap_cred_cnt > 1) { if (sm->ap_cred_cnt > 1) {
evt.ap_cred_cnt = sm->ap_cred_cnt; evt.ap_cred_cnt = sm->ap_cred_cnt;
for (i = 0; i < MAX_WPS_AP_CRED; i++) { for (i = 0; i < MAX_WPS_AP_CRED; i++) {
os_memcpy(evt.ap_cred[i].ssid, sm->ssid[i], sm->ssid_len[i]); os_memcpy(evt.ap_cred[i].ssid, sm->creds[i].ssid, sm->creds[i].ssid_len);
os_memcpy(evt.ap_cred[i].passphrase, sm->key[i], sm->key_len[i]); os_memcpy(evt.ap_cred[i].passphrase, sm->creds[i].key, sm->creds[i].key_len);
} }
esp_event_post(WIFI_EVENT, WIFI_EVENT_STA_WPS_ER_SUCCESS, &evt, esp_event_post(WIFI_EVENT, WIFI_EVENT_STA_WPS_ER_SUCCESS, &evt,
sizeof(evt), OS_BLOCK); sizeof(evt), OS_BLOCK);
@ -1355,17 +1365,13 @@ void wifi_station_wps_eapol_start_handle(void *data, void *user_ctx)
static int save_credentials_cb(void *ctx, const struct wps_credential *cred) static int save_credentials_cb(void *ctx, const struct wps_credential *cred)
{ {
if (!gWpsSm || !cred || gWpsSm->ap_cred_cnt > 2) { struct wps_credential *creds;
if (!gWpsSm || !cred || gWpsSm->ap_cred_cnt >= MAX_CRED_COUNT) {
return ESP_FAIL; return ESP_FAIL;
} }
os_memset(gWpsSm->ssid[gWpsSm->ap_cred_cnt], 0x00, sizeof(gWpsSm->ssid[gWpsSm->ap_cred_cnt])); creds = &gWpsSm->creds[gWpsSm->ap_cred_cnt];
os_memset(gWpsSm->key[gWpsSm->ap_cred_cnt], 0x00, sizeof(gWpsSm->key[gWpsSm->ap_cred_cnt])); memcpy(creds, cred, sizeof(*creds));
os_memcpy(gWpsSm->ssid[gWpsSm->ap_cred_cnt], cred->ssid, cred->ssid_len);
gWpsSm->ssid_len[gWpsSm->ap_cred_cnt] = cred->ssid_len;
os_memcpy(gWpsSm->key[gWpsSm->ap_cred_cnt], cred->key, cred->key_len);
gWpsSm->key_len[gWpsSm->ap_cred_cnt] = cred->key_len;
gWpsSm->ap_cred_cnt++; gWpsSm->ap_cred_cnt++;
@ -1618,14 +1624,15 @@ wifi_wps_scan_done(void *arg, ETS_STATUS status)
esp_wifi_disconnect(); esp_wifi_disconnect();
os_memcpy(wifi_config.sta.bssid, sm->bssid, ETH_ALEN); os_memcpy(wifi_config.sta.bssid, sm->bssid, ETH_ALEN);
os_memcpy(wifi_config.sta.ssid, (char *)sm->ssid[0], sm->ssid_len[0]); os_memcpy(wifi_config.sta.ssid, (char *)sm->creds[0].ssid, sm->creds[0].ssid_len);
wifi_config.sta.bssid_set = 1; wifi_config.sta.bssid_set = 1;
wifi_config.sta.channel = sm->channel; wifi_config.sta.channel = sm->channel;
wpa_printf(MSG_INFO, "WPS: connecting to %s, bssid=" MACSTR, wpa_printf(MSG_INFO, "WPS: connecting to %s, bssid=" MACSTR,
(char *)sm->ssid[0], MAC2STR(wifi_config.sta.bssid)); (char *)sm->creds[0].ssid, MAC2STR(wifi_config.sta.bssid));
esp_wifi_set_config(0, &wifi_config); esp_wifi_set_config(0, &wifi_config);
wpa_printf(MSG_DEBUG, "WPS: neg start"); wpa_printf(MSG_DEBUG, "WPS: neg start");
wifi_config.sta.failure_retry_cnt = 2;
esp_wifi_connect(); esp_wifi_connect();
sm->state = WAIT_START; sm->state = WAIT_START;
eloop_cancel_timeout(wifi_station_wps_msg_timeout, NULL, NULL); eloop_cancel_timeout(wifi_station_wps_msg_timeout, NULL, NULL);

View File

@ -6,6 +6,8 @@
#include "esp_wifi_driver.h" #include "esp_wifi_driver.h"
#include "esp_wps.h" #include "esp_wps.h"
#include "wps/wps.h"
#include "wps/wps_attr_parse.h"
/* WPS message flag */ /* WPS message flag */
enum wps_msg_flag { enum wps_msg_flag {
@ -57,15 +59,6 @@ struct discard_ap_list_t{
u8 bssid[6]; u8 bssid[6];
}; };
#ifndef MAX_PASSPHRASE_LEN
#define MAX_PASSPHRASE_LEN 64
#endif
#ifndef MAX_CRED_COUNT
#define MAX_CRED_COUNT 10
#endif
#define WPS_OUTBUF_SIZE 500
struct wps_sm { struct wps_sm {
u8 state; u8 state;
struct wps_config *wps_cfg; struct wps_config *wps_cfg;
@ -75,10 +68,7 @@ struct wps_sm {
u8 identity_len; u8 identity_len;
u8 ownaddr[ETH_ALEN]; u8 ownaddr[ETH_ALEN];
u8 bssid[ETH_ALEN]; u8 bssid[ETH_ALEN];
u8 ssid[MAX_CRED_COUNT][SSID_MAX_LEN]; struct wps_credential creds[MAX_CRED_COUNT];
u8 ssid_len[MAX_CRED_COUNT];
char key[MAX_CRED_COUNT][MAX_PASSPHRASE_LEN];
u8 key_len[MAX_CRED_COUNT];
u8 ap_cred_cnt; u8 ap_cred_cnt;
struct wps_device_data *dev; struct wps_device_data *dev;
u8 uuid[16]; u8 uuid[16];
@ -147,3 +137,4 @@ static inline int wps_set_status(uint32_t status)
bool is_wps_enabled(void); bool is_wps_enabled(void);
int wps_init_cfg_pin(struct wps_config *cfg); int wps_init_cfg_pin(struct wps_config *cfg);
void wifi_station_wps_eapol_start_handle(void *data, void *user_ctx); void wifi_station_wps_eapol_start_handle(void *data, void *user_ctx);
int wifi_ap_wps_disable_internal(void);

View File

@ -691,8 +691,10 @@ int wnm_scan_process(struct wpa_supplicant *wpa_s, int reply_on_fail)
enum mbo_transition_reject_reason reason = enum mbo_transition_reject_reason reason =
MBO_TRANSITION_REJECT_REASON_UNSPECIFIED; MBO_TRANSITION_REJECT_REASON_UNSPECIFIED;
if (!wpa_s->wnm_neighbor_report_elements) if (!wpa_s->wnm_neighbor_report_elements) {
wpa_printf(MSG_INFO, "WNM: Neighbor report not available");
return 0; return 0;
}
wpa_dbg(wpa_s, MSG_DEBUG, wpa_dbg(wpa_s, MSG_DEBUG,
"WNM: Process scan results for BSS Transition Management"); "WNM: Process scan results for BSS Transition Management");
@ -706,7 +708,7 @@ int wnm_scan_process(struct wpa_supplicant *wpa_s, int reply_on_fail)
/* Compare the Neighbor Report and scan results */ /* Compare the Neighbor Report and scan results */
bss = compare_scan_neighbor_results(wpa_s, 0, &reason); bss = compare_scan_neighbor_results(wpa_s, 0, &reason);
if (!bss) { if (!bss) {
wpa_printf(MSG_DEBUG, "WNM: No BSS transition candidate match found"); wpa_printf(MSG_INFO, "WNM: No BSS transition candidate match found");
status = WNM_BSS_TM_REJECT_NO_SUITABLE_CANDIDATES; status = WNM_BSS_TM_REJECT_NO_SUITABLE_CANDIDATES;
goto send_bss_resp_fail; goto send_bss_resp_fail;
} }

View File

@ -84,7 +84,11 @@ struct wps_parse_attr {
u16 oob_dev_password_len; u16 oob_dev_password_len;
/* attributes that can occur multiple times */ /* attributes that can occur multiple times */
#ifdef ESP_SUPPLICANT
#define MAX_CRED_COUNT MAX_WPS_AP_CRED
#else
#define MAX_CRED_COUNT 10 #define MAX_CRED_COUNT 10
#endif
#define MAX_REQ_DEV_TYPE_COUNT 10 #define MAX_REQ_DEV_TYPE_COUNT 10
unsigned int num_cred; unsigned int num_cred;

View File

@ -5,7 +5,7 @@
(See the README.md file in the upper level 'examples' directory for more information about examples.) (See the README.md file in the upper level 'examples' directory for more information about examples.)
This example demonstrate a roaming example using 11k and 11v APIs. This example demonstrates a roaming example using 802.11k and 802.11v APIs. 802.11r(FT-PSK) is enabled by default in this example.
## How to use example ## How to use example