From ec2c59f99935bb95e3af5a1fdb55f4a480493005 Mon Sep 17 00:00:00 2001 From: "sanket.wadekar" Date: Fri, 25 Nov 2022 13:56:45 +0530 Subject: [PATCH 1/6] Fixed issue where esp32 won't reconnect to WiFi AP if the AP was restarted --- libraries/WiFi/src/WiFiGeneric.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/libraries/WiFi/src/WiFiGeneric.cpp b/libraries/WiFi/src/WiFiGeneric.cpp index a94b1419414..3caa0451864 100644 --- a/libraries/WiFi/src/WiFiGeneric.cpp +++ b/libraries/WiFi/src/WiFiGeneric.cpp @@ -1068,6 +1068,7 @@ esp_err_t WiFiGenericClass::_eventCallback(arduino_event_t *event) bool WiFiGenericClass::_isReconnectableReason(uint8_t reason) { switch(reason) { + case WIFI_REASON_UNSPECIFIED: //Timeouts (retry) case WIFI_REASON_AUTH_EXPIRE: case WIFI_REASON_4WAY_HANDSHAKE_TIMEOUT: From eada20c70dab2b899047ac4e1528b5da442b7a74 Mon Sep 17 00:00:00 2001 From: "pedro.minatel" Date: Thu, 15 Dec 2022 13:50:31 +0000 Subject: [PATCH 2/6] Added the autoReconnect condition and removed the reconnect reason --- libraries/WiFi/src/WiFiGeneric.cpp | 35 ++---------------------------- libraries/WiFi/src/WiFiGeneric.h | 3 --- libraries/WiFi/src/WiFiSTA.cpp | 11 ++++++++++ 3 files changed, 13 insertions(+), 36 deletions(-) diff --git a/libraries/WiFi/src/WiFiGeneric.cpp b/libraries/WiFi/src/WiFiGeneric.cpp index 3caa0451864..ba41fa9a22e 100644 --- a/libraries/WiFi/src/WiFiGeneric.cpp +++ b/libraries/WiFi/src/WiFiGeneric.cpp @@ -972,9 +972,9 @@ esp_err_t WiFiGenericClass::_eventCallback(arduino_event_t *event) DoReconnect = true; log_d("WiFi Reconnect Running"); } - else if(WiFi.getAutoReconnect() && _isReconnectableReason(reason)) { + else if(WiFi.getAutoReconnect()) { DoReconnect = true; - log_d("WiFi AutoReconnect Running"); + log_d("WiFi Auto Reconnect Running"); } else if(reason == WIFI_REASON_ASSOC_FAIL) { WiFiSTAClass::_setStatus(WL_CONNECT_FAILED); @@ -1066,37 +1066,6 @@ esp_err_t WiFiGenericClass::_eventCallback(arduino_event_t *event) return ESP_OK; } -bool WiFiGenericClass::_isReconnectableReason(uint8_t reason) { - switch(reason) { - case WIFI_REASON_UNSPECIFIED: - //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 2f670a34d05..69dc26dbbc0 100644 --- a/libraries/WiFi/src/WiFiGeneric.h +++ b/libraries/WiFi/src/WiFiGeneric.h @@ -207,9 +207,6 @@ 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); diff --git a/libraries/WiFi/src/WiFiSTA.cpp b/libraries/WiFi/src/WiFiSTA.cpp index 7bcafea1d3e..1bfe8f8bc01 100644 --- a/libraries/WiFi/src/WiFiSTA.cpp +++ b/libraries/WiFi/src/WiFiSTA.cpp @@ -278,6 +278,8 @@ wl_status_t WiFiSTAClass::begin(const char* ssid, const char *passphrase, int32_ log_e("connect failed!"); return WL_CONNECT_FAILED; } + // Set to auto reconnect + WiFi.setAutoReconnect(true); } return status(); @@ -317,6 +319,8 @@ wl_status_t WiFiSTAClass::begin() log_e("connect failed! 0x%x", err); return WL_CONNECT_FAILED; } + // Set to auto reconnect + WiFi.setAutoReconnect(true); } return status(); @@ -330,6 +334,8 @@ bool WiFiSTAClass::reconnect() { if(WiFi.getMode() & WIFI_MODE_STA) { if(esp_wifi_disconnect() == ESP_OK) { + // Set to auto reconnect + WiFi.setAutoReconnect(true); return esp_wifi_connect() == ESP_OK; } } @@ -360,6 +366,10 @@ bool WiFiSTAClass::disconnect(bool wifioff, bool eraseap) if(wifioff) { return WiFi.enableSTA(false); } + // Disable the auto reconnect in case of disconnection from the user + if(WiFi.getAutoReconnect()){ + WiFi.setAutoReconnect(false); + } return true; } @@ -460,6 +470,7 @@ bool WiFiSTAClass::getAutoConnect() */ bool WiFiSTAClass::setAutoReconnect(bool autoReconnect) { + log_d("Set Auto Reconnect to %d", autoReconnect); _autoReconnect = autoReconnect; return true; } From 0d33a6ffe33032de3ff2ea33443688cd0a1a3787 Mon Sep 17 00:00:00 2001 From: "pedro.minatel" Date: Fri, 16 Dec 2022 10:42:30 +0000 Subject: [PATCH 3/6] Chenges on the WiFi reconnection and added new example --- .../WiFi/examples/WiFiClientConnect/README.md | 75 +++++++++++++ .../WiFiClientConnect/WiFiClientConnect.ino | 100 ++++++++++++++++++ libraries/WiFi/src/WiFiGeneric.cpp | 77 +++++++------- libraries/WiFi/src/WiFiSTA.cpp | 10 -- 4 files changed, 216 insertions(+), 46 deletions(-) create mode 100644 libraries/WiFi/examples/WiFiClientConnect/README.md create mode 100644 libraries/WiFi/examples/WiFiClientConnect/WiFiClientConnect.ino diff --git a/libraries/WiFi/examples/WiFiClientConnect/README.md b/libraries/WiFi/examples/WiFiClientConnect/README.md new file mode 100644 index 00000000000..5e6760a9bee --- /dev/null +++ b/libraries/WiFi/examples/WiFiClientConnect/README.md @@ -0,0 +1,75 @@ +# WiFiClientConnect Example + +This example demonstrates how to connect to the WiFi and manage the status and disconnection from STA. + +# Supported Targets + +Currently, this example supports the following targets. + +| Supported Targets | ESP32 | ESP32-S2 | ESP32-C3 | +| ----------------- | ----- | -------- | -------- | + +## How to Use Example + +* How to install the Arduino IDE: [Install Arduino IDE](https://github.com/espressif/arduino-esp32/tree/master/docs/arduino-ide). + +#### Using Arduino IDE + +* Before Compile/Verify, select the correct board: `Tools -> Board`. +* Select the COM port: `Tools -> Port: xxx` where the `xxx` is the detected COM port. + +#### Using Platform IO + +* Select the COM port: `Devices` or set the `upload_port`` option on the `platformio.ini` file. + +## Example/Log Output + +``` +[WiFi] Connecting to MyWiFiNetwork +[ 66][D][WiFiGeneric.cpp:929] _eventCallback(): Arduino Event: 0 - WIFI_READY +[ 150][V][WiFiGeneric.cpp:338] _arduino_event_cb(): STA Started +[ 151][V][WiFiGeneric.cpp:97] set_esp_interface_ip(): Configuring Station static IP: 0.0.0.0, MASK: 0.0.0.0, GW: 0.0.0.0 +[ 151][D][WiFiGeneric.cpp:929] _eventCallback(): Arduino Event: 2 - STA_START +[WiFi] WiFi is disconnected +[ 234][V][WiFiGeneric.cpp:353] _arduino_event_cb(): STA Connected: SSID: MyWiFiNetwork, BSSID: xx:xx:xx:xx:xx:xx, Channel: 8, Auth: WPA2_PSK +[ 235][D][WiFiGeneric.cpp:929] _eventCallback(): Arduino Event: 4 - STA_CONNECTED +[ 560][V][WiFiGeneric.cpp:367] _arduino_event_cb(): STA Got New IP:192.168.68.114 +[ 561][D][WiFiGeneric.cpp:929] _eventCallback(): Arduino Event: 7 - STA_GOT_IP +[ 564][D][WiFiGeneric.cpp:1004] _eventCallback(): STA IP: 192.168.68.114, MASK: 255.255.255.0, GW: 192.168.68.1 +[WiFi] WiFi is connected! +[WiFi] IP address: 192.168.68.114 +[WiFi] Disconnecting from WiFi! +[ 2633][V][WiFiGeneric.cpp:360] _arduino_event_cb(): STA Disconnected: SSID: MyWiFiNetwork, BSSID: xx:xx:xx:xx:xx:xx, Reason: 8 +[ 2634][D][WiFiGeneric.cpp:929] _eventCallback(): Arduino Event: 5 - STA_DISCONNECTED +[ 2635][V][WiFiGeneric.cpp:341] _arduino_event_cb(): STA Stopped +[ 2641][W][WiFiGeneric.cpp:953] _eventCallback(): Reason: 8 - ASSOC_LEAVE +[ 2654][D][WiFiGeneric.cpp:975] _eventCallback(): WiFi the station is disconnected +[ 2661][D][WiFiGeneric.cpp:929] _eventCallback(): Arduino Event: 3 - STA_STOP +[WiFi] Disconnected from WiFi! +... +``` + +## Troubleshooting + +***Important: Be sure you're using a good quality USB cable that has enough power for your project.*** + +* **Programming Fail:** If the programming/flash procedure fails, try to reduce the serial connection speed. +* **COM port not detected:** Check the USB cable connection and the USB to Serial driver installation. + +If the error persists, you can ask for help at the official [ESP32 forum](https://esp32.com) or see [Contribute](#contribute). + +## Contribute + +To know how to contribute to this project, see [How to contribute.](https://github.com/espressif/arduino-esp32/blob/master/CONTRIBUTING.rst) + +If you have any **feedback** or **issue** to report on this example/library, please open an issue or fix it by creating a new PR. Contributions are more than welcome! + +Before creating a new issue, be sure to try Troubleshooting and check if the same issue was already created by someone else. + +## Resources + +* Arduino-ESP32 Official Repository: [espressif/arduino-esp32](https://github.com/espressif/arduino-esp32) +* ESP32 Datasheet: [Link to datasheet](https://www.espressif.com/sites/default/files/documentation/esp32_datasheet_en.pdf) +* ESP32-S2 Datasheet: [Link to datasheet](https://www.espressif.com/sites/default/files/documentation/esp32-s2_datasheet_en.pdf) +* ESP32-C3 Datasheet: [Link to datasheet](https://www.espressif.com/sites/default/files/documentation/esp32-c3_datasheet_en.pdf) +* Official ESP-IDF documentation: [ESP-IDF](https://idf.espressif.com) diff --git a/libraries/WiFi/examples/WiFiClientConnect/WiFiClientConnect.ino b/libraries/WiFi/examples/WiFiClientConnect/WiFiClientConnect.ino new file mode 100644 index 00000000000..40395803cc2 --- /dev/null +++ b/libraries/WiFi/examples/WiFiClientConnect/WiFiClientConnect.ino @@ -0,0 +1,100 @@ +/* Wi-Fi STA Connect and Disconnect Example + + This example code is in the Public Domain (or CC0 licensed, at your option.) + + Unless required by applicable law or agreed to in writing, this + software is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR + CONDITIONS OF ANY KIND, either express or implied. + +*/ +#include + +const char* ssid = "your-ssid"; +const char* password = "your-password"; + +int btnGPIO = 0; +int btnState = false; + +void setup() +{ + Serial.begin(115200); + delay(10); + + // Set GPIO0 Boot button as input + pinMode(btnGPIO, INPUT); + + // We start by connecting to a WiFi network + // To debug, please enable Core Debug Level to Verbose + + Serial.println(); + Serial.print("[WiFi] Connecting to "); + Serial.println(ssid); + + WiFi.begin(ssid, password); +// Auto reconnect is set true as default +// To set auto connect off, use the following function +// WiFi.setAutoReconnect(false); + + // Will try for about 10 seconds (20x 500ms) + int tryDelay = 500; + int numberOfTries = 20; + + // Wait for the WiFi event + while (true) { + + switch(WiFi.status()) { + case WL_NO_SSID_AVAIL: + Serial.println("[WiFi] SSID not found"); + break; + case WL_CONNECT_FAILED: + Serial.print("[WiFi] Failed - WiFi not connected! Reason: "); + return; + break; + case WL_CONNECTION_LOST: + Serial.println("[WiFi] Connection was lost"); + break; + case WL_SCAN_COMPLETED: + Serial.println("[WiFi] Scan is completed"); + break; + case WL_DISCONNECTED: + Serial.println("[WiFi] WiFi is disconnected"); + break; + case WL_CONNECTED: + Serial.println("[WiFi] WiFi is connected!"); + Serial.print("[WiFi] IP address: "); + Serial.println(WiFi.localIP()); + return; + break; + default: + Serial.print("[WiFi] WiFi Status: "); + Serial.println(WiFi.status()); + break; + } + delay(tryDelay); + + if(numberOfTries <= 0){ + Serial.print("[WiFi] Failed to connect to WiFi!"); + // Use disconnect function to force stop trying to connect + WiFi.disconnect(); + return; + } else { + numberOfTries--; + } + } +} + +void loop() +{ + // Read the button state + btnState = digitalRead(btnGPIO); + + if (btnState == LOW) { + // Disconnect from WiFi + Serial.println("[WiFi] Disconnecting from WiFi!"); + // This function will disconnect and turn off the WiFi (NVS WiFi data is kept) + if(WiFi.disconnect(true, false)){ + Serial.println("[WiFi] Disconnected from WiFi!"); + } + delay(1000); + } +} \ No newline at end of file diff --git a/libraries/WiFi/src/WiFiGeneric.cpp b/libraries/WiFi/src/WiFiGeneric.cpp index 81ef3611f52..82b2283160e 100644 --- a/libraries/WiFi/src/WiFiGeneric.cpp +++ b/libraries/WiFi/src/WiFiGeneric.cpp @@ -188,20 +188,18 @@ esp_err_t set_esp_interface_ip(esp_interface_t interface, IPAddress local_ip=IPA lease.start_ip.addr = _byte_swap32(lease.start_ip.addr); lease.end_ip.addr = _byte_swap32(lease.end_ip.addr); log_v("DHCP Server Range: %s to %s", IPAddress(lease.start_ip.addr).toString().c_str(), IPAddress(lease.end_ip.addr).toString().c_str()); - err = esp_netif_dhcps_option( - esp_netif, - ESP_NETIF_OP_SET, - ESP_NETIF_SUBNET_MASK, + err = tcpip_adapter_dhcps_option( + (tcpip_adapter_dhcp_option_mode_t)TCPIP_ADAPTER_OP_SET, + (tcpip_adapter_dhcp_option_id_t)ESP_NETIF_SUBNET_MASK, (void*)&info.netmask.addr, sizeof(info.netmask.addr) ); if(err){ log_e("DHCPS Set Netmask Failed! 0x%04x", err); return err; } - err = esp_netif_dhcps_option( - esp_netif, - ESP_NETIF_OP_SET, - ESP_NETIF_REQUESTED_IP_ADDRESS, + err = tcpip_adapter_dhcps_option( + (tcpip_adapter_dhcp_option_mode_t)TCPIP_ADAPTER_OP_SET, + (tcpip_adapter_dhcp_option_id_t)REQUESTED_IP_ADDRESS, (void*)&lease, sizeof(dhcps_lease_t) ); if(err){ @@ -953,35 +951,45 @@ esp_err_t WiFiGenericClass::_eventCallback(arduino_event_t *event) if(!reason) reason = WIFI_REASON_UNSPECIFIED; log_w("Reason: %u - %s", reason, reason2str(reason)); + // Get auto reconnect status + bool DoReconnect = WiFi.getAutoReconnect(); if(reason == WIFI_REASON_NO_AP_FOUND) { WiFiSTAClass::_setStatus(WL_NO_SSID_AVAIL); } else if((reason == WIFI_REASON_AUTH_FAIL) && !first_connect){ WiFiSTAClass::_setStatus(WL_CONNECT_FAILED); + DoReconnect = false; } else if(reason == WIFI_REASON_BEACON_TIMEOUT || reason == WIFI_REASON_HANDSHAKE_TIMEOUT) { WiFiSTAClass::_setStatus(WL_CONNECTION_LOST); + } else if(reason == WIFI_REASON_4WAY_HANDSHAKE_TIMEOUT) { + WiFiSTAClass::_setStatus(WL_CONNECT_FAILED); + DoReconnect = false; } else if(reason == WIFI_REASON_AUTH_EXPIRE) { - + WiFiSTAClass::_setStatus(WL_CONNECT_FAILED); + DoReconnect = false; } else { WiFiSTAClass::_setStatus(WL_DISCONNECTED); } clearStatusBits(STA_CONNECTED_BIT | STA_HAS_IP_BIT | STA_HAS_IP6_BIT); - bool DoReconnect = false; - if(reason == WIFI_REASON_ASSOC_LEAVE) { //Voluntarily disconnected. Don't reconnect! + if(reason == WIFI_REASON_ASSOC_LEAVE) { //Voluntarily disconnected. Don't reconnect! + log_d("WiFi the station is disconnected"); + WiFiSTAClass::_setStatus(WL_CONNECT_FAILED); + WiFi.disconnect(); + DoReconnect = false; } else if(first_connect) { //Retry once for all failure reasons first_connect = false; - DoReconnect = true; - log_d("WiFi Reconnect Running"); - } - else if(WiFi.getAutoReconnect()) { - DoReconnect = true; - log_d("WiFi Auto Reconnect Running"); + // Force reconnect + WiFi.disconnect(); + WiFi.begin(); } else if(reason == WIFI_REASON_ASSOC_FAIL) { WiFiSTAClass::_setStatus(WL_CONNECT_FAILED); + DoReconnect = false; } + // Try to reconnect depending on the reason if(DoReconnect) { + log_d("WiFi Auto Reconnect Running"); WiFi.disconnect(); WiFi.begin(); } @@ -1419,31 +1427,28 @@ static void wifi_dns_found_callback(const char *name, const ip_addr_t *ipaddr, v } /** - * Resolve the given hostname to an IP address. If passed hostname is an IP address, it will be parsed into IPAddress structure. - * @param aHostname Name to be resolved or string containing IP address + * Resolve the given hostname to an IP address. + * @param aHostname Name to be resolved * @param aResult IPAddress structure to store the returned IP address * @return 1 if aIPAddrString was successfully converted to an IP address, * else error code */ int WiFiGenericClass::hostByName(const char* aHostname, IPAddress& aResult) { - if (!aResult.fromString(aHostname)) - { - ip_addr_t addr; - aResult = static_cast(0); - waitStatusBits(WIFI_DNS_IDLE_BIT, 16000); - clearStatusBits(WIFI_DNS_IDLE_BIT | WIFI_DNS_DONE_BIT); - err_t err = dns_gethostbyname(aHostname, &addr, &wifi_dns_found_callback, &aResult); - if(err == ERR_OK && addr.u_addr.ip4.addr) { - aResult = addr.u_addr.ip4.addr; - } else if(err == ERR_INPROGRESS) { - waitStatusBits(WIFI_DNS_DONE_BIT, 15000); //real internal timeout in lwip library is 14[s] - clearStatusBits(WIFI_DNS_DONE_BIT); - } - setStatusBits(WIFI_DNS_IDLE_BIT); - if((uint32_t)aResult == 0){ - log_e("DNS Failed for %s", aHostname); - } + ip_addr_t addr; + aResult = static_cast(0); + waitStatusBits(WIFI_DNS_IDLE_BIT, 16000); + clearStatusBits(WIFI_DNS_IDLE_BIT | WIFI_DNS_DONE_BIT); + err_t err = dns_gethostbyname(aHostname, &addr, &wifi_dns_found_callback, &aResult); + if(err == ERR_OK && addr.u_addr.ip4.addr) { + aResult = addr.u_addr.ip4.addr; + } else if(err == ERR_INPROGRESS) { + waitStatusBits(WIFI_DNS_DONE_BIT, 15000); //real internal timeout in lwip library is 14[s] + clearStatusBits(WIFI_DNS_DONE_BIT); + } + setStatusBits(WIFI_DNS_IDLE_BIT); + if((uint32_t)aResult == 0){ + log_e("DNS Failed for %s", aHostname); } return (uint32_t)aResult != 0; } diff --git a/libraries/WiFi/src/WiFiSTA.cpp b/libraries/WiFi/src/WiFiSTA.cpp index 1bfe8f8bc01..44e9e3c74da 100644 --- a/libraries/WiFi/src/WiFiSTA.cpp +++ b/libraries/WiFi/src/WiFiSTA.cpp @@ -278,8 +278,6 @@ wl_status_t WiFiSTAClass::begin(const char* ssid, const char *passphrase, int32_ log_e("connect failed!"); return WL_CONNECT_FAILED; } - // Set to auto reconnect - WiFi.setAutoReconnect(true); } return status(); @@ -319,8 +317,6 @@ wl_status_t WiFiSTAClass::begin() log_e("connect failed! 0x%x", err); return WL_CONNECT_FAILED; } - // Set to auto reconnect - WiFi.setAutoReconnect(true); } return status(); @@ -334,8 +330,6 @@ bool WiFiSTAClass::reconnect() { if(WiFi.getMode() & WIFI_MODE_STA) { if(esp_wifi_disconnect() == ESP_OK) { - // Set to auto reconnect - WiFi.setAutoReconnect(true); return esp_wifi_connect() == ESP_OK; } } @@ -366,10 +360,6 @@ bool WiFiSTAClass::disconnect(bool wifioff, bool eraseap) if(wifioff) { return WiFi.enableSTA(false); } - // Disable the auto reconnect in case of disconnection from the user - if(WiFi.getAutoReconnect()){ - WiFi.setAutoReconnect(false); - } return true; } From 682d73c8bfda28e563f696d293c2531039fcf491 Mon Sep 17 00:00:00 2001 From: "pedro.minatel" Date: Fri, 16 Dec 2022 10:49:01 +0000 Subject: [PATCH 4/6] Added new line at the end --- libraries/WiFi/examples/WiFiClientConnect/WiFiClientConnect.ino | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libraries/WiFi/examples/WiFiClientConnect/WiFiClientConnect.ino b/libraries/WiFi/examples/WiFiClientConnect/WiFiClientConnect.ino index 40395803cc2..687258b3e09 100644 --- a/libraries/WiFi/examples/WiFiClientConnect/WiFiClientConnect.ino +++ b/libraries/WiFi/examples/WiFiClientConnect/WiFiClientConnect.ino @@ -97,4 +97,4 @@ void loop() } delay(1000); } -} \ No newline at end of file +} From a920587203fb6e9b6309078e6a3abf59c90ecf06 Mon Sep 17 00:00:00 2001 From: "pedro.minatel" Date: Fri, 16 Dec 2022 15:51:42 +0000 Subject: [PATCH 5/6] Changes reverted with some minor changes. New example remained --- libraries/WiFi/src/WiFiGeneric.cpp | 63 +++++++++++++++++++++--------- libraries/WiFi/src/WiFiGeneric.h | 3 ++ libraries/WiFi/src/WiFiSTA.cpp | 11 +++++- 3 files changed, 57 insertions(+), 20 deletions(-) diff --git a/libraries/WiFi/src/WiFiGeneric.cpp b/libraries/WiFi/src/WiFiGeneric.cpp index 82b2283160e..75ab169008b 100644 --- a/libraries/WiFi/src/WiFiGeneric.cpp +++ b/libraries/WiFi/src/WiFiGeneric.cpp @@ -951,45 +951,39 @@ esp_err_t WiFiGenericClass::_eventCallback(arduino_event_t *event) if(!reason) reason = WIFI_REASON_UNSPECIFIED; log_w("Reason: %u - %s", reason, reason2str(reason)); - // Get auto reconnect status - bool DoReconnect = WiFi.getAutoReconnect(); if(reason == WIFI_REASON_NO_AP_FOUND) { WiFiSTAClass::_setStatus(WL_NO_SSID_AVAIL); } else if((reason == WIFI_REASON_AUTH_FAIL) && !first_connect){ WiFiSTAClass::_setStatus(WL_CONNECT_FAILED); - DoReconnect = false; } else if(reason == WIFI_REASON_BEACON_TIMEOUT || reason == WIFI_REASON_HANDSHAKE_TIMEOUT) { WiFiSTAClass::_setStatus(WL_CONNECTION_LOST); - } else if(reason == WIFI_REASON_4WAY_HANDSHAKE_TIMEOUT) { - WiFiSTAClass::_setStatus(WL_CONNECT_FAILED); - DoReconnect = false; } else if(reason == WIFI_REASON_AUTH_EXPIRE) { - WiFiSTAClass::_setStatus(WL_CONNECT_FAILED); - DoReconnect = false; + } else { WiFiSTAClass::_setStatus(WL_DISCONNECTED); } clearStatusBits(STA_CONNECTED_BIT | STA_HAS_IP_BIT | STA_HAS_IP6_BIT); - if(reason == WIFI_REASON_ASSOC_LEAVE) { //Voluntarily disconnected. Don't reconnect! - log_d("WiFi the station is disconnected"); - WiFiSTAClass::_setStatus(WL_CONNECT_FAILED); - WiFi.disconnect(); - DoReconnect = false; + bool DoReconnect = false; + if(reason == WIFI_REASON_ASSOC_LEAVE) { + WiFiSTAClass::_setStatus(WL_DISCONNECTED); //Voluntarily disconnected. Don't reconnect! } else if(first_connect) { //Retry once for all failure reasons first_connect = false; - // Force reconnect - WiFi.disconnect(); - WiFi.begin(); + DoReconnect = true; + log_d("WiFi Reconnect Running"); + } + else if(WiFi.getAutoReconnect() && _isReconnectableReason(reason)) { + DoReconnect = true; + log_d("WiFi AutoReconnect Running"); } else if(reason == WIFI_REASON_ASSOC_FAIL) { WiFiSTAClass::_setStatus(WL_CONNECT_FAILED); - DoReconnect = false; } - // Try to reconnect depending on the reason + else if(reason == WIFI_REASON_AUTH_EXPIRE) { + WiFiSTAClass::_setStatus(WL_CONNECT_FAILED); + } if(DoReconnect) { - log_d("WiFi Auto Reconnect Running"); WiFi.disconnect(); WiFi.begin(); } @@ -1076,6 +1070,37 @@ esp_err_t WiFiGenericClass::_eventCallback(arduino_event_t *event) return ESP_OK; } +bool WiFiGenericClass::_isReconnectableReason(uint8_t reason) { + switch(reason) { + case WIFI_REASON_UNSPECIFIED: + //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 69dc26dbbc0..2f670a34d05 100644 --- a/libraries/WiFi/src/WiFiGeneric.h +++ b/libraries/WiFi/src/WiFiGeneric.h @@ -207,6 +207,9 @@ 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); diff --git a/libraries/WiFi/src/WiFiSTA.cpp b/libraries/WiFi/src/WiFiSTA.cpp index 44e9e3c74da..e9466f78103 100644 --- a/libraries/WiFi/src/WiFiSTA.cpp +++ b/libraries/WiFi/src/WiFiSTA.cpp @@ -278,6 +278,8 @@ wl_status_t WiFiSTAClass::begin(const char* ssid, const char *passphrase, int32_ log_e("connect failed!"); return WL_CONNECT_FAILED; } + // Set to auto reconnect + WiFi.setAutoReconnect(true); } return status(); @@ -317,6 +319,8 @@ wl_status_t WiFiSTAClass::begin() log_e("connect failed! 0x%x", err); return WL_CONNECT_FAILED; } + // Set to auto reconnect + WiFi.setAutoReconnect(true); } return status(); @@ -330,6 +334,8 @@ bool WiFiSTAClass::reconnect() { if(WiFi.getMode() & WIFI_MODE_STA) { if(esp_wifi_disconnect() == ESP_OK) { + // Set to auto reconnect + WiFi.setAutoReconnect(true); return esp_wifi_connect() == ESP_OK; } } @@ -360,6 +366,10 @@ bool WiFiSTAClass::disconnect(bool wifioff, bool eraseap) if(wifioff) { return WiFi.enableSTA(false); } + // Disable the auto reconnect in case of disconnection from the user + if(WiFi.getAutoReconnect()){ + WiFi.setAutoReconnect(false); + } return true; } @@ -460,7 +470,6 @@ bool WiFiSTAClass::getAutoConnect() */ bool WiFiSTAClass::setAutoReconnect(bool autoReconnect) { - log_d("Set Auto Reconnect to %d", autoReconnect); _autoReconnect = autoReconnect; return true; } From cbb4dc47adef5d84fc42ff1bfc9ee3f83210c89b Mon Sep 17 00:00:00 2001 From: "pedro.minatel" Date: Fri, 16 Dec 2022 16:00:41 +0000 Subject: [PATCH 6/6] Changes reverted and sync --- libraries/WiFi/src/WiFiGeneric.cpp | 55 +++++++++++++++--------------- libraries/WiFi/src/WiFiSTA.cpp | 10 ------ 2 files changed, 28 insertions(+), 37 deletions(-) diff --git a/libraries/WiFi/src/WiFiGeneric.cpp b/libraries/WiFi/src/WiFiGeneric.cpp index 75ab169008b..1b74d322739 100644 --- a/libraries/WiFi/src/WiFiGeneric.cpp +++ b/libraries/WiFi/src/WiFiGeneric.cpp @@ -188,18 +188,20 @@ esp_err_t set_esp_interface_ip(esp_interface_t interface, IPAddress local_ip=IPA lease.start_ip.addr = _byte_swap32(lease.start_ip.addr); lease.end_ip.addr = _byte_swap32(lease.end_ip.addr); log_v("DHCP Server Range: %s to %s", IPAddress(lease.start_ip.addr).toString().c_str(), IPAddress(lease.end_ip.addr).toString().c_str()); - err = tcpip_adapter_dhcps_option( - (tcpip_adapter_dhcp_option_mode_t)TCPIP_ADAPTER_OP_SET, - (tcpip_adapter_dhcp_option_id_t)ESP_NETIF_SUBNET_MASK, + err = esp_netif_dhcps_option( + esp_netif, + ESP_NETIF_OP_SET, + ESP_NETIF_SUBNET_MASK, (void*)&info.netmask.addr, sizeof(info.netmask.addr) ); if(err){ log_e("DHCPS Set Netmask Failed! 0x%04x", err); return err; } - err = tcpip_adapter_dhcps_option( - (tcpip_adapter_dhcp_option_mode_t)TCPIP_ADAPTER_OP_SET, - (tcpip_adapter_dhcp_option_id_t)REQUESTED_IP_ADDRESS, + err = esp_netif_dhcps_option( + esp_netif, + ESP_NETIF_OP_SET, + ESP_NETIF_REQUESTED_IP_ADDRESS, (void*)&lease, sizeof(dhcps_lease_t) ); if(err){ @@ -965,8 +967,7 @@ esp_err_t WiFiGenericClass::_eventCallback(arduino_event_t *event) clearStatusBits(STA_CONNECTED_BIT | STA_HAS_IP_BIT | STA_HAS_IP6_BIT); bool DoReconnect = false; - if(reason == WIFI_REASON_ASSOC_LEAVE) { - WiFiSTAClass::_setStatus(WL_DISCONNECTED); //Voluntarily disconnected. Don't reconnect! + if(reason == WIFI_REASON_ASSOC_LEAVE) { //Voluntarily disconnected. Don't reconnect! } else if(first_connect) { //Retry once for all failure reasons first_connect = false; @@ -980,9 +981,6 @@ esp_err_t WiFiGenericClass::_eventCallback(arduino_event_t *event) else if(reason == WIFI_REASON_ASSOC_FAIL) { WiFiSTAClass::_setStatus(WL_CONNECT_FAILED); } - else if(reason == WIFI_REASON_AUTH_EXPIRE) { - WiFiSTAClass::_setStatus(WL_CONNECT_FAILED); - } if(DoReconnect) { WiFi.disconnect(); WiFi.begin(); @@ -1452,28 +1450,31 @@ static void wifi_dns_found_callback(const char *name, const ip_addr_t *ipaddr, v } /** - * Resolve the given hostname to an IP address. - * @param aHostname Name to be resolved + * Resolve the given hostname to an IP address. If passed hostname is an IP address, it will be parsed into IPAddress structure. + * @param aHostname Name to be resolved or string containing IP address * @param aResult IPAddress structure to store the returned IP address * @return 1 if aIPAddrString was successfully converted to an IP address, * else error code */ int WiFiGenericClass::hostByName(const char* aHostname, IPAddress& aResult) { - ip_addr_t addr; - aResult = static_cast(0); - waitStatusBits(WIFI_DNS_IDLE_BIT, 16000); - clearStatusBits(WIFI_DNS_IDLE_BIT | WIFI_DNS_DONE_BIT); - err_t err = dns_gethostbyname(aHostname, &addr, &wifi_dns_found_callback, &aResult); - if(err == ERR_OK && addr.u_addr.ip4.addr) { - aResult = addr.u_addr.ip4.addr; - } else if(err == ERR_INPROGRESS) { - waitStatusBits(WIFI_DNS_DONE_BIT, 15000); //real internal timeout in lwip library is 14[s] - clearStatusBits(WIFI_DNS_DONE_BIT); - } - setStatusBits(WIFI_DNS_IDLE_BIT); - if((uint32_t)aResult == 0){ - log_e("DNS Failed for %s", aHostname); + if (!aResult.fromString(aHostname)) + { + ip_addr_t addr; + aResult = static_cast(0); + waitStatusBits(WIFI_DNS_IDLE_BIT, 16000); + clearStatusBits(WIFI_DNS_IDLE_BIT | WIFI_DNS_DONE_BIT); + err_t err = dns_gethostbyname(aHostname, &addr, &wifi_dns_found_callback, &aResult); + if(err == ERR_OK && addr.u_addr.ip4.addr) { + aResult = addr.u_addr.ip4.addr; + } else if(err == ERR_INPROGRESS) { + waitStatusBits(WIFI_DNS_DONE_BIT, 15000); //real internal timeout in lwip library is 14[s] + clearStatusBits(WIFI_DNS_DONE_BIT); + } + setStatusBits(WIFI_DNS_IDLE_BIT); + if((uint32_t)aResult == 0){ + log_e("DNS Failed for %s", aHostname); + } } return (uint32_t)aResult != 0; } diff --git a/libraries/WiFi/src/WiFiSTA.cpp b/libraries/WiFi/src/WiFiSTA.cpp index e9466f78103..7bcafea1d3e 100644 --- a/libraries/WiFi/src/WiFiSTA.cpp +++ b/libraries/WiFi/src/WiFiSTA.cpp @@ -278,8 +278,6 @@ wl_status_t WiFiSTAClass::begin(const char* ssid, const char *passphrase, int32_ log_e("connect failed!"); return WL_CONNECT_FAILED; } - // Set to auto reconnect - WiFi.setAutoReconnect(true); } return status(); @@ -319,8 +317,6 @@ wl_status_t WiFiSTAClass::begin() log_e("connect failed! 0x%x", err); return WL_CONNECT_FAILED; } - // Set to auto reconnect - WiFi.setAutoReconnect(true); } return status(); @@ -334,8 +330,6 @@ bool WiFiSTAClass::reconnect() { if(WiFi.getMode() & WIFI_MODE_STA) { if(esp_wifi_disconnect() == ESP_OK) { - // Set to auto reconnect - WiFi.setAutoReconnect(true); return esp_wifi_connect() == ESP_OK; } } @@ -366,10 +360,6 @@ bool WiFiSTAClass::disconnect(bool wifioff, bool eraseap) if(wifioff) { return WiFi.enableSTA(false); } - // Disable the auto reconnect in case of disconnection from the user - if(WiFi.getAutoReconnect()){ - WiFi.setAutoReconnect(false); - } return true; }