From abcf363a3cc33657a7a8d8e2f68d3700efdde2bd Mon Sep 17 00:00:00 2001 From: "J. Nick Koston" Date: Thu, 1 Jan 2026 12:02:20 -1000 Subject: [PATCH] [wifi] Reduce heap fragmentation from WiFi scan results with SSID deduplication --- .../components/improv_serial/improv_serial_component.cpp | 2 +- esphome/components/wifi/wifi_component.h | 8 ++++---- esphome/components/wifi/wifi_component_esp8266.cpp | 4 ++-- esphome/components/wifi/wifi_component_esp_idf.cpp | 4 ++-- 4 files changed, 9 insertions(+), 9 deletions(-) diff --git a/esphome/components/improv_serial/improv_serial_component.cpp b/esphome/components/improv_serial/improv_serial_component.cpp index 9622e2dffb..acccf607be 100644 --- a/esphome/components/improv_serial/improv_serial_component.cpp +++ b/esphome/components/improv_serial/improv_serial_component.cpp @@ -266,7 +266,7 @@ bool ImprovSerialComponent::parse_improv_payload_(improv::ImprovCommand &command std::vector data = improv::build_rpc_response( improv::GET_WIFI_NETWORKS, {ssid, str_sprintf("%d", scan.get_rssi()), YESNO(scan.get_with_auth())}, false); this->send_response_(data); - networks.push_back(ssid); + networks.emplace_back(ssid); } // Send empty response to signify the end of the list. std::vector data = diff --git a/esphome/components/wifi/wifi_component.h b/esphome/components/wifi/wifi_component.h index f4ef5617a4..dcc867da11 100644 --- a/esphome/components/wifi/wifi_component.h +++ b/esphome/components/wifi/wifi_component.h @@ -63,10 +63,10 @@ namespace esphome::wifi { static constexpr int8_t WIFI_RSSI_DISCONNECTED = -127; /// Maximum SSID length per IEEE 802.11 -static constexpr uint8_t MAX_SSID_LEN = 32; +static constexpr uint8_t ESPHOME_MAX_SSID_LEN = 32; /// Buffer size for SSID (max length + null terminator) -static constexpr size_t SSID_BUFFER_SIZE = MAX_SSID_LEN + 1; +static constexpr size_t SSID_BUFFER_SIZE = ESPHOME_MAX_SSID_LEN + 1; /// Maximum password length per WPA2 static constexpr uint8_t MAX_PASSWORD_LEN = 64; @@ -249,7 +249,7 @@ class WiFiScanResult { /// SSID entry with length for efficient comparison struct SSIDEntry { char ssid[SSID_BUFFER_SIZE]; // SSID data, always null-terminated - uint8_t len{0}; // Length of SSID (0-MAX_SSID_LEN) + uint8_t len{0}; // Length of SSID (0-ESPHOME_MAX_SSID_LEN) /// Get null-terminated SSID const char *c_str() const { return this->ssid; } @@ -261,7 +261,7 @@ struct SSIDEntry { /// Store an SSID with its length (always null-terminates) void set(const char *data, uint8_t length) { - this->len = length > MAX_SSID_LEN ? MAX_SSID_LEN : length; + this->len = length > ESPHOME_MAX_SSID_LEN ? ESPHOME_MAX_SSID_LEN : length; memcpy(this->ssid, data, this->len); this->ssid[this->len] = '\0'; } diff --git a/esphome/components/wifi/wifi_component_esp8266.cpp b/esphome/components/wifi/wifi_component_esp8266.cpp index 72ddf306bc..ecdfb8f285 100644 --- a/esphome/components/wifi/wifi_component_esp8266.cpp +++ b/esphome/components/wifi/wifi_component_esp8266.cpp @@ -757,13 +757,13 @@ void WiFiComponent::wifi_scan_done_callback_(void *arg, STATUS status) { UniqueSSIDCounter ssid_counter; for (bss_info *it = head; it != nullptr; it = STAILQ_NEXT(it, next)) { count++; - uint8_t len = std::min(it->ssid_len, static_cast(MAX_SSID_LEN)); + uint8_t len = std::min(it->ssid_len, static_cast(ESPHOME_MAX_SSID_LEN)); ssid_counter.add(reinterpret_cast(it->ssid), len); } this->scan_result_.init(count, ssid_counter.pool_size()); for (bss_info *it = head; it != nullptr; it = STAILQ_NEXT(it, next)) { - uint8_t len = std::min(it->ssid_len, static_cast(MAX_SSID_LEN)); + uint8_t len = std::min(it->ssid_len, static_cast(ESPHOME_MAX_SSID_LEN)); this->scan_result_.emplace_back( bssid_t{it->bssid[0], it->bssid[1], it->bssid[2], it->bssid[3], it->bssid[4], it->bssid[5]}, reinterpret_cast(it->ssid), len, it->channel, it->rssi, it->authmode != AUTH_OPEN, diff --git a/esphome/components/wifi/wifi_component_esp_idf.cpp b/esphome/components/wifi/wifi_component_esp_idf.cpp index d2af909ceb..5dd6b0993c 100644 --- a/esphome/components/wifi/wifi_component_esp_idf.cpp +++ b/esphome/components/wifi/wifi_component_esp_idf.cpp @@ -1108,8 +1108,8 @@ const char *WiFiComponent::wifi_ssid_to(std::span buffer buffer[0] = '\0'; return buffer.data(); } - // info.ssid is uint8[33], but only MAX_SSID_LEN bytes are SSID data - size_t len = strnlen(reinterpret_cast(info.ssid), MAX_SSID_LEN); + // info.ssid is uint8[33], but only ESPHOME_MAX_SSID_LEN bytes are SSID data + size_t len = strnlen(reinterpret_cast(info.ssid), ESPHOME_MAX_SSID_LEN); memcpy(buffer.data(), info.ssid, len); buffer[len] = '\0'; return buffer.data();