Просмотр исходного кода

Merge branch 'bugfix/wps_multiple_ap_creds_v3.3' into 'release/v3.3'

Bugfix/wps multiple ap creds v3.3 (backport v3.3)

See merge request espressif/esp-idf!11727
Jiang Jiang Jian 5 лет назад
Родитель
Сommit
8ff6e2eee5

+ 4 - 0
components/esp32/include/esp_event_legacy.h

@@ -106,6 +106,9 @@ typedef struct {
     tcpip_adapter_ip6_info_t ip6_info;
 } system_event_got_ip6_t;
 
+/** Argument structure of SYSTEM_EVENT_STA_WPS_ER_SUCCESS event */
+typedef wifi_event_sta_wps_er_success_t system_event_sta_wps_er_success_t;
+
 typedef struct {
     uint8_t mac[6];           /**< MAC address of the station connected to ESP32 soft-AP */
     uint8_t aid;              /**< the aid that ESP32 soft-AP gives to the station connected to  */
@@ -133,6 +136,7 @@ typedef union {
     system_event_sta_got_ip_t                  got_ip;             /**< ESP32 station got IP, first time got IP or when IP is changed */
     system_event_sta_wps_er_pin_t              sta_er_pin;         /**< ESP32 station WPS enrollee mode PIN code received */
     system_event_sta_wps_fail_reason_t         sta_er_fail_reason;/**< ESP32 station WPS enrollee mode failed reason code received */
+    system_event_sta_wps_er_success_t          sta_er_success;     /*!< ESP32 station WPS enrollee success */
     system_event_ap_staconnected_t             sta_connected;      /**< a station connected to ESP32 soft-AP */
     system_event_ap_stadisconnected_t          sta_disconnected;   /**< a station disconnected to ESP32 soft-AP */
     system_event_ap_probe_req_rx_t             ap_probereqrecved;  /**< ESP32 soft-AP receive probe request packet */

+ 2 - 1
components/esp32/include/esp_wifi_internal.h

@@ -51,7 +51,8 @@ typedef struct {
   *
   */
 typedef enum {
-    WIFI_LOG_ERROR = 0,   /*enabled by default*/
+    WIFI_LOG_NONE = 0,
+    WIFI_LOG_ERROR,       /*enabled by default*/
     WIFI_LOG_WARNING,     /*enabled by default*/
     WIFI_LOG_INFO,        /*enabled by default*/
     WIFI_LOG_DEBUG,       /*can be set in menuconfig*/

+ 13 - 0
components/esp32/include/esp_wifi_types.h

@@ -502,6 +502,19 @@ typedef enum {
     WIFI_IOCTL_MAX,
 } wifi_ioctl_cmd_t;
 
+#define MAX_SSID_LEN        32
+#define MAX_PASSPHRASE_LEN  64
+#define MAX_WPS_AP_CRED     3
+
+/** Argument structure for WIFI_EVENT_STA_WPS_ER_SUCCESS event */
+typedef struct {
+    uint8_t ap_cred_cnt;                        /**< Number of AP credentials received */
+    struct {
+        uint8_t ssid[MAX_SSID_LEN];             /**< SSID of AP */
+        uint8_t passphrase[MAX_PASSPHRASE_LEN]; /**< Passphrase for the AP */
+    } ap_cred[MAX_WPS_AP_CRED];                 /**< All AP credentials received from WPS handshake */
+} wifi_event_sta_wps_er_success_t;
+
 /** 
  * @brief Configuration for STA's HT2040 coexist management
  *

+ 1 - 1
components/esp32/lib

@@ -1 +1 @@
-Subproject commit f2cebd142ccae8d3db3a6c6bfed5743171f99a38
+Subproject commit 60ac0520227376e4351a9e29b9a714dc22f2ebf9

+ 2 - 0
components/esp32/wifi_init.c

@@ -60,6 +60,8 @@ static void __attribute__((constructor)) s_set_default_wifi_log_level()
     */
     esp_log_level_set("wifi", CONFIG_LOG_DEFAULT_LEVEL);
     esp_log_level_set("mesh", CONFIG_LOG_DEFAULT_LEVEL);
+    esp_log_level_set("smartconfig", CONFIG_LOG_DEFAULT_LEVEL);
+    esp_log_level_set("ESPNOW", CONFIG_LOG_DEFAULT_LEVEL);
 }
 
 static void esp_wifi_set_debug_log()

+ 7 - 6
components/wpa_supplicant/include/wps/wps.h

@@ -1024,13 +1024,14 @@ struct wps_sm {
     u8 identity_len;
     u8 ownaddr[ETH_ALEN];
     u8 bssid[ETH_ALEN];
-    u8 ssid[32];
-    u8 ssid_len;
+    u8 ssid[MAX_WPS_AP_CRED][MAX_SSID_LEN];
+    u8 ssid_len[MAX_WPS_AP_CRED];
+    char key[MAX_WPS_AP_CRED][MAX_PASSPHRASE_LEN];
+    u8 key_len[MAX_WPS_AP_CRED];
+    u8 ap_cred_cnt;
     struct wps_device_data *dev;
     u8 uuid[16];
     u8 eapol_version;
-    char key[64];
-    u8 key_len;
     ETSTimer wps_timeout_timer;
     ETSTimer wps_msg_timeout_timer;
     ETSTimer wps_scan_timer;
@@ -1054,8 +1055,8 @@ struct wps_sm {
 #define    IEEE80211_CAPINFO_PRIVACY        0x0010
 
 struct wps_sm *wps_sm_get(void);
-int wps_ssid_save(u8 *ssid, u8 ssid_len);
-int wps_key_save(char *key, u8 key_len);
+int wps_ssid_save(u8 *ssid, u8 ssid_len, u8 idx);
+int wps_key_save(char *key, u8 key_len, u8 idx);
 int wps_station_wps_register_cb(wps_st_cb_t cb);
 int wps_station_wps_unregister_cb(void); 
 int wps_start_pending(void);

+ 4 - 4
components/wpa_supplicant/src/wps/wps_enrollee.c

@@ -673,7 +673,7 @@ static int wps_process_r_snonce2(struct wps_data *wps, const u8 *r_snonce2)
 
 
 static int wps_process_cred_e(struct wps_data *wps, const u8 *cred,
-			      size_t cred_len, int wps2)
+			      size_t cred_len, int cred_idx, int wps2)
 {
 	struct wps_parse_attr *attr;
 	struct wpabuf msg;
@@ -734,8 +734,8 @@ static int wps_process_cred_e(struct wps_data *wps, const u8 *cred,
 	}
 #endif /* CONFIG_WPS2 */
 
-	    wps_ssid_save(wps->cred.ssid, wps->cred.ssid_len);
-        wps_key_save((char *)wps->cred.key, wps->cred.key_len);
+	    wps_ssid_save(wps->cred.ssid, wps->cred.ssid_len, cred_idx);
+        wps_key_save((char *)wps->cred.key, wps->cred.key_len, cred_idx);
 
 	if (wps->wps->cred_cb) {
 		wps->cred.cred_attr = cred - 4;
@@ -770,7 +770,7 @@ static int wps_process_creds(struct wps_data *wps, const u8 *cred[],
 
 	for (i = 0; i < num_cred; i++) {
 		int res;
-		res = wps_process_cred_e(wps, cred[i], cred_len[i], wps2);
+		res = wps_process_cred_e(wps, cred[i], cred_len[i], i, wps2);
 		if (res == 0)
 			ok++;
 		else if (res == -2) {

+ 46 - 4
examples/wifi/wps/main/wps.c

@@ -21,6 +21,7 @@
 #include "esp_wps.h"
 #include "esp_event_loop.h"
 #include "nvs_flash.h"
+#include <string.h>
 
 
 /*set wps mode via "make menuconfig"*/
@@ -32,6 +33,7 @@
 #define WPS_TEST_MODE WPS_TYPE_DISABLE
 #endif /*CONFIG_EXAMPLE_WPS_TYPE_PBC*/
 
+#define MAX_RETRY_ATTEMPTS     2
 
 #ifndef PIN2STR
 #define PIN2STR(a) (a)[0], (a)[1], (a)[2], (a)[3], (a)[4], (a)[5], (a)[6], (a)[7]
@@ -41,9 +43,14 @@
 
 static const char *TAG = "example_wps";
 static esp_wps_config_t config = WPS_CONFIG_INIT_DEFAULT(WPS_TEST_MODE);
+static wifi_config_t wps_ap_creds[MAX_WPS_AP_CRED];
+static int s_ap_creds_num = 0;
+static int s_retry_num = 0;
 
 static esp_err_t event_handler(void *ctx, system_event_t *event)
 {
+    static int ap_idx = 1;
+
     switch(event->event_id) {
     case SYSTEM_EVENT_STA_START:
 	ESP_LOGI(TAG, "SYSTEM_EVENT_STA_START");
@@ -54,16 +61,51 @@ static esp_err_t event_handler(void *ctx, system_event_t *event)
 		ip4addr_ntoa(&event->event_info.got_ip.ip_info.ip));
         break;
     case SYSTEM_EVENT_STA_DISCONNECTED:
-	ESP_LOGI(TAG, "SYSTEM_EVENT_STA_DISCONNECTED");
-	ESP_ERROR_CHECK(esp_wifi_connect());
+    ESP_LOGI(TAG, "SYSTEM_EVENT_STA_DISCONNECTED");
+        if (s_retry_num < MAX_RETRY_ATTEMPTS) {
+            ESP_ERROR_CHECK(esp_wifi_connect());
+            s_retry_num++;
+        } else if (ap_idx < s_ap_creds_num) {
+            /* Try the next AP credential if first one fails */
+	
+            if (ap_idx < s_ap_creds_num) {
+                ESP_LOGI(TAG, "Connecting to SSID: %s, Passphrase: %s",
+                wps_ap_creds[ap_idx].sta.ssid, wps_ap_creds[ap_idx].sta.password);
+                    ESP_ERROR_CHECK(esp_wifi_set_config(ESP_IF_WIFI_STA, &wps_ap_creds[ap_idx++]) );
+                    ESP_ERROR_CHECK(esp_wifi_connect());
+                }
+            s_retry_num = 0;
+        } else {
+            ESP_LOGI(TAG, "Failed to connect!");
+        }
+
         break;
     case SYSTEM_EVENT_STA_WPS_ER_SUCCESS:
 	/*point: the function esp_wifi_wps_start() only get ssid & password
 	 * so call the function esp_wifi_connect() here
 	 * */
 	ESP_LOGI(TAG, "SYSTEM_EVENT_STA_WPS_ER_SUCCESS");
-	ESP_ERROR_CHECK(esp_wifi_wps_disable());
-	ESP_ERROR_CHECK(esp_wifi_connect());
+    {
+        wifi_event_sta_wps_er_success_t *evt = &event->event_info.sta_er_success;
+        int i;
+        if (evt && evt->ap_cred_cnt > 1) {
+            s_ap_creds_num = evt->ap_cred_cnt;
+            for (i = 0; i < s_ap_creds_num; i++) {
+                memcpy(wps_ap_creds[i].sta.ssid, evt->ap_cred[i].ssid, sizeof(evt->ap_cred[i].ssid));
+                memcpy(wps_ap_creds[i].sta.password, evt->ap_cred[i].passphrase, sizeof(evt->ap_cred[i].passphrase));
+            }
+            /* If multiple AP credentials are received from WPS, connect with first one */
+            ESP_LOGI(TAG, "Connecting to SSID: %s, Passphrase: %s", wps_ap_creds[0].sta.ssid, wps_ap_creds[0].sta.password);
+            ESP_ERROR_CHECK(esp_wifi_set_config(ESP_IF_WIFI_STA, &wps_ap_creds[0]) );
+        }
+        /*
+         * If only one AP credential is received from WPS, there will be no event data and
+         * esp_wifi_set_config() is already called by WPS modules for backward compatibility
+         * with legacy apps. So directly attempt connection here.
+         */
+         ESP_ERROR_CHECK(esp_wifi_wps_disable());
+         ESP_ERROR_CHECK(esp_wifi_connect());
+    }
 	break;
     case SYSTEM_EVENT_STA_WPS_ER_FAILED:
 	ESP_LOGI(TAG, "SYSTEM_EVENT_STA_WPS_ER_FAILED");