diff --git a/libraries/WiFi/src/WiFiGeneric.cpp b/libraries/WiFi/src/WiFiGeneric.cpp index bb41dfa18c0938d5dab49805bf5462269d89279d..a94b14194148f5f24c795118f61965108cbd9b34 100644 --- a/libraries/WiFi/src/WiFiGeneric.cpp +++ b/libraries/WiFi/src/WiFiGeneric.cpp @@ -963,26 +963,26 @@ esp_err_t WiFiGenericClass::_eventCallback(arduino_event_t *event) WiFiSTAClass::_setStatus(WL_DISCONNECTED); } clearStatusBits(STA_CONNECTED_BIT | STA_HAS_IP_BIT | STA_HAS_IP6_BIT); - if(first_connect && ((reason == WIFI_REASON_AUTH_EXPIRE) || - (reason >= WIFI_REASON_BEACON_TIMEOUT))) - { - log_d("WiFi Reconnect Running"); - WiFi.disconnect(); - WiFi.begin(); + + bool DoReconnect = false; + if(reason == WIFI_REASON_ASSOC_LEAVE) { //Voluntarily disconnected. Don't reconnect! + } + else if(first_connect) { //Retry once for all failure reasons first_connect = false; + DoReconnect = true; + log_d("WiFi Reconnect Running"); } - else if(WiFi.getAutoReconnect()){ - if((reason == WIFI_REASON_AUTH_EXPIRE) || - (reason >= WIFI_REASON_BEACON_TIMEOUT && reason != WIFI_REASON_AUTH_FAIL)) - { - log_d("WiFi AutoReconnect Running"); - WiFi.disconnect(); - WiFi.begin(); - } + else if(WiFi.getAutoReconnect() && _isReconnectableReason(reason)) { + DoReconnect = true; + log_d("WiFi AutoReconnect Running"); } - else if (reason == WIFI_REASON_ASSOC_FAIL){ + else if(reason == WIFI_REASON_ASSOC_FAIL) { WiFiSTAClass::_setStatus(WL_CONNECT_FAILED); } + if(DoReconnect) { + WiFi.disconnect(); + WiFi.begin(); + } } else if(event->event_id == ARDUINO_EVENT_WIFI_STA_GOT_IP) { #if ARDUHAL_LOG_LEVEL >= ARDUHAL_LOG_LEVEL_DEBUG uint8_t * ip = (uint8_t *)&(event->event_info.got_ip.ip_info.ip.addr); @@ -1066,6 +1066,36 @@ esp_err_t WiFiGenericClass::_eventCallback(arduino_event_t *event) return ESP_OK; } +bool WiFiGenericClass::_isReconnectableReason(uint8_t reason) { + switch(reason) { + //Timeouts (retry) + case WIFI_REASON_AUTH_EXPIRE: + case WIFI_REASON_4WAY_HANDSHAKE_TIMEOUT: + case WIFI_REASON_GROUP_KEY_UPDATE_TIMEOUT: + case WIFI_REASON_802_1X_AUTH_FAILED: + case WIFI_REASON_HANDSHAKE_TIMEOUT: + //Transient error (reconnect) + case WIFI_REASON_AUTH_LEAVE: + case WIFI_REASON_ASSOC_EXPIRE: + case WIFI_REASON_ASSOC_TOOMANY: + case WIFI_REASON_NOT_AUTHED: + case WIFI_REASON_NOT_ASSOCED: + case WIFI_REASON_ASSOC_NOT_AUTHED: + case WIFI_REASON_MIC_FAILURE: + case WIFI_REASON_IE_IN_4WAY_DIFFERS: + case WIFI_REASON_INVALID_PMKID: + case WIFI_REASON_BEACON_TIMEOUT: + case WIFI_REASON_NO_AP_FOUND: + case WIFI_REASON_ASSOC_FAIL: + case WIFI_REASON_CONNECTION_FAIL: + case WIFI_REASON_AP_TSF_RESET: + case WIFI_REASON_ROAMING: + return true; + default: + return false; + } +} + /** * Return the current channel associated with the network * @return channel (1-13) diff --git a/libraries/WiFi/src/WiFiGeneric.h b/libraries/WiFi/src/WiFiGeneric.h index 62642b43dc746bbdaa0f9af5181810c164857ff1..2f670a34d058c97bd623f733f88c65738668dbe1 100644 --- a/libraries/WiFi/src/WiFiGeneric.h +++ b/libraries/WiFi/src/WiFiGeneric.h @@ -206,7 +206,10 @@ class WiFiGenericClass static int setStatusBits(int bits); static int clearStatusBits(int bits); - + + private: + static bool _isReconnectableReason(uint8_t reason); + public: static int hostByName(const char *aHostname, IPAddress &aResult);