mirror of
https://github.com/esphome/esphome.git
synced 2026-08-22 22:26:21 +00:00
[wifi] Fix ESP8266 crash in cnx_node_search when lwIP transmits after disconnect (#18333)
This commit is contained in:
@@ -136,10 +136,21 @@ bool WiFiComponent::wifi_apply_power_save_() {
|
|||||||
https://github.com/d-a-v/Arduino/blob/0e7d21e17144cfc5f53c016191daca8723e89ee8/libraries/ESP8266WiFi/src/ESP8266WiFiSTA.cpp#L251
|
https://github.com/d-a-v/Arduino/blob/0e7d21e17144cfc5f53c016191daca8723e89ee8/libraries/ESP8266WiFi/src/ESP8266WiFiSTA.cpp#L251
|
||||||
*/
|
*/
|
||||||
#undef netif_set_addr // need to call lwIP-v1.4 netif_set_addr()
|
#undef netif_set_addr // need to call lwIP-v1.4 netif_set_addr()
|
||||||
|
#undef netif_set_down // need to call lwIP-v1.4 netif_set_down()
|
||||||
extern "C" {
|
extern "C" {
|
||||||
struct netif *eagle_lwip_getif(int netif_index);
|
struct netif *eagle_lwip_getif(int netif_index);
|
||||||
void netif_set_addr(struct netif *netif, const ip4_addr_t *ip, const ip4_addr_t *netmask, const ip4_addr_t *gw);
|
void netif_set_addr(struct netif *netif, const ip4_addr_t *ip, const ip4_addr_t *netmask, const ip4_addr_t *gw);
|
||||||
|
void netif_set_down(struct netif *netif);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// The SDK can free its WiFi connection node before taking the STA netif down, letting lwIP
|
||||||
|
// timers (e.g. IGMP reports armed by mDNS) transmit into the dead driver and crash in
|
||||||
|
// cnx_node_search; taking the netif down first makes the glue drop such frames (#18308).
|
||||||
|
static void sta_netif_down() {
|
||||||
|
struct netif *iface = eagle_lwip_getif(STATION_IF);
|
||||||
|
if (iface != nullptr)
|
||||||
|
netif_set_down(iface);
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
bool WiFiComponent::wifi_sta_ip_config_(const optional<ManualIP> &manual_ip) {
|
bool WiFiComponent::wifi_sta_ip_config_(const optional<ManualIP> &manual_ip) {
|
||||||
@@ -523,6 +534,9 @@ void WiFiComponent::wifi_event_callback(System_Event_t *event) {
|
|||||||
global_wifi_component->sta_state_ = static_cast<uint8_t>(ESP8266WiFiSTAState::ERROR_FAILED);
|
global_wifi_component->sta_state_ = static_cast<uint8_t>(ESP8266WiFiSTAState::ERROR_FAILED);
|
||||||
}
|
}
|
||||||
global_wifi_component->error_from_callback_ = true;
|
global_wifi_component->error_from_callback_ = true;
|
||||||
|
#if LWIP_VERSION_MAJOR != 1
|
||||||
|
sta_netif_down();
|
||||||
|
#endif
|
||||||
#ifdef USE_WIFI_CONNECT_STATE_LISTENERS
|
#ifdef USE_WIFI_CONNECT_STATE_LISTENERS
|
||||||
global_wifi_component->pending_.disconnect = true;
|
global_wifi_component->pending_.disconnect = true;
|
||||||
#endif
|
#endif
|
||||||
@@ -536,6 +550,9 @@ void WiFiComponent::wifi_event_callback(System_Event_t *event) {
|
|||||||
// https://lbsfilm.at/blog/wpa2-authenticationmode-downgrade-in-espressif-microprocessors
|
// https://lbsfilm.at/blog/wpa2-authenticationmode-downgrade-in-espressif-microprocessors
|
||||||
if (it.old_mode != AUTH_OPEN && it.new_mode == AUTH_OPEN) {
|
if (it.old_mode != AUTH_OPEN && it.new_mode == AUTH_OPEN) {
|
||||||
ESP_LOGW(TAG, "Potential Authmode downgrade detected, disconnecting");
|
ESP_LOGW(TAG, "Potential Authmode downgrade detected, disconnecting");
|
||||||
|
#if LWIP_VERSION_MAJOR != 1
|
||||||
|
sta_netif_down();
|
||||||
|
#endif
|
||||||
wifi_station_disconnect();
|
wifi_station_disconnect();
|
||||||
global_wifi_component->error_from_callback_ = true;
|
global_wifi_component->error_from_callback_ = true;
|
||||||
}
|
}
|
||||||
@@ -719,8 +736,12 @@ bool WiFiComponent::wifi_scan_start_(bool passive) {
|
|||||||
bool WiFiComponent::wifi_disconnect_() {
|
bool WiFiComponent::wifi_disconnect_() {
|
||||||
bool ret = true;
|
bool ret = true;
|
||||||
// Only call disconnect if interface is up
|
// Only call disconnect if interface is up
|
||||||
if (wifi_get_opmode() & WIFI_STA)
|
if (wifi_get_opmode() & WIFI_STA) {
|
||||||
|
#if LWIP_VERSION_MAJOR != 1
|
||||||
|
sta_netif_down();
|
||||||
|
#endif
|
||||||
ret = wifi_station_disconnect();
|
ret = wifi_station_disconnect();
|
||||||
|
}
|
||||||
station_config conf{};
|
station_config conf{};
|
||||||
memset(&conf, 0, sizeof(conf));
|
memset(&conf, 0, sizeof(conf));
|
||||||
ETS_UART_INTR_DISABLE();
|
ETS_UART_INTR_DISABLE();
|
||||||
|
|||||||
Reference in New Issue
Block a user