Răsfoiți Sursa

Merge branch 'bugfix/add_multiple_scan_mode' into 'master'

Bugfix: Connect example to add scan mode config

Closes IDFGH-4793 and IDFGH-4812

See merge request espressif/esp-idf!12525
Jiang Jiang Jian 4 ani în urmă
părinte
comite
813d9ca420

+ 10 - 0
components/esp_wifi/Kconfig

@@ -430,6 +430,16 @@ menu "PHY"
 
 
             If unsure, choose 'n'.
             If unsure, choose 'n'.
 
 
+    config ESP32_PHY_DEFAULT_INIT_IF_INVALID
+        bool "Reset default PHY init data if invalid"
+        default n
+        depends on ESP32_PHY_INIT_DATA_IN_PARTITION
+        help
+            If enabled, PHY init data will be restored to default if
+            it cannot be verified successfully to avoid endless bootloops.
+
+            If unsure, choose 'n'.
+
     if ESP32_PHY_INIT_DATA_IN_PARTITION
     if ESP32_PHY_INIT_DATA_IN_PARTITION
         config ESP32_SUPPORT_MULTIPLE_PHY_INIT_DATA_BIN
         config ESP32_SUPPORT_MULTIPLE_PHY_INIT_DATA_BIN
             bool "Support multiple PHY init data bin"
             bool "Support multiple PHY init data bin"

+ 36 - 8
components/esp_wifi/src/phy_init.c

@@ -339,16 +339,43 @@ const esp_phy_init_data_t* esp_phy_get_init_data(void)
         ESP_LOGE(TAG, "failed to allocate memory for PHY init data");
         ESP_LOGE(TAG, "failed to allocate memory for PHY init data");
         return NULL;
         return NULL;
     }
     }
+    // read phy data from flash
     esp_err_t err = esp_partition_read(partition, 0, init_data_store, init_data_store_length);
     esp_err_t err = esp_partition_read(partition, 0, init_data_store, init_data_store_length);
     if (err != ESP_OK) {
     if (err != ESP_OK) {
         ESP_LOGE(TAG, "failed to read PHY data partition (0x%x)", err);
         ESP_LOGE(TAG, "failed to read PHY data partition (0x%x)", err);
+        free(init_data_store);
         return NULL;
         return NULL;
     }
     }
+    // verify data
     if (memcmp(init_data_store, PHY_INIT_MAGIC, sizeof(phy_init_magic_pre)) != 0 ||
     if (memcmp(init_data_store, PHY_INIT_MAGIC, sizeof(phy_init_magic_pre)) != 0 ||
         memcmp(init_data_store + init_data_store_length - sizeof(phy_init_magic_post),
         memcmp(init_data_store + init_data_store_length - sizeof(phy_init_magic_post),
                 PHY_INIT_MAGIC, sizeof(phy_init_magic_post)) != 0) {
                 PHY_INIT_MAGIC, sizeof(phy_init_magic_post)) != 0) {
+#ifndef CONFIG_ESP32_PHY_DEFAULT_INIT_IF_INVALID
         ESP_LOGE(TAG, "failed to validate PHY data partition");
         ESP_LOGE(TAG, "failed to validate PHY data partition");
+        free(init_data_store);
         return NULL;
         return NULL;
+#else
+        ESP_LOGE(TAG, "failed to validate PHY data partition, restoring default data into flash...");
+
+        memcpy(init_data_store,
+               PHY_INIT_MAGIC, sizeof(phy_init_magic_pre));
+        memcpy(init_data_store + sizeof(phy_init_magic_pre),
+               &phy_init_data, sizeof(phy_init_data));
+        memcpy(init_data_store + sizeof(phy_init_magic_pre) + sizeof(phy_init_data),
+               PHY_INIT_MAGIC, sizeof(phy_init_magic_post));
+
+        assert(memcmp(init_data_store, PHY_INIT_MAGIC, sizeof(phy_init_magic_pre)) == 0);
+        assert(memcmp(init_data_store + init_data_store_length - sizeof(phy_init_magic_post),
+                      PHY_INIT_MAGIC, sizeof(phy_init_magic_post)) == 0);
+
+        // write default data
+        err = esp_partition_write(partition, 0, init_data_store, init_data_store_length);
+        if (err != ESP_OK) {
+            ESP_LOGE(TAG, "failed to write default PHY data partition (0x%x)", err);
+            free(init_data_store);
+            return NULL;
+        }
+#endif // CONFIG_ESP32_PHY_DEFAULT_INIT_IF_INVALID
     }
     }
 #if CONFIG_ESP32_SUPPORT_MULTIPLE_PHY_INIT_DATA_BIN
 #if CONFIG_ESP32_SUPPORT_MULTIPLE_PHY_INIT_DATA_BIN
     if ((*(init_data_store + (sizeof(phy_init_magic_pre) + PHY_SUPPORT_MULTIPLE_BIN_OFFSET)))) {
     if ((*(init_data_store + (sizeof(phy_init_magic_pre) + PHY_SUPPORT_MULTIPLE_BIN_OFFSET)))) {
@@ -751,8 +778,8 @@ static esp_err_t phy_get_multiple_init_data(const esp_partition_t* partition,
 
 
     err = phy_find_bin_data_according_type(init_data_store, init_data_control_info, init_data_multiple, init_data_type);
     err = phy_find_bin_data_according_type(init_data_store, init_data_control_info, init_data_multiple, init_data_type);
     if (err != ESP_OK) {
     if (err != ESP_OK) {
-		ESP_LOGW(TAG, "%s has not been certified, use DEFAULT PHY init data", s_phy_type[init_data_type]);
-		s_phy_init_data_type = ESP_PHY_INIT_DATA_TYPE_DEFAULT;
+        ESP_LOGW(TAG, "%s has not been certified, use DEFAULT PHY init data", s_phy_type[init_data_type]);
+        s_phy_init_data_type = ESP_PHY_INIT_DATA_TYPE_DEFAULT;
     } else {
     } else {
         s_phy_init_data_type = init_data_type;
         s_phy_init_data_type = init_data_type;
     }
     }
@@ -829,18 +856,19 @@ esp_err_t esp_phy_update_country_info(const char *country)
 {
 {
 #if CONFIG_ESP32_SUPPORT_MULTIPLE_PHY_INIT_DATA_BIN
 #if CONFIG_ESP32_SUPPORT_MULTIPLE_PHY_INIT_DATA_BIN
     uint8_t phy_init_data_type_map = 0;
     uint8_t phy_init_data_type_map = 0;
-    //if country equal s_phy_current_country, return;
-    if (!memcmp(country, s_phy_current_country, sizeof(s_phy_current_country))) {
-        return ESP_OK;
-    }
-
-    memcpy(s_phy_current_country, country, sizeof(s_phy_current_country));
 
 
     if (!s_multiple_phy_init_data_bin) {
     if (!s_multiple_phy_init_data_bin) {
         ESP_LOGD(TAG, "Does not support multiple PHY init data bins");
         ESP_LOGD(TAG, "Does not support multiple PHY init data bins");
         return ESP_FAIL;
         return ESP_FAIL;
     }
     }
 
 
+   //if country equal s_phy_current_country, return;
+    if (!memcmp(country, s_phy_current_country, sizeof(s_phy_current_country))) {
+        return ESP_OK;
+    }
+
+    memcpy(s_phy_current_country, country, sizeof(s_phy_current_country));
+
     phy_init_data_type_map = phy_find_bin_type_according_country(country);
     phy_init_data_type_map = phy_find_bin_type_according_country(country);
     if (phy_init_data_type_map == s_phy_init_data_type) {
     if (phy_init_data_type_map == s_phy_init_data_type) {
         return ESP_OK;
         return ESP_OK;

+ 68 - 0
examples/common_components/protocol_examples_common/Kconfig.projbuild

@@ -20,6 +20,74 @@ menu "Example Connection Configuration"
             help
             help
                 WiFi password (WPA or WPA2) for the example to use.
                 WiFi password (WPA or WPA2) for the example to use.
                 Can be left blank if the network has no security set.
                 Can be left blank if the network has no security set.
+
+        choice EXAMPLE_WIFI_SCAN_METHOD
+            prompt "WiFi Scan Method"
+            default EXAMPLE_WIFI_SCAN_METHOD_FAST
+            help
+                WiFi scan method:
+
+                If "Fast" is selected, scan will end after find SSID match AP.
+
+                If "All Channel" is selected, scan will end after scan all the channel.
+
+            config EXAMPLE_WIFI_SCAN_METHOD_FAST
+                bool "Fast"
+            config EXAMPLE_WIFI_SCAN_METHOD_ALL_CHANNEL
+                bool "All Channel"
+        endchoice
+
+        menu "WiFi Scan threshold"
+            config EXAMPLE_WIFI_SCAN_RSSI_THRESHOLD
+                int "WiFi minimum rssi"
+                range -127 0
+
+                default -127
+                help
+                    The minimum rssi to accept in the scan mode.
+
+            choice EXAMPLE_WIFI_SCAN_AUTH_MODE_THRESHOLD
+                prompt "WiFi Scan auth mode threshold"
+                default EXAMPLE_WIFI_AUTH_OPEN
+                help
+                    The weakest authmode to accept in the scan mode.
+
+                config EXAMPLE_WIFI_AUTH_OPEN
+                    bool "OPEN"
+                config EXAMPLE_WIFI_AUTH_WEP
+                    bool "WEP"
+                config EXAMPLE_WIFI_AUTH_WPA_PSK
+                    bool "WPA PSK"
+                config EXAMPLE_WIFI_AUTH_WPA2_PSK
+                    bool "WPA2 PSK"
+                config EXAMPLE_WIFI_AUTH_WPA_WPA2_PSK
+                    bool "WPA WPA2 PSK"
+                config EXAMPLE_WIFI_AUTH_WPA2_ENTERPRISE
+                    bool "WPA2 ENTERPRISE"
+                config EXAMPLE_WIFI_AUTH_WPA3_PSK
+                    bool "WPA3 PSK"
+                config EXAMPLE_WIFI_AUTH_WPA2_WPA3_PSK
+                    bool "WPA2 WPA3 PSK"
+                config EXAMPLE_WIFI_AUTH_WAPI_PSK
+                    bool "WAPI PSK"
+            endchoice
+        endmenu
+
+        choice EXAMPLE_WIFI_CONNECT_AP_SORT_METHOD
+            prompt "WiFi Connect AP Sort Method"
+            default EXAMPLE_WIFI_CONNECT_AP_BY_SIGNAL
+            help
+                WiFi connect AP sort method:
+
+                If "Signal" is selected, Sort matched APs in scan list by RSSI.
+
+                If "Security" is selected, Sort matched APs in scan list by security mode.
+
+            config EXAMPLE_WIFI_CONNECT_AP_BY_SIGNAL
+                bool "Signal"
+            config EXAMPLE_WIFI_CONNECT_AP_BY_SECURITY
+                bool "Security"
+        endchoice
     endif
     endif
 
 
     config EXAMPLE_CONNECT_ETHERNET
     config EXAMPLE_CONNECT_ETHERNET

+ 36 - 0
examples/common_components/protocol_examples_common/connect.c

@@ -48,6 +48,38 @@
 
 
 #define EXAMPLE_DO_CONNECT CONFIG_EXAMPLE_CONNECT_WIFI || CONFIG_EXAMPLE_CONNECT_ETHERNET
 #define EXAMPLE_DO_CONNECT CONFIG_EXAMPLE_CONNECT_WIFI || CONFIG_EXAMPLE_CONNECT_ETHERNET
 
 
+#if CONFIG_EXAMPLE_WIFI_SCAN_METHOD_FAST
+#define EXAMPLE_WIFI_SCAN_METHOD WIFI_FAST_SCAN
+#elif CONFIG_EXAMPLE_WIFI_SCAN_METHOD_ALL_CHANNEL
+#define EXAMPLE_WIFI_SCAN_METHOD WIFI_ALL_CHANNEL_SCAN
+#endif
+
+#if CONFIG_EXAMPLE_WIFI_CONNECT_AP_BY_SIGNAL
+#define EXAMPLE_WIFI_CONNECT_AP_SORT_METHOD WIFI_CONNECT_AP_BY_SIGNAL
+#elif CONFIG_EXAMPLE_WIFI_CONNECT_AP_BY_SECURITY
+#define EXAMPLE_WIFI_CONNECT_AP_SORT_METHOD WIFI_CONNECT_AP_BY_SECURITY
+#endif
+
+#if CONFIG_EXAMPLE_WIFI_AUTH_OPEN
+#define EXAMPLE_WIFI_SCAN_AUTH_MODE_THRESHOLD WIFI_AUTH_OPEN
+#elif CONFIG_EXAMPLE_WIFI_AUTH_WEP
+#define EXAMPLE_WIFI_SCAN_AUTH_MODE_THRESHOLD WIFI_AUTH_WEP
+#elif CONFIG_EXAMPLE_WIFI_AUTH_WPA_PSK
+#define EXAMPLE_WIFI_SCAN_AUTH_MODE_THRESHOLD WIFI_AUTH_WPA_PSK
+#elif CONFIG_EXAMPLE_WIFI_AUTH_WPA2_PSK
+#define EXAMPLE_WIFI_SCAN_AUTH_MODE_THRESHOLD WIFI_AUTH_WPA2_PSK
+#elif CONFIG_EXAMPLE_WIFI_AUTH_WPA_WPA2_PSK
+#define EXAMPLE_WIFI_SCAN_AUTH_MODE_THRESHOLD WIFI_AUTH_WPA_WPA2_PSK
+#elif CONFIG_EXAMPLE_WIFI_AUTH_WPA2_ENTERPRISE
+#define EXAMPLE_WIFI_SCAN_AUTH_MODE_THRESHOLD WIFI_AUTH_WPA2_ENTERPRISE
+#elif CONFIG_EXAMPLE_WIFI_AUTH_WPA3_PSK
+#define EXAMPLE_WIFI_SCAN_AUTH_MODE_THRESHOLD WIFI_AUTH_WPA3_PSK
+#elif CONFIG_EXAMPLE_WIFI_AUTH_WPA2_WPA3_PSK
+#define EXAMPLE_WIFI_SCAN_AUTH_MODE_THRESHOLD WIFI_AUTH_WPA2_WPA3_PSK
+#elif CONFIG_EXAMPLE_WIFI_AUTH_WAPI_PSK
+#define EXAMPLE_WIFI_SCAN_AUTH_MODE_THRESHOLD WIFI_AUTH_WAPI_PSK
+#endif
+
 static int s_active_interfaces = 0;
 static int s_active_interfaces = 0;
 static xSemaphoreHandle s_semph_get_ip_addrs;
 static xSemaphoreHandle s_semph_get_ip_addrs;
 static esp_netif_t *s_example_esp_netif = NULL;
 static esp_netif_t *s_example_esp_netif = NULL;
@@ -265,6 +297,10 @@ static esp_netif_t *wifi_start(void)
         .sta = {
         .sta = {
             .ssid = CONFIG_EXAMPLE_WIFI_SSID,
             .ssid = CONFIG_EXAMPLE_WIFI_SSID,
             .password = CONFIG_EXAMPLE_WIFI_PASSWORD,
             .password = CONFIG_EXAMPLE_WIFI_PASSWORD,
+            .scan_method = EXAMPLE_WIFI_SCAN_METHOD,
+            .sort_method = EXAMPLE_WIFI_CONNECT_AP_SORT_METHOD,
+            .threshold.rssi = CONFIG_EXAMPLE_WIFI_SCAN_RSSI_THRESHOLD,
+            .threshold.authmode = EXAMPLE_WIFI_SCAN_AUTH_MODE_THRESHOLD,
         },
         },
     };
     };
     ESP_LOGI(TAG, "Connecting to %s...", wifi_config.sta.ssid);
     ESP_LOGI(TAG, "Connecting to %s...", wifi_config.sta.ssid);