mirror of
https://github.com/esphome/esphome.git
synced 2026-01-09 19:50:49 -07:00
[wifi] Replace optional with sentinel values to reduce RAM and clarify API (#12446)
This commit is contained in:
@@ -2,6 +2,7 @@
|
||||
#ifdef USE_WIFI
|
||||
#include <cassert>
|
||||
#include <cinttypes>
|
||||
#include <cmath>
|
||||
|
||||
#ifdef USE_ESP32
|
||||
#if (ESP_IDF_VERSION_MAJOR >= 5 && ESP_IDF_VERSION_MINOR >= 1)
|
||||
@@ -394,7 +395,7 @@ void WiFiComponent::start() {
|
||||
|
||||
if (this->has_sta()) {
|
||||
this->wifi_sta_pre_setup_();
|
||||
if (this->output_power_.has_value() && !this->wifi_apply_output_power_(*this->output_power_)) {
|
||||
if (!std::isnan(this->output_power_) && !this->wifi_apply_output_power_(this->output_power_)) {
|
||||
ESP_LOGV(TAG, "Setting Output Power Option failed");
|
||||
}
|
||||
|
||||
@@ -441,7 +442,7 @@ void WiFiComponent::start() {
|
||||
#ifdef USE_WIFI_AP
|
||||
} else if (this->has_ap()) {
|
||||
this->setup_ap_config_();
|
||||
if (this->output_power_.has_value() && !this->wifi_apply_output_power_(*this->output_power_)) {
|
||||
if (!std::isnan(this->output_power_) && !this->wifi_apply_output_power_(this->output_power_)) {
|
||||
ESP_LOGV(TAG, "Setting Output Power Option failed");
|
||||
}
|
||||
#ifdef USE_CAPTIVE_PORTAL
|
||||
@@ -713,8 +714,8 @@ WiFiAP WiFiComponent::build_params_for_current_phase_() {
|
||||
case WiFiRetryPhase::RETRY_HIDDEN:
|
||||
// Hidden network mode: clear BSSID/channel to trigger probe request
|
||||
// (both explicit hidden and retry hidden use same behavior)
|
||||
params.set_bssid(optional<bssid_t>{});
|
||||
params.set_channel(optional<uint8_t>{});
|
||||
params.clear_bssid();
|
||||
params.clear_channel();
|
||||
break;
|
||||
|
||||
case WiFiRetryPhase::SCAN_CONNECTING:
|
||||
@@ -766,21 +767,20 @@ void WiFiComponent::start_connecting(const WiFiAP &ap) {
|
||||
char bssid_s[18];
|
||||
int8_t priority = 0;
|
||||
|
||||
if (ap.get_bssid().has_value()) {
|
||||
format_mac_addr_upper(ap.get_bssid().value().data(), bssid_s);
|
||||
priority = this->get_sta_priority(ap.get_bssid().value());
|
||||
if (ap.has_bssid()) {
|
||||
format_mac_addr_upper(ap.get_bssid().data(), bssid_s);
|
||||
priority = this->get_sta_priority(ap.get_bssid());
|
||||
}
|
||||
|
||||
ESP_LOGI(TAG,
|
||||
"Connecting to " LOG_SECRET("'%s'") " " LOG_SECRET("(%s)") " (priority %d, attempt %u/%u in phase %s)...",
|
||||
ap.get_ssid().c_str(), ap.get_bssid().has_value() ? bssid_s : LOG_STR_LITERAL("any"), priority,
|
||||
this->num_retried_ + 1, get_max_retries_for_phase(this->retry_phase_),
|
||||
LOG_STR_ARG(retry_phase_to_log_string(this->retry_phase_)));
|
||||
ap.get_ssid().c_str(), ap.has_bssid() ? bssid_s : LOG_STR_LITERAL("any"), priority, this->num_retried_ + 1,
|
||||
get_max_retries_for_phase(this->retry_phase_), LOG_STR_ARG(retry_phase_to_log_string(this->retry_phase_)));
|
||||
|
||||
#ifdef ESPHOME_LOG_HAS_VERBOSE
|
||||
ESP_LOGV(TAG, "Connection Params:");
|
||||
ESP_LOGV(TAG, " SSID: '%s'", ap.get_ssid().c_str());
|
||||
if (ap.get_bssid().has_value()) {
|
||||
if (ap.has_bssid()) {
|
||||
ESP_LOGV(TAG, " BSSID: %s", bssid_s);
|
||||
} else {
|
||||
ESP_LOGV(TAG, " BSSID: Not Set");
|
||||
@@ -808,8 +808,8 @@ void WiFiComponent::start_connecting(const WiFiAP &ap) {
|
||||
#ifdef USE_WIFI_WPA2_EAP
|
||||
}
|
||||
#endif
|
||||
if (ap.get_channel().has_value()) {
|
||||
ESP_LOGV(TAG, " Channel: %u", *ap.get_channel());
|
||||
if (ap.has_channel()) {
|
||||
ESP_LOGV(TAG, " Channel: %u", ap.get_channel());
|
||||
} else {
|
||||
ESP_LOGV(TAG, " Channel not set");
|
||||
}
|
||||
@@ -919,8 +919,8 @@ void WiFiComponent::print_connect_params_() {
|
||||
get_wifi_channel(), wifi_subnet_mask_().str().c_str(), wifi_gateway_ip_().str().c_str(),
|
||||
wifi_dns_ip_(0).str().c_str(), wifi_dns_ip_(1).str().c_str());
|
||||
#ifdef ESPHOME_LOG_HAS_VERBOSE
|
||||
if (const WiFiAP *config = this->get_selected_sta_(); config && config->get_bssid().has_value()) {
|
||||
ESP_LOGV(TAG, " Priority: %d", this->get_sta_priority(*config->get_bssid()));
|
||||
if (const WiFiAP *config = this->get_selected_sta_(); config && config->has_bssid()) {
|
||||
ESP_LOGV(TAG, " Priority: %d", this->get_sta_priority(config->get_bssid()));
|
||||
}
|
||||
#endif
|
||||
#ifdef USE_WIFI_11KV_SUPPORT
|
||||
@@ -1514,9 +1514,9 @@ void WiFiComponent::log_and_adjust_priority_for_failed_connect_() {
|
||||
if (this->retry_phase_ == WiFiRetryPhase::SCAN_CONNECTING && !this->scan_result_.empty()) {
|
||||
// Scan-based phase: always use best result (index 0)
|
||||
failed_bssid = this->scan_result_[0].get_bssid();
|
||||
} else if (const WiFiAP *config = this->get_selected_sta_(); config && config->get_bssid()) {
|
||||
} else if (const WiFiAP *config = this->get_selected_sta_(); config && config->has_bssid()) {
|
||||
// Config has specific BSSID (fast_connect or user-specified)
|
||||
failed_bssid = *config->get_bssid();
|
||||
failed_bssid = config->get_bssid();
|
||||
}
|
||||
|
||||
if (!failed_bssid.has_value()) {
|
||||
@@ -1784,24 +1784,27 @@ void WiFiComponent::save_fast_connect_settings_() {
|
||||
#endif
|
||||
|
||||
void WiFiAP::set_ssid(const std::string &ssid) { this->ssid_ = ssid; }
|
||||
void WiFiAP::set_bssid(bssid_t bssid) { this->bssid_ = bssid; }
|
||||
void WiFiAP::set_bssid(optional<bssid_t> bssid) { this->bssid_ = bssid; }
|
||||
void WiFiAP::set_bssid(const bssid_t &bssid) { this->bssid_ = bssid; }
|
||||
void WiFiAP::clear_bssid() { this->bssid_ = {}; }
|
||||
void WiFiAP::set_password(const std::string &password) { this->password_ = password; }
|
||||
#ifdef USE_WIFI_WPA2_EAP
|
||||
void WiFiAP::set_eap(optional<EAPAuth> eap_auth) { this->eap_ = std::move(eap_auth); }
|
||||
#endif
|
||||
void WiFiAP::set_channel(optional<uint8_t> channel) { this->channel_ = channel; }
|
||||
void WiFiAP::set_channel(uint8_t channel) { this->channel_ = channel; }
|
||||
void WiFiAP::clear_channel() { this->channel_ = 0; }
|
||||
#ifdef USE_WIFI_MANUAL_IP
|
||||
void WiFiAP::set_manual_ip(optional<ManualIP> manual_ip) { this->manual_ip_ = manual_ip; }
|
||||
#endif
|
||||
void WiFiAP::set_hidden(bool hidden) { this->hidden_ = hidden; }
|
||||
const std::string &WiFiAP::get_ssid() const { return this->ssid_; }
|
||||
const optional<bssid_t> &WiFiAP::get_bssid() const { return this->bssid_; }
|
||||
const bssid_t &WiFiAP::get_bssid() const { return this->bssid_; }
|
||||
bool WiFiAP::has_bssid() const { return this->bssid_ != bssid_t{}; }
|
||||
const std::string &WiFiAP::get_password() const { return this->password_; }
|
||||
#ifdef USE_WIFI_WPA2_EAP
|
||||
const optional<EAPAuth> &WiFiAP::get_eap() const { return this->eap_; }
|
||||
#endif
|
||||
const optional<uint8_t> &WiFiAP::get_channel() const { return this->channel_; }
|
||||
uint8_t WiFiAP::get_channel() const { return this->channel_; }
|
||||
bool WiFiAP::has_channel() const { return this->channel_ != 0; }
|
||||
#ifdef USE_WIFI_MANUAL_IP
|
||||
const optional<ManualIP> &WiFiAP::get_manual_ip() const { return this->manual_ip_; }
|
||||
#endif
|
||||
@@ -1829,7 +1832,7 @@ bool WiFiScanResult::matches(const WiFiAP &config) const {
|
||||
// network is configured without SSID - match other settings
|
||||
}
|
||||
// If BSSID configured, only match for correct BSSIDs
|
||||
if (config.get_bssid().has_value() && *config.get_bssid() != this->bssid_)
|
||||
if (config.has_bssid() && config.get_bssid() != this->bssid_)
|
||||
return false;
|
||||
|
||||
#ifdef USE_WIFI_WPA2_EAP
|
||||
@@ -1847,7 +1850,7 @@ bool WiFiScanResult::matches(const WiFiAP &config) const {
|
||||
#endif
|
||||
|
||||
// If channel configured, only match networks on that channel.
|
||||
if (config.get_channel().has_value() && *config.get_channel() != this->channel_) {
|
||||
if (config.has_channel() && config.get_channel() != this->channel_) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
|
||||
@@ -151,25 +151,28 @@ template<typename T> using wifi_scan_vector_t = FixedVector<T>;
|
||||
class WiFiAP {
|
||||
public:
|
||||
void set_ssid(const std::string &ssid);
|
||||
void set_bssid(bssid_t bssid);
|
||||
void set_bssid(optional<bssid_t> bssid);
|
||||
void set_bssid(const bssid_t &bssid);
|
||||
void clear_bssid();
|
||||
void set_password(const std::string &password);
|
||||
#ifdef USE_WIFI_WPA2_EAP
|
||||
void set_eap(optional<EAPAuth> eap_auth);
|
||||
#endif // USE_WIFI_WPA2_EAP
|
||||
void set_channel(optional<uint8_t> channel);
|
||||
void set_channel(uint8_t channel);
|
||||
void clear_channel();
|
||||
void set_priority(int8_t priority) { priority_ = priority; }
|
||||
#ifdef USE_WIFI_MANUAL_IP
|
||||
void set_manual_ip(optional<ManualIP> manual_ip);
|
||||
#endif
|
||||
void set_hidden(bool hidden);
|
||||
const std::string &get_ssid() const;
|
||||
const optional<bssid_t> &get_bssid() const;
|
||||
const bssid_t &get_bssid() const;
|
||||
bool has_bssid() const;
|
||||
const std::string &get_password() const;
|
||||
#ifdef USE_WIFI_WPA2_EAP
|
||||
const optional<EAPAuth> &get_eap() const;
|
||||
#endif // USE_WIFI_WPA2_EAP
|
||||
const optional<uint8_t> &get_channel() const;
|
||||
uint8_t get_channel() const;
|
||||
bool has_channel() const;
|
||||
int8_t get_priority() const { return priority_; }
|
||||
#ifdef USE_WIFI_MANUAL_IP
|
||||
const optional<ManualIP> &get_manual_ip() const;
|
||||
@@ -179,16 +182,17 @@ class WiFiAP {
|
||||
protected:
|
||||
std::string ssid_;
|
||||
std::string password_;
|
||||
optional<bssid_t> bssid_;
|
||||
#ifdef USE_WIFI_WPA2_EAP
|
||||
optional<EAPAuth> eap_;
|
||||
#endif // USE_WIFI_WPA2_EAP
|
||||
#ifdef USE_WIFI_MANUAL_IP
|
||||
optional<ManualIP> manual_ip_;
|
||||
#endif
|
||||
optional<uint8_t> channel_;
|
||||
int8_t priority_{0};
|
||||
bool hidden_{false};
|
||||
// Group small types together to minimize padding
|
||||
bssid_t bssid_{}; // 6 bytes, all zeros = any/not set
|
||||
uint8_t channel_{0}; // 1 byte, 0 = auto/not set
|
||||
int8_t priority_{0}; // 1 byte
|
||||
bool hidden_{false}; // 1 byte (+ 3 bytes end padding to 4-byte align)
|
||||
};
|
||||
|
||||
class WiFiScanResult {
|
||||
@@ -590,7 +594,7 @@ class WiFiComponent : public Component {
|
||||
#ifdef USE_WIFI_AP
|
||||
WiFiAP ap_;
|
||||
#endif
|
||||
optional<float> output_power_;
|
||||
float output_power_{NAN};
|
||||
#ifdef USE_WIFI_LISTENERS
|
||||
std::vector<WiFiIPStateListener *> ip_state_listeners_;
|
||||
std::vector<WiFiScanResultsListener *> scan_results_listeners_;
|
||||
|
||||
@@ -257,9 +257,9 @@ bool WiFiComponent::wifi_sta_connect_(const WiFiAP &ap) {
|
||||
memcpy(reinterpret_cast<char *>(conf.ssid), ap.get_ssid().c_str(), ap.get_ssid().size());
|
||||
memcpy(reinterpret_cast<char *>(conf.password), ap.get_password().c_str(), ap.get_password().size());
|
||||
|
||||
if (ap.get_bssid().has_value()) {
|
||||
if (ap.has_bssid()) {
|
||||
conf.bssid_set = 1;
|
||||
memcpy(conf.bssid, ap.get_bssid()->data(), 6);
|
||||
memcpy(conf.bssid, ap.get_bssid().data(), 6);
|
||||
} else {
|
||||
conf.bssid_set = 0;
|
||||
}
|
||||
@@ -381,8 +381,8 @@ bool WiFiComponent::wifi_sta_connect_(const WiFiAP &ap) {
|
||||
}
|
||||
#endif /* USE_NETWORK_IPV6 */
|
||||
|
||||
if (ap.get_channel().has_value()) {
|
||||
ret = wifi_set_channel(*ap.get_channel());
|
||||
if (ap.has_channel()) {
|
||||
ret = wifi_set_channel(ap.get_channel());
|
||||
if (!ret) {
|
||||
ESP_LOGV(TAG, "wifi_set_channel failed");
|
||||
return false;
|
||||
@@ -845,7 +845,7 @@ bool WiFiComponent::wifi_start_ap_(const WiFiAP &ap) {
|
||||
}
|
||||
memcpy(reinterpret_cast<char *>(conf.ssid), ap.get_ssid().c_str(), ap.get_ssid().size());
|
||||
conf.ssid_len = static_cast<uint8>(ap.get_ssid().size());
|
||||
conf.channel = ap.get_channel().value_or(1);
|
||||
conf.channel = ap.has_channel() ? ap.get_channel() : 1;
|
||||
conf.ssid_hidden = ap.get_hidden();
|
||||
conf.max_connection = 5;
|
||||
conf.beacon_interval = 100;
|
||||
|
||||
@@ -339,14 +339,14 @@ bool WiFiComponent::wifi_sta_connect_(const WiFiAP &ap) {
|
||||
conf.sta.rm_enabled = this->rrm_;
|
||||
#endif
|
||||
|
||||
if (ap.get_bssid().has_value()) {
|
||||
if (ap.has_bssid()) {
|
||||
conf.sta.bssid_set = true;
|
||||
memcpy(conf.sta.bssid, ap.get_bssid()->data(), 6);
|
||||
memcpy(conf.sta.bssid, ap.get_bssid().data(), 6);
|
||||
} else {
|
||||
conf.sta.bssid_set = false;
|
||||
}
|
||||
if (ap.get_channel().has_value()) {
|
||||
conf.sta.channel = *ap.get_channel();
|
||||
if (ap.has_channel()) {
|
||||
conf.sta.channel = ap.get_channel();
|
||||
conf.sta.scan_method = WIFI_FAST_SCAN;
|
||||
} else {
|
||||
conf.sta.scan_method = WIFI_ALL_CHANNEL_SCAN;
|
||||
@@ -1003,7 +1003,7 @@ bool WiFiComponent::wifi_start_ap_(const WiFiAP &ap) {
|
||||
return false;
|
||||
}
|
||||
memcpy(reinterpret_cast<char *>(conf.ap.ssid), ap.get_ssid().c_str(), ap.get_ssid().size());
|
||||
conf.ap.channel = ap.get_channel().value_or(1);
|
||||
conf.ap.channel = ap.has_channel() ? ap.get_channel() : 1;
|
||||
conf.ap.ssid_hidden = ap.get_ssid().size();
|
||||
conf.ap.max_connection = 5;
|
||||
conf.ap.beacon_interval = 100;
|
||||
|
||||
@@ -139,8 +139,8 @@ bool WiFiComponent::wifi_sta_connect_(const WiFiAP &ap) {
|
||||
s_sta_connecting = true;
|
||||
|
||||
WiFiStatus status = WiFi.begin(ap.get_ssid().c_str(), ap.get_password().empty() ? NULL : ap.get_password().c_str(),
|
||||
ap.get_channel().has_value() ? *ap.get_channel() : 0,
|
||||
ap.get_bssid().has_value() ? ap.get_bssid()->data() : NULL);
|
||||
ap.get_channel(), // 0 = auto
|
||||
ap.has_bssid() ? ap.get_bssid().data() : NULL);
|
||||
if (status != WL_CONNECTED) {
|
||||
ESP_LOGW(TAG, "esp_wifi_connect failed: %d", status);
|
||||
return false;
|
||||
@@ -522,7 +522,7 @@ bool WiFiComponent::wifi_start_ap_(const WiFiAP &ap) {
|
||||
yield();
|
||||
|
||||
return WiFi.softAP(ap.get_ssid().c_str(), ap.get_password().empty() ? NULL : ap.get_password().c_str(),
|
||||
ap.get_channel().value_or(1), ap.get_hidden());
|
||||
ap.has_channel() ? ap.get_channel() : 1, ap.get_hidden());
|
||||
}
|
||||
|
||||
network::IPAddress WiFiComponent::wifi_soft_ap_ip() { return {WiFi.softAPIP()}; }
|
||||
|
||||
@@ -192,7 +192,7 @@ bool WiFiComponent::wifi_start_ap_(const WiFiAP &ap) {
|
||||
}
|
||||
#endif
|
||||
|
||||
WiFi.beginAP(ap.get_ssid().c_str(), ap.get_password().c_str(), ap.get_channel().value_or(1));
|
||||
WiFi.beginAP(ap.get_ssid().c_str(), ap.get_password().c_str(), ap.has_channel() ? ap.get_channel() : 1);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user