mirror of
https://github.com/esphome/esphome.git
synced 2025-10-17 09:13:45 +01:00
[wifi] Use FixedVector for scan results to reduce flash usage (#11216)
This commit is contained in:
@@ -218,7 +218,7 @@ bool ImprovSerialComponent::parse_improv_payload_(improv::ImprovCommand &command
|
||||
}
|
||||
case improv::GET_WIFI_NETWORKS: {
|
||||
std::vector<std::string> networks;
|
||||
auto results = wifi::global_wifi_component->get_scan_result();
|
||||
const auto &results = wifi::global_wifi_component->get_scan_result();
|
||||
for (auto &scan : results) {
|
||||
if (scan.get_is_hidden())
|
||||
continue;
|
||||
|
@@ -549,7 +549,7 @@ void WiFiComponent::start_scanning() {
|
||||
// Using insertion sort instead of std::stable_sort saves flash memory
|
||||
// by avoiding template instantiations (std::rotate, std::stable_sort, lambdas)
|
||||
// IMPORTANT: This sort is stable (preserves relative order of equal elements)
|
||||
static void insertion_sort_scan_results(std::vector<WiFiScanResult> &results) {
|
||||
template<typename VectorType> static void insertion_sort_scan_results(VectorType &results) {
|
||||
const size_t size = results.size();
|
||||
for (size_t i = 1; i < size; i++) {
|
||||
// Make a copy to avoid issues with move semantics during comparison
|
||||
|
@@ -121,6 +121,14 @@ struct EAPAuth {
|
||||
|
||||
using bssid_t = std::array<uint8_t, 6>;
|
||||
|
||||
// Use std::vector for RP2040 since scan count is unknown (callback-based)
|
||||
// Use FixedVector for other platforms where count is queried first
|
||||
#ifdef USE_RP2040
|
||||
template<typename T> using wifi_scan_vector_t = std::vector<T>;
|
||||
#else
|
||||
template<typename T> using wifi_scan_vector_t = FixedVector<T>;
|
||||
#endif
|
||||
|
||||
class WiFiAP {
|
||||
public:
|
||||
void set_ssid(const std::string &ssid);
|
||||
@@ -278,7 +286,7 @@ class WiFiComponent : public Component {
|
||||
const std::string &get_use_address() const;
|
||||
void set_use_address(const std::string &use_address);
|
||||
|
||||
const std::vector<WiFiScanResult> &get_scan_result() const { return scan_result_; }
|
||||
const wifi_scan_vector_t<WiFiScanResult> &get_scan_result() const { return scan_result_; }
|
||||
|
||||
network::IPAddress wifi_soft_ap_ip();
|
||||
|
||||
@@ -386,7 +394,7 @@ class WiFiComponent : public Component {
|
||||
std::string use_address_;
|
||||
std::vector<WiFiAP> sta_;
|
||||
std::vector<WiFiSTAPriority> sta_priorities_;
|
||||
std::vector<WiFiScanResult> scan_result_;
|
||||
wifi_scan_vector_t<WiFiScanResult> scan_result_;
|
||||
WiFiAP selected_ap_;
|
||||
WiFiAP ap_;
|
||||
optional<float> output_power_;
|
||||
|
@@ -696,7 +696,15 @@ void WiFiComponent::wifi_scan_done_callback_(void *arg, STATUS status) {
|
||||
this->retry_connect();
|
||||
return;
|
||||
}
|
||||
|
||||
// Count the number of results first
|
||||
auto *head = reinterpret_cast<bss_info *>(arg);
|
||||
size_t count = 0;
|
||||
for (bss_info *it = head; it != nullptr; it = STAILQ_NEXT(it, next)) {
|
||||
count++;
|
||||
}
|
||||
|
||||
this->scan_result_.init(count);
|
||||
for (bss_info *it = head; it != nullptr; it = STAILQ_NEXT(it, next)) {
|
||||
WiFiScanResult res({it->bssid[0], it->bssid[1], it->bssid[2], it->bssid[3], it->bssid[4], it->bssid[5]},
|
||||
std::string(reinterpret_cast<char *>(it->ssid), it->ssid_len), it->channel, it->rssi,
|
||||
|
@@ -784,7 +784,7 @@ void WiFiComponent::wifi_process_event_(IDFWiFiEvent *data) {
|
||||
}
|
||||
records.resize(number);
|
||||
|
||||
scan_result_.reserve(number);
|
||||
scan_result_.init(number);
|
||||
for (int i = 0; i < number; i++) {
|
||||
auto &record = records[i];
|
||||
bssid_t bssid;
|
||||
|
@@ -411,7 +411,7 @@ void WiFiComponent::wifi_scan_done_callback_() {
|
||||
if (num < 0)
|
||||
return;
|
||||
|
||||
this->scan_result_.reserve(static_cast<unsigned int>(num));
|
||||
this->scan_result_.init(static_cast<unsigned int>(num));
|
||||
for (int i = 0; i < num; i++) {
|
||||
String ssid = WiFi.SSID(i);
|
||||
wifi_auth_mode_t authmode = WiFi.encryptionType(i);
|
||||
|
Reference in New Issue
Block a user