diff --git a/components/esp_wifi/include/esp_wifi_types.h b/components/esp_wifi/include/esp_wifi_types.h index 3db75e9ca3..3bd7c51630 100644 --- a/components/esp_wifi/include/esp_wifi_types.h +++ b/components/esp_wifi/include/esp_wifi_types.h @@ -79,10 +79,13 @@ typedef enum { WIFI_REASON_UNSPECIFIED = 1, WIFI_REASON_AUTH_EXPIRE = 2, WIFI_REASON_AUTH_LEAVE = 3, - WIFI_REASON_ASSOC_EXPIRE = 4, + WIFI_REASON_ASSOC_EXPIRE = 4, /* Deprecated, will be removed in next IDF major release */ + WIFI_REASON_DISASSOC_DUE_TO_INACTIVITY = 4, WIFI_REASON_ASSOC_TOOMANY = 5, - WIFI_REASON_NOT_AUTHED = 6, - WIFI_REASON_NOT_ASSOCED = 7, + WIFI_REASON_NOT_AUTHED = 6, /* Deprecated, will be removed in next IDF major release */ + WIFI_REASON_CLASS2_FRAME_FROM_NONAUTH_STA = 6, + WIFI_REASON_NOT_ASSOCED = 7, /* Deprecated, will be removed in next IDF major release */ + WIFI_REASON_CLASS3_FRAME_FROM_NONASSOC_STA = 7, WIFI_REASON_ASSOC_LEAVE = 8, WIFI_REASON_ASSOC_NOT_AUTHED = 9, WIFI_REASON_DISASSOC_PWRCAP_BAD = 10, diff --git a/components/esp_wifi/lib b/components/esp_wifi/lib index c3542aed20..12538105bc 160000 --- a/components/esp_wifi/lib +++ b/components/esp_wifi/lib @@ -1 +1 @@ -Subproject commit c3542aed20c060e52be9f7663f6acf8880b149a3 +Subproject commit 12538105bcb0a52fc1d2b8724ed82c8510588af0 diff --git a/components/wpa_supplicant/esp_supplicant/src/esp_hostap.c b/components/wpa_supplicant/esp_supplicant/src/esp_hostap.c index faf643b75c..82ff55ee40 100644 --- a/components/wpa_supplicant/esp_supplicant/src/esp_hostap.c +++ b/components/wpa_supplicant/esp_supplicant/src/esp_hostap.c @@ -7,6 +7,7 @@ #include "utils/includes.h" #include "utils/common.h" +#include "utils/eloop.h" #include "crypto/sha1.h" #include "common/ieee802_11_defs.h" #include "common/eapol_common.h" @@ -21,6 +22,9 @@ #include "esp_wps.h" #include "esp_wps_i.h" +#include "ap/sta_info.h" +#include "common/sae.h" +#include "ap/ieee802_11.h" #define WIFI_PASSWORD_LEN_MAX 65 struct hostapd_data *global_hapd; @@ -322,3 +326,143 @@ done: os_free(reply); return res; } + +uint8_t wpa_status_to_reason_code(int status) +{ + switch (status) { + case WLAN_STATUS_INVALID_IE: + return WLAN_REASON_INVALID_IE; + case WLAN_STATUS_GROUP_CIPHER_NOT_VALID: + return WLAN_REASON_GROUP_CIPHER_NOT_VALID; + case WLAN_STATUS_PAIRWISE_CIPHER_NOT_VALID: + return WLAN_REASON_PAIRWISE_CIPHER_NOT_VALID; + case WLAN_STATUS_AKMP_NOT_VALID: + return WLAN_REASON_AKMP_NOT_VALID; + case WLAN_STATUS_CIPHER_REJECTED_PER_POLICY: + return WLAN_REASON_CIPHER_SUITE_REJECTED; + case WLAN_STATUS_INVALID_PMKID: + return WLAN_REASON_INVALID_PMKID; + case WLAN_STATUS_INVALID_MDIE: + return WLAN_REASON_INVALID_MDE; + default: + return WLAN_REASON_UNSPECIFIED; + } +} + +bool hostap_new_assoc_sta(struct sta_info *sta, uint8_t *bssid, uint8_t *wpa_ie, + uint8_t wpa_ie_len, uint8_t *rsnxe, uint8_t rsnxe_len, + bool *pmf_enable, int subtype, uint8_t *pairwise_cipher, uint8_t *reason) +{ + struct hostapd_data *hapd = (struct hostapd_data*)esp_wifi_get_hostap_private_internal(); + enum wpa_validate_result res = WPA_IE_OK; + int status = WLAN_STATUS_SUCCESS; + bool omit_rsnxe = false; + + if (!sta || !bssid || !wpa_ie) { + return false; + } + + if (hapd) { + if (hapd->wpa_auth->conf.wpa) { + if (sta->wpa_sm) { + wpa_auth_sta_deinit(sta->wpa_sm); + } + + sta->wpa_sm = wpa_auth_sta_init(hapd->wpa_auth, bssid); + wpa_printf(MSG_DEBUG, "init wpa sm=%p", sta->wpa_sm); + + if (sta->wpa_sm == NULL) { + status = WLAN_STATUS_AP_UNABLE_TO_HANDLE_NEW_STA; + goto send_resp; + } + + res = wpa_validate_wpa_ie(hapd->wpa_auth, sta->wpa_sm, wpa_ie, wpa_ie_len, rsnxe, rsnxe_len); + +#ifdef CONFIG_SAE + if (wpa_auth_uses_sae(sta->wpa_sm) && sta->sae && + sta->sae->state == SAE_ACCEPTED) { + wpa_auth_add_sae_pmkid(sta->wpa_sm, sta->sae->pmkid); + } +#endif /* CONFIG_SAE */ + + status = wpa_res_to_status_code(res); + +send_resp: + if (!rsnxe) { + omit_rsnxe = true; + } + + if (esp_send_assoc_resp(hapd, bssid, status, omit_rsnxe, subtype) != WLAN_STATUS_SUCCESS) { + status = WLAN_STATUS_AP_UNABLE_TO_HANDLE_NEW_STA; + } + + if (status != WLAN_STATUS_SUCCESS) { + *reason = wpa_status_to_reason_code(status); + return false; + } + + //Check whether AP uses Management Frame Protection for this connection + *pmf_enable = wpa_auth_uses_mfp(sta->wpa_sm); + *pairwise_cipher = GET_BIT_POSITION(sta->wpa_sm->pairwise); + } + + wpa_auth_sta_associated(hapd->wpa_auth, sta->wpa_sm); + } + + return true; +} + +#ifdef CONFIG_WPS_REGISTRAR +static void ap_free_sta_timeout(void *ctx, void *data) +{ + struct hostapd_data *hapd = (struct hostapd_data *) ctx; + u8 *addr = (u8 *) data; + struct sta_info *sta = ap_get_sta(hapd, addr); + + if (sta) { + ap_free_sta(hapd, sta); + } + + os_free(addr); +} +#endif + +bool wpa_ap_remove(u8* bssid) +{ + struct hostapd_data *hapd = hostapd_get_hapd_data(); + + if (!hapd) { + return false; + } + struct sta_info *sta = ap_get_sta(hapd, bssid); + if (!sta) { + return false; + } + +#ifdef CONFIG_SAE + if (sta->lock) { + if (os_semphr_take(sta->lock, 0)) { + ap_free_sta(hapd, sta); + } else { + sta->remove_pending = true; + } + return true; + } +#endif /* CONFIG_SAE */ + +#ifdef CONFIG_WPS_REGISTRAR + wpa_printf(MSG_DEBUG, "wps_status=%d", wps_get_status()); + if (wps_get_status() == WPS_STATUS_PENDING) { + u8 *addr = os_malloc(ETH_ALEN); + + if (!addr) { + return false; + } + os_memcpy(addr, sta->addr, ETH_ALEN); + eloop_register_timeout(0, 10000, ap_free_sta_timeout, hapd, addr); + } else +#endif + ap_free_sta(hapd, sta); + + return true; +} diff --git a/components/wpa_supplicant/esp_supplicant/src/esp_wpa_main.c b/components/wpa_supplicant/esp_supplicant/src/esp_wpa_main.c index ae59766941..be88ac5b16 100644 --- a/components/wpa_supplicant/esp_supplicant/src/esp_wpa_main.c +++ b/components/wpa_supplicant/esp_supplicant/src/esp_wpa_main.c @@ -251,8 +251,8 @@ static void wpa_sta_disconnected_cb(uint8_t reason_code) { switch (reason_code) { case WIFI_REASON_AUTH_EXPIRE: - case WIFI_REASON_NOT_AUTHED: - case WIFI_REASON_NOT_ASSOCED: + case WIFI_REASON_CLASS2_FRAME_FROM_NONAUTH_STA: + case WIFI_REASON_CLASS3_FRAME_FROM_NONASSOC_STA: case WIFI_REASON_4WAY_HANDSHAKE_TIMEOUT: case WIFI_REASON_INVALID_PMKID: case WIFI_REASON_AUTH_FAIL: @@ -321,6 +321,7 @@ static bool hostap_sta_join(void **sta, u8 *bssid, u8 *wpa_ie, u8 wpa_ie_len, u8 { struct sta_info *sta_info = NULL; struct hostapd_data *hapd = hostapd_get_hapd_data(); + uint8_t reason = WLAN_REASON_PREV_AUTH_NOT_VALID; if (!hapd) { goto fail; @@ -379,7 +380,7 @@ process_old_sta: goto fail; } #endif - if (wpa_ap_join(sta_info, bssid, wpa_ie, wpa_ie_len, rsnxe, rsnxe_len, pmf_enable, subtype, pairwise_cipher)) { + if (hostap_new_assoc_sta(sta_info, bssid, wpa_ie, wpa_ie_len, rsnxe, rsnxe_len, pmf_enable, subtype, pairwise_cipher, &reason)) { goto done; } else { goto fail; @@ -400,7 +401,7 @@ fail: os_semphr_give(sta_info->lock); } #endif /* CONFIG_SAE */ - esp_wifi_ap_deauth_internal(bssid, WLAN_REASON_PREV_AUTH_NOT_VALID); + esp_wifi_ap_deauth_internal(bssid, reason); return false; } #endif diff --git a/components/wpa_supplicant/esp_supplicant/src/esp_wps.c b/components/wpa_supplicant/esp_supplicant/src/esp_wps.c index fa9d4abf52..33ffe416da 100644 --- a/components/wpa_supplicant/esp_supplicant/src/esp_wps.c +++ b/components/wpa_supplicant/esp_supplicant/src/esp_wps.c @@ -901,7 +901,7 @@ int wps_start_msg_timer(void) ret = 0; } else if (sm->wps->state == RECV_M2) { msg_timeout = 5; - wpa_printf(MSG_DEBUG, "start msg timer RECV_M2 %" PRId32 " ms", msg_timeout); + wpa_printf(MSG_DEBUG, "start msg timer RECV_M2 %" PRId32 " s", msg_timeout); eloop_cancel_timeout(wifi_station_wps_msg_timeout, NULL, NULL); eloop_register_timeout(msg_timeout, 0, wifi_station_wps_msg_timeout, NULL, NULL); ret = 0; diff --git a/components/wpa_supplicant/src/ap/ap_config.h b/components/wpa_supplicant/src/ap/ap_config.h index 486d802a11..1d11dd4816 100644 --- a/components/wpa_supplicant/src/ap/ap_config.h +++ b/components/wpa_supplicant/src/ap/ap_config.h @@ -382,9 +382,9 @@ const u8 * hostapd_get_psk(const struct hostapd_bss_config *conf, const u8 *addr, const u8 *prev_psk); int hostapd_setup_wpa_psk(struct hostapd_bss_config *conf); struct sta_info; -bool wpa_ap_join(struct sta_info *sta, uint8_t *bssid, uint8_t *wpa_ie, +bool hostap_new_assoc_sta(struct sta_info *sta, uint8_t *bssid, uint8_t *wpa_ie, uint8_t wpa_ie_len,uint8_t *rsnxe, uint8_t rsnxe_len, - bool *pmf_enable, int subtype, uint8_t *pairwise_cipher); + bool *pmf_enable, int subtype, uint8_t *pairwise_cipher, uint8_t *reason); bool wpa_ap_remove(u8* bssid); #endif /* HOSTAPD_CONFIG_H */ diff --git a/components/wpa_supplicant/src/ap/wpa_auth.c b/components/wpa_supplicant/src/ap/wpa_auth.c index 513ec9fa82..58748a85ff 100644 --- a/components/wpa_supplicant/src/ap/wpa_auth.c +++ b/components/wpa_supplicant/src/ap/wpa_auth.c @@ -13,7 +13,6 @@ #include "common/ieee802_11_defs.h" #include "common/sae.h" #include "ap/sta_info.h" -#include "ap/ieee802_11.h" #include "ap/wpa_auth.h" #include "ap/wpa_auth_i.h" #include "ap/wpa_auth_ie.h" @@ -36,7 +35,6 @@ #include "esp_wifi.h" #include "esp_private/wifi.h" #include "esp_wpas_glue.h" -#include "esp_wps_i.h" #include "esp_hostap.h" #define STATE_MACHINE_DATA struct wpa_state_machine @@ -2557,97 +2555,6 @@ void wpa_deinit(struct wpa_authenticator *wpa_auth) } -#ifdef CONFIG_ESP_WIFI_SOFTAP_SUPPORT -bool wpa_ap_join(struct sta_info *sta, uint8_t *bssid, uint8_t *wpa_ie, - uint8_t wpa_ie_len, uint8_t *rsnxe, uint8_t rsnxe_len, - bool *pmf_enable, int subtype, uint8_t *pairwise_cipher) -{ - struct hostapd_data *hapd = (struct hostapd_data*)esp_wifi_get_hostap_private_internal(); - enum wpa_validate_result status_code = WPA_IE_OK; - int resp = WLAN_STATUS_SUCCESS; - bool omit_rsnxe = false; - - if (!sta || !bssid || !wpa_ie) { - return false; - } - - if (hapd) { - if (hapd->wpa_auth->conf.wpa) { - if (sta->wpa_sm){ - wpa_auth_sta_deinit(sta->wpa_sm); - } - - sta->wpa_sm = wpa_auth_sta_init(hapd->wpa_auth, bssid); - wpa_printf( MSG_DEBUG, "init wpa sm=%p", sta->wpa_sm); - - if (sta->wpa_sm == NULL) { - resp = WLAN_STATUS_AP_UNABLE_TO_HANDLE_NEW_STA; - goto send_resp; - } - - status_code = wpa_validate_wpa_ie(hapd->wpa_auth, sta->wpa_sm, wpa_ie, wpa_ie_len, rsnxe, rsnxe_len); - -#ifdef CONFIG_SAE - if (wpa_auth_uses_sae(sta->wpa_sm) && sta->sae && - sta->sae->state == SAE_ACCEPTED) { - wpa_auth_add_sae_pmkid(sta->wpa_sm, sta->sae->pmkid); - } -#endif /* CONFIG_SAE */ - - resp = wpa_res_to_status_code(status_code); - -send_resp: - if (!rsnxe) { - omit_rsnxe = true; - } - - if (esp_send_assoc_resp(hapd, bssid, resp, omit_rsnxe, subtype) != WLAN_STATUS_SUCCESS) { - resp = WLAN_STATUS_AP_UNABLE_TO_HANDLE_NEW_STA; - } - - if (resp != WLAN_STATUS_SUCCESS) { - return false; - } - - //Check whether AP uses Management Frame Protection for this connection - *pmf_enable = wpa_auth_uses_mfp(sta->wpa_sm); - *pairwise_cipher = GET_BIT_POSITION(sta->wpa_sm->pairwise); - } - - wpa_auth_sta_associated(hapd->wpa_auth, sta->wpa_sm); - } - - return true; -} - -bool wpa_ap_remove(u8* bssid) -{ - struct hostapd_data *hapd = hostapd_get_hapd_data(); - - if (!hapd) { - return false; - } - struct sta_info *sta = ap_get_sta(hapd, bssid); - if (!sta) { - return false; - } - -#ifdef CONFIG_SAE - if (sta->lock) { - if (os_semphr_take(sta->lock, 0)) { - ap_free_sta(hapd, sta); - } else { - sta->remove_pending = true; - } - return true; - } -#endif /* CONFIG_SAE */ - ap_free_sta(hapd, sta); - - return true; -} -#endif /* CONFIG_ESP_WIFI_SOFTAP_SUPPORT */ - void wpa_auth_pmksa_remove(struct wpa_authenticator *wpa_auth, const u8 *sta_addr) { diff --git a/components/wpa_supplicant/src/common/ieee802_11_defs.h b/components/wpa_supplicant/src/common/ieee802_11_defs.h index b496690ab7..958bf5feeb 100644 --- a/components/wpa_supplicant/src/common/ieee802_11_defs.h +++ b/components/wpa_supplicant/src/common/ieee802_11_defs.h @@ -186,6 +186,8 @@ #define WLAN_REASON_INVALID_RSN_IE_CAPAB 22 #define WLAN_REASON_IEEE_802_1X_AUTH_FAILED 23 #define WLAN_REASON_CIPHER_SUITE_REJECTED 24 +#define WLAN_REASON_INVALID_PMKID 49 +#define WLAN_REASON_INVALID_MDE 50 /* Information Element IDs (IEEE Std 802.11-2016, 9.4.2.1, Table 9-77) */ #define WLAN_EID_SSID 0 diff --git a/docs/en/api-guides/wifi.rst b/docs/en/api-guides/wifi.rst index 4ec26bdc68..e9d852e85a 100644 --- a/docs/en/api-guides/wifi.rst +++ b/docs/en/api-guides/wifi.rst @@ -811,7 +811,7 @@ Association Phase +++++++++++++++++++++ - s3.1: The association request is sent and the association timer is enabled. - - s3.2: If the association response is not received before the association timer times out, `WIFI_EVENT_STA_DISCONNECTED`_ will arise and the reason code will be ``WIFI_REASON_ASSOC_EXPIRE``. Refer to `Wi-Fi Reason Code`_. + - s3.2: If the association response is not received before the association timer times out, `WIFI_EVENT_STA_DISCONNECTED`_ will arise and the reason code will be ``WIFI_REASON_DISASSOC_DUE_TO_INACTIVITY``. Refer to `Wi-Fi Reason Code`_. - s3.3: The association response is received and the association timer is stopped. - s3.4: The AP rejects the association in the response and `WIFI_EVENT_STA_DISCONNECTED`_ arises, while the reason code is the one specified in the association response. Refer to `Wi-Fi Reason Code`_. @@ -875,19 +875,15 @@ Following reason codes are renamed to their shorter form to wrap the table in pa For the ESP station, this reason is reported when: - it is received from the AP. - * - ASSOC_EXPIRE + * - DISASSOC_DUE_TO_INACTIVITY - 4 - Disassociated due to inactivity. For the ESP station, this reason is reported when: + - assoc is timed out. - it is received from the AP. - For the ESP AP, this reason is reported when: - - - the AP has not received any packets from the station in the past five minutes. - - the AP is stopped by calling :cpp:func:`esp_wifi_stop()`. - - the station is de-authed by calling :cpp:func:`esp_wifi_deauth_sta()`. * - ASSOC_TOOMANY - 5 - Disassociated, because the AP is unable to handle all currently associated STAs at the same time. @@ -899,7 +895,7 @@ Following reason codes are renamed to their shorter form to wrap the table in pa For the ESP AP, this reason is reported when: - the stations associated with the AP reach the maximum number that the AP can support. - * - NOT_AUTHED + * - CLASS2_FRAME_FROM_NONAUTH_STA - 6 - Class-2 frame received from a non-authenticated STA. @@ -910,7 +906,7 @@ Following reason codes are renamed to their shorter form to wrap the table in pa For the ESP AP, this reason is reported when: - the AP receives a packet with data from a non-authenticated station. - * - NOT_ASSOCED + * - CLASS3_FRAME_FROM_NONASSOC_STA - 7 - Class-3 frame received from a non-associated STA. @@ -1137,7 +1133,7 @@ Following reason codes are renamed to their shorter form to wrap the table in pa - Espressif-specific Wi-Fi reason code: the authentication fails, but not because of a timeout. * - ASSOC_FAIL - 203 - - Espressif-specific Wi-Fi reason code: the association fails, but not because of ASSOC_EXPIRE or ASSOC_TOOMANY. + - Espressif-specific Wi-Fi reason code: the association fails, but not because of DISASSOC_DUE_TO_INACTIVITY or ASSOC_TOOMANY. * - HANDSHAKE_TIMEOUT - 204 - Espressif-specific Wi-Fi reason code: the handshake fails for the same reason as that in WIFI_REASON_4WAY_HANDSHAKE_TIMEOUT. diff --git a/docs/zh_CN/api-guides/wifi.rst b/docs/zh_CN/api-guides/wifi.rst index 2bdf7e2dd4..19e119de2a 100644 --- a/docs/zh_CN/api-guides/wifi.rst +++ b/docs/zh_CN/api-guides/wifi.rst @@ -807,7 +807,7 @@ Wi-Fi 驱动程序内部扫描阶段 +++++++++++++++++++++ - s3.1:发送关联请求并使能关联计时器。 - - s3.2:如果在关联计时器超时之前未接收到关联响应,将产生 `WIFI_EVENT_STA_DISCONNECTED`_ 事件,且原因代码为 ``WIFI_REASON_ASSOC_EXPIRE``。请参阅 `Wi-Fi 原因代码`_。 + - s3.2:如果在关联计时器超时之前未接收到关联响应,将产生 `WIFI_EVENT_STA_DISCONNECTED`_ 事件,且原因代码为 ``WIFI_REASON_DISASSOC_DUE_TO_INACTIVITY``。请参阅 `Wi-Fi 原因代码`_。 - s3.3:接收到关联响应,且关联计时器终止。 - s3.4:AP 在响应中拒绝关联且产生 `WIFI_EVENT_STA_DISCONNECTED`_ 事件,原因代码将在关联响应中指定。请参阅 `Wi-Fi 原因代码`_。 @@ -864,7 +864,7 @@ Wi-Fi 原因代码 对于 ESP station,出现以下情况时报告该代码: - 从 AP 接收到该代码。 - * - ASSOC_EXPIRE + * - DISASSOC_DUE_TO_INACTIVITY - 4 - 4 - 因为 AP 不活跃,association 取消。 @@ -890,7 +890,7 @@ Wi-Fi 原因代码 对于 ESP AP,出现以下情况时将报告该代码: - 与 AP 相关联的 station 数量已到达 AP 可支持的最大值。 - * - NOT_AUTHED + * - CLASS2_FRAME_FROM_NONAUTH_STA - 6 - 6 - 从一个未认证 station 接收到 class-2 frame。 @@ -902,7 +902,7 @@ Wi-Fi 原因代码 对于 ESP AP,出现以下情况时将报告该代码: - AP 从一个未认证 station 接收到数据包。 - * - NOT_ASSOCED + * - CLASS3_FRAME_FROM_NONASSOC_STA - 7 - 7 - 从一个未关联 station 接收到的 class-3 frame。 @@ -1167,7 +1167,7 @@ Wi-Fi 原因代码 * - ASSOC_FAIL - 203 - 保留 - - 乐鑫特有的 Wi-Fi 原因代码: association 失败,但并非由 ASSOC_EXPIRE 或 ASSOC_TOOMANY 引发。 + - 乐鑫特有的 Wi-Fi 原因代码: association 失败,但并非由 DISASSOC_DUE_TO_INACTIVITY 或 ASSOC_TOOMANY 引发。 * - HANDSHAKE_TIMEOUT - 204 - 保留