mirror of
https://github.com/esphome/esphome.git
synced 2026-09-15 17:18:40 +00:00
[wifi] Fix RP2040 falsely reporting WiFi connected after AP fallback
Two bugs combined to make the RP2040 Pico W immediately think it was
connected to WiFi after starting the fallback AP, causing it to disable
the AP and stop retrying:
1. wifi_mode_(false, {}) was a no-op for STA disable — restart_adapter()
calls this to tear down STA, but the implementation only handled
sta=true. The CYW43 STA link state remained CYW43_LINK_JOIN from
the timed-out connection attempt.
2. wifi_ap_ip_config_() called WiFi.config(192.168.4.1) which configured
the STA interface's IP (not the AP's). When wifi_sta_connect_status_()
checked WiFi.status(), CYW43lwIP::status() saw CYW43_LINK_JOIN +
localIP().isSet() and returned WL_CONNECTED.
Fix wifi_mode_() to call WiFi.disconnect() when sta=false to clear stale
link state. Remove the WiFi.config() call from wifi_ap_ip_config_() since
WiFi.beginAP() already configures the AP IP internally. Also fix
wifi_soft_ap_ip() to use WiFi.softAPIP() instead of WiFi.localIP().
This commit is contained in:
@@ -27,6 +27,11 @@ bool WiFiComponent::wifi_mode_(optional<bool> sta, optional<bool> ap) {
|
||||
if (sta.has_value()) {
|
||||
if (sta.value()) {
|
||||
cyw43_wifi_set_up(&cyw43_state, CYW43_ITF_STA, true, CYW43_COUNTRY_WORLDWIDE);
|
||||
} else {
|
||||
// Disconnect STA to clear stale link state (e.g. CYW43_LINK_JOIN from a
|
||||
// timed-out connection). Without this, restart_adapter() leaves the STA
|
||||
// interface joined and wifi_sta_connect_status_() can falsely report CONNECTED.
|
||||
WiFi.disconnect();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -188,19 +193,11 @@ bool WiFiComponent::wifi_scan_start_(bool passive) {
|
||||
|
||||
#ifdef USE_WIFI_AP
|
||||
bool WiFiComponent::wifi_ap_ip_config_(const optional<ManualIP> &manual_ip) {
|
||||
esphome::network::IPAddress ip_address, gateway, subnet, dns;
|
||||
if (manual_ip.has_value()) {
|
||||
ip_address = manual_ip->static_ip;
|
||||
gateway = manual_ip->gateway;
|
||||
subnet = manual_ip->subnet;
|
||||
dns = manual_ip->static_ip;
|
||||
} else {
|
||||
ip_address = network::IPAddress(192, 168, 4, 1);
|
||||
gateway = network::IPAddress(192, 168, 4, 1);
|
||||
subnet = network::IPAddress(255, 255, 255, 0);
|
||||
dns = network::IPAddress(192, 168, 4, 1);
|
||||
}
|
||||
WiFi.config(ip_address, dns, gateway, subnet);
|
||||
// AP IP is configured by WiFi.beginAP() internally using defaults (192.168.4.1).
|
||||
// Do NOT use WiFi.config() here — that configures the STA interface's IP, which
|
||||
// poisons the STA localIP() and causes wifi_sta_connect_status_() to falsely
|
||||
// report CONNECTED when the AP is active.
|
||||
// Manual AP IP is not currently supported on RP2040.
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -224,7 +221,7 @@ bool WiFiComponent::wifi_start_ap_(const WiFiAP &ap) {
|
||||
return true;
|
||||
}
|
||||
|
||||
network::IPAddress WiFiComponent::wifi_soft_ap_ip() { return {(const ip_addr_t *) WiFi.localIP()}; }
|
||||
network::IPAddress WiFiComponent::wifi_soft_ap_ip() { return {(const ip_addr_t *) WiFi.softAPIP()}; }
|
||||
#endif // USE_WIFI_AP
|
||||
|
||||
bool WiFiComponent::wifi_disconnect_() {
|
||||
|
||||
Reference in New Issue
Block a user