From 2128dfbadeb628e7a775a37c7d3eb83896cce944 Mon Sep 17 00:00:00 2001 From: s-hadinger <49731213+s-hadinger@users.noreply.github.com> Date: Fri, 5 Apr 2024 23:44:21 +0200 Subject: [PATCH] Refactored Wifi for ESP32 to allow for Core3 (#21106) * Refactored Wifi for ESP32 to allow for Core3 * Fix case in include * Grrr * Fix compilation * Fix Ethernet IPv6 * Fix wrong hostname due to mac address unknown at start --- CHANGELOG.md | 1 + lib/default/WiFiHelper/README.adoc | 19 +++ lib/default/WiFiHelper/library.json | 8 ++ lib/default/WiFiHelper/src/WiFiHelper.h | 86 +++++++++++++ .../WiFiHelper/src/WiFiHelper_ESP32.cpp} | 118 +++++++++--------- .../WiFiHelper/src/WiFiHelper_ESP8266.cpp | 76 +++++++++++ .../src/WiFiClientSecureLightBearSSL.cpp | 5 +- .../ESP-Mail-Client/src/ESP_Mail_TCPClient.h | 3 +- .../ESP32-to-ESP8266-compat/src/ESP8266WiFi.h | 74 +---------- .../HttpClientLight/src/HttpClientLight.cpp | 2 +- tasmota/tasmota.ino | 5 + tasmota/tasmota_support/support_command.ino | 2 +- tasmota/tasmota_support/support_esp32.ino | 2 +- tasmota/tasmota_support/support_esp8266.ino | 2 +- tasmota/tasmota_support/support_wifi.ino | 41 +++--- .../xdrv_82_esp32_ethernet.ino | 22 +++- 16 files changed, 308 insertions(+), 158 deletions(-) create mode 100644 lib/default/WiFiHelper/README.adoc create mode 100644 lib/default/WiFiHelper/library.json create mode 100644 lib/default/WiFiHelper/src/WiFiHelper.h rename lib/{libesp32/ESP32-to-ESP8266-compat/src/ESP32Wifi.cpp => default/WiFiHelper/src/WiFiHelper_ESP32.cpp} (74%) create mode 100644 lib/default/WiFiHelper/src/WiFiHelper_ESP8266.cpp diff --git a/CHANGELOG.md b/CHANGELOG.md index 295ed5f39..fe5141323 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -12,6 +12,7 @@ All notable changes to this project will be documented in this file. ### Breaking Changed ### Changed +- Refactored Wifi for ESP32 to allow for Core3 ### Fixed - NeoPool hydrolysis unit for Hidrolife, Bionet and Generic device (#21098) diff --git a/lib/default/WiFiHelper/README.adoc b/lib/default/WiFiHelper/README.adoc new file mode 100644 index 000000000..66c26d5cc --- /dev/null +++ b/lib/default/WiFiHelper/README.adoc @@ -0,0 +1,19 @@ +Wifi Helper for Tasmota bridging differences between ESP8266 and ESP32 + +This Class is for compatibility with esp8266 code + +== License == + +This library is free software; you can redistribute it and/or +modify it under the terms of the GNU Lesser General Public +License as published by the Free Software Foundation; either +version 2.1 of the License, or (at your option) any later version. + +This library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Lesser General Public License for more details. + +You should have received a copy of the GNU Lesser General Public +License along with this library; if not, write to the Free Software +Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA diff --git a/lib/default/WiFiHelper/library.json b/lib/default/WiFiHelper/library.json new file mode 100644 index 000000000..56676a297 --- /dev/null +++ b/lib/default/WiFiHelper/library.json @@ -0,0 +1,8 @@ +{ + "name": "WiFiHelper", + "keywords": "esp32, esp8266", + "description": "Bridges differences in Arduino WiFi between ESP32 and ESP8266", + "version": "1.0.0", + "frameworks": "arduino", + "platforms": "*" +} diff --git a/lib/default/WiFiHelper/src/WiFiHelper.h b/lib/default/WiFiHelper/src/WiFiHelper.h new file mode 100644 index 000000000..c7e248495 --- /dev/null +++ b/lib/default/WiFiHelper/src/WiFiHelper.h @@ -0,0 +1,86 @@ +/* + WiFiHelper.h - provide a wrapper for differences between ESP8266 and ESP32 WiFi + + Copyright (C) 2024 Theo Arends / Stephan Hadinger + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . +*/ +#ifndef WIFIHELPER_H +#define WIFIHELPER_H + + +// ====================================================== +// ESP8266 specific section +// ====================================================== +#ifdef ESP8266 +#include "ESP8266WiFi.h" +#endif + + +// ====================================================== +// ESP32 specific section +// ====================================================== +#ifdef ESP32 +#include + +#define ENC_TYPE_NONE WIFI_AUTH_OPEN +#define ENC_TYPE_WEP WIFI_AUTH_WEP +#define ENC_TYPE_CCMP WIFI_AUTH_WPA2_PSK +#define ENC_TYPE_TKIP WIFI_AUTH_WPA_WPA2_PSK +#define ENC_TYPE_AUTO WIFI_AUTH_MAX + 1 + +#define WIFI_NONE_SLEEP 0 +#define WIFI_LIGHT_SLEEP 1 +#define WIFI_MODEM_SLEEP 2 + +// ESP8266 +typedef enum WiFiPhyMode +{ + TAS_WIFI_PHY_MODE_LR = 0, TAS_WIFI_PHY_MODE_11B = 1, TAS_WIFI_PHY_MODE_11G = 2, TAS_WIFI_PHY_MODE_11N = 3 +#if ESP_IDF_VERSION_MAJOR >= 5 + , TAS_WIFI_PHY_MODE_11AX = 4 +#endif +} WiFiPhyMode_t; + +#endif // ESP32 + +// This is an abstract class containing wrappers to call WiFi +class WiFiHelper { +public: +#ifdef ESP32 + static wl_status_t begin(const char* wpa2_ssid, wpa2_auth_method_t method, const char* wpa2_identity=NULL, const char* wpa2_username=NULL, const char *wpa2_password=NULL, const char* ca_pem=NULL, const char* client_crt=NULL, const char* client_key=NULL, int32_t channel=0, const uint8_t* bssid=0, bool connect=true); +#endif + static wl_status_t begin(const char* ssid, const char *passphrase = NULL, int32_t channel = 0, const uint8_t* bssid = NULL, bool connect = true); + static wl_status_t begin(char* ssid, char *passphrase = NULL, int32_t channel = 0, const uint8_t* bssid = NULL, bool connect = true); + static wl_status_t begin(); + + static void hostname(const char* aHostname); + static void setSleepMode(int iSleepMode); + static int getPhyMode(); + static bool setPhyMode(WiFiPhyMode_t mode); + + static void setOutputPower(int n); + static void forceSleepBegin(); + static void forceSleepWake(); + static bool getNetworkInfo(uint8_t i, String &ssid, uint8_t &encType, int32_t &rssi, uint8_t* &bssid, int32_t &channel, bool &hidden_scan); + + static int hostByName(const char* aHostname, IPAddress& aResult, int32_t timer_ms); + static int hostByName(const char* aHostname, IPAddress& aResult); + + static void scrubDNS(void); +}; + + + +#endif // WIFIHELPER_H \ No newline at end of file diff --git a/lib/libesp32/ESP32-to-ESP8266-compat/src/ESP32Wifi.cpp b/lib/default/WiFiHelper/src/WiFiHelper_ESP32.cpp similarity index 74% rename from lib/libesp32/ESP32-to-ESP8266-compat/src/ESP32Wifi.cpp rename to lib/default/WiFiHelper/src/WiFiHelper_ESP32.cpp index 6bdfc4587..908e8f2ee 100644 --- a/lib/libesp32/ESP32-to-ESP8266-compat/src/ESP32Wifi.cpp +++ b/lib/default/WiFiHelper/src/WiFiHelper_ESP32.cpp @@ -16,48 +16,48 @@ You should have received a copy of the GNU General Public License along with this program. If not, see . */ -// +#ifdef ESP32 + #include "Arduino.h" -#include +#include "WiFiHelper.h" #include extern void AddLog(uint32_t loglevel, PGM_P formatP, ...); enum LoggingLevels {LOG_LEVEL_NONE, LOG_LEVEL_ERROR, LOG_LEVEL_INFO, LOG_LEVEL_DEBUG, LOG_LEVEL_DEBUG_MORE}; -// -// Wifi -// -#ifdef WiFi -#undef WiFi -#endif + +#ifdef USE_IPV6 +ip_addr_t dns_save4[DNS_MAX_SERVERS] = {}; // IPv4 DNS servers +ip_addr_t dns_save6[DNS_MAX_SERVERS] = {}; // IPv6 DNS servers +#endif // USE_IPV6 #include "tasmota_options.h" #include "lwip/dns.h" -wl_status_t WiFiClass32::begin(const char* wpa2_ssid, wpa2_auth_method_t method, const char* wpa2_identity, const char* wpa2_username, const char *wpa2_password, const char* ca_pem, const char* client_crt, const char* client_key, int32_t channel, const uint8_t* bssid, bool connect) { - scrubDNS(); - wl_status_t ret = WiFiClass::begin(wpa2_ssid, method, wpa2_identity, wpa2_username, wpa2_password, ca_pem, client_crt, client_key, channel, bssid, connect); - scrubDNS(); +wl_status_t WiFiHelper::begin(const char* wpa2_ssid, wpa2_auth_method_t method, const char* wpa2_identity, const char* wpa2_username, const char *wpa2_password, const char* ca_pem, const char* client_crt, const char* client_key, int32_t channel, const uint8_t* bssid, bool connect) { + WiFiHelper::scrubDNS(); + wl_status_t ret = WiFi.begin(wpa2_ssid, method, wpa2_identity, wpa2_username, wpa2_password, ca_pem, client_crt, client_key, channel, bssid, connect); + WiFiHelper::scrubDNS(); return ret; } -wl_status_t WiFiClass32::begin(const char* ssid, const char *passphrase, int32_t channel, const uint8_t* bssid, bool connect) { - scrubDNS(); - wl_status_t ret = WiFiClass::begin(ssid, passphrase, channel, bssid, connect); - scrubDNS(); +wl_status_t WiFiHelper::begin(const char* ssid, const char *passphrase, int32_t channel, const uint8_t* bssid, bool connect) { + WiFiHelper::scrubDNS(); + wl_status_t ret = WiFi.begin(ssid, passphrase, channel, bssid, connect); + WiFiHelper::scrubDNS(); return ret; } -wl_status_t WiFiClass32::begin(char* ssid, char *passphrase, int32_t channel, const uint8_t* bssid, bool connect) { - scrubDNS(); - wl_status_t ret = WiFiClass::begin(ssid, passphrase, channel, bssid, connect); - scrubDNS(); +wl_status_t WiFiHelper::begin(char* ssid, char *passphrase, int32_t channel, const uint8_t* bssid, bool connect) { + WiFiHelper::scrubDNS(); + wl_status_t ret = WiFi.begin(ssid, passphrase, channel, bssid, connect); + WiFiHelper::scrubDNS(); return ret; } -wl_status_t WiFiClass32::begin() { - scrubDNS(); - wl_status_t ret = WiFiClass::begin(); - scrubDNS(); +wl_status_t WiFiHelper::begin() { + WiFiHelper::scrubDNS(); + wl_status_t ret = WiFi.begin(); + WiFiHelper::scrubDNS(); return ret; } @@ -73,7 +73,7 @@ extern bool EthernetHasIPv4(void); extern bool WifiHasIPv6(void); extern bool EthernetHasIPv6(void); -void WiFiClass32::scrubDNS(void) { +void WiFiHelper::scrubDNS(void) { // String dns_entry0 = IPAddress(dns_getserver(0)).toString(); // String dns_entry1 = IPAddress(dns_getserver(1)).toString(); // scan DNS entries @@ -118,12 +118,17 @@ void WiFiClass32::scrubDNS(void) { // AddLog(LOG_LEVEL_DEBUG, "IP>: DNS: from(%s %s) to (%s %s) has4/6:%i-%i", dns_entry0.c_str(), dns_entry1.c_str(), IPAddress(dns_getserver(0)).toString().c_str(), IPAddress(dns_getserver(1)).toString().c_str(), has_v4, has_v6); } -void WiFiClass32::setSleepMode(int iSleepMode) { + +void WiFiHelper::hostname(const char* aHostname) { + WiFi.setHostname(aHostname); +} + +void WiFiHelper::setSleepMode(int iSleepMode) { // WIFI_LIGHT_SLEEP and WIFI_MODEM_SLEEP WiFi.setSleep(iSleepMode != WIFI_NONE_SLEEP); } -int WiFiClass32::getPhyMode() { +int WiFiHelper::getPhyMode() { /* typedef enum { @@ -146,7 +151,7 @@ int WiFiClass32::getPhyMode() { return phy_mode; } -bool WiFiClass32::setPhyMode(WiFiPhyMode_t mode) { +bool WiFiHelper::setPhyMode(WiFiPhyMode_t mode) { uint8_t protocol_bitmap = WIFI_PROTOCOL_11B; // 1 switch (mode) { #if ESP_IDF_VERSION_MAJOR >= 5 @@ -158,10 +163,7 @@ bool WiFiClass32::setPhyMode(WiFiPhyMode_t mode) { return (ESP_OK == esp_wifi_set_protocol(WIFI_IF_STA, protocol_bitmap)); } -void WiFiClass32::wps_disable() { -} - -void WiFiClass32::setOutputPower(int n) { +void WiFiHelper::setOutputPower(int n) { wifi_power_t p = WIFI_POWER_2dBm; if (n > 19) p = WIFI_POWER_19_5dBm; @@ -184,13 +186,13 @@ void WiFiClass32::setOutputPower(int n) { WiFi.setTxPower(p); } -void WiFiClass32::forceSleepBegin() { +void WiFiHelper::forceSleepBegin() { } -void WiFiClass32::forceSleepWake() { +void WiFiHelper::forceSleepWake() { } -bool WiFiClass32::getNetworkInfo(uint8_t i, String &ssid, uint8_t &encType, int32_t &rssi, uint8_t *&bssid, int32_t &channel, bool &hidden_scan) { +bool WiFiHelper::getNetworkInfo(uint8_t i, String &ssid, uint8_t &encType, int32_t &rssi, uint8_t *&bssid, int32_t &channel, bool &hidden_scan) { hidden_scan = false; return WiFi.getNetworkInfo(i, ssid, encType, rssi, bssid, channel); } @@ -213,6 +215,16 @@ static volatile uint32_t ip_addr_counter = 0; // counter for requests extern int32_t WifiDNSGetTimeout(void); extern bool WifiDNSGetIPv6Priority(void); +static volatile bool dns_found = false; + +bool DNS_TimeReached(uint32_t timer) +{ + // Check if a certain timeout has been reached. + int32_t passed = ((int32_t) (millis() - timer)); + return (passed >= 0); +} + + static void wifi32_dns_found_callback(const char *name, const ip_addr_t *ipaddr, void *callback_arg) { // Serial.printf("DNS: cb name=%s ipaddr=%s arg=%i counter=%i\n", name ? name : "", IPAddress(ipaddr).toString().c_str(), (int) callback_arg, ip_addr_counter); @@ -224,13 +236,9 @@ static void wifi32_dns_found_callback(const char *name, const ip_addr_t *ipaddr, } else { dns_ipaddr = *IP4_ADDR_ANY; // set to IPv4 0.0.0.0 } - WiFiClass32::dnsDone(); + dns_found = true; // AddLog(LOG_LEVEL_DEBUG, "WIF: dns_found=%s", ipaddr ? IPAddress(*ipaddr).toString().c_str() : ""); } -// We need this helper method to access protected methods from WiFiGeneric -void WiFiClass32::dnsDone(void) { - setStatusBits(NET_DNS_DONE_BIT); -} /** * Resolve the given hostname to an IP address. @@ -239,19 +247,22 @@ void WiFiClass32::dnsDone(void) { * @return 1 if aIPAddrString was successfully converted to an IP address, * else error code */ -int WiFiClass32::hostByName(const char* aHostname, IPAddress& aResult, int32_t timer_ms) +int WiFiHelper::hostByName(const char* aHostname, IPAddress& aResult, int32_t timer_ms) { +// return WiFi.hostByName(aHostname, aResult); +// #if 0 ip_addr_t addr; aResult = (uint32_t) 0; // by default set to IPv4 0.0.0.0 dns_ipaddr = *IP4_ADDR_ANY; // by default set to IPv4 0.0.0.0 - scrubDNS(); // internal calls to reconnect can zero the DNS servers, save DNS for future use + WiFiHelper::scrubDNS(); // internal calls to reconnect can zero the DNS servers, save DNS for future use ip_addr_counter++; // increase counter, from now ignore previous responses - clearStatusBits(NET_DNS_IDLE_BIT | NET_DNS_DONE_BIT); + // clearStatusBits(NET_DNS_IDLE_BIT | NET_DNS_DONE_BIT); uint8_t v4v6priority = LWIP_DNS_ADDRTYPE_IPV4; #ifdef USE_IPV6 v4v6priority = WifiDNSGetIPv6Priority() ? LWIP_DNS_ADDRTYPE_IPV6_IPV4 : LWIP_DNS_ADDRTYPE_IPV4_IPV6; #endif // USE_IPV6 + dns_found = false; err_t err = dns_gethostbyname_addrtype(aHostname, &dns_ipaddr, &wifi32_dns_found_callback, (void*) ip_addr_counter, v4v6priority); // Serial.printf("DNS: dns_gethostbyname_addrtype errg=%i counter=%i\n", err, ip_addr_counter); if(err == ERR_OK && !ip_addr_isany_val(dns_ipaddr)) { @@ -261,8 +272,10 @@ int WiFiClass32::hostByName(const char* aHostname, IPAddress& aResult, int32_t t aResult = ip_addr_get_ip4_u32(&dns_ipaddr); #endif // USE_IPV6 } else if(err == ERR_INPROGRESS) { - waitStatusBits(NET_DNS_DONE_BIT, timer_ms); //real internal timeout in lwip library is 14[s] - clearStatusBits(NET_DNS_DONE_BIT); + uint32_t deadline = millis() + timer_ms; + while ((!DNS_TimeReached(deadline)) && !dns_found) { + delay(1); + } } if (!ip_addr_isany_val(dns_ipaddr)) { @@ -274,19 +287,12 @@ int WiFiClass32::hostByName(const char* aHostname, IPAddress& aResult, int32_t t return true; } return false; +// #endif } -int WiFiClass32::hostByName(const char* aHostname, IPAddress& aResult) +int WiFiHelper::hostByName(const char* aHostname, IPAddress& aResult) { - return hostByName(aHostname, aResult, WifiDNSGetTimeout()); + return WiFiHelper::hostByName(aHostname, aResult, WifiDNSGetTimeout()); } -void wifi_station_disconnect() { - // erase ap: empty ssid, ... - WiFi.disconnect(true, true); -} - -void wifi_station_dhcpc_start() { -} - -WiFiClass32 WiFi32; +#endif // ESP32 diff --git a/lib/default/WiFiHelper/src/WiFiHelper_ESP8266.cpp b/lib/default/WiFiHelper/src/WiFiHelper_ESP8266.cpp new file mode 100644 index 000000000..2abcfd098 --- /dev/null +++ b/lib/default/WiFiHelper/src/WiFiHelper_ESP8266.cpp @@ -0,0 +1,76 @@ +/* + WiFi compat with ESP32 + + Copyright (C) 2021 Theo Arends / Jörg Schüler-Maroldt + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . +*/ +// +#ifdef ESP8266 +#include "Arduino.h" +#include "WiFiHelper.h" + +wl_status_t WiFiHelper::begin(const char* ssid, const char *passphrase, int32_t channel, const uint8_t* bssid, bool connect) { + return WiFi.begin(ssid, passphrase, channel, bssid, connect); +} + +wl_status_t WiFiHelper::begin(char* ssid, char *passphrase, int32_t channel, const uint8_t* bssid, bool connect) { + return WiFi.begin(ssid, passphrase, channel, bssid, connect); +} + +wl_status_t WiFiHelper::begin() { + return WiFi.begin(); +} + +void WiFiHelper::scrubDNS(void) { +} + + +void WiFiHelper::hostname(const char* aHostname) { + WiFi.hostname(aHostname); +} + +void WiFiHelper::setSleepMode(int iSleepMode) { + WiFi.setSleepMode((WiFiSleepType_t)iSleepMode); +} + +int WiFiHelper::getPhyMode() { + return WiFi.getPhyMode(); +} + +bool WiFiHelper::setPhyMode(WiFiPhyMode_t mode) { + return WiFi.setPhyMode(mode); +} + +void WiFiHelper::setOutputPower(int n) { + WiFi.setOutputPower(n); +} +void WiFiHelper::forceSleepBegin() { + WiFi.forceSleepBegin(); +} +void WiFiHelper::forceSleepWake() { + WiFi.forceSleepWake(); +} +bool WiFiHelper::getNetworkInfo(uint8_t i, String &ssid, uint8_t &encType, int32_t &rssi, uint8_t* &bssid, int32_t &channel, bool &hidden_scan) { + return WiFi.getNetworkInfo(i, ssid, encType, rssi, bssid, channel, hidden_scan); +} + +int WiFiHelper::hostByName(const char* aHostname, IPAddress& aResult, int32_t timer_ms) { + return WiFi.hostByName(aHostname, aResult, timer_ms); +} +int WiFiHelper::hostByName(const char* aHostname, IPAddress& aResult) { + return WiFi.hostByName(aHostname, aResult); +} + +#endif // ESP8266 diff --git a/lib/lib_ssl/tls_mini/src/WiFiClientSecureLightBearSSL.cpp b/lib/lib_ssl/tls_mini/src/WiFiClientSecureLightBearSSL.cpp index da8b3b50a..1cc2ae2b3 100755 --- a/lib/lib_ssl/tls_mini/src/WiFiClientSecureLightBearSSL.cpp +++ b/lib/lib_ssl/tls_mini/src/WiFiClientSecureLightBearSSL.cpp @@ -34,6 +34,7 @@ #include "WiFiClientSecureLightBearSSL.h" // needs to be before "ESP8266WiFi.h" to avoid conflict with Arduino headers #include "ESP8266WiFi.h" +#include "WiFiHelper.h" #include "WiFiClient.h" #include "StackThunk_light.h" #include "lwip/opt.h" @@ -318,7 +319,7 @@ int WiFiClientSecure_light::connect(const char* name, uint16_t port, int32_t tim DEBUG_BSSL("connect(%s,%d)\n", name, port); IPAddress remote_addr; clearLastError(); - if (!WiFi.hostByName(name, remote_addr)) { + if (!WiFiHelper::hostByName(name, remote_addr)) { DEBUG_BSSL("connect: Name loopup failure\n"); setLastError(ERR_CANT_RESOLVE_IP); return 0; @@ -337,7 +338,7 @@ int WiFiClientSecure_light::connect(const char* name, uint16_t port) { DEBUG_BSSL("connect(%s,%d)\n", name, port); IPAddress remote_addr; clearLastError(); - if (!WiFi.hostByName(name, remote_addr)) { + if (!WiFiHelper::hostByName(name, remote_addr)) { DEBUG_BSSL("connect: Name loopup failure\n"); setLastError(ERR_CANT_RESOLVE_IP); return 0; diff --git a/lib/libesp32/ESP-Mail-Client/src/ESP_Mail_TCPClient.h b/lib/libesp32/ESP-Mail-Client/src/ESP_Mail_TCPClient.h index 9302f6d4e..43bb799d2 100644 --- a/lib/libesp32/ESP-Mail-Client/src/ESP_Mail_TCPClient.h +++ b/lib/libesp32/ESP-Mail-Client/src/ESP_Mail_TCPClient.h @@ -46,6 +46,7 @@ #if defined(ESP32) +#include "ESP8266WiFi.h" #if defined(ESP_MAIL_WIFI_IS_AVAILABLE) #define WIFI_HAS_HOST_BY_NAME #endif @@ -456,7 +457,7 @@ public: int hostByName(const char *name, IPAddress &ip) { #if defined(ESP_MAIL_WIFI_IS_AVAILABLE) - return WiFi.hostByName(name, ip); + return WiFiHelper::hostByName(name, ip); #else return 1; #endif diff --git a/lib/libesp32/ESP32-to-ESP8266-compat/src/ESP8266WiFi.h b/lib/libesp32/ESP32-to-ESP8266-compat/src/ESP8266WiFi.h index 881caff0c..425e4d1b2 100644 --- a/lib/libesp32/ESP32-to-ESP8266-compat/src/ESP8266WiFi.h +++ b/lib/libesp32/ESP32-to-ESP8266-compat/src/ESP8266WiFi.h @@ -16,76 +16,4 @@ You should have received a copy of the GNU General Public License along with this program. If not, see . */ -#pragma once -#include - -#define ENC_TYPE_NONE WIFI_AUTH_OPEN -#define ENC_TYPE_WEP WIFI_AUTH_WEP -#define ENC_TYPE_CCMP WIFI_AUTH_WPA2_PSK -#define ENC_TYPE_TKIP WIFI_AUTH_WPA_WPA2_PSK -#define ENC_TYPE_AUTO WIFI_AUTH_MAX + 1 - -#define WIFI_NONE_SLEEP 0 -#define WIFI_LIGHT_SLEEP 1 -#define WIFI_MODEM_SLEEP 2 - -// ESP8266 -typedef enum WiFiPhyMode -{ - TAS_WIFI_PHY_MODE_LR = 0, TAS_WIFI_PHY_MODE_11B = 1, TAS_WIFI_PHY_MODE_11G = 2, TAS_WIFI_PHY_MODE_11N = 3 -#if ESP_IDF_VERSION_MAJOR >= 5 - , TAS_WIFI_PHY_MODE_11AX = 4 -#endif -} WiFiPhyMode_t; - -/* -// ESP32 was never defined until IDF 4.4 -typedef enum -{ - WIFI_PHY_MODE_LR, // PHY mode for Low Rate - WIFI_PHY_MODE_11B, // PHY mode for 11b - WIFI_PHY_MODE_11G, // PHY mode for 11g - WIFI_PHY_MODE_HT20, // PHY mode for 11n Bandwidth HT20 - WIFI_PHY_MODE_HT40, // PHY mode for 11n Bandwidth HT40 - WIFI_PHY_MODE_HE20, // PHY mode for 11n Bandwidth HE20 -} wifi_phy_mode_t; -*/ - -class WiFiClass32 : public WiFiClass -{ -public: - wl_status_t begin(const char* wpa2_ssid, wpa2_auth_method_t method, const char* wpa2_identity=NULL, const char* wpa2_username=NULL, const char *wpa2_password=NULL, const char* ca_pem=NULL, const char* client_crt=NULL, const char* client_key=NULL, int32_t channel=0, const uint8_t* bssid=0, bool connect=true); - wl_status_t begin(const char* ssid, const char *passphrase = NULL, int32_t channel = 0, const uint8_t* bssid = NULL, bool connect = true); - wl_status_t begin(char* ssid, char *passphrase = NULL, int32_t channel = 0, const uint8_t* bssid = NULL, bool connect = true); - wl_status_t begin(); - - static void hostname(const char* aHostname) - { - WiFi.setHostname(aHostname); - } - static void setSleepMode(int iSleepMode); - static int getPhyMode(); - static bool setPhyMode(WiFiPhyMode_t mode); - - static void wps_disable(); - static void setOutputPower(int n); - static void forceSleepBegin(); - static void forceSleepWake(); - static bool getNetworkInfo(uint8_t i, String &ssid, uint8_t &encType, int32_t &rssi, uint8_t* &bssid, int32_t &channel, bool &hidden_scan); - - static void dnsDone(void); // used by the callback to stop the dns timer - int hostByName(const char* aHostname, IPAddress& aResult, int32_t timer_ms); - int hostByName(const char* aHostname, IPAddress& aResult); - - void scrubDNS(void); -protected: -#ifdef USE_IPV6 - ip_addr_t dns_save4[DNS_MAX_SERVERS] = {}; // IPv4 DNS servers - ip_addr_t dns_save6[DNS_MAX_SERVERS] = {}; // IPv6 DNS servers -#endif // USE_IPV6 -}; - -void wifi_station_disconnect(); -void wifi_station_dhcpc_start(); -extern WiFiClass32 WiFi32; -#define WiFi WiFi32 +#include diff --git a/lib/libesp32/HttpClientLight/src/HttpClientLight.cpp b/lib/libesp32/HttpClientLight/src/HttpClientLight.cpp index 62eea2ea8..2705d9694 100644 --- a/lib/libesp32/HttpClientLight/src/HttpClientLight.cpp +++ b/lib/libesp32/HttpClientLight/src/HttpClientLight.cpp @@ -1166,7 +1166,7 @@ bool HTTPClientLight::connect(void) } else { IPAddress remote_addr; // Add include "ESP8266WiFi.h" for this to work - if (!WiFi.hostByName(_host.c_str(), remote_addr)) { + if (!WiFiHelper::hostByName(_host.c_str(), remote_addr)) { return false; } if(!_client->connect(remote_addr, _port, _connectTimeout)) { diff --git a/tasmota/tasmota.ino b/tasmota/tasmota.ino index f43a34b9c..d6492aad9 100644 --- a/tasmota/tasmota.ino +++ b/tasmota/tasmota.ino @@ -40,6 +40,7 @@ #endif // Libraries +#include #include // Ota #include // Ota #ifdef ESP32 @@ -713,6 +714,10 @@ void setup(void) { // Github inserts "release" or "commit number" before compiling using sed -i -e 's/TASMOTA_SHA_SHORT/TASMOTA_SHA_SHORT 85cff52-/g' tasmota_version.h snprintf_P(TasmotaGlobal.image_name, sizeof(TasmotaGlobal.image_name), PSTR("(" STR(TASMOTA_SHA_SHORT) "%s)"), PSTR(CODE_IMAGE_STR)); // Results in (85cff52-tasmota) or (release-tasmota) +#if defined(ESP32) && (ESP_IDF_VERSION_MAJOR >= 5) + WiFi.begin(); // force wifi start so that the Mac address is known +#endif + Format(TasmotaGlobal.mqtt_client, SettingsText(SET_MQTT_CLIENT), sizeof(TasmotaGlobal.mqtt_client)); Format(TasmotaGlobal.mqtt_topic, SettingsText(SET_MQTT_TOPIC), sizeof(TasmotaGlobal.mqtt_topic)); if (strchr(SettingsText(SET_HOSTNAME), '%') != nullptr) { diff --git a/tasmota/tasmota_support/support_command.ino b/tasmota/tasmota_support/support_command.ino index 8785eefa7..a1acf500f 100644 --- a/tasmota/tasmota_support/support_command.ino +++ b/tasmota/tasmota_support/support_command.ino @@ -2680,7 +2680,7 @@ void CmndWifi(void) { #ifdef ESP32 Wifi.phy_mode = option; #endif // ESP32 - WiFi.setPhyMode(WiFiPhyMode_t(option)); // 1=B/2=BG/3=BGN/4=BGNAX + WiFiHelper::setPhyMode(WiFiPhyMode_t(option)); // 1=B/2=BG/3=BGN/4=BGNAX break; } } diff --git a/tasmota/tasmota_support/support_esp32.ino b/tasmota/tasmota_support/support_esp32.ino index 7130f5215..cbba427cc 100644 --- a/tasmota/tasmota_support/support_esp32.ino +++ b/tasmota/tasmota_support/support_esp32.ino @@ -981,7 +981,7 @@ String ESP_getEfuseMac(void) { String WifiGetPhyMode(void) { char stemp[10]; - return String(GetTextIndexed(stemp, sizeof(stemp), WiFi.getPhyMode(), kWifiPhyMode)); + return String(GetTextIndexed(stemp, sizeof(stemp), WiFiHelper::getPhyMode(), kWifiPhyMode)); } /*********************************************************************************************\ diff --git a/tasmota/tasmota_support/support_esp8266.ino b/tasmota/tasmota_support/support_esp8266.ino index 2f043aa64..839ce87dc 100644 --- a/tasmota/tasmota_support/support_esp8266.ino +++ b/tasmota/tasmota_support/support_esp8266.ino @@ -262,7 +262,7 @@ String ESP_getEfuseMac(void) { String WifiGetPhyMode(void) { char stemp[10]; - return String(GetTextIndexed(stemp, sizeof(stemp), WiFi.getPhyMode() & 0x3, kWifiPhyMode)); + return String(GetTextIndexed(stemp, sizeof(stemp), WiFiHelper::getPhyMode() & 0x3, kWifiPhyMode)); } /*********************************************************************************************\ diff --git a/tasmota/tasmota_support/support_wifi.ino b/tasmota/tasmota_support/support_wifi.ino index 546986653..76fb4b28f 100644 --- a/tasmota/tasmota_support/support_wifi.ino +++ b/tasmota/tasmota_support/support_wifi.ino @@ -146,7 +146,7 @@ void WifiSetMode(WiFiMode_t wifi_mode) { WiFi.hostname(TasmotaGlobal.hostname); // ESP32 needs this here (before WiFi.mode) for core 2.0.0 // See: https://github.com/esp8266/Arduino/issues/6172#issuecomment-500457407 - WiFi.forceSleepWake(); // Make sure WiFi is really active. + WiFiHelper::forceSleepWake(); // Make sure WiFi is really active. } uint32_t retry = 2; @@ -157,7 +157,7 @@ void WifiSetMode(WiFiMode_t wifi_mode) { if (wifi_mode == WIFI_OFF) { delay(1000); - WiFi.forceSleepBegin(); + WiFiHelper::forceSleepBegin(); } delay(100); // Must allow for some time to init. } @@ -179,9 +179,9 @@ void WiFiSetSleepMode(void) // Sleep explanation: https://github.com/esp8266/Arduino/blob/3f0c601cfe81439ce17e9bd5d28994a7ed144482/libraries/ESP8266WiFi/src/ESP8266WiFiGeneric.cpp#L255 /* if (TasmotaGlobal.sleep && Settings->flag3.sleep_normal) { // SetOption60 - Enable normal sleep instead of dynamic sleep - WiFi.setSleepMode(WIFI_LIGHT_SLEEP); // Allow light sleep during idle times + WiFiHelper::setSleepMode(WIFI_LIGHT_SLEEP); // Allow light sleep during idle times } else { - WiFi.setSleepMode(WIFI_MODEM_SLEEP); // Disable sleep (Esp8288/Arduino core and sdk default) + WiFiHelper::setSleepMode(WIFI_MODEM_SLEEP); // Disable sleep (Esp8288/Arduino core and sdk default) } */ bool wifi_no_sleep = Settings->flag5.wifi_no_sleep; @@ -190,13 +190,13 @@ void WiFiSetSleepMode(void) #endif if (0 == TasmotaGlobal.sleep || wifi_no_sleep) { if (!TasmotaGlobal.wifi_stay_asleep) { - WiFi.setSleepMode(WIFI_NONE_SLEEP); // Disable sleep + WiFiHelper::setSleepMode(WIFI_NONE_SLEEP); // Disable sleep } } else { if (Settings->flag3.sleep_normal) { // SetOption60 - Enable normal sleep instead of dynamic sleep - WiFi.setSleepMode(WIFI_LIGHT_SLEEP); // Allow light sleep during idle times + WiFiHelper::setSleepMode(WIFI_LIGHT_SLEEP); // Allow light sleep during idle times } else { - WiFi.setSleepMode(WIFI_MODEM_SLEEP); // Sleep (Esp8288/Arduino core and sdk default) + WiFiHelper::setSleepMode(WIFI_MODEM_SLEEP); // Sleep (Esp8288/Arduino core and sdk default) } } delay(100); @@ -224,15 +224,14 @@ void WifiBegin(uint8_t flag, uint8_t channel) { WiFiSetSleepMode(); WifiSetOutputPower(); -// if (WiFi.getPhyMode() != WIFI_PHY_MODE_11N) { WiFi.setPhyMode(WIFI_PHY_MODE_11N); } // B/G/N -// if (WiFi.getPhyMode() != WIFI_PHY_MODE_11G) { WiFi.setPhyMode(WIFI_PHY_MODE_11G); } // B/G +// if (WiFiHelper::getPhyMode() != WIFI_PHY_MODE_11N) { WiFiHelper::setPhyMode(WIFI_PHY_MODE_11N); } // B/G/N +// if (WiFiHelper::getPhyMode() != WIFI_PHY_MODE_11G) { WiFiHelper::setPhyMode(WIFI_PHY_MODE_11G); } // B/G #ifdef ESP32 if (Wifi.phy_mode) { - WiFi.setPhyMode(WiFiPhyMode_t(Wifi.phy_mode)); // 1-B/2-BG/3-BGN/4-BGNAX + WiFiHelper::setPhyMode(WiFiPhyMode_t(Wifi.phy_mode)); // 1-B/2-BG/3-BGN/4-BGNAX } #endif - if (!WiFi.getAutoConnect()) { WiFi.setAutoConnect(true); } -// WiFi.setAutoReconnect(true); + WiFi.setAutoReconnect(true); switch (flag) { case 0: // AP1 case 1: // AP2 @@ -321,7 +320,7 @@ void WifiBeginAfterScan(void) int32_t chan_scan; bool hidden_scan; - WiFi.getNetworkInfo(i, ssid_scan, sec_scan, rssi_scan, bssid_scan, chan_scan, hidden_scan); + WiFiHelper::getNetworkInfo(i, ssid_scan, sec_scan, rssi_scan, bssid_scan, chan_scan, hidden_scan); bool known = false; uint32_t j; @@ -631,7 +630,7 @@ String EthernetGetIPv6LinkLocalStr(void) bool DNSGetIP(IPAddress *ip, uint32_t idx) { #ifdef ESP32 - WiFi.scrubDNS(); // internal calls to reconnect can zero the DNS servers, restore the previous values + WiFiHelper::scrubDNS(); // internal calls to reconnect can zero the DNS servers, restore the previous values #endif const ip_addr_t *ip_dns = dns_getserver(idx); if (!ip_addr_isany(ip_dns)) { @@ -990,7 +989,7 @@ float WifiGetOutputPower(void) { void WifiSetOutputPower(void) { if (Settings->wifi_output_power) { - WiFi.setOutputPower((float)(Settings->wifi_output_power) / 10); + WiFiHelper::setOutputPower((float)(Settings->wifi_output_power) / 10); delay(100); } else { AddLog(LOG_LEVEL_DEBUG, PSTR("WIF: Dynamic Tx power enabled")); // WifiPower 0 @@ -1008,7 +1007,7 @@ void WiFiSetTXpowerBasedOnRssi(void) { // Range ESP8266: 0dBm - 20.5dBm int max_tx_pwr = MAX_TX_PWR_DBM_11b; int threshold = WIFI_SENSITIVITY_n; - int phy_mode = WiFi.getPhyMode(); + int phy_mode = WiFiHelper::getPhyMode(); switch (phy_mode) { case 1: // 11b (WIFI_PHY_MODE_11B) threshold = WIFI_SENSITIVITY_11b; @@ -1040,7 +1039,7 @@ void WiFiSetTXpowerBasedOnRssi(void) { if (min_tx_pwr > max_tx_pwr) { min_tx_pwr = max_tx_pwr; } - WiFi.setOutputPower((float)min_tx_pwr / 10); + WiFiHelper::setOutputPower((float)min_tx_pwr / 10); delay(Wifi.last_tx_pwr < min_tx_pwr); // If increase the TX power, give power supply of the unit some rest /* if (Wifi.last_tx_pwr != min_tx_pwr) { @@ -1150,7 +1149,11 @@ void WifiShutdown(bool option) { // Courtesy of EspEasy // WiFi.persistent(true); // use SDK storage of SSID/WPA parameters ETS_UART_INTR_DISABLE(); +#ifdef ESP8266 wifi_station_disconnect(); // this will store empty ssid/wpa into sdk storage +#else + WiFi.disconnect(true, true); +#endif ETS_UART_INTR_ENABLE(); // WiFi.persistent(false); // Do not use SDK storage of SSID/WPA parameters } @@ -1291,7 +1294,7 @@ bool WifiHostByName(const char* aHostname, IPAddress& aResult) { #endif // USE_IPV6 uint32_t dns_start = millis(); - bool success = WiFi.hostByName(aHostname, aResult, Settings->dns_timeout); + bool success = WiFiHelper::hostByName(aHostname, aResult, Settings->dns_timeout); uint32_t dns_end = millis(); if (success) { // Host name resolved @@ -1515,6 +1518,6 @@ void WifiEvents(arduino_event_t *event) { default: break; } - WiFi.scrubDNS(); // internal calls to reconnect can zero the DNS servers, restore the previous values + WiFiHelper::scrubDNS(); // internal calls to reconnect can zero the DNS servers, restore the previous values } #endif // ESP32 diff --git a/tasmota/tasmota_xdrv_driver/xdrv_82_esp32_ethernet.ino b/tasmota/tasmota_xdrv_driver/xdrv_82_esp32_ethernet.ino index 7f11df7a2..ae1b9649e 100644 --- a/tasmota/tasmota_xdrv_driver/xdrv_82_esp32_ethernet.ino +++ b/tasmota/tasmota_xdrv_driver/xdrv_82_esp32_ethernet.ino @@ -111,6 +111,15 @@ void EthernetEvent(arduino_event_t *event) { // workaround for the race condition in LWIP, see https://github.com/espressif/arduino-esp32/pull/9016#discussion_r1451774885 { uint32_t i = 5; // try 5 times only +#if ESP_IDF_VERSION_MAJOR >= 5 + while (esp_netif_create_ip6_linklocal(ETH.netif()) != ESP_OK) { + delay(1); + if (i-- == 0) { + AddLog(LOG_LEVEL_INFO, PSTR(D_LOG_ETH ">>>> HELP")); + break; + } + } +#else while (esp_netif_create_ip6_linklocal(get_esp_interface_netif(ESP_IF_ETH)) != ESP_OK) { delay(1); if (i-- == 0) { @@ -118,6 +127,7 @@ void EthernetEvent(arduino_event_t *event) { break; } } +#endif AddLog(LOG_LEVEL_DEBUG_MORE, PSTR(D_LOG_ETH "ESP_IF_ETH i=%i"), i); } #endif // USE_IPV6 @@ -145,7 +155,7 @@ void EthernetEvent(arduino_event_t *event) { event->event_info.got_ip.ip_info.ip.addr, event->event_info.got_ip.ip_info.netmask.addr, event->event_info.got_ip.ip_info.gw.addr); - WiFi.scrubDNS(); // internal calls to reconnect can zero the DNS servers, save DNS for future use + WiFiHelper::scrubDNS(); // internal calls to reconnect can zero the DNS servers, save DNS for future use break; #ifdef USE_IPV6 @@ -161,7 +171,7 @@ void EthernetEvent(arduino_event_t *event) { TasmotaGlobal.rules_flag.eth_connected = 1; TasmotaGlobal.global_state.eth_down = 0; } - WiFi.scrubDNS(); // internal calls to reconnect can zero the DNS servers, save DNS for future use + WiFiHelper::scrubDNS(); // internal calls to reconnect can zero the DNS servers, save DNS for future use } break; #endif // USE_IPV6 @@ -233,6 +243,12 @@ void EthernetInit(void) { int eth_mdio = Pin(GPIO_ETH_PHY_MDIO); // Ethernet SPI IRQ int eth_power = Pin(GPIO_ETH_PHY_POWER); // Ethernet SPI RST +#if ESP_IDF_VERSION_MAJOR >= 5 +#ifdef USE_IPV6 + ETH.enableIPv6(); // enable Link-Local +#endif // USE_IPV6 +#endif // ESP_IDF_VERSION_MAJOR >= 5 + bool init_ok = false; #if ESP_IDF_VERSION_MAJOR >= 5 if (Settings->eth_type < 7) { @@ -241,7 +257,7 @@ void EthernetInit(void) { #endif // CONFIG_ETH_USE_ESP32_EMAC } else { // ETH_SPI_SUPPORTS_CUSTOM -// SPISettings(ETH_PHY_SPI_FREQ_MHZ * 1000 * 1000, MSBFIRST, SPI_MODE0); // 20MHz + // SPISettings(ETH_PHY_SPI_FREQ_MHZ * 1000 * 1000, MSBFIRST, SPI_MODE0); // 20MHz SPI.begin(Pin(GPIO_SPI_CLK), Pin(GPIO_SPI_MISO), Pin(GPIO_SPI_MOSI), -1); init_ok = (ETH.begin((eth_phy_type_t)eth_type, Settings->eth_address, eth_mdc, eth_mdio, eth_power, SPI, ETH_PHY_SPI_FREQ_MHZ)); }