From 6d1d01352c898e2aeac472decfc3a941ece12e94 Mon Sep 17 00:00:00 2001 From: TD-er Date: Wed, 20 Dec 2023 18:11:10 +0100 Subject: [PATCH] [ESP-IDF5.1] Add initial support for IPv6 --- platformio_esp32_envs.ini | 4 +- src/src/DataStructs/TimingStats.h | 7 ++- src/src/ESPEasyCore/ESPEasyNetwork.cpp | 67 ++++++++++++++++++++++++ src/src/ESPEasyCore/ESPEasyNetwork.h | 4 ++ src/src/ESPEasyCore/ESPEasyWiFiEvent.cpp | 12 +++++ src/src/ESPEasyCore/ESPEasyWifi.cpp | 4 ++ src/src/Helpers/StringProvider.cpp | 8 +++ src/src/Helpers/StringProvider.h | 6 +++ src/src/WebServer/JSON.cpp | 4 ++ src/src/WebServer/RootPage.cpp | 8 +++ src/src/WebServer/SysInfoPage.cpp | 9 ++++ 11 files changed, 130 insertions(+), 3 deletions(-) diff --git a/platformio_esp32_envs.ini b/platformio_esp32_envs.ini index 7639cccd6..5b13b43d1 100644 --- a/platformio_esp32_envs.ini +++ b/platformio_esp32_envs.ini @@ -50,7 +50,6 @@ extra_scripts = post:tools/pio/post_esp32.py ; -mtext-section-literals may be required when building large builds ; However LTO cannot optimize builds with text section literals and thus will result in quite a lot larger builds (80k - 140k larger) build_unflags = -Wall - -DLWIP_IPV6 -fno-lto build_flags = ${core_esp32_IDF5_1__3_0_0.build_flags} ; ${mqtt_flags.build_flags} @@ -60,7 +59,8 @@ build_flags = ${core_esp32_IDF5_1__3_0_0.build_flags} -fno-strict-aliasing -flto=auto -Wswitch - -DCORE_DEBUG_LEVEL=ARDUHAL_LOG_LEVEL_ERROR + -DCORE_DEBUG_LEVEL=ARDUHAL_LOG_LEVEL_NONE + -DLWIP_IPV6 monitor_filters = esp32_exception_decoder lib_ignore = ${core_esp32_IDF5_1__3_0_0.lib_ignore} diff --git a/src/src/DataStructs/TimingStats.h b/src/src/DataStructs/TimingStats.h index cd751ad02..f7cf26915 100644 --- a/src/src/DataStructs/TimingStats.h +++ b/src/src/DataStructs/TimingStats.h @@ -25,6 +25,9 @@ enum class TimingStatsElements { // Controller queue MQTT_DELAY_QUEUE, + + // Do not interrupt this sequence of Cxxx_DELAY_QUEUE + // as its order is used to generate MiscStatsName C001_DELAY_QUEUE, C002_DELAY_QUEUE, C003_DELAY_QUEUE, @@ -43,7 +46,6 @@ enum class TimingStatsElements { C016_DELAY_QUEUE, C017_DELAY_QUEUE, C018_DELAY_QUEUE, - C018_AIR_TIME, C019_DELAY_QUEUE, C020_DELAY_QUEUE, C021_DELAY_QUEUE, @@ -52,6 +54,9 @@ enum class TimingStatsElements { C024_DELAY_QUEUE, C025_DELAY_QUEUE, + // Controller specific timing stats + C018_AIR_TIME, + // Related to Task runs & sending data + rules PLUGIN_CALL_50PS, diff --git a/src/src/ESPEasyCore/ESPEasyNetwork.cpp b/src/src/ESPEasyCore/ESPEasyNetwork.cpp index 443a09c27..affd8180c 100644 --- a/src/src/ESPEasyCore/ESPEasyNetwork.cpp +++ b/src/src/ESPEasyCore/ESPEasyNetwork.cpp @@ -18,6 +18,18 @@ #include #endif + +#ifdef LWIP_IPV6 +#include + +// ----------------------------------------------------------------------------------------------------------------------- +// ---------------------------------------------------- Private functions ------------------------------------------------ +// ----------------------------------------------------------------------------------------------------------------------- + +esp_netif_t* get_esp_interface_netif(esp_interface_t interface); +#endif + + void setNetworkMedium(NetworkMedium_t new_medium) { #if !(FEATURE_ETHERNET) if (new_medium == NetworkMedium_t::Ethernet) { @@ -139,6 +151,61 @@ IPAddress NetworkDnsIP(uint8_t dns_no) { return WiFi.dnsIP(dns_no); } +#ifdef LWIP_IPV6 + + +IPAddress NetworkLocalIP6() { + esp_interface_t iface = ESP_IF_MAX; + #if FEATURE_ETHERNET + if(active_network_medium == NetworkMedium_t::Ethernet) { + if(EthEventData.ethInitSuccess) { + iface = ESP_IF_ETH; + } + } else + #endif + { + if (WifiIsSTA(WiFi.getMode())) { + iface = ESP_IF_WIFI_STA; + } + } + esp_ip6_addr_t addr; + if(ESP_IF_MAX == iface || + esp_netif_get_ip6_linklocal(get_esp_interface_netif(iface), &addr)) + { + return IN6ADDR_ANY; + } + + IPAddress res(IPv6, (const uint8_t*)addr.addr, addr.zone); + return res; +} + +IPAddress NetworkGlobalIP6() { + esp_interface_t iface = ESP_IF_MAX; + #if FEATURE_ETHERNET + if(active_network_medium == NetworkMedium_t::Ethernet) { + if(EthEventData.ethInitSuccess) { + iface = ESP_IF_ETH; + } + } else + #endif + { + if (WifiIsSTA(WiFi.getMode())) { + iface = ESP_IF_WIFI_STA; + } + } + esp_ip6_addr_t addr; + if(ESP_IF_MAX == iface || + esp_netif_get_ip6_global(get_esp_interface_netif(iface), &addr)) + { + return IN6ADDR_ANY; + } + + IPAddress res(IPv6, (const uint8_t*)addr.addr, addr.zone); + return res; +} +#endif + + MAC_address NetworkMacAddress() { #if FEATURE_ETHERNET if(active_network_medium == NetworkMedium_t::Ethernet) { diff --git a/src/src/ESPEasyCore/ESPEasyNetwork.h b/src/src/ESPEasyCore/ESPEasyNetwork.h index 0da1e4b61..509514286 100644 --- a/src/src/ESPEasyCore/ESPEasyNetwork.h +++ b/src/src/ESPEasyCore/ESPEasyNetwork.h @@ -15,6 +15,10 @@ IPAddress NetworkLocalIP(); IPAddress NetworkSubnetMask(); IPAddress NetworkGatewayIP(); IPAddress NetworkDnsIP (uint8_t dns_no); +#ifdef LWIP_IPV6 +IPAddress NetworkLocalIP6(); +IPAddress NetworkGlobalIP6(); +#endif MAC_address NetworkMacAddress(); String NetworkGetHostNameFromSettings(bool force_add_unitnr = false); String NetworkGetHostname(); diff --git a/src/src/ESPEasyCore/ESPEasyWiFiEvent.cpp b/src/src/ESPEasyCore/ESPEasyWiFiEvent.cpp index 9815a8860..5e3199354 100644 --- a/src/src/ESPEasyCore/ESPEasyWiFiEvent.cpp +++ b/src/src/ESPEasyCore/ESPEasyWiFiEvent.cpp @@ -160,6 +160,18 @@ void WiFiEvent(WiFiEvent_t event, arduino_event_info_t info) { ignoreDisconnectEvent = false; WiFiEventData.markGotIP(); break; + #if ESP_IDF_VERSION_MAJOR >= 5 + case ARDUINO_EVENT_WIFI_STA_GOT_IP6: + { + ip_event_got_ip6_t * event = static_cast(&info.got_ip6); + IPAddress ip(IPv6, (const uint8_t*)event->ip6_info.ip.addr, event->ip6_info.ip.zone); + addLog(LOG_LEVEL_INFO, String(F("WIFI : STA got IP6 ")) + ip.toString()); + break; + } + case ARDUINO_EVENT_WIFI_AP_GOT_IP6: + addLog(LOG_LEVEL_INFO, F("WIFI : AP got IP6")); + break; + #endif case ARDUINO_EVENT_WIFI_AP_STACONNECTED: #if ESP_IDF_VERSION_MAJOR > 3 WiFiEventData.markConnectedAPmode(info.wifi_ap_staconnected.mac); diff --git a/src/src/ESPEasyCore/ESPEasyWifi.cpp b/src/src/ESPEasyCore/ESPEasyWifi.cpp index b42771c95..d3a640d97 100644 --- a/src/src/ESPEasyCore/ESPEasyWifi.cpp +++ b/src/src/ESPEasyCore/ESPEasyWifi.cpp @@ -469,6 +469,10 @@ void AttemptWiFiConnect() { WiFiEventData.wifiConnectInProgress = true; const String key = WiFi_AP_CandidatesList::get_key(candidate.index); +#if ESP_IDF_VERSION_MAJOR>=5 && defined(LWIP_IPV6) + WiFi.IPv6(true); +#endif + if ((Settings.HiddenSSID_SlowConnectPerBSSID() || !candidate.isHidden) && candidate.allowQuickConnect()) { WiFi.begin(candidate.ssid.c_str(), key.c_str(), candidate.channel, candidate.bssid.mac); diff --git a/src/src/Helpers/StringProvider.cpp b/src/src/Helpers/StringProvider.cpp index 00d44aabb..2155c9940 100644 --- a/src/src/Helpers/StringProvider.cpp +++ b/src/src/Helpers/StringProvider.cpp @@ -151,6 +151,10 @@ const __FlashStringHelper * getLabel(LabelType::Enum label) { case LabelType::WIFI_CONNECTION: return F("WiFi Connection"); case LabelType::WIFI_RSSI: return F("RSSI"); case LabelType::IP_CONFIG: return F("IP Config"); +#ifdef LWIP_IPV6 + case LabelType::IP6_LOCAL: return F("IPv6 link local"); + case LabelType::IP6_GLOBAL: return F("IPv6 global"); +#endif case LabelType::IP_CONFIG_STATIC: return F("Static"); case LabelType::IP_CONFIG_DYNAMIC: return F("DHCP"); case LabelType::IP_ADDRESS: return F("IP Address"); @@ -427,6 +431,10 @@ String getValue(LabelType::Enum label) { case LabelType::IP_SUBNET: return formatIP(NetworkSubnetMask()); case LabelType::IP_ADDRESS_SUBNET: return strformat(F("%s / %s"), getValue(LabelType::IP_ADDRESS).c_str(), getValue(LabelType::IP_SUBNET).c_str()); case LabelType::GATEWAY: return formatIP(NetworkGatewayIP()); +#ifdef LWIP_IPV6 + case LabelType::IP6_LOCAL: return formatIP(NetworkLocalIP6()); + case LabelType::IP6_GLOBAL: return formatIP(NetworkGlobalIP6()); +#endif case LabelType::CLIENT_IP: return formatIP(web_server.client().remoteIP()); #if FEATURE_INTERNAL_TEMPERATURE case LabelType::INTERNAL_TEMPERATURE: return toString(getInternalTemperature()); diff --git a/src/src/Helpers/StringProvider.h b/src/src/Helpers/StringProvider.h index 292ba7818..07546da95 100644 --- a/src/src/Helpers/StringProvider.h +++ b/src/src/Helpers/StringProvider.h @@ -104,6 +104,12 @@ struct LabelType { IP_SUBNET, // 255.255.255.0 IP_ADDRESS_SUBNET, // 192.168.1.123 / 255.255.255.0 GATEWAY, // 192.168.1.1 +#ifdef LWIP_IPV6 + IP6_LOCAL, + IP6_GLOBAL, +// IP6_ADDRESS_CDIR, +// IP6_GATEWAY, +#endif CLIENT_IP, // 192.168.1.67 #if FEATURE_MDNS M_DNS, // breadboard.local diff --git a/src/src/WebServer/JSON.cpp b/src/src/WebServer/JSON.cpp index 67e866472..44836976c 100644 --- a/src/src/WebServer/JSON.cpp +++ b/src/src/WebServer/JSON.cpp @@ -235,6 +235,10 @@ void handle_json() #endif // if FEATURE_MDNS LabelType::IP_CONFIG, LabelType::IP_ADDRESS, +#ifdef LWIP_IPV6 + LabelType::IP6_LOCAL, + LabelType::IP6_GLOBAL, +#endif LabelType::IP_SUBNET, LabelType::GATEWAY, LabelType::STA_MAC, diff --git a/src/src/WebServer/RootPage.cpp b/src/src/WebServer/RootPage.cpp index 7c53405a3..5d3801ee9 100644 --- a/src/src/WebServer/RootPage.cpp +++ b/src/src/WebServer/RootPage.cpp @@ -196,6 +196,10 @@ void handle_root() { if (!WiFiEventData.WiFiDisconnected()) { addRowLabelValue(LabelType::IP_ADDRESS); +#ifdef LWIP_IPV6 + addRowLabelValue(LabelType::IP6_LOCAL); + addRowLabelValue(LabelType::IP6_GLOBAL); +#endif addRowLabel(LabelType::WIFI_RSSI); addHtml(strformat( F("%d dBm (%s)"), @@ -208,6 +212,10 @@ void handle_root() { if (active_network_medium == NetworkMedium_t::Ethernet) { addRowLabelValue(LabelType::ETH_SPEED_STATE); addRowLabelValue(LabelType::ETH_IP_ADDRESS); +#ifdef LWIP_IPV6 + addRowLabelValue(LabelType::IP6_LOCAL); + addRowLabelValue(LabelType::IP6_GLOBAL); +#endif } # endif // if FEATURE_ETHERNET diff --git a/src/src/WebServer/SysInfoPage.cpp b/src/src/WebServer/SysInfoPage.cpp index c7d8b64f8..4b3ef01c3 100644 --- a/src/src/WebServer/SysInfoPage.cpp +++ b/src/src/WebServer/SysInfoPage.cpp @@ -120,6 +120,11 @@ void handle_sysinfo_json() { json_number(F("rssi"), String(WiFi.RSSI())); json_prop(F("dhcp"), useStaticIP() ? getLabel(LabelType::IP_CONFIG_STATIC) : getLabel(LabelType::IP_CONFIG_DYNAMIC)); json_prop(F("ip"), getValue(LabelType::IP_ADDRESS)); +#ifdef LWIP_IPV6 + json_prop(F("ip6_local"), getValue(LabelType::IP6_LOCAL)); + json_prop(F("ip6_global"), getValue(LabelType::IP6_GLOBAL)); +#endif + json_prop(F("subnet"), getValue(LabelType::IP_SUBNET)); json_prop(F("gw"), getValue(LabelType::GATEWAY)); json_prop(F("dns1"), getValue(LabelType::DNS_1)); @@ -428,6 +433,10 @@ void handle_sysinfo_Network() { # endif LabelType::IP_CONFIG, LabelType::IP_ADDRESS_SUBNET, +#ifdef LWIP_IPV6 + LabelType::IP6_LOCAL, + LabelType::IP6_GLOBAL, +#endif LabelType::GATEWAY, LabelType::CLIENT_IP, LabelType::DNS,