1
0
mirror of https://github.com/esphome/esphome.git synced 2026-02-08 00:31:58 +00:00

[wifi] Reduce heap fragmentation from WiFi scan results with SSID deduplication

This commit is contained in:
J. Nick Koston
2026-01-01 12:02:20 -10:00
parent 127c910207
commit abcf363a3c
4 changed files with 9 additions and 9 deletions

View File

@@ -266,7 +266,7 @@ bool ImprovSerialComponent::parse_improv_payload_(improv::ImprovCommand &command
std::vector<uint8_t> 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<uint8_t> data =

View File

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

View File

@@ -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<uint8>(MAX_SSID_LEN));
uint8_t len = std::min(it->ssid_len, static_cast<uint8>(ESPHOME_MAX_SSID_LEN));
ssid_counter.add(reinterpret_cast<const char *>(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<uint8>(MAX_SSID_LEN));
uint8_t len = std::min(it->ssid_len, static_cast<uint8>(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<const char *>(it->ssid), len, it->channel, it->rssi, it->authmode != AUTH_OPEN,

View File

@@ -1108,8 +1108,8 @@ const char *WiFiComponent::wifi_ssid_to(std::span<char, SSID_BUFFER_SIZE> 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<const char *>(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<const char *>(info.ssid), ESPHOME_MAX_SSID_LEN);
memcpy(buffer.data(), info.ssid, len);
buffer[len] = '\0';
return buffer.data();