From d610c3ae913ccb5d1a417592020262f25e719d43 Mon Sep 17 00:00:00 2001 From: "J. Nick Koston" Date: Tue, 20 Jan 2026 20:54:30 -1000 Subject: [PATCH] fix bssid only --- esphome/components/wifi/wifi_component.cpp | 17 +++++++++++++---- esphome/components/wifi/wifi_component.h | 5 +++-- .../components/wifi/wifi_component_esp8266.cpp | 4 ++-- .../components/wifi/wifi_component_esp_idf.cpp | 2 +- .../wifi/wifi_component_libretiny.cpp | 4 ++-- .../components/wifi/wifi_component_pico_w.cpp | 4 ++-- 6 files changed, 23 insertions(+), 13 deletions(-) diff --git a/esphome/components/wifi/wifi_component.cpp b/esphome/components/wifi/wifi_component.cpp index 002c11be5f9..151dece9bb6 100644 --- a/esphome/components/wifi/wifi_component.cpp +++ b/esphome/components/wifi/wifi_component.cpp @@ -399,16 +399,25 @@ bool WiFiComponent::needs_full_scan_results_() const { return false; } -bool WiFiComponent::matches_configured_ssid_(const char *ssid) const { +bool WiFiComponent::matches_configured_network_(const char *ssid, const uint8_t *bssid) const { // Hidden networks in scan results have empty SSIDs - skip them if (ssid[0] == '\0') { return false; } for (const auto &sta : this->sta_) { // Skip hidden network configs (they don't appear in normal scans) - // For BSSID-only configs (empty SSID), match all networks since we can't filter by SSID - // Otherwise, match only the specific configured SSID - if (!sta.get_hidden() && (sta.get_ssid().empty() || sta.get_ssid() == ssid)) { + if (sta.get_hidden()) { + continue; + } + // For BSSID-only configs (empty SSID), match by BSSID + if (sta.get_ssid().empty()) { + if (sta.has_bssid() && std::memcmp(sta.get_bssid().data(), bssid, 6) == 0) { + return true; + } + continue; + } + // Match by SSID + if (sta.get_ssid() == ssid) { return true; } } diff --git a/esphome/components/wifi/wifi_component.h b/esphome/components/wifi/wifi_component.h index 514aabc2492..3ad404e6fcd 100644 --- a/esphome/components/wifi/wifi_component.h +++ b/esphome/components/wifi/wifi_component.h @@ -544,8 +544,9 @@ class WiFiComponent : public Component { bool ssid_was_seen_in_scan_(const std::string &ssid) const; /// Check if full scan results are needed (captive portal active, improv, listeners) bool needs_full_scan_results_() const; - /// Check if SSID matches any configured network (for scan result filtering) - bool matches_configured_ssid_(const char *ssid) const; + /// Check if network matches any configured network (for scan result filtering) + /// Matches by SSID when configured, or by BSSID for BSSID-only configs + bool matches_configured_network_(const char *ssid, const uint8_t *bssid) const; /// Log a discarded scan result at VERBOSE level static void log_discarded_scan_result_(const char *ssid, const uint8_t *bssid, int8_t rssi, uint8_t channel); /// Find next SSID that wasn't in scan results (might be hidden) diff --git a/esphome/components/wifi/wifi_component_esp8266.cpp b/esphome/components/wifi/wifi_component_esp8266.cpp index fbfa423ef7d..78a301cae74 100644 --- a/esphome/components/wifi/wifi_component_esp8266.cpp +++ b/esphome/components/wifi/wifi_component_esp8266.cpp @@ -763,7 +763,7 @@ void WiFiComponent::wifi_scan_done_callback_(void *arg, STATUS status) { size_t count = 0; for (bss_info *it = head; it != nullptr; it = STAILQ_NEXT(it, next)) { const char *ssid_cstr = reinterpret_cast(it->ssid); - if (needs_full || this->matches_configured_ssid_(ssid_cstr)) { + if (needs_full || this->matches_configured_network_(ssid_cstr, it->bssid)) { count++; } } @@ -773,7 +773,7 @@ void WiFiComponent::wifi_scan_done_callback_(void *arg, STATUS status) { // Second pass: store matching networks for (bss_info *it = head; it != nullptr; it = STAILQ_NEXT(it, next)) { const char *ssid_cstr = reinterpret_cast(it->ssid); - if (needs_full || this->matches_configured_ssid_(ssid_cstr)) { + if (needs_full || this->matches_configured_network_(ssid_cstr, it->bssid)) { 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]}, std::string(ssid_cstr, it->ssid_len), it->channel, it->rssi, it->authmode != AUTH_OPEN, it->is_hidden != 0); diff --git a/esphome/components/wifi/wifi_component_esp_idf.cpp b/esphome/components/wifi/wifi_component_esp_idf.cpp index 00890771bf1..ef3aecc1a18 100644 --- a/esphome/components/wifi/wifi_component_esp_idf.cpp +++ b/esphome/components/wifi/wifi_component_esp_idf.cpp @@ -850,7 +850,7 @@ void WiFiComponent::wifi_process_event_(IDFWiFiEvent *data) { const char *ssid_cstr = reinterpret_cast(record.ssid); // Only construct std::string and store if needed - if (needs_full || this->matches_configured_ssid_(ssid_cstr)) { + if (needs_full || this->matches_configured_network_(ssid_cstr, record.bssid)) { bssid_t bssid; std::copy(record.bssid, record.bssid + 6, bssid.begin()); std::string ssid(ssid_cstr); diff --git a/esphome/components/wifi/wifi_component_libretiny.cpp b/esphome/components/wifi/wifi_component_libretiny.cpp index f16d8b22a3e..d2ebf267b67 100644 --- a/esphome/components/wifi/wifi_component_libretiny.cpp +++ b/esphome/components/wifi/wifi_component_libretiny.cpp @@ -674,7 +674,7 @@ void WiFiComponent::wifi_scan_done_callback_() { size_t count = 0; for (int i = 0; i < num; i++) { const char *ssid_cstr = scan->ap[i].ssid; - if (needs_full || this->matches_configured_ssid_(ssid_cstr)) { + if (needs_full || this->matches_configured_network_(ssid_cstr, scan->ap[i].bssid.addr)) { count++; } } @@ -684,7 +684,7 @@ void WiFiComponent::wifi_scan_done_callback_() { // Second pass: store matching networks for (int i = 0; i < num; i++) { const char *ssid_cstr = scan->ap[i].ssid; - if (needs_full || this->matches_configured_ssid_(ssid_cstr)) { + if (needs_full || this->matches_configured_network_(ssid_cstr, scan->ap[i].bssid.addr)) { auto &ap = scan->ap[i]; this->scan_result_.emplace_back(bssid_t{ap.bssid.addr[0], ap.bssid.addr[1], ap.bssid.addr[2], ap.bssid.addr[3], ap.bssid.addr[4], ap.bssid.addr[5]}, diff --git a/esphome/components/wifi/wifi_component_pico_w.cpp b/esphome/components/wifi/wifi_component_pico_w.cpp index d80ff87da65..d6d2ce09480 100644 --- a/esphome/components/wifi/wifi_component_pico_w.cpp +++ b/esphome/components/wifi/wifi_component_pico_w.cpp @@ -139,8 +139,8 @@ int WiFiComponent::s_wifi_scan_result(void *env, const cyw43_ev_scan_result_t *r void WiFiComponent::wifi_scan_result(void *env, const cyw43_ev_scan_result_t *result) { const char *ssid_cstr = reinterpret_cast(result->ssid); - // Skip networks that don't match any configured SSID (unless full results needed) - if (!this->needs_full_scan_results_() && !this->matches_configured_ssid_(ssid_cstr)) { + // Skip networks that don't match any configured network (unless full results needed) + if (!this->needs_full_scan_results_() && !this->matches_configured_network_(ssid_cstr, result->bssid)) { WiFiComponent::log_discarded_scan_result_(ssid_cstr, result->bssid, result->rssi, result->channel); return; }