mirror of
				https://github.com/esphome/esphome.git
				synced 2025-10-30 22:53:59 +00:00 
			
		
		
		
	Add support for passive WiFi scanning (#4666)
* Add support for passive WiFi scanning. * Apply suggestions from code review Made changes suggested by @jesserockz Co-authored-by: Jesse Hills <3060199+jesserockz@users.noreply.github.com> --------- Co-authored-by: BellaCoola <unknown> Co-authored-by: Jesse Hills <3060199+jesserockz@users.noreply.github.com>
This commit is contained in:
		| @@ -252,6 +252,7 @@ def _validate(config): | |||||||
|  |  | ||||||
|  |  | ||||||
| CONF_OUTPUT_POWER = "output_power" | CONF_OUTPUT_POWER = "output_power" | ||||||
|  | CONF_PASSIVE_SCAN = "passive_scan" | ||||||
| CONFIG_SCHEMA = cv.All( | CONFIG_SCHEMA = cv.All( | ||||||
|     cv.Schema( |     cv.Schema( | ||||||
|         { |         { | ||||||
| @@ -280,6 +281,7 @@ CONFIG_SCHEMA = cv.All( | |||||||
|             cv.SplitDefault(CONF_ENABLE_RRM, esp32_idf=False): cv.All( |             cv.SplitDefault(CONF_ENABLE_RRM, esp32_idf=False): cv.All( | ||||||
|                 cv.boolean, cv.only_with_esp_idf |                 cv.boolean, cv.only_with_esp_idf | ||||||
|             ), |             ), | ||||||
|  |             cv.Optional(CONF_PASSIVE_SCAN, default=False): cv.boolean, | ||||||
|             cv.Optional("enable_mdns"): cv.invalid( |             cv.Optional("enable_mdns"): cv.invalid( | ||||||
|                 "This option has been removed. Please use the [disabled] option under the " |                 "This option has been removed. Please use the [disabled] option under the " | ||||||
|                 "new mdns component instead." |                 "new mdns component instead." | ||||||
| @@ -379,6 +381,7 @@ async def to_code(config): | |||||||
|     cg.add(var.set_reboot_timeout(config[CONF_REBOOT_TIMEOUT])) |     cg.add(var.set_reboot_timeout(config[CONF_REBOOT_TIMEOUT])) | ||||||
|     cg.add(var.set_power_save_mode(config[CONF_POWER_SAVE_MODE])) |     cg.add(var.set_power_save_mode(config[CONF_POWER_SAVE_MODE])) | ||||||
|     cg.add(var.set_fast_connect(config[CONF_FAST_CONNECT])) |     cg.add(var.set_fast_connect(config[CONF_FAST_CONNECT])) | ||||||
|  |     cg.add(var.set_passive_scan(config[CONF_PASSIVE_SCAN])) | ||||||
|     if CONF_OUTPUT_POWER in config: |     if CONF_OUTPUT_POWER in config: | ||||||
|         cg.add(var.set_output_power(config[CONF_OUTPUT_POWER])) |         cg.add(var.set_output_power(config[CONF_OUTPUT_POWER])) | ||||||
|  |  | ||||||
|   | |||||||
| @@ -385,7 +385,7 @@ void WiFiComponent::print_connect_params_() { | |||||||
| void WiFiComponent::start_scanning() { | void WiFiComponent::start_scanning() { | ||||||
|   this->action_started_ = millis(); |   this->action_started_ = millis(); | ||||||
|   ESP_LOGD(TAG, "Starting scan..."); |   ESP_LOGD(TAG, "Starting scan..."); | ||||||
|   this->wifi_scan_start_(); |   this->wifi_scan_start_(this->passive_scan_); | ||||||
|   this->state_ = WIFI_COMPONENT_STATE_STA_SCANNING; |   this->state_ = WIFI_COMPONENT_STATE_STA_SCANNING; | ||||||
| } | } | ||||||
|  |  | ||||||
| @@ -615,6 +615,8 @@ bool WiFiComponent::is_connected() { | |||||||
| } | } | ||||||
| void WiFiComponent::set_power_save_mode(WiFiPowerSaveMode power_save) { this->power_save_ = power_save; } | void WiFiComponent::set_power_save_mode(WiFiPowerSaveMode power_save) { this->power_save_ = power_save; } | ||||||
|  |  | ||||||
|  | void WiFiComponent::set_passive_scan(bool passive) { this->passive_scan_ = passive; } | ||||||
|  |  | ||||||
| std::string WiFiComponent::format_mac_addr(const uint8_t *mac) { | std::string WiFiComponent::format_mac_addr(const uint8_t *mac) { | ||||||
|   char buf[20]; |   char buf[20]; | ||||||
|   sprintf(buf, "%02X:%02X:%02X:%02X:%02X:%02X", mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]); |   sprintf(buf, "%02X:%02X:%02X:%02X:%02X:%02X", mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]); | ||||||
|   | |||||||
| @@ -217,6 +217,8 @@ class WiFiComponent : public Component { | |||||||
|   void set_power_save_mode(WiFiPowerSaveMode power_save); |   void set_power_save_mode(WiFiPowerSaveMode power_save); | ||||||
|   void set_output_power(float output_power) { output_power_ = output_power; } |   void set_output_power(float output_power) { output_power_ = output_power; } | ||||||
|  |  | ||||||
|  |   void set_passive_scan(bool passive); | ||||||
|  |  | ||||||
|   void save_wifi_sta(const std::string &ssid, const std::string &password); |   void save_wifi_sta(const std::string &ssid, const std::string &password); | ||||||
|   // ========== INTERNAL METHODS ========== |   // ========== INTERNAL METHODS ========== | ||||||
|   // (In most use cases you won't need these) |   // (In most use cases you won't need these) | ||||||
| @@ -294,7 +296,7 @@ class WiFiComponent : public Component { | |||||||
|   bool wifi_sta_connect_(const WiFiAP &ap); |   bool wifi_sta_connect_(const WiFiAP &ap); | ||||||
|   void wifi_pre_setup_(); |   void wifi_pre_setup_(); | ||||||
|   WiFiSTAConnectStatus wifi_sta_connect_status_(); |   WiFiSTAConnectStatus wifi_sta_connect_status_(); | ||||||
|   bool wifi_scan_start_(); |   bool wifi_scan_start_(bool passive); | ||||||
|   bool wifi_ap_ip_config_(optional<ManualIP> manual_ip); |   bool wifi_ap_ip_config_(optional<ManualIP> manual_ip); | ||||||
|   bool wifi_start_ap_(const WiFiAP &ap); |   bool wifi_start_ap_(const WiFiAP &ap); | ||||||
|   bool wifi_disconnect_(); |   bool wifi_disconnect_(); | ||||||
| @@ -349,6 +351,7 @@ class WiFiComponent : public Component { | |||||||
|   bool scan_done_{false}; |   bool scan_done_{false}; | ||||||
|   bool ap_setup_{false}; |   bool ap_setup_{false}; | ||||||
|   optional<float> output_power_; |   optional<float> output_power_; | ||||||
|  |   bool passive_scan_{false}; | ||||||
|   ESPPreferenceObject pref_; |   ESPPreferenceObject pref_; | ||||||
|   bool has_saved_wifi_settings_{false}; |   bool has_saved_wifi_settings_{false}; | ||||||
| #ifdef USE_WIFI_11KV_SUPPORT | #ifdef USE_WIFI_11KV_SUPPORT | ||||||
|   | |||||||
| @@ -618,13 +618,13 @@ WiFiSTAConnectStatus WiFiComponent::wifi_sta_connect_status_() { | |||||||
|   } |   } | ||||||
|   return WiFiSTAConnectStatus::IDLE; |   return WiFiSTAConnectStatus::IDLE; | ||||||
| } | } | ||||||
| bool WiFiComponent::wifi_scan_start_() { | bool WiFiComponent::wifi_scan_start_(bool passive) { | ||||||
|   // enable STA |   // enable STA | ||||||
|   if (!this->wifi_mode_(true, {})) |   if (!this->wifi_mode_(true, {})) | ||||||
|     return false; |     return false; | ||||||
|  |  | ||||||
|   // need to use WiFi because of WiFiScanClass allocations :( |   // need to use WiFi because of WiFiScanClass allocations :( | ||||||
|   int16_t err = WiFi.scanNetworks(true, true, false, 200); |   int16_t err = WiFi.scanNetworks(true, true, passive, 200); | ||||||
|   if (err != WIFI_SCAN_RUNNING) { |   if (err != WIFI_SCAN_RUNNING) { | ||||||
|     ESP_LOGV(TAG, "WiFi.scanNetworks failed! %d", err); |     ESP_LOGV(TAG, "WiFi.scanNetworks failed! %d", err); | ||||||
|     return false; |     return false; | ||||||
|   | |||||||
| @@ -601,7 +601,7 @@ WiFiSTAConnectStatus WiFiComponent::wifi_sta_connect_status_() { | |||||||
|       return WiFiSTAConnectStatus::IDLE; |       return WiFiSTAConnectStatus::IDLE; | ||||||
|   } |   } | ||||||
| } | } | ||||||
| bool WiFiComponent::wifi_scan_start_() { | bool WiFiComponent::wifi_scan_start_(bool passive) { | ||||||
|   static bool first_scan = false; |   static bool first_scan = false; | ||||||
|  |  | ||||||
|   // enable STA |   // enable STA | ||||||
| @@ -615,14 +615,22 @@ bool WiFiComponent::wifi_scan_start_() { | |||||||
|   config.channel = 0; |   config.channel = 0; | ||||||
|   config.show_hidden = 1; |   config.show_hidden = 1; | ||||||
| #if USE_ARDUINO_VERSION_CODE >= VERSION_CODE(2, 4, 0) | #if USE_ARDUINO_VERSION_CODE >= VERSION_CODE(2, 4, 0) | ||||||
|   config.scan_type = WIFI_SCAN_TYPE_ACTIVE; |   config.scan_type = passive ? WIFI_SCAN_TYPE_PASSIVE : WIFI_SCAN_TYPE_ACTIVE; | ||||||
|   if (first_scan) { |   if (first_scan) { | ||||||
|  |     if (passive) { | ||||||
|  |       config.scan_time.passive = 200; | ||||||
|  |     } else { | ||||||
|       config.scan_time.active.min = 100; |       config.scan_time.active.min = 100; | ||||||
|       config.scan_time.active.max = 200; |       config.scan_time.active.max = 200; | ||||||
|  |     } | ||||||
|  |   } else { | ||||||
|  |     if (passive) { | ||||||
|  |       config.scan_time.passive = 500; | ||||||
|     } else { |     } else { | ||||||
|       config.scan_time.active.min = 400; |       config.scan_time.active.min = 400; | ||||||
|       config.scan_time.active.max = 500; |       config.scan_time.active.max = 500; | ||||||
|     } |     } | ||||||
|  |   } | ||||||
| #endif | #endif | ||||||
|   first_scan = false; |   first_scan = false; | ||||||
|   bool ret = wifi_station_scan(&config, &WiFiComponent::s_wifi_scan_done_callback); |   bool ret = wifi_station_scan(&config, &WiFiComponent::s_wifi_scan_done_callback); | ||||||
|   | |||||||
| @@ -736,7 +736,7 @@ WiFiSTAConnectStatus WiFiComponent::wifi_sta_connect_status_() { | |||||||
|   } |   } | ||||||
|   return WiFiSTAConnectStatus::IDLE; |   return WiFiSTAConnectStatus::IDLE; | ||||||
| } | } | ||||||
| bool WiFiComponent::wifi_scan_start_() { | bool WiFiComponent::wifi_scan_start_(bool passive) { | ||||||
|   // enable STA |   // enable STA | ||||||
|   if (!this->wifi_mode_(true, {})) |   if (!this->wifi_mode_(true, {})) | ||||||
|     return false; |     return false; | ||||||
| @@ -746,9 +746,13 @@ bool WiFiComponent::wifi_scan_start_() { | |||||||
|   config.bssid = nullptr; |   config.bssid = nullptr; | ||||||
|   config.channel = 0; |   config.channel = 0; | ||||||
|   config.show_hidden = true; |   config.show_hidden = true; | ||||||
|   config.scan_type = WIFI_SCAN_TYPE_ACTIVE; |   config.scan_type = passive ? WIFI_SCAN_TYPE_PASSIVE : WIFI_SCAN_TYPE_ACTIVE; | ||||||
|  |   if (passive) { | ||||||
|  |     config.scan_time.passive = 300; | ||||||
|  |   } else { | ||||||
|     config.scan_time.active.min = 100; |     config.scan_time.active.min = 100; | ||||||
|     config.scan_time.active.max = 300; |     config.scan_time.active.max = 300; | ||||||
|  |   } | ||||||
|  |  | ||||||
|   esp_err_t err = esp_wifi_scan_start(&config, false); |   esp_err_t err = esp_wifi_scan_start(&config, false); | ||||||
|   if (err != ESP_OK) { |   if (err != ESP_OK) { | ||||||
|   | |||||||
| @@ -125,10 +125,11 @@ void WiFiComponent::wifi_scan_result(void *env, const cyw43_ev_scan_result_t *re | |||||||
|   } |   } | ||||||
| } | } | ||||||
|  |  | ||||||
| bool WiFiComponent::wifi_scan_start_() { | bool WiFiComponent::wifi_scan_start_(bool passive) { | ||||||
|   this->scan_result_.clear(); |   this->scan_result_.clear(); | ||||||
|   this->scan_done_ = false; |   this->scan_done_ = false; | ||||||
|   cyw43_wifi_scan_options_t scan_options = {0}; |   cyw43_wifi_scan_options_t scan_options = {0}; | ||||||
|  |   scan_options.scan_type = passive ? 1 : 0; | ||||||
|   int err = cyw43_wifi_scan(&cyw43_state, &scan_options, nullptr, &s_wifi_scan_result); |   int err = cyw43_wifi_scan(&cyw43_state, &scan_options, nullptr, &s_wifi_scan_result); | ||||||
|   if (err) { |   if (err) { | ||||||
|     ESP_LOGV(TAG, "cyw43_wifi_scan failed!"); |     ESP_LOGV(TAG, "cyw43_wifi_scan failed!"); | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user