diff --git a/esphome/components/wifi/wifi_component.h b/esphome/components/wifi/wifi_component.h index 130fcb8291..d92a7faeb3 100644 --- a/esphome/components/wifi/wifi_component.h +++ b/esphome/components/wifi/wifi_component.h @@ -750,24 +750,24 @@ class WiFiComponent : public Component { #endif // Bools and bitfields -#if defined(USE_WIFI_CONNECT_STATE_LISTENERS) || defined(USE_ESP8266) // Pending listener callbacks deferred from platform callbacks to main loop. struct { #ifdef USE_WIFI_CONNECT_STATE_LISTENERS // Deferred until state machine reaches STA_CONNECTED so wifi.connected // condition returns true in listener automations. bool connect_state : 1; -#endif #ifdef USE_ESP8266 - // ESP8266 callbacks run in SDK system context with ~2KB stack where - // calling arbitrary listener callbacks is unsafe. These flags defer - // listener notifications to wifi_loop_() which runs with full stack. - bool disconnect : 1; // STA disconnected, notify listeners - bool got_ip : 1; // Got IP, notify listeners - bool scan_complete : 1; // Scan complete, notify listeners + // ESP8266: also defer disconnect notification to main loop + bool disconnect : 1; +#endif +#endif +#if defined(USE_ESP8266) && defined(USE_WIFI_IP_STATE_LISTENERS) + bool got_ip : 1; +#endif +#if defined(USE_ESP8266) && defined(USE_WIFI_SCAN_RESULTS_LISTENERS) + bool scan_complete : 1; #endif } pending_{}; -#endif bool has_ap_{false}; #if defined(USE_WIFI_CONNECT_TRIGGER) || defined(USE_WIFI_DISCONNECT_TRIGGER) bool handled_connected_state_{false}; diff --git a/esphome/components/wifi/wifi_component_esp8266.cpp b/esphome/components/wifi/wifi_component_esp8266.cpp index 99b66a76d6..5026fbcb94 100644 --- a/esphome/components/wifi/wifi_component_esp8266.cpp +++ b/esphome/components/wifi/wifi_component_esp8266.cpp @@ -539,7 +539,9 @@ void WiFiComponent::wifi_event_callback(System_Event_t *event) { s_sta_connecting = false; // Store reason as error flag; defer listener callbacks to main loop global_wifi_component->error_from_callback_ = it.reason; +#ifdef USE_WIFI_CONNECT_STATE_LISTENERS global_wifi_component->pending_.disconnect = true; +#endif break; } case EVENT_STAMODE_AUTHMODE_CHANGE: { @@ -562,8 +564,10 @@ void WiFiComponent::wifi_event_callback(System_Event_t *event) { ESP_LOGV(TAG, "static_ip=%s gateway=%s netmask=%s", network::IPAddress(&it.ip).str_to(ip_buf), network::IPAddress(&it.gw).str_to(gw_buf), network::IPAddress(&it.mask).str_to(mask_buf)); s_sta_got_ip = true; +#ifdef USE_WIFI_IP_STATE_LISTENERS // Defer listener callbacks to main loop - system context has limited stack global_wifi_component->pending_.got_ip = true; +#endif break; } case EVENT_STAMODE_DHCP_TIMEOUT: { @@ -773,7 +777,9 @@ void WiFiComponent::wifi_scan_done_callback_(void *arg, STATUS status) { ESP_LOGV(TAG, "Scan complete: %zu found, %zu stored%s", total, this->scan_result_.size(), needs_full ? "" : " (filtered)"); this->scan_done_ = true; +#ifdef USE_WIFI_SCAN_RESULTS_LISTENERS this->pending_.scan_complete = true; // Defer listener callbacks to main loop +#endif } #ifdef USE_WIFI_AP @@ -966,29 +972,26 @@ void WiFiComponent::process_pending_callbacks_() { // to main loop context (full stack). Connect state listeners are handled // by notify_connect_state_listeners_() in the shared state machine code. - // Notify listeners for disconnect event (logging already done in callback) +#ifdef USE_WIFI_CONNECT_STATE_LISTENERS if (this->pending_.disconnect) { this->pending_.disconnect = false; -#ifdef USE_WIFI_CONNECT_STATE_LISTENERS this->notify_disconnect_state_listeners_(); -#endif } +#endif - // Notify listeners for got IP event (logging already done in callback) +#ifdef USE_WIFI_IP_STATE_LISTENERS if (this->pending_.got_ip) { this->pending_.got_ip = false; -#ifdef USE_WIFI_IP_STATE_LISTENERS this->notify_ip_state_listeners_(); -#endif } +#endif - // Notify listeners for scan complete (logging already done in callback) +#ifdef USE_WIFI_SCAN_RESULTS_LISTENERS if (this->pending_.scan_complete) { this->pending_.scan_complete = false; -#ifdef USE_WIFI_SCAN_RESULTS_LISTENERS this->notify_scan_results_listeners_(); -#endif } +#endif } } // namespace esphome::wifi