mirror of
https://github.com/esphome/esphome.git
synced 2026-10-02 17:30:22 +00:00
[wifi] Share the scan list dedupe helper with improv_serial (#18612)
Co-authored-by: pre-commit-ci-lite[bot] <117423508+pre-commit-ci-lite[bot]@users.noreply.github.com> Co-authored-by: J. Nick Koston <nick@koston.org> Co-authored-by: Bluetooth Devices Bot <bluetooth@koston.org>
This commit is contained in:
co-authored by
pre-commit-ci-lite[bot]
J. Nick Koston
Bluetooth Devices Bot
parent
1ceaf699c2
commit
3c56b9e66e
@@ -4,9 +4,9 @@
|
||||
#include "esphome/core/application.h"
|
||||
#include "esphome/core/helpers.h"
|
||||
#include "esphome/core/string_ref.h"
|
||||
#include "esphome/components/wifi/scan_list.h"
|
||||
#include "esphome/components/wifi/wifi_component.h"
|
||||
#include "captive_index.h"
|
||||
#include "scan_list.h"
|
||||
|
||||
namespace esphome::captive_portal {
|
||||
|
||||
@@ -37,7 +37,7 @@ void CaptivePortal::handle_config(AsyncWebServerRequest *request) {
|
||||
const auto &results = wifi::global_wifi_component->get_scan_result();
|
||||
for (const auto &scan : results) {
|
||||
bool with_auth = false;
|
||||
if (!should_show_scan_entry(results, scan, with_auth))
|
||||
if (!wifi::should_show_scan_entry(results, scan, with_auth))
|
||||
continue;
|
||||
|
||||
json_escape_into_buffer(escaped_ssid, scan.get_ssid());
|
||||
|
||||
@@ -7,6 +7,7 @@
|
||||
#include "esphome/core/version.h"
|
||||
|
||||
#include "esphome/components/logger/logger.h"
|
||||
#include "esphome/components/wifi/scan_list.h"
|
||||
|
||||
namespace esphome::improv_serial {
|
||||
|
||||
@@ -230,31 +231,17 @@ bool ImprovSerialComponent::parse_improv_payload_(improv::ImprovCommand &command
|
||||
return true;
|
||||
}
|
||||
case improv::GET_WIFI_NETWORKS: {
|
||||
std::vector<std::string> networks;
|
||||
const auto &results = wifi::global_wifi_component->get_scan_result();
|
||||
for (auto &scan : results) {
|
||||
if (scan.get_is_hidden())
|
||||
for (const auto &scan : results) {
|
||||
bool with_auth = false;
|
||||
if (!wifi::should_show_scan_entry(results, scan, with_auth))
|
||||
continue;
|
||||
const char *ssid_cstr = scan.get_ssid().c_str();
|
||||
// Check if we've already sent this SSID
|
||||
bool duplicate = false;
|
||||
for (const auto &seen : networks) {
|
||||
if (strcmp(seen.c_str(), ssid_cstr) == 0) {
|
||||
duplicate = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (duplicate)
|
||||
continue;
|
||||
// Only allocate std::string after confirming it's not a duplicate
|
||||
std::string ssid(ssid_cstr);
|
||||
// Send each ssid separately to avoid overflowing the buffer
|
||||
char rssi_buf[5]; // int8_t: -128 to 127, max 4 chars + null
|
||||
*int8_to_str(rssi_buf, scan.get_rssi()) = '\0';
|
||||
std::vector<uint8_t> data =
|
||||
improv::build_rpc_response(improv::GET_WIFI_NETWORKS, {ssid, rssi_buf, YESNO(scan.get_with_auth())}, false);
|
||||
std::vector<uint8_t> data = improv::build_rpc_response(
|
||||
improv::GET_WIFI_NETWORKS, {scan.get_ssid().str(), rssi_buf, YESNO(with_auth)}, false);
|
||||
this->send_response_(data);
|
||||
networks.push_back(std::move(ssid));
|
||||
}
|
||||
// Send empty response to signify the end of the list.
|
||||
std::vector<uint8_t> data =
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
#pragma once
|
||||
#include <cstdint>
|
||||
|
||||
namespace esphome::captive_portal {
|
||||
namespace esphome::wifi {
|
||||
|
||||
// A scan lists every BSSID, so one SSID can appear several times. Returns true for
|
||||
// the strongest entry per SSID (earliest on ties), never for hidden entries. scan
|
||||
@@ -25,4 +25,4 @@ bool should_show_scan_entry(const Results &results, const Entry &scan, bool &wit
|
||||
return true;
|
||||
}
|
||||
|
||||
} // namespace esphome::captive_portal
|
||||
} // namespace esphome::wifi
|
||||
@@ -1,10 +0,0 @@
|
||||
from tests.testing_helpers import ComponentManifestOverride
|
||||
|
||||
|
||||
def override_manifest(manifest: ComponentManifestOverride) -> None:
|
||||
# The scan list helper is header-only and needs none of the component's real
|
||||
# dependencies. Pulling them in breaks the host build: web_server_base
|
||||
# includes ESPAsyncWebServer.h and ota.web_server includes md5/md5.h, neither
|
||||
# of which exists there.
|
||||
manifest.dependencies = []
|
||||
manifest.auto_load = []
|
||||
+6
-6
@@ -4,13 +4,13 @@
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include "esphome/components/captive_portal/scan_list.h"
|
||||
#include "esphome/components/wifi/scan_list.h"
|
||||
|
||||
namespace esphome::captive_portal::testing {
|
||||
namespace esphome::wifi::testing {
|
||||
|
||||
namespace {
|
||||
|
||||
// Stand-in for wifi::WiFiScanResult, which does not compile on the host.
|
||||
// Stand-in for WiFiScanResult, which does not compile on the host.
|
||||
struct Entry {
|
||||
std::string ssid;
|
||||
int8_t rssi;
|
||||
@@ -24,7 +24,7 @@ struct Entry {
|
||||
bool get_is_hidden() const { return this->is_hidden; }
|
||||
};
|
||||
|
||||
// One row as the portal would emit it.
|
||||
// One network as a consumer would emit it.
|
||||
struct Row {
|
||||
std::string ssid;
|
||||
int8_t rssi;
|
||||
@@ -33,7 +33,7 @@ struct Row {
|
||||
bool operator==(const Row &rhs) const { return ssid == rhs.ssid && rssi == rhs.rssi && lock == rhs.lock; }
|
||||
};
|
||||
|
||||
// Walk the results the way handle_config does and collect the rows that survive.
|
||||
// Walk the results the way the consumers do and collect the rows that survive.
|
||||
std::vector<Row> rows(const std::vector<Entry> &results) {
|
||||
std::vector<Row> out;
|
||||
for (size_t i = 0; i < results.size(); i++) {
|
||||
@@ -127,4 +127,4 @@ TEST(ScanList, EmptyListShowsNothing) {
|
||||
EXPECT_TRUE(rows(results).empty());
|
||||
}
|
||||
|
||||
} // namespace esphome::captive_portal::testing
|
||||
} // namespace esphome::wifi::testing
|
||||
Reference in New Issue
Block a user