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

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

See merge request espressif/esp-idf!33714
This commit is contained in:
Jiang Jiang Jian
2024-10-08 16:03:50 +08:00
12 changed files with 241 additions and 97 deletions

View File

@@ -468,7 +468,12 @@ static const esp_err_msg_t esp_err_msg_table[] = {
ERR_TBL_IT(ESP_ERR_DPP_INVALID_ATTR), /* 12441 0x3099 Encountered invalid DPP Attribute */ ERR_TBL_IT(ESP_ERR_DPP_INVALID_ATTR), /* 12441 0x3099 Encountered invalid DPP Attribute */
# endif # endif
# ifdef ESP_ERR_DPP_AUTH_TIMEOUT # ifdef ESP_ERR_DPP_AUTH_TIMEOUT
ERR_TBL_IT(ESP_ERR_DPP_AUTH_TIMEOUT), /* 12442 0x309a DPP Auth response was not recieved in time */ ERR_TBL_IT(ESP_ERR_DPP_AUTH_TIMEOUT), /* 12442 0x309a DPP Auth response was not received in time */
# endif
# ifdef ESP_ERR_DPP_INVALID_LIST
ERR_TBL_IT(ESP_ERR_DPP_INVALID_LIST), /* 12443 0x309b Channel list given in
esp_supp_dpp_bootstrap_gen() is not
valid or too big */
# endif # endif
// components/esp_common/include/esp_err.h // components/esp_common/include/esp_err.h
# ifdef ESP_ERR_MESH_BASE # ifdef ESP_ERR_MESH_BASE
@@ -781,7 +786,7 @@ static const esp_err_msg_t esp_err_msg_table[] = {
ERR_TBL_IT(ESP_ERR_HTTPD_RESP_HDR), /* 45061 0xb005 Response header field larger than supported */ ERR_TBL_IT(ESP_ERR_HTTPD_RESP_HDR), /* 45061 0xb005 Response header field larger than supported */
# endif # endif
# ifdef ESP_ERR_HTTPD_RESP_SEND # ifdef ESP_ERR_HTTPD_RESP_SEND
ERR_TBL_IT(ESP_ERR_HTTPD_RESP_SEND), /* 45062 0xb006 Error occured while sending response packet */ ERR_TBL_IT(ESP_ERR_HTTPD_RESP_SEND), /* 45062 0xb006 Error occurred while sending response packet */
# endif # endif
# ifdef ESP_ERR_HTTPD_ALLOC_MEM # ifdef ESP_ERR_HTTPD_ALLOC_MEM
ERR_TBL_IT(ESP_ERR_HTTPD_ALLOC_MEM), /* 45063 0xb007 Failed to dynamically allocate memory ERR_TBL_IT(ESP_ERR_HTTPD_ALLOC_MEM), /* 45063 0xb007 Failed to dynamically allocate memory

View File

@@ -1,5 +1,5 @@
/* /*
* SPDX-FileCopyrightText: 2018-2021 Espressif Systems (Shanghai) CO LTD * SPDX-FileCopyrightText: 2018-2024 Espressif Systems (Shanghai) CO LTD
* *
* SPDX-License-Identifier: Apache-2.0 * SPDX-License-Identifier: Apache-2.0
*/ */
@@ -85,7 +85,7 @@ initializer that should be kept in sync
#define ESP_ERR_HTTPD_INVALID_REQ (ESP_ERR_HTTPD_BASE + 3) /*!< Invalid request pointer */ #define ESP_ERR_HTTPD_INVALID_REQ (ESP_ERR_HTTPD_BASE + 3) /*!< Invalid request pointer */
#define ESP_ERR_HTTPD_RESULT_TRUNC (ESP_ERR_HTTPD_BASE + 4) /*!< Result string truncated */ #define ESP_ERR_HTTPD_RESULT_TRUNC (ESP_ERR_HTTPD_BASE + 4) /*!< Result string truncated */
#define ESP_ERR_HTTPD_RESP_HDR (ESP_ERR_HTTPD_BASE + 5) /*!< Response header field larger than supported */ #define ESP_ERR_HTTPD_RESP_HDR (ESP_ERR_HTTPD_BASE + 5) /*!< Response header field larger than supported */
#define ESP_ERR_HTTPD_RESP_SEND (ESP_ERR_HTTPD_BASE + 6) /*!< Error occured while sending response packet */ #define ESP_ERR_HTTPD_RESP_SEND (ESP_ERR_HTTPD_BASE + 6) /*!< Error occurred while sending response packet */
#define ESP_ERR_HTTPD_ALLOC_MEM (ESP_ERR_HTTPD_BASE + 7) /*!< Failed to dynamically allocate memory for resource */ #define ESP_ERR_HTTPD_ALLOC_MEM (ESP_ERR_HTTPD_BASE + 7) /*!< Failed to dynamically allocate memory for resource */
#define ESP_ERR_HTTPD_TASK (ESP_ERR_HTTPD_BASE + 8) /*!< Failed to launch server task/thread */ #define ESP_ERR_HTTPD_TASK (ESP_ERR_HTTPD_BASE + 8) /*!< Failed to launch server task/thread */
@@ -1028,7 +1028,7 @@ esp_err_t httpd_query_key_value(const char *qry, const char *key, char *val, siz
* @param[in] cookie_name The cookie name to be searched in the request * @param[in] cookie_name The cookie name to be searched in the request
* @param[out] val Pointer to the buffer into which the value of cookie will be copied if the cookie is found * @param[out] val Pointer to the buffer into which the value of cookie will be copied if the cookie is found
* @param[inout] val_size Pointer to size of the user buffer "val". This variable will contain cookie length if * @param[inout] val_size Pointer to size of the user buffer "val". This variable will contain cookie length if
* ESP_OK is returned and required buffer length incase ESP_ERR_HTTPD_RESULT_TRUNC is returned. * ESP_OK is returned and required buffer length in case ESP_ERR_HTTPD_RESULT_TRUNC is returned.
* *
* @return * @return
* - ESP_OK : Key is found in the cookie string and copied to buffer * - ESP_OK : Key is found in the cookie string and copied to buffer
@@ -1048,9 +1048,9 @@ esp_err_t httpd_req_get_cookie_val(httpd_req_t *req, const char *cookie_name, ch
* *
* Example: * Example:
* - * matches everything * - * matches everything
* - /foo/? matches /foo and /foo/ * - /api/? matches /api and /api/
* - /foo/\* (sans the backslash) matches /foo/ and /foo/bar, but not /foo or /fo * - /api/\* (sans the backslash) matches /api/ and /api/status, but not /api or /ap
* - /foo/?* or /foo/\*? (sans the backslash) matches /foo/, /foo/bar, and also /foo, but not /foox or /fo * - /api/?* or /api/\*? (sans the backslash) matches /api/, /api/status, and also /api, but not /apix or /ap
* *
* The special characters "?" and "*" anywhere else in the template will be taken literally. * The special characters "?" and "*" anywhere else in the template will be taken literally.
* *
@@ -1400,7 +1400,7 @@ static inline esp_err_t httpd_resp_send_500(httpd_req_t *r) {
* Call this API if you wish to construct your custom response packet. * Call this API if you wish to construct your custom response packet.
* When using this, all essential header, eg. HTTP version, Status Code, * When using this, all essential header, eg. HTTP version, Status Code,
* Content Type and Length, Encoding, etc. will have to be constructed * Content Type and Length, Encoding, etc. will have to be constructed
* manually, and HTTP delimeters (CRLF) will need to be placed correctly * manually, and HTTP delimiters (CRLF) will need to be placed correctly
* for separating sub-sections of the HTTP response packet. * for separating sub-sections of the HTTP response packet.
* *
* If the send override function is set, this API will end up * If the send override function is set, this API will end up

View File

@@ -1,5 +1,5 @@
/* /*
* SPDX-FileCopyrightText: 2020-2023 Espressif Systems (Shanghai) CO LTD * SPDX-FileCopyrightText: 2020-2024 Espressif Systems (Shanghai) CO LTD
* *
* SPDX-License-Identifier: Apache-2.0 * SPDX-License-Identifier: Apache-2.0
*/ */
@@ -17,11 +17,14 @@ extern "C" {
#endif #endif
#define ESP_DPP_AUTH_TIMEOUT_SECS 1 #define ESP_DPP_AUTH_TIMEOUT_SECS 1
#define ESP_DPP_MAX_CHAN_COUNT 5
#define ESP_ERR_DPP_FAILURE (ESP_ERR_WIFI_BASE + 151) /*!< Generic failure during DPP Operation */ #define ESP_ERR_DPP_FAILURE (ESP_ERR_WIFI_BASE + 151) /*!< Generic failure during DPP Operation */
#define ESP_ERR_DPP_TX_FAILURE (ESP_ERR_WIFI_BASE + 152) /*!< DPP Frame Tx failed OR not Acked */ #define ESP_ERR_DPP_TX_FAILURE (ESP_ERR_WIFI_BASE + 152) /*!< DPP Frame Tx failed OR not Acked */
#define ESP_ERR_DPP_INVALID_ATTR (ESP_ERR_WIFI_BASE + 153) /*!< Encountered invalid DPP Attribute */ #define ESP_ERR_DPP_INVALID_ATTR (ESP_ERR_WIFI_BASE + 153) /*!< Encountered invalid DPP Attribute */
#define ESP_ERR_DPP_AUTH_TIMEOUT (ESP_ERR_WIFI_BASE + 154) /*!< DPP Auth response was not recieved in time */ #define ESP_ERR_DPP_AUTH_TIMEOUT (ESP_ERR_WIFI_BASE + 154) /*!< DPP Auth response was not received in time */
#define ESP_ERR_DPP_INVALID_LIST (ESP_ERR_WIFI_BASE + 155) /*!< Channel list given in esp_supp_dpp_bootstrap_gen() is not valid or too big */
/** @brief Types of Bootstrap Methods for DPP. */ /** @brief Types of Bootstrap Methods for DPP. */
typedef enum dpp_bootstrap_type { typedef enum dpp_bootstrap_type {
DPP_BOOTSTRAP_QR_CODE, /**< QR Code Method */ DPP_BOOTSTRAP_QR_CODE, /**< QR Code Method */
@@ -83,6 +86,7 @@ esp_err_t esp_supp_dpp_deinit(void);
* *
* @return * @return
* - ESP_OK: Success * - ESP_OK: Success
* - ESP_ERR_DPP_INVALID_LIST: Channel list not valid
* - ESP_FAIL: Failure * - ESP_FAIL: Failure
*/ */
esp_err_t esp_err_t

View File

@@ -15,6 +15,7 @@
#include "esp_event.h" #include "esp_event.h"
#include "esp_wifi.h" #include "esp_wifi.h"
#include "common/ieee802_11_defs.h" #include "common/ieee802_11_defs.h"
#include "common/ieee802_11_common.h"
#include "esp_wps_i.h" #include "esp_wps_i.h"
#include "rsn_supp/wpa.h" #include "rsn_supp/wpa.h"
#include "rsn_supp/pmksa_cache.h" #include "rsn_supp/pmksa_cache.h"
@@ -574,6 +575,7 @@ static void esp_dpp_task(void *pvParameters)
break; break;
} }
channel = p->chan_list[counter++ % p->num_chan]; channel = p->chan_list[counter++ % p->num_chan];
wpa_printf(MSG_DEBUG, "Listening on channel=%d", channel);
ret = esp_wifi_remain_on_channel(WIFI_IF_STA, WIFI_ROC_REQ, channel, ret = esp_wifi_remain_on_channel(WIFI_IF_STA, WIFI_ROC_REQ, channel,
BOOTSTRAP_ROC_WAIT_TIME, s_action_rx_cb); BOOTSTRAP_ROC_WAIT_TIME, s_action_rx_cb);
if (ret != ESP_OK) { if (ret != ESP_OK) {
@@ -683,50 +685,91 @@ static void offchan_event_handler(void *arg, esp_event_base_t event_base,
} }
} }
#ifndef CHANNEL_TO_BIT_NUMBER
#define CHANNEL_TO_BIT_NUMBER(channel) ((channel >= 1 && channel <= 14) ? (channel) : \
((channel >= 36 && channel <= 64 && (channel - 36) % 4 == 0) ? ((channel - 36) / 4 + 1) : \
((channel >= 100 && channel <= 144 && (channel - 100) % 4 == 0) ? ((channel - 100) / 4 + 9) : \
((channel >= 149 && channel <= 177 && (channel - 149) % 4 == 0) ? ((channel - 149) / 4 + 21) : 0))))
#endif
static char *esp_dpp_parse_chan_list(const char *chan_list) static char *esp_dpp_parse_chan_list(const char *chan_list)
{ {
struct dpp_bootstrap_params_t *params = &s_dpp_ctx.bootstrap_params; struct dpp_bootstrap_params_t *params = &s_dpp_ctx.bootstrap_params;
char *uri_channels = os_zalloc(14 * 6 + 1); size_t max_uri_len = ESP_DPP_MAX_CHAN_COUNT * 8 + strlen(" chan=") + 1;
const char *pos = chan_list;
const char *pos2; char *uri_channels = os_zalloc(max_uri_len);
char *pos3 = uri_channels; if (!uri_channels) {
wpa_printf(MSG_WARNING, "DPP: URI allocation failed");
return NULL;
}
char *uri_ptr = uri_channels;
params->num_chan = 0; params->num_chan = 0;
os_memcpy(pos3, " chan=", strlen(" chan=")); /* Append " chan=" at the beginning of the URI */
pos3 += strlen(" chan="); strcpy(uri_ptr, " chan=");
uri_ptr += strlen(" chan=");
while (pos && *pos) { while (*chan_list && params->num_chan < ESP_DPP_MAX_CHAN_COUNT) {
int channel; int channel = 0;
int len = strlen(chan_list);
pos2 = pos; /* Parse the channel number */
while (*pos2 >= '0' && *pos2 <= '9') { while (*chan_list >= '0' && *chan_list <= '9') {
pos2++; channel = channel * 10 + (*chan_list - '0');
chan_list++;
} }
if (*pos2 == ',' || *pos2 == ' ' || *pos2 == '\0') {
channel = atoi(pos); /* Validate the channel number */
if (channel < 1 || channel > 14) { if (CHANNEL_TO_BIT_NUMBER(channel) == 0) {
wpa_printf(MSG_WARNING, "DPP: Skipping invalid channel %d", channel);
/* Skip to the next valid entry */
while (*chan_list == ',' || *chan_list == ' ') {
chan_list++;
}
continue; // Skip the bad channel and move to the next one
}
/* Get the operating class for the channel */
u8 oper_class = get_operating_class(channel, 0);
if (oper_class == 0) {
wpa_printf(MSG_WARNING, "DPP: Skipping channel %d due to missing operating class", channel);
/* Skip to the next valid entry */
while (*chan_list == ',' || *chan_list == ' ') {
chan_list++;
}
continue; /* Skip to the next channel if no operating class found */
}
/* Add the valid channel to the list */
params->chan_list[params->num_chan++] = channel;
/* Check if there's space left in uri_channels buffer */
size_t remaining_space = max_uri_len - (uri_ptr - uri_channels);
if (remaining_space <= 8) { // Oper class + "/" + channel + "," + null terminator
wpa_printf(MSG_ERROR, "DPP: Not enough space in URI buffer");
os_free(uri_channels); os_free(uri_channels);
return NULL; return NULL;
} }
params->chan_list[params->num_chan++] = channel;
os_memcpy(pos3, "81/", strlen("81/"));
pos3 += strlen("81/");
os_memcpy(pos3, pos, (pos2 - pos));
pos3 += (pos2 - pos);
*pos3++ = ',';
pos = pos2 + 1; /* Append the operating class and channel to the URI */
uri_ptr += sprintf(uri_ptr, "%d/%d,", oper_class, channel);
/* Skip any delimiters (comma or space) */
while (*chan_list == ',' || *chan_list == ' ') {
chan_list++;
} }
while (*pos == ',' || *pos == ' ' || *pos == '\0') {
pos++;
} }
if (((int)(pos - chan_list) >= len)) { if (!params->num_chan) {
break; wpa_printf(MSG_ERROR, "DPP: No valid channel in the list");
os_free(uri_channels);
return NULL;
} }
/* Replace the last comma with a space if there was content added */
if (uri_ptr > uri_channels && *(uri_ptr - 1) == ',') {
*(uri_ptr - 1) = ' ';
} }
*(pos3 - 1) = ' ';
return uri_channels; return uri_channels;
} }
@@ -741,10 +784,16 @@ esp_supp_dpp_bootstrap_gen(const char *chan_list, enum dpp_bootstrap_type type,
} }
struct dpp_bootstrap_params_t *params = &s_dpp_ctx.bootstrap_params; struct dpp_bootstrap_params_t *params = &s_dpp_ctx.bootstrap_params;
char *uri_chan_list = esp_dpp_parse_chan_list(chan_list); char *uri_chan_list = esp_dpp_parse_chan_list(chan_list);
if (params->num_chan > ESP_DPP_MAX_CHAN_COUNT) {
os_free(uri_chan_list);
return ESP_ERR_DPP_INVALID_LIST;
}
char *command = os_zalloc(1200); char *command = os_zalloc(1200);
int ret; int ret;
if (!uri_chan_list || !command || params->num_chan >= 14 || params->num_chan == 0) { if (!uri_chan_list || !command || params->num_chan > ESP_DPP_MAX_CHAN_COUNT || params->num_chan == 0) {
wpa_printf(MSG_ERROR, "Invalid Channel list - %s", chan_list); wpa_printf(MSG_ERROR, "Invalid Channel list - %s", chan_list);
if (command) { if (command) {
os_free(command); os_free(command);

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
@@ -236,6 +237,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

@@ -367,16 +367,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;
} }
@@ -384,6 +387,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;
@@ -353,11 +354,32 @@ static bool ap_supports_sae(struct wps_scan_ie *scan)
return false; return false;
} }
static bool
is_wps_pbc_overlap(struct wps_sm *sm, const u8 *sel_uuid)
{
if (!sel_uuid) {
wpa_printf(MSG_DEBUG, "WPS: null uuid field");
return false;
}
if (os_memcmp(sel_uuid, sm->uuid, WPS_UUID_LEN) != 0) {
wpa_printf(MSG_DEBUG, "uuid is not same");
wpa_hexdump(MSG_DEBUG, "WPS: UUID of scanned BSS is",
sel_uuid, WPS_UUID_LEN);
wpa_hexdump(MSG_DEBUG, "WPS: UUID of sm BSS is",
sm->uuid, WPS_UUID_LEN);
return true;
}
return false;
}
static bool static bool
wps_parse_scan_result(struct wps_scan_ie *scan) wps_parse_scan_result(struct wps_scan_ie *scan)
{ {
struct wps_sm *sm = gWpsSm; struct wps_sm *sm = gWpsSm;
wifi_mode_t op_mode = 0; wifi_mode_t op_mode = 0;
sm->wps_pbc_overlap = false;
if (!sm->is_wps_scan || !scan->bssid) { if (!sm->is_wps_scan || !scan->bssid) {
return false; return false;
@@ -393,6 +415,7 @@ wps_parse_scan_result(struct wps_scan_ie *scan)
bool ap_found = false; bool ap_found = false;
struct wpabuf *buf = wpabuf_alloc_copy(scan->wps + 6, scan->wps[1] - 4); struct wpabuf *buf = wpabuf_alloc_copy(scan->wps + 6, scan->wps[1] - 4);
int count; int count;
const u8 *scan_uuid;
if ((wps_get_type() == WPS_TYPE_PBC && wps_is_selected_pbc_registrar(buf)) || if ((wps_get_type() == WPS_TYPE_PBC && wps_is_selected_pbc_registrar(buf)) ||
(wps_get_type() == WPS_TYPE_PIN && wps_is_addr_authorized(buf, sm->ownaddr, 1))) { (wps_get_type() == WPS_TYPE_PIN && wps_is_addr_authorized(buf, sm->ownaddr, 1))) {
@@ -413,19 +436,30 @@ wps_parse_scan_result(struct wps_scan_ie *scan)
} }
if (ap_found || sm->ignore_sel_reg) { if (ap_found || sm->ignore_sel_reg) {
wpabuf_free(buf);
if (scan->ssid[1] > SSID_MAX_LEN) { if (scan->ssid[1] > SSID_MAX_LEN) {
wpabuf_free(buf);
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));
sm->discover_ssid_cnt++; sm->discover_ssid_cnt++;
wpa_printf(MSG_INFO, "discoverd cnt is %d and chan is %d ", sm->discover_ssid_cnt, scan->chan);
os_memcpy(sm->bssid, scan->bssid, ETH_ALEN); os_memcpy(sm->bssid, scan->bssid, ETH_ALEN);
scan_uuid = wps_get_uuid_e(buf);
if (scan_uuid) {
if (wps_get_type() == WPS_TYPE_PBC && is_wps_pbc_overlap(sm, scan_uuid) == true) {
wpa_printf(MSG_INFO, "pbc_overlap flag is true");
sm->wps_pbc_overlap = true;
}
os_memcpy(sm->uuid, scan_uuid, WPS_UUID_LEN);
}
if (ap_supports_sae(scan)) { if (ap_supports_sae(scan)) {
wpa_printf(MSG_INFO, "AP supports SAE, get password in passphrase"); wpa_printf(MSG_INFO, "AP supports SAE, get password in passphrase");
sm->dev->config_methods |= WPS_CONFIG_DISPLAY | WPS_CONFIG_VIRT_DISPLAY; sm->dev->config_methods |= WPS_CONFIG_DISPLAY | WPS_CONFIG_VIRT_DISPLAY;
@@ -434,7 +468,8 @@ 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); wpabuf_free(buf);
wpa_printf(MSG_DEBUG, "wps discover [%s] ", (char *)sm->creds[0].ssid);
sm->channel = scan->chan; sm->channel = scan->chan;
return true; return true;
@@ -589,14 +624,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));
@@ -759,8 +794,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;
@@ -801,7 +835,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));
@@ -811,12 +846,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);
} }
@@ -829,8 +873,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);
@@ -1053,6 +1096,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;
} }
@@ -1279,8 +1324,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);
@@ -1310,8 +1354,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);
@@ -1349,17 +1393,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++;
@@ -1594,7 +1634,8 @@ wifi_wps_scan_done(void *arg, ETS_STATUS status)
} else if (sm->discover_ssid_cnt == 0) { } else if (sm->discover_ssid_cnt == 0) {
wps_set_status(WPS_STATUS_SCANNING); wps_set_status(WPS_STATUS_SCANNING);
} else { } else {
if (wps_get_type() == WPS_TYPE_PBC) { if (sm->wps_pbc_overlap) {
sm->wps_pbc_overlap = false;
wpa_printf(MSG_INFO, "PBC session overlap!"); wpa_printf(MSG_INFO, "PBC session overlap!");
wps_set_status(WPS_STATUS_DISABLE); wps_set_status(WPS_STATUS_DISABLE);
esp_event_post(WIFI_EVENT, WIFI_EVENT_STA_WPS_ER_PBC_OVERLAP, 0, 0, OS_BLOCK); esp_event_post(WIFI_EVENT, WIFI_EVENT_STA_WPS_ER_PBC_OVERLAP, 0, 0, OS_BLOCK);
@@ -1611,14 +1652,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];
@@ -91,6 +81,7 @@ struct wps_sm {
#endif #endif
u8 discover_ssid_cnt; u8 discover_ssid_cnt;
bool ignore_sel_reg; bool ignore_sel_reg;
bool wps_pbc_overlap;
struct discard_ap_list_t dis_ap_list[WPS_MAX_DIS_AP_NUM]; struct discard_ap_list_t dis_ap_list[WPS_MAX_DIS_AP_NUM];
u8 discard_ap_cnt; u8 discard_ap_cnt;
}; };
@@ -147,3 +138,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

@@ -353,16 +353,54 @@ int ieee802_11_ext_capab(const u8 *ie, unsigned int capab)
u8 get_operating_class(u8 chan, int sec_channel) u8 get_operating_class(u8 chan, int sec_channel)
{ {
u8 op_class; u8 op_class = 0;
if (chan < 1 || chan > 14) if (chan >= 1 && chan < 14) {
return 0;
if (sec_channel == 1) if (sec_channel == 1)
op_class = 83; op_class = 83;
else if (sec_channel == -1) else if (sec_channel == -1)
op_class = 84; op_class = 84;
else else
op_class = 81; op_class = 81;
}
if (chan == 14)
op_class = 82;
#if SOC_WIFI_SUPPORT_5G
if (chan >= 36 && chan <= 48) {
if (sec_channel == 1)
op_class = 116;
else if (sec_channel == -1)
op_class = 117;
else
op_class = 115;
}
if (chan >= 52 && chan <= 64) {
if (sec_channel == 1)
op_class = 119;
else if (sec_channel == -1)
op_class = 120;
else
op_class = 118;
}
if (chan >= 149 && chan <= 177) {
if (sec_channel == 1)
op_class = 126;
else if (sec_channel == -1)
op_class = 127;
else
op_class = 125;
}
if (chan >= 100 && chan <= 144) {
if (sec_channel == 1)
op_class = 122;
else if (sec_channel == -1)
op_class = 123;
else
op_class = 121;
}
#endif
return op_class; return op_class;
} }

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