7#if (ESP_IDF_VERSION_MAJOR >= 5 && ESP_IDF_VERSION_MINOR >= 1)
8#include <esp_eap_client.h>
14#if defined(USE_ESP32) || defined(USE_ESP_IDF)
18#include <user_interface.h>
32#ifdef USE_CAPTIVE_PORTAL
43static const char *
const TAG =
"wifi";
75 ESP_LOGD(TAG,
"Loaded settings: %s", save.ssid);
79 sta.set_password(save.password);
86 ESP_LOGV(TAG,
"Setting Output Power Option failed");
90 ESP_LOGV(TAG,
"Setting Power Save Option failed");
104 }
else if (this->
has_ap()) {
107 ESP_LOGV(TAG,
"Setting Output Power Option failed");
109#ifdef USE_CAPTIVE_PORTAL
128 ESP_LOGW(TAG,
"Restarting adapter");
177 ESP_LOGW(TAG,
"Connection lost; reconnecting");
196 ESP_LOGI(TAG,
"Starting fallback AP");
198#ifdef USE_CAPTIVE_PORTAL
218 ESP_LOGE(TAG,
"Can't connect; rebooting");
230#ifdef USE_WIFI_11KV_SUPPORT
267 if (name.length() > 32) {
269 name.erase(name.begin() + 25, name.end() - 7);
271 name = name.substr(0, 32);
279 " AP Password: '%s'",
280 this->
ap_.
get_ssid().c_str(), this->ap_.get_password().c_str());
284 " AP Static IP: '%s'\n"
285 " AP Gateway: '%s'\n"
287 manual.static_ip.str().c_str(), manual.gateway.str().c_str(), manual.subnet.str().c_str());
291 ESP_LOGCONFIG(TAG,
" IP Address: %s", this->
wifi_soft_ap_ip().str().c_str());
316 snprintf(save.ssid,
sizeof(save.ssid),
"%s", ssid.c_str());
317 snprintf(save.password,
sizeof(save.password),
"%s", password.c_str());
324 sta.set_password(password);
329 ESP_LOGI(TAG,
"Connecting to '%s'", ap.
get_ssid().c_str());
330#ifdef ESPHOME_LOG_HAS_VERBOSE
331 ESP_LOGV(TAG,
"Connection Params:");
332 ESP_LOGV(TAG,
" SSID: '%s'", ap.
get_ssid().c_str());
335 ESP_LOGV(TAG,
" BSSID: %02X:%02X:%02X:%02X:%02X:%02X", b[0], b[1], b[2], b[3], b[4], b[5]);
337 ESP_LOGV(TAG,
" BSSID: Not Set");
340#ifdef USE_WIFI_WPA2_EAP
341 if (ap.
get_eap().has_value()) {
342 ESP_LOGV(TAG,
" WPA2 Enterprise authentication configured:");
344 ESP_LOGV(TAG,
" Identity: " LOG_SECRET(
"'%s'"), eap_config.
identity.c_str());
345 ESP_LOGV(TAG,
" Username: " LOG_SECRET(
"'%s'"), eap_config.
username.c_str());
346 ESP_LOGV(TAG,
" Password: " LOG_SECRET(
"'%s'"), eap_config.
password.c_str());
348#if ESPHOME_LOG_LEVEL >= ESPHOME_LOG_LEVEL_VERBOSE
349 std::map<esp_eap_ttls_phase2_types, std::string> phase2types = {{ESP_EAP_TTLS_PHASE2_PAP,
"pap"},
350 {ESP_EAP_TTLS_PHASE2_CHAP,
"chap"},
351 {ESP_EAP_TTLS_PHASE2_MSCHAP,
"mschap"},
352 {ESP_EAP_TTLS_PHASE2_MSCHAPV2,
"mschapv2"},
353 {ESP_EAP_TTLS_PHASE2_EAP,
"eap"}};
354 ESP_LOGV(TAG,
" TTLS Phase 2: " LOG_SECRET(
"'%s'"), phase2types[eap_config.
ttls_phase_2].c_str());
357 bool ca_cert_present = eap_config.
ca_cert !=
nullptr && strlen(eap_config.
ca_cert);
360 ESP_LOGV(TAG,
" CA Cert: %s", ca_cert_present ?
"present" :
"not present");
361 ESP_LOGV(TAG,
" Client Cert: %s", client_cert_present ?
"present" :
"not present");
362 ESP_LOGV(TAG,
" Client Key: %s", client_key_present ?
"present" :
"not present");
365 ESP_LOGV(TAG,
" Password: " LOG_SECRET(
"'%s'"), ap.
get_password().c_str());
366#ifdef USE_WIFI_WPA2_EAP
372 ESP_LOGV(TAG,
" Channel not set");
376 ESP_LOGV(TAG,
" Manual IP: Static IP=%s Gateway=%s Subnet=%s DNS1=%s DNS2=%s",
m.static_ip.str().c_str(),
377 m.gateway.str().c_str(),
m.subnet.str().c_str(),
m.dns1.str().c_str(),
m.dns2.str().c_str());
379 ESP_LOGV(TAG,
" Using DHCP IP");
381 ESP_LOGV(TAG,
" Hidden: %s", YESNO(ap.
get_hidden()));
385 ESP_LOGE(TAG,
"wifi_sta_connect_ failed");
408 return LOG_STR(
"\033[0;32m"
414 }
else if (rssi >= -65) {
415 return LOG_STR(
"\033[0;33m"
422 }
else if (rssi >= -85) {
423 return LOG_STR(
"\033[0;33m"
431 return LOG_STR(
"\033[0;31m"
446 ESP_LOGCONFIG(TAG,
" Disabled");
449 ESP_LOGCONFIG(TAG,
" SSID: " LOG_SECRET(
"'%s'"),
wifi_ssid().c_str());
452 ESP_LOGCONFIG(TAG,
" IP Address: %s", ip.str().c_str());
457 " BSSID: " LOG_SECRET(
"%02X:%02X:%02X:%02X:%02X:%02X")
"\n"
459 " Signal strength: %d dB %s",
460 bssid[0], bssid[1], bssid[2], bssid[3], bssid[4], bssid[5],
App.
get_name().c_str(), rssi,
462#ifdef ESPHOME_LOG_HAS_VERBOSE
468 " Channel: %" PRId32
"\n"
475#ifdef USE_WIFI_11KV_SUPPORT
479 this->
btm_ ?
"enabled" :
"disabled", this->
rrm_ ?
"enabled" :
"disabled");
487 ESP_LOGD(TAG,
"Enabling");
497 ESP_LOGD(TAG,
"Disabling");
507 ESP_LOGD(TAG,
"Starting scan");
543static void insertion_sort_scan_results(std::vector<WiFiScanResult> &results) {
544 const size_t size = results.size();
545 for (
size_t i = 1; i < size; i++) {
547 WiFiScanResult key = results[i];
552 while (j >= 0 && wifi_scan_result_is_better(key, results[j])) {
553 results[j + 1] = results[j];
556 results[j + 1] = key;
563 ESP_LOGE(TAG,
"Scan timeout");
571 ESP_LOGW(TAG,
"No networks found");
576 ESP_LOGD(TAG,
"Found networks:");
578 for (
auto &ap : this->
sta_) {
579 if (res.matches(ap)) {
580 res.set_matches(
true);
591 insertion_sort_scan_results(this->scan_result_);
593 for (
auto &res : this->scan_result_) {
595 auto bssid = res.get_bssid();
596 sprintf(bssid_s,
"%02X:%02X:%02X:%02X:%02X:%02X", bssid[0], bssid[1], bssid[2], bssid[3], bssid[4], bssid[5]);
598 if (res.get_matches()) {
599 ESP_LOGI(TAG,
"- '%s' %s" LOG_SECRET(
"(%s) ")
"%s", res.get_ssid().c_str(),
600 res.get_is_hidden() ?
"(HIDDEN) " :
"", bssid_s, LOG_STR_ARG(
get_signal_bars(res.get_rssi())));
604 res.get_channel(), res.get_rssi());
606 ESP_LOGD(TAG,
"- " LOG_SECRET(
"'%s'")
" " LOG_SECRET(
"(%s) ")
"%s", res.get_ssid().c_str(), bssid_s,
611 if (!this->scan_result_[0].get_matches()) {
612 ESP_LOGW(TAG,
"No matching network found");
619 for (
auto &config : this->
sta_) {
621 if (!scan_res.
matches(config)) {
625 if (config.get_hidden()) {
628 connect_params.
set_ssid(config.get_ssid());
643#ifdef USE_WIFI_WPA2_EAP
645 connect_params.
set_eap(config.get_eap());
661 ESP_LOGCONFIG(TAG,
"WiFi:");
670 ESP_LOGW(TAG,
"Connection incomplete");
675 ESP_LOGI(TAG,
"Connected");
678 ESP_LOGW(TAG,
"Network '%s' should be marked as hidden", this->
selected_ap_.
get_ssid().c_str());
684#ifdef USE_CAPTIVE_PORTAL
689 ESP_LOGD(TAG,
"Disabling AP");
710 ESP_LOGW(TAG,
"Connection timeout");
716 ESP_LOGW(TAG,
"Connecting to network failed");
726 ESP_LOGW(TAG,
"Network no longer found");
732 ESP_LOGW(TAG,
"Connecting to network failed");
737 ESP_LOGW(TAG,
"Unknown connection status %d", (
int)
status);
756 ESP_LOGW(TAG,
"No more APs to try");
771 ESP_LOGD(TAG,
"Retrying with hidden networks");
807#ifdef USE_CAPTIVE_PORTAL
826 std::copy(fast_connect_save.bssid, fast_connect_save.bssid + 6, bssid.begin());
827 this->
ap_index_ = fast_connect_save.ap_index;
832 ESP_LOGD(TAG,
"Loaded fast_connect settings");
846 memcpy(fast_connect_save.bssid, bssid.data(), 6);
847 fast_connect_save.channel = channel;
848 fast_connect_save.ap_index = this->
ap_index_;
852 ESP_LOGD(TAG,
"Saved fast_connect settings");
860#ifdef USE_WIFI_WPA2_EAP
869#ifdef USE_WIFI_WPA2_EAP
879 ssid_(std::move(ssid)),
882 with_auth_(with_auth),
883 is_hidden_(is_hidden) {}
890 }
else if (!config.
get_ssid().empty()) {
892 if (config.
get_ssid() != this->ssid_)
901#ifdef USE_WIFI_WPA2_EAP
std::string get_compilation_time() const
bool is_name_add_mac_suffix_enabled() const
const std::string & get_name() const
Get the name of this Application set by pre_setup().
uint32_t IRAM_ATTR HOT get_loop_component_start_time() const
Get the cached time in milliseconds from when the current component started its loop execution.
void status_set_warning(const char *message=nullptr)
void status_clear_warning()
virtual bool sync()=0
Commit pending writes to flash.
virtual ESPPreferenceObject make_preference(size_t length, uint32_t type, bool in_flash)=0
void trigger(Ts... x)
Inform the parent automation that the event has triggered.
const optional< bssid_t > & get_bssid() const
const std::string & get_ssid() const
void set_ssid(const std::string &ssid)
const optional< uint8_t > & get_channel() const
const optional< EAPAuth > & get_eap() const
void set_channel(optional< uint8_t > channel)
const std::string & get_password() const
void set_bssid(bssid_t bssid)
optional< uint8_t > channel_
optional< bssid_t > bssid_
optional< ManualIP > manual_ip_
void set_eap(optional< EAPAuth > eap_auth)
void set_password(const std::string &password)
void set_manual_ip(optional< ManualIP > manual_ip)
const optional< ManualIP > & get_manual_ip() const
void set_hidden(bool hidden)
This component is responsible for managing the ESP WiFi interface.
bool is_captive_portal_active_()
bool error_from_callback_
void add_sta(const WiFiAP &ap)
bool wifi_apply_power_save_()
void set_ap(const WiFiAP &ap)
Setup an Access Point that should be created if no connection to a station can be made.
ESPPreferenceObject pref_
void set_sta(const WiFiAP &ap)
WiFiPowerSaveMode power_save_
bool has_sta_priority(const bssid_t &bssid)
std::string get_use_address() const
void check_connecting_finished()
void save_wifi_sta(const std::string &ssid, const std::string &password)
WiFiComponentState state_
bool load_fast_connect_settings_()
void print_connect_params_()
void loop() override
Reconnect WiFi if required.
void check_scanning_finished()
float get_sta_priority(const bssid_t bssid)
network::IPAddress get_dns_address(int num)
WiFiComponent()
Construct a WiFiComponent.
std::vector< WiFiScanResult > scan_result_
void save_fast_connect_settings_()
bool wifi_start_ap_(const WiFiAP &ap)
int32_t get_wifi_channel()
void start_connecting(const WiFiAP &ap, bool two)
network::IPAddress wifi_subnet_mask_()
network::IPAddress wifi_soft_ap_ip()
void set_passive_scan(bool passive)
network::IPAddress wifi_gateway_ip_()
void set_power_save_mode(WiFiPowerSaveMode power_save)
Trigger * connect_trigger_
void set_use_address(const std::string &use_address)
ESPPreferenceObject fast_connect_pref_
network::IPAddress wifi_dns_ip_(int num)
float get_loop_priority() const override
bool wifi_apply_hostname_()
bool wifi_sta_pre_setup_()
network::IPAddresses get_ip_addresses()
Trigger * disconnect_trigger_
std::vector< WiFiAP > sta_
float get_setup_priority() const override
WIFI setup_priority.
bool is_esp32_improv_active_()
void dump_config() override
optional< float > output_power_
void set_sta_priority(const bssid_t bssid, float priority)
void set_fast_connect(bool fast_connect)
WiFiSTAConnectStatus wifi_sta_connect_status_()
bool wifi_sta_connect_(const WiFiAP &ap)
bool wifi_mode_(optional< bool > sta, optional< bool > ap)
void set_reboot_timeout(uint32_t reboot_timeout)
bool can_proceed() override
network::IPAddresses wifi_sta_ip_addresses()
bool wifi_scan_start_(bool passive)
bool handled_connected_state_
void setup() override
Setup WiFi interface.
const std::string & get_ssid() const
uint8_t get_channel() const
bool get_with_auth() const
const bssid_t & get_bssid() const
WiFiScanResult(const bssid_t &bssid, std::string ssid, uint8_t channel, int8_t rssi, bool with_auth, bool is_hidden)
void set_matches(bool matches)
bool matches(const WiFiAP &config)
bool get_is_hidden() const
bool operator==(const WiFiScanResult &rhs) const
float get_priority() const
CaptivePortal * global_captive_portal
ESP32ImprovComponent * global_improv_component
std::array< IPAddress, 5 > IPAddresses
std::array< uint8_t, 6 > bssid_t
const LogString * get_signal_bars(int8_t rssi)
@ ERROR_NETWORK_NOT_FOUND
WiFiComponent * global_wifi_component
@ WIFI_COMPONENT_STATE_DISABLED
WiFi is disabled.
@ WIFI_COMPONENT_STATE_AP
WiFi is in AP-only mode and internal AP is already enabled.
@ WIFI_COMPONENT_STATE_STA_CONNECTING
WiFi is in STA(+AP) mode and currently connecting to an AP.
@ WIFI_COMPONENT_STATE_OFF
Nothing has been initialized yet.
@ WIFI_COMPONENT_STATE_STA_SCANNING
WiFi is in STA-only mode and currently scanning for APs.
@ WIFI_COMPONENT_STATE_STA_CONNECTING_2
WiFi is in STA(+AP) mode and currently connecting to an AP a second time.
@ WIFI_COMPONENT_STATE_COOLDOWN
WiFi is in cooldown mode because something went wrong, scanning will begin after a short period of ti...
@ WIFI_COMPONENT_STATE_STA_CONNECTED
WiFi is in STA(+AP) mode and successfully connected.
Providing packet encoding functions for exchanging data with a remote host.
uint32_t fnv1_hash(const std::string &str)
Calculate a FNV-1 hash of str.
ESPPreferences * global_preferences
std::string get_mac_address_pretty()
Get the device MAC address as a string, in colon-separated uppercase hex notation.
void IRAM_ATTR HOT yield()
void IRAM_ATTR HOT delay(uint32_t ms)
uint32_t IRAM_ATTR HOT millis()
Application App
Global storage of Application pointer - only one Application can exist.
esp_eap_ttls_phase2_types ttls_phase_2
Struct for setting static IPs in WiFiComponent.