ESPHome  2023.9.1
wifi_component.cpp
Go to the documentation of this file.
1 #include "wifi_component.h"
2 #include <cinttypes>
3 
4 #if defined(USE_ESP32) || defined(USE_ESP_IDF)
5 #include <esp_wifi.h>
6 #endif
7 #ifdef USE_ESP8266
8 #include <user_interface.h>
9 #endif
10 
11 #include <utility>
12 #include <algorithm>
13 #include "lwip/err.h"
14 #include "lwip/dns.h"
15 
16 #include "esphome/core/helpers.h"
17 #include "esphome/core/log.h"
18 #include "esphome/core/hal.h"
19 #include "esphome/core/util.h"
21 
22 #ifdef USE_CAPTIVE_PORTAL
24 #endif
25 
26 #ifdef USE_IMPROV
28 #endif
29 
30 namespace esphome {
31 namespace wifi {
32 
33 static const char *const TAG = "wifi";
34 
36 
38  ESP_LOGCONFIG(TAG, "Setting up WiFi...");
39  this->wifi_pre_setup_();
40  if (this->enable_on_boot_) {
41  this->start();
42  } else {
43 #ifdef USE_ESP32
44  esp_netif_init();
45 #endif
47  }
48 }
49 
51  ESP_LOGCONFIG(TAG, "Starting WiFi...");
52  ESP_LOGCONFIG(TAG, " Local MAC: %s", get_mac_address_pretty().c_str());
53  this->last_connected_ = millis();
54 
55  uint32_t hash = this->has_sta() ? fnv1_hash(App.get_compilation_time()) : 88491487UL;
56 
58 
59  SavedWifiSettings save{};
60  if (this->pref_.load(&save)) {
61  ESP_LOGD(TAG, "Loaded saved wifi settings: %s", save.ssid);
62 
63  WiFiAP sta{};
64  sta.set_ssid(save.ssid);
65  sta.set_password(save.password);
66  this->set_sta(sta);
67  }
68 
69  if (this->has_sta()) {
70  this->wifi_sta_pre_setup_();
71  if (this->output_power_.has_value() && !this->wifi_apply_output_power_(*this->output_power_)) {
72  ESP_LOGV(TAG, "Setting Output Power Option failed!");
73  }
74 
75  if (!this->wifi_apply_power_save_()) {
76  ESP_LOGV(TAG, "Setting Power Save Option failed!");
77  }
78 
79  if (this->fast_connect_) {
80  this->selected_ap_ = this->sta_[0];
81  this->start_connecting(this->selected_ap_, false);
82  } else {
83  this->start_scanning();
84  }
85  } else if (this->has_ap()) {
86  this->setup_ap_config_();
87  if (this->output_power_.has_value() && !this->wifi_apply_output_power_(*this->output_power_)) {
88  ESP_LOGV(TAG, "Setting Output Power Option failed!");
89  }
90 #ifdef USE_CAPTIVE_PORTAL
92  this->wifi_sta_pre_setup_();
93  this->start_scanning();
95  }
96 #endif
97  }
98 #ifdef USE_IMPROV
100  if (this->wifi_mode_(true, {}))
102  }
103 #endif
104  this->wifi_apply_hostname_();
105 }
106 
108  this->wifi_loop_();
109  const uint32_t now = millis();
110 
111  if (this->has_sta()) {
112  switch (this->state_) {
114  this->status_set_warning();
115  if (millis() - this->action_started_ > 5000) {
116  if (this->fast_connect_) {
117  this->start_connecting(this->sta_[0], false);
118  } else {
119  this->start_scanning();
120  }
121  }
122  break;
123  }
125  this->status_set_warning();
126  this->check_scanning_finished();
127  break;
128  }
131  this->status_set_warning();
133  break;
134  }
135 
137  if (!this->is_connected()) {
138  ESP_LOGW(TAG, "WiFi Connection lost... Reconnecting...");
140  this->retry_connect();
141  } else {
142  this->status_clear_warning();
143  this->last_connected_ = now;
144  }
145  break;
146  }
149  break;
151  return;
152  }
153 
154  if (this->has_ap() && !this->ap_setup_) {
155  if (now - this->last_connected_ > this->ap_timeout_) {
156  ESP_LOGI(TAG, "Starting fallback AP!");
157  this->setup_ap_config_();
158 #ifdef USE_CAPTIVE_PORTAL
161 #endif
162  }
163  }
164 
165 #ifdef USE_IMPROV
166  if (esp32_improv::global_improv_component != nullptr) {
167  if (!this->is_connected()) {
168  if (this->wifi_mode_(true, {}))
170  }
171  }
172 
173 #endif
174 
175  if (!this->has_ap() && this->reboot_timeout_ != 0) {
176  if (now - this->last_connected_ > this->reboot_timeout_) {
177  ESP_LOGE(TAG, "Can't connect to WiFi, rebooting...");
178  App.reboot();
179  }
180  }
181  }
182 }
183 
185 
186 bool WiFiComponent::has_ap() const { return this->has_ap_; }
187 bool WiFiComponent::has_sta() const { return !this->sta_.empty(); }
188 void WiFiComponent::set_fast_connect(bool fast_connect) { this->fast_connect_ = fast_connect; }
189 #ifdef USE_WIFI_11KV_SUPPORT
190 void WiFiComponent::set_btm(bool btm) { this->btm_ = btm; }
191 void WiFiComponent::set_rrm(bool rrm) { this->rrm_ = rrm; }
192 #endif
194  if (this->has_sta())
195  return this->wifi_sta_ip();
196  if (this->has_ap())
197  return this->wifi_soft_ap_ip();
198  return {};
199 }
201  if (this->has_sta())
202  return this->wifi_dns_ip_(num);
203  return {};
204 }
205 std::string WiFiComponent::get_use_address() const {
206  if (this->use_address_.empty()) {
207  return App.get_name() + ".local";
208  }
209  return this->use_address_;
210 }
211 void WiFiComponent::set_use_address(const std::string &use_address) { this->use_address_ = use_address; }
213  this->wifi_mode_({}, true);
214 
215  if (this->ap_setup_)
216  return;
217 
218  if (this->ap_.get_ssid().empty()) {
219  std::string name = App.get_name();
220  if (name.length() > 32) {
222  name.erase(name.begin() + 25, name.end() - 7); // Remove characters between 25 and the mac address
223  } else {
224  name = name.substr(0, 32);
225  }
226  }
227  this->ap_.set_ssid(name);
228  }
229 
230  ESP_LOGCONFIG(TAG, "Setting up AP...");
231 
232  ESP_LOGCONFIG(TAG, " AP SSID: '%s'", this->ap_.get_ssid().c_str());
233  ESP_LOGCONFIG(TAG, " AP Password: '%s'", this->ap_.get_password().c_str());
234  if (this->ap_.get_manual_ip().has_value()) {
235  auto manual = *this->ap_.get_manual_ip();
236  ESP_LOGCONFIG(TAG, " AP Static IP: '%s'", manual.static_ip.str().c_str());
237  ESP_LOGCONFIG(TAG, " AP Gateway: '%s'", manual.gateway.str().c_str());
238  ESP_LOGCONFIG(TAG, " AP Subnet: '%s'", manual.subnet.str().c_str());
239  }
240 
241  this->ap_setup_ = this->wifi_start_ap_(this->ap_);
242  ESP_LOGCONFIG(TAG, " IP Address: %s", this->wifi_soft_ap_ip().str().c_str());
243 
244  if (!this->has_sta()) {
246  }
247 }
248 
250  return 10.0f; // before other loop components
251 }
252 void WiFiComponent::set_ap(const WiFiAP &ap) {
253  this->ap_ = ap;
254  this->has_ap_ = true;
255 }
256 void WiFiComponent::add_sta(const WiFiAP &ap) { this->sta_.push_back(ap); }
258  this->clear_sta();
259  this->add_sta(ap);
260 }
261 void WiFiComponent::clear_sta() { this->sta_.clear(); }
262 void WiFiComponent::save_wifi_sta(const std::string &ssid, const std::string &password) {
263  SavedWifiSettings save{};
264  strncpy(save.ssid, ssid.c_str(), sizeof(save.ssid));
265  strncpy(save.password, password.c_str(), sizeof(save.password));
266  this->pref_.save(&save);
267  // ensure it's written immediately
269 
270  WiFiAP sta{};
271  sta.set_ssid(ssid);
272  sta.set_password(password);
273  this->set_sta(sta);
274 }
275 
276 void WiFiComponent::start_connecting(const WiFiAP &ap, bool two) {
277  ESP_LOGI(TAG, "WiFi Connecting to '%s'...", ap.get_ssid().c_str());
278 #ifdef ESPHOME_LOG_HAS_VERBOSE
279  ESP_LOGV(TAG, "Connection Params:");
280  ESP_LOGV(TAG, " SSID: '%s'", ap.get_ssid().c_str());
281  if (ap.get_bssid().has_value()) {
282  bssid_t b = *ap.get_bssid();
283  ESP_LOGV(TAG, " BSSID: %02X:%02X:%02X:%02X:%02X:%02X", b[0], b[1], b[2], b[3], b[4], b[5]);
284  } else {
285  ESP_LOGV(TAG, " BSSID: Not Set");
286  }
287 
288 #ifdef USE_WIFI_WPA2_EAP
289  if (ap.get_eap().has_value()) {
290  ESP_LOGV(TAG, " WPA2 Enterprise authentication configured:");
291  EAPAuth eap_config = ap.get_eap().value();
292  ESP_LOGV(TAG, " Identity: " LOG_SECRET("'%s'"), eap_config.identity.c_str());
293  ESP_LOGV(TAG, " Username: " LOG_SECRET("'%s'"), eap_config.username.c_str());
294  ESP_LOGV(TAG, " Password: " LOG_SECRET("'%s'"), eap_config.password.c_str());
295  bool ca_cert_present = eap_config.ca_cert != nullptr && strlen(eap_config.ca_cert);
296  bool client_cert_present = eap_config.client_cert != nullptr && strlen(eap_config.client_cert);
297  bool client_key_present = eap_config.client_key != nullptr && strlen(eap_config.client_key);
298  ESP_LOGV(TAG, " CA Cert: %s", ca_cert_present ? "present" : "not present");
299  ESP_LOGV(TAG, " Client Cert: %s", client_cert_present ? "present" : "not present");
300  ESP_LOGV(TAG, " Client Key: %s", client_key_present ? "present" : "not present");
301  } else {
302 #endif
303  ESP_LOGV(TAG, " Password: " LOG_SECRET("'%s'"), ap.get_password().c_str());
304 #ifdef USE_WIFI_WPA2_EAP
305  }
306 #endif
307  if (ap.get_channel().has_value()) {
308  ESP_LOGV(TAG, " Channel: %u", *ap.get_channel());
309  } else {
310  ESP_LOGV(TAG, " Channel: Not Set");
311  }
312  if (ap.get_manual_ip().has_value()) {
313  ManualIP m = *ap.get_manual_ip();
314  ESP_LOGV(TAG, " Manual IP: Static IP=%s Gateway=%s Subnet=%s DNS1=%s DNS2=%s", m.static_ip.str().c_str(),
315  m.gateway.str().c_str(), m.subnet.str().c_str(), m.dns1.str().c_str(), m.dns2.str().c_str());
316  } else {
317  ESP_LOGV(TAG, " Using DHCP IP");
318  }
319  ESP_LOGV(TAG, " Hidden: %s", YESNO(ap.get_hidden()));
320 #endif
321 
322  if (!this->wifi_sta_connect_(ap)) {
323  ESP_LOGE(TAG, "wifi_sta_connect_ failed!");
324  this->retry_connect();
325  return;
326  }
327 
328  if (!two) {
330  } else {
332  }
333  this->action_started_ = millis();
334 }
335 
336 const LogString *get_signal_bars(int8_t rssi) {
337  // LOWER ONE QUARTER BLOCK
338  // Unicode: U+2582, UTF-8: E2 96 82
339  // LOWER HALF BLOCK
340  // Unicode: U+2584, UTF-8: E2 96 84
341  // LOWER THREE QUARTERS BLOCK
342  // Unicode: U+2586, UTF-8: E2 96 86
343  // FULL BLOCK
344  // Unicode: U+2588, UTF-8: E2 96 88
345  if (rssi >= -50) {
346  return LOG_STR("\033[0;32m" // green
347  "\xe2\x96\x82"
348  "\xe2\x96\x84"
349  "\xe2\x96\x86"
350  "\xe2\x96\x88"
351  "\033[0m");
352  } else if (rssi >= -65) {
353  return LOG_STR("\033[0;33m" // yellow
354  "\xe2\x96\x82"
355  "\xe2\x96\x84"
356  "\xe2\x96\x86"
357  "\033[0;37m"
358  "\xe2\x96\x88"
359  "\033[0m");
360  } else if (rssi >= -85) {
361  return LOG_STR("\033[0;33m" // yellow
362  "\xe2\x96\x82"
363  "\xe2\x96\x84"
364  "\033[0;37m"
365  "\xe2\x96\x86"
366  "\xe2\x96\x88"
367  "\033[0m");
368  } else {
369  return LOG_STR("\033[0;31m" // red
370  "\xe2\x96\x82"
371  "\033[0;37m"
372  "\xe2\x96\x84"
373  "\xe2\x96\x86"
374  "\xe2\x96\x88"
375  "\033[0m");
376  }
377 }
378 
380  bssid_t bssid = wifi_bssid();
381 
382  ESP_LOGCONFIG(TAG, " Local MAC: %s", get_mac_address_pretty().c_str());
383  ESP_LOGCONFIG(TAG, " SSID: " LOG_SECRET("'%s'"), wifi_ssid().c_str());
384  ESP_LOGCONFIG(TAG, " IP Address: %s", wifi_sta_ip().str().c_str());
385  ESP_LOGCONFIG(TAG, " BSSID: " LOG_SECRET("%02X:%02X:%02X:%02X:%02X:%02X"), bssid[0], bssid[1], bssid[2], bssid[3],
386  bssid[4], bssid[5]);
387  ESP_LOGCONFIG(TAG, " Hostname: '%s'", App.get_name().c_str());
388  int8_t rssi = wifi_rssi();
389  ESP_LOGCONFIG(TAG, " Signal strength: %d dB %s", rssi, LOG_STR_ARG(get_signal_bars(rssi)));
390  if (this->selected_ap_.get_bssid().has_value()) {
391  ESP_LOGV(TAG, " Priority: %.1f", this->get_sta_priority(*this->selected_ap_.get_bssid()));
392  }
393  ESP_LOGCONFIG(TAG, " Channel: %" PRId32, wifi_channel_());
394  ESP_LOGCONFIG(TAG, " Subnet: %s", wifi_subnet_mask_().str().c_str());
395  ESP_LOGCONFIG(TAG, " Gateway: %s", wifi_gateway_ip_().str().c_str());
396  ESP_LOGCONFIG(TAG, " DNS1: %s", wifi_dns_ip_(0).str().c_str());
397  ESP_LOGCONFIG(TAG, " DNS2: %s", wifi_dns_ip_(1).str().c_str());
398 #ifdef USE_WIFI_11KV_SUPPORT
399  ESP_LOGCONFIG(TAG, " BTM: %s", this->btm_ ? "enabled" : "disabled");
400  ESP_LOGCONFIG(TAG, " RRM: %s", this->rrm_ ? "enabled" : "disabled");
401 #endif
402 }
403 
406  return;
407 
408  ESP_LOGD(TAG, "Enabling WIFI...");
409  this->error_from_callback_ = false;
411  this->start();
412 }
413 
416  return;
417 
418  ESP_LOGD(TAG, "Disabling WIFI...");
420  this->wifi_disconnect_();
421  this->wifi_mode_(false, false);
422 }
423 
425 
427  this->action_started_ = millis();
428  ESP_LOGD(TAG, "Starting scan...");
429  this->wifi_scan_start_(this->passive_scan_);
431 }
432 
434  if (!this->scan_done_) {
435  if (millis() - this->action_started_ > 30000) {
436  ESP_LOGE(TAG, "Scan timeout!");
437  this->retry_connect();
438  }
439  return;
440  }
441  this->scan_done_ = false;
442 
443  ESP_LOGD(TAG, "Found networks:");
444  if (this->scan_result_.empty()) {
445  ESP_LOGD(TAG, " No network found!");
446  this->retry_connect();
447  return;
448  }
449 
450  for (auto &res : this->scan_result_) {
451  for (auto &ap : this->sta_) {
452  if (res.matches(ap)) {
453  res.set_matches(true);
454  if (!this->has_sta_priority(res.get_bssid())) {
455  this->set_sta_priority(res.get_bssid(), ap.get_priority());
456  }
457  res.set_priority(this->get_sta_priority(res.get_bssid()));
458  break;
459  }
460  }
461  }
462 
463  std::stable_sort(this->scan_result_.begin(), this->scan_result_.end(),
464  [](const WiFiScanResult &a, const WiFiScanResult &b) {
465  // return true if a is better than b
466  if (a.get_matches() && !b.get_matches())
467  return true;
468  if (!a.get_matches() && b.get_matches())
469  return false;
470 
471  if (a.get_matches() && b.get_matches()) {
472  // if both match, check priority
473  if (a.get_priority() != b.get_priority())
474  return a.get_priority() > b.get_priority();
475  }
476 
477  return a.get_rssi() > b.get_rssi();
478  });
479 
480  for (auto &res : this->scan_result_) {
481  char bssid_s[18];
482  auto bssid = res.get_bssid();
483  sprintf(bssid_s, "%02X:%02X:%02X:%02X:%02X:%02X", bssid[0], bssid[1], bssid[2], bssid[3], bssid[4], bssid[5]);
484 
485  if (res.get_matches()) {
486  ESP_LOGI(TAG, "- '%s' %s" LOG_SECRET("(%s) ") "%s", res.get_ssid().c_str(),
487  res.get_is_hidden() ? "(HIDDEN) " : "", bssid_s, LOG_STR_ARG(get_signal_bars(res.get_rssi())));
488  ESP_LOGD(TAG, " Channel: %u", res.get_channel());
489  ESP_LOGD(TAG, " RSSI: %d dB", res.get_rssi());
490  } else {
491  ESP_LOGD(TAG, "- " LOG_SECRET("'%s'") " " LOG_SECRET("(%s) ") "%s", res.get_ssid().c_str(), bssid_s,
492  LOG_STR_ARG(get_signal_bars(res.get_rssi())));
493  }
494  }
495 
496  if (!this->scan_result_[0].get_matches()) {
497  ESP_LOGW(TAG, "No matching network found!");
498  this->retry_connect();
499  return;
500  }
501 
502  WiFiAP connect_params;
503  WiFiScanResult scan_res = this->scan_result_[0];
504  for (auto &config : this->sta_) {
505  // search for matching STA config, at least one will match (from checks before)
506  if (!scan_res.matches(config)) {
507  continue;
508  }
509 
510  if (config.get_hidden()) {
511  // selected network is hidden, we use the data from the config
512  connect_params.set_hidden(true);
513  connect_params.set_ssid(config.get_ssid());
514  // don't set BSSID and channel, there might be multiple hidden networks
515  // but we can't know which one is the correct one. Rely on probe-req with just SSID.
516  } else {
517  // selected network is visible, we use the data from the scan
518  // limit the connect params to only connect to exactly this network
519  // (network selection is done during scan phase).
520  connect_params.set_hidden(false);
521  connect_params.set_ssid(scan_res.get_ssid());
522  connect_params.set_channel(scan_res.get_channel());
523  connect_params.set_bssid(scan_res.get_bssid());
524  }
525  // copy manual IP (if set)
526  connect_params.set_manual_ip(config.get_manual_ip());
527 
528 #ifdef USE_WIFI_WPA2_EAP
529  // copy EAP parameters (if set)
530  connect_params.set_eap(config.get_eap());
531 #endif
532 
533  // copy password (if set)
534  connect_params.set_password(config.get_password());
535 
536  break;
537  }
538 
539  yield();
540 
541  this->selected_ap_ = connect_params;
542  this->start_connecting(connect_params, false);
543 }
544 
546  ESP_LOGCONFIG(TAG, "WiFi:");
547  this->print_connect_params_();
548 }
549 
551  auto status = this->wifi_sta_connect_status_();
552 
554  if (wifi_ssid().empty()) {
555  ESP_LOGW(TAG, "Incomplete connection.");
556  this->retry_connect();
557  return;
558  }
559 
560  ESP_LOGI(TAG, "WiFi Connected!");
561  this->print_connect_params_();
562 
563  if (this->has_ap()) {
564 #ifdef USE_CAPTIVE_PORTAL
565  if (this->is_captive_portal_active_()) {
567  }
568 #endif
569  ESP_LOGD(TAG, "Disabling AP...");
570  this->wifi_mode_({}, false);
571  }
572 #ifdef USE_IMPROV
573  if (this->is_esp32_improv_active_()) {
575  }
576 #endif
577 
579  this->num_retried_ = 0;
580  return;
581  }
582 
583  uint32_t now = millis();
584  if (now - this->action_started_ > 30000) {
585  ESP_LOGW(TAG, "Timeout while connecting to WiFi.");
586  this->retry_connect();
587  return;
588  }
589 
590  if (this->error_from_callback_) {
591  ESP_LOGW(TAG, "Error while connecting to network.");
592  this->retry_connect();
593  return;
594  }
595 
597  return;
598  }
599 
601  ESP_LOGW(TAG, "WiFi network can not be found anymore.");
602  this->retry_connect();
603  return;
604  }
605 
607  ESP_LOGW(TAG, "Connecting to WiFi network failed. Are the credentials wrong?");
608  this->retry_connect();
609  return;
610  }
611 
612  ESP_LOGW(TAG, "WiFi Unknown connection status %d", (int) status);
613  this->retry_connect();
614 }
615 
617  if (this->selected_ap_.get_bssid()) {
618  auto bssid = *this->selected_ap_.get_bssid();
619  float priority = this->get_sta_priority(bssid);
620  this->set_sta_priority(bssid, priority - 1.0f);
621  }
622 
623  delay(10);
624  if (!this->is_captive_portal_active_() && !this->is_esp32_improv_active_() &&
625  (this->num_retried_ > 5 || this->error_from_callback_)) {
626  // If retry failed for more than 5 times, let's restart STA
627  ESP_LOGW(TAG, "Restarting WiFi adapter...");
628  this->wifi_mode_(false, {});
629  delay(100); // NOLINT
630  this->num_retried_ = 0;
631  } else {
632  this->num_retried_++;
633  }
634  this->error_from_callback_ = false;
636  yield();
638  this->start_connecting(this->selected_ap_, true);
639  return;
640  }
641 
643  this->action_started_ = millis();
644 }
645 
647  if (!this->has_sta() || this->state_ == WIFI_COMPONENT_STATE_DISABLED) {
648  return true;
649  }
650  return this->is_connected();
651 }
652 void WiFiComponent::set_reboot_timeout(uint32_t reboot_timeout) { this->reboot_timeout_ = reboot_timeout; }
654  return this->state_ == WIFI_COMPONENT_STATE_STA_CONNECTED &&
656 }
657 void WiFiComponent::set_power_save_mode(WiFiPowerSaveMode power_save) { this->power_save_ = power_save; }
658 
659 void WiFiComponent::set_passive_scan(bool passive) { this->passive_scan_ = passive; }
660 
661 std::string WiFiComponent::format_mac_addr(const uint8_t *mac) {
662  char buf[20];
663  sprintf(buf, "%02X:%02X:%02X:%02X:%02X:%02X", mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]);
664  return buf;
665 }
667 #ifdef USE_CAPTIVE_PORTAL
669 #else
670  return false;
671 #endif
672 }
674 #ifdef USE_IMPROV
676 #else
677  return false;
678 #endif
679 }
680 
681 void WiFiAP::set_ssid(const std::string &ssid) { this->ssid_ = ssid; }
682 void WiFiAP::set_bssid(bssid_t bssid) { this->bssid_ = bssid; }
683 void WiFiAP::set_bssid(optional<bssid_t> bssid) { this->bssid_ = bssid; }
684 void WiFiAP::set_password(const std::string &password) { this->password_ = password; }
685 #ifdef USE_WIFI_WPA2_EAP
686 void WiFiAP::set_eap(optional<EAPAuth> eap_auth) { this->eap_ = std::move(eap_auth); }
687 #endif
688 void WiFiAP::set_channel(optional<uint8_t> channel) { this->channel_ = channel; }
689 void WiFiAP::set_manual_ip(optional<ManualIP> manual_ip) { this->manual_ip_ = manual_ip; }
690 void WiFiAP::set_hidden(bool hidden) { this->hidden_ = hidden; }
691 const std::string &WiFiAP::get_ssid() const { return this->ssid_; }
692 const optional<bssid_t> &WiFiAP::get_bssid() const { return this->bssid_; }
693 const std::string &WiFiAP::get_password() const { return this->password_; }
694 #ifdef USE_WIFI_WPA2_EAP
695 const optional<EAPAuth> &WiFiAP::get_eap() const { return this->eap_; }
696 #endif
697 const optional<uint8_t> &WiFiAP::get_channel() const { return this->channel_; }
698 const optional<ManualIP> &WiFiAP::get_manual_ip() const { return this->manual_ip_; }
699 bool WiFiAP::get_hidden() const { return this->hidden_; }
700 
701 WiFiScanResult::WiFiScanResult(const bssid_t &bssid, std::string ssid, uint8_t channel, int8_t rssi, bool with_auth,
702  bool is_hidden)
703  : bssid_(bssid),
704  ssid_(std::move(ssid)),
705  channel_(channel),
706  rssi_(rssi),
707  with_auth_(with_auth),
708  is_hidden_(is_hidden) {}
709 bool WiFiScanResult::matches(const WiFiAP &config) {
710  if (config.get_hidden()) {
711  // User configured a hidden network, only match actually hidden networks
712  // don't match SSID
713  if (!this->is_hidden_)
714  return false;
715  } else if (!config.get_ssid().empty()) {
716  // check if SSID matches
717  if (config.get_ssid() != this->ssid_)
718  return false;
719  } else {
720  // network is configured without SSID - match other settings
721  }
722  // If BSSID configured, only match for correct BSSIDs
723  if (config.get_bssid().has_value() && *config.get_bssid() != this->bssid_)
724  return false;
725 
726 #ifdef USE_WIFI_WPA2_EAP
727  // BSSID requires auth but no PSK or EAP credentials given
728  if (this->with_auth_ && (config.get_password().empty() && !config.get_eap().has_value()))
729  return false;
730 
731  // BSSID does not require auth, but PSK or EAP credentials given
732  if (!this->with_auth_ && (!config.get_password().empty() || config.get_eap().has_value()))
733  return false;
734 #else
735  // If PSK given, only match for networks with auth (and vice versa)
736  if (config.get_password().empty() == this->with_auth_)
737  return false;
738 #endif
739 
740  // If channel configured, only match networks on that channel.
741  if (config.get_channel().has_value() && *config.get_channel() != this->channel_) {
742  return false;
743  }
744  return true;
745 }
746 bool WiFiScanResult::get_matches() const { return this->matches_; }
748 const bssid_t &WiFiScanResult::get_bssid() const { return this->bssid_; }
749 const std::string &WiFiScanResult::get_ssid() const { return this->ssid_; }
750 uint8_t WiFiScanResult::get_channel() const { return this->channel_; }
751 int8_t WiFiScanResult::get_rssi() const { return this->rssi_; }
752 bool WiFiScanResult::get_with_auth() const { return this->with_auth_; }
753 bool WiFiScanResult::get_is_hidden() const { return this->is_hidden_; }
754 
755 bool WiFiScanResult::operator==(const WiFiScanResult &rhs) const { return this->bssid_ == rhs.bssid_; }
756 
757 WiFiComponent *global_wifi_component; // NOLINT(cppcoreguidelines-avoid-non-const-global-variables)
758 
759 } // namespace wifi
760 } // namespace esphome
Nothing has been initialized yet.
const char * name
Definition: stm32flash.h:78
This component is responsible for managing the ESP WiFi interface.
const std::string & get_ssid() const
std::array< uint8_t, 6 > bssid_t
const optional< EAPAuth > & get_eap() const
static std::string format_mac_addr(const uint8_t mac[6])
const std::string & get_password() const
WiFiPowerSaveMode power_save_
void save_wifi_sta(const std::string &ssid, const std::string &password)
network::IPAddress wifi_dns_ip_(int num)
void set_sta_priority(const bssid_t bssid, float priority)
bool wifi_mode_(optional< bool > sta, optional< bool > ap)
const optional< bssid_t > & get_bssid() const
std::string str() const
Definition: ip_address.h:28
bool wifi_apply_output_power_(float output_power)
void add_sta(const WiFiAP &ap)
WiFi is in STA(+AP) mode and currently connecting to an AP a second time.
STL namespace.
WiFi is in STA(+AP) mode and successfully connected.
bool has_value() const
Definition: optional.h:87
network::IPAddress static_ip
void set_ap(const WiFiAP &ap)
Setup an Access Point that should be created if no connection to a station can be made...
network::IPAddress get_ip_address()
uint32_t IRAM_ATTR HOT millis()
Definition: core.cpp:25
const bssid_t & get_bssid() const
void set_channel(optional< uint8_t > channel)
bool save(const T *src)
Definition: preferences.h:21
network::IPAddress gateway
void start_connecting(const WiFiAP &ap, bool two)
WiFiComponent()
Construct a WiFiComponent.
CaptivePortal * global_captive_portal
void set_passive_scan(bool passive)
std::vector< WiFiScanResult > scan_result_
WiFi is in STA-only mode and currently scanning for APs.
uint8_t m
Definition: bl0939.h:20
Struct for setting static IPs in WiFiComponent.
void set_power_save_mode(WiFiPowerSaveMode power_save)
network::IPAddress dns1
The first DNS server. 0.0.0.0 for default.
WiFi is in STA(+AP) mode and currently connecting to an AP.
bool has_sta_priority(const bssid_t &bssid)
const optional< ManualIP > & get_manual_ip() const
ESPPreferences * global_preferences
const optional< uint8_t > & get_channel() const
void status_clear_warning()
Definition: component.cpp:153
WiFi is in cooldown mode because something went wrong, scanning will begin after a short period of ti...
void set_ssid(const std::string &ssid)
Application App
Global storage of Application pointer - only one Application can exist.
bool matches(const WiFiAP &config)
WiFiComponent * global_wifi_component
const std::string & get_name() const
Get the name of this Application set by pre_setup().
Definition: application.h:152
void status_set_warning()
Definition: component.cpp:145
network::IPAddress get_dns_address(int num)
void set_reboot_timeout(uint32_t reboot_timeout)
bool is_name_add_mac_suffix_enabled() const
Definition: application.h:159
ESP32ImprovComponent * global_improv_component
void loop() override
Reconnect WiFi if required.
uint8_t priority
bool operator==(const WiFiScanResult &rhs) const
uint8_t status
Definition: bl0942.h:23
ESPPreferenceObject pref_
network::IPAddress dns2
The second DNS server. 0.0.0.0 for default.
const char * client_cert
void IRAM_ATTR HOT yield()
Definition: core.cpp:24
void set_fast_connect(bool fast_connect)
void set_manual_ip(optional< ManualIP > manual_ip)
virtual ESPPreferenceObject make_preference(size_t length, uint32_t type, bool in_flash)=0
uint32_t fnv1_hash(const std::string &str)
Calculate a FNV-1 hash of str.
Definition: helpers.cpp:176
std::vector< WiFiAP > sta_
optional< float > output_power_
network::IPAddress subnet
void set_sta(const WiFiAP &ap)
Implementation of SPI Controller mode.
Definition: a01nyub.cpp:7
void set_bssid(bssid_t bssid)
const std::string & get_ssid() const
void set_eap(optional< EAPAuth > eap_auth)
void set_hidden(bool hidden)
float get_loop_priority() const override
void set_use_address(const std::string &use_address)
WiFiScanResult(const bssid_t &bssid, std::string ssid, uint8_t channel, int8_t rssi, bool with_auth, bool is_hidden)
std::string get_mac_address_pretty()
Get the device MAC address as a string, in colon-separated uppercase hex notation.
Definition: helpers.cpp:576
virtual bool sync()=0
Commit pending writes to flash.
std::string get_use_address() const
std::string get_compilation_time() const
Definition: application.h:161
float get_sta_priority(const bssid_t bssid)
void set_password(const std::string &password)
void setup() override
Setup WiFi interface.
float get_setup_priority() const override
WIFI setup_priority.
WiFi is in AP-only mode and internal AP is already enabled.
void IRAM_ATTR HOT delay(uint32_t ms)
Definition: core.cpp:26
const LogString * get_signal_bars(int8_t rssi)