mirror of
https://github.com/esphome/esphome.git
synced 2026-09-03 03:26:02 +00:00
[mdns] Skip MDNS.update() while the ESP8266 radio cannot transmit (#18785)
This commit is contained in:
@@ -41,7 +41,19 @@ static void register_esp8266(MDNSComponent *, StaticVector<MDNSService, MDNS_SER
|
||||
#ifdef USE_MDNS_EVENT_DRIVEN_POLLING
|
||||
void MDNSComponent::start_polling_window_() {
|
||||
// uint32_t-ID set_interval/set_timeout already does atomic cancel-and-add.
|
||||
this->set_interval(MDNS_POLL_ID, MDNS_UPDATE_INTERVAL_MS, []() { MDNS.update(); });
|
||||
this->set_interval(MDNS_POLL_ID, MDNS_UPDATE_INTERVAL_MS, []() {
|
||||
#ifdef USE_MDNS_WIFI_LISTENER
|
||||
// MDNS.update() can suspend the loop in UdpContext::sendTimeout() while a send is
|
||||
// failing (radio off-channel during a roam scan, or mid reconnect); an incoming
|
||||
// packet then re-enters LEAmDNS from lwIP and corrupts shared UdpContext state.
|
||||
// Skip the tick while the radio cannot transmit (#18760), but keep polling while
|
||||
// the AP is serving clients (AP-only or fallback AP with the STA down).
|
||||
auto *wifi = wifi::global_wifi_component;
|
||||
if (wifi->is_roaming() || (!wifi->is_connected() && !wifi->is_ap_active()))
|
||||
return;
|
||||
#endif
|
||||
MDNS.update();
|
||||
});
|
||||
this->set_timeout(MDNS_POLL_STOP_ID, MDNS_POLL_WINDOW_MS, [this]() { this->cancel_interval(MDNS_POLL_ID); });
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -530,7 +530,7 @@ void WiFiComponent::log_discarded_scan_result_(const char *ssid, const uint8_t *
|
||||
#if ESPHOME_LOG_LEVEL >= ESPHOME_LOG_LEVEL_VERBOSE
|
||||
// Skip logging during roaming scans to avoid log buffer overflow
|
||||
// (roaming scans typically find many networks but only care about same-SSID APs)
|
||||
if (this->roaming_state_ == RoamingState::SCANNING) {
|
||||
if (this->is_roaming_scan_active()) {
|
||||
return;
|
||||
}
|
||||
char bssid_s[MAC_ADDRESS_PRETTY_BUFFER_SIZE];
|
||||
@@ -835,7 +835,7 @@ void WiFiComponent::loop() {
|
||||
|
||||
// Post-connect roaming: check for better AP
|
||||
if (this->post_connect_roaming_) {
|
||||
if (this->roaming_state_ == RoamingState::SCANNING) {
|
||||
if (this->is_roaming_scan_active()) {
|
||||
if (this->scan_done_) {
|
||||
this->process_roaming_scan_();
|
||||
}
|
||||
@@ -2152,7 +2152,7 @@ void WiFiComponent::retry_connect() {
|
||||
// Roam connection failed - transition to reconnecting
|
||||
ESP_LOGD(TAG, "Roam failed, reconnecting (attempt %u/%u)", this->roaming_attempts_, ROAMING_MAX_ATTEMPTS);
|
||||
this->roaming_state_ = RoamingState::RECONNECTING;
|
||||
} else if (this->roaming_state_ == RoamingState::SCANNING) {
|
||||
} else if (this->is_roaming_scan_active()) {
|
||||
// Disconnected during roam scan - transition to RECONNECTING so the attempts
|
||||
// counter is preserved when reconnection succeeds (IDLE would reset it)
|
||||
ESP_LOGD(TAG, "Disconnected during roam scan (attempt %u/%u)", this->roaming_attempts_, ROAMING_MAX_ATTEMPTS);
|
||||
|
||||
@@ -475,6 +475,13 @@ class WiFiComponent final : public Component {
|
||||
|
||||
bool is_connected() const { return this->connected_; }
|
||||
|
||||
/// True while a post-connect roaming scan holds the radio off-channel.
|
||||
bool is_roaming_scan_active() const { return this->roaming_state_ == RoamingState::SCANNING; }
|
||||
|
||||
/// True while a post-connect roam is in progress (scanning off-channel, reassociating,
|
||||
/// or recovering from a failed roam).
|
||||
bool is_roaming() const { return this->roaming_state_ != RoamingState::IDLE; }
|
||||
|
||||
#ifdef USE_ESP32
|
||||
/// esp_netif handle of the station interface, used by network for default-route
|
||||
/// arbitration. nullptr until wifi_lazy_init_() has run.
|
||||
|
||||
@@ -717,7 +717,7 @@ bool WiFiComponent::wifi_scan_start_(bool passive) {
|
||||
static constexpr uint32_t SCAN_ACTIVE_MAX_DEFAULT_MS = 500;
|
||||
static constexpr uint32_t SCAN_ACTIVE_MIN_ROAMING_MS = 100;
|
||||
static constexpr uint32_t SCAN_ACTIVE_MAX_ROAMING_MS = 300;
|
||||
bool roaming = this->roaming_state_ == RoamingState::SCANNING;
|
||||
bool roaming = this->is_roaming_scan_active();
|
||||
if (passive) {
|
||||
config.scan_time.passive = roaming ? SCAN_PASSIVE_ROAMING_MS : SCAN_PASSIVE_DEFAULT_MS;
|
||||
} else {
|
||||
|
||||
@@ -1064,7 +1064,7 @@ bool WiFiComponent::wifi_scan_start_(bool passive) {
|
||||
// When scanning while connected (roaming), return to home channel between
|
||||
// each scanned channel to maintain the connection (helps with BLE/WiFi coexistence)
|
||||
#ifdef CONFIG_SOC_WIFI_SUPPORTED
|
||||
if (this->roaming_state_ == RoamingState::SCANNING) {
|
||||
if (this->is_roaming_scan_active()) {
|
||||
config.coex_background_scan = true;
|
||||
}
|
||||
#endif
|
||||
|
||||
Reference in New Issue
Block a user