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:
Bella Coola 2023-04-20 03:53:42 +00:00 committed by GitHub
parent afc2b3b74f
commit 4c39631428
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
7 changed files with 36 additions and 15 deletions

View file

@ -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]))

View file

@ -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]);

View file

@ -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

View file

@ -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;

View file

@ -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);

View file

@ -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) {

View file

@ -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!");