From dadbc1aefa267d1868aa189da6a3ee16bb318674 Mon Sep 17 00:00:00 2001 From: Jimmy Hedman Date: Tue, 12 Sep 2023 22:05:02 +0200 Subject: [PATCH] Enable IPv6 for ESP8266 and Raspberry pi pico w (RP2040) (#4759) --- esphome/components/async_tcp/__init__.py | 2 +- esphome/components/mdns/mdns_esp8266.cpp | 3 +- esphome/components/mqtt/__init__.py | 4 +-- esphome/components/mqtt/mqtt_client.cpp | 10 ------- esphome/components/network/__init__.py | 29 ++++++++++--------- esphome/components/socket/socket.cpp | 2 +- .../wifi/wifi_component_esp8266.cpp | 17 +++++++++-- .../components/wifi/wifi_component_pico_w.cpp | 4 +++ platformio.ini | 4 +-- 9 files changed, 41 insertions(+), 34 deletions(-) diff --git a/esphome/components/async_tcp/__init__.py b/esphome/components/async_tcp/__init__.py index 1677d4b9a8..fa74f7103f 100644 --- a/esphome/components/async_tcp/__init__.py +++ b/esphome/components/async_tcp/__init__.py @@ -19,4 +19,4 @@ async def to_code(config): cg.add_library("esphome/AsyncTCP-esphome", "2.0.1") elif CORE.is_esp8266: # https://github.com/esphome/ESPAsyncTCP - cg.add_library("esphome/ESPAsyncTCP-esphome", "1.2.3") + cg.add_library("esphome/ESPAsyncTCP-esphome", "2.0.0") diff --git a/esphome/components/mdns/mdns_esp8266.cpp b/esphome/components/mdns/mdns_esp8266.cpp index 4ccfe42baa..5ff1b86341 100644 --- a/esphome/components/mdns/mdns_esp8266.cpp +++ b/esphome/components/mdns/mdns_esp8266.cpp @@ -13,8 +13,7 @@ namespace mdns { void MDNSComponent::setup() { this->compile_records_(); - network::IPAddress addr = network::get_ip_address(); - MDNS.begin(this->hostname_.c_str(), (uint32_t) addr); + MDNS.begin(this->hostname_.c_str()); for (const auto &service : this->services_) { // Strip the leading underscore from the proto and service_type. While it is diff --git a/esphome/components/mqtt/__init__.py b/esphome/components/mqtt/__init__.py index 102c070eb6..9df2067832 100644 --- a/esphome/components/mqtt/__init__.py +++ b/esphome/components/mqtt/__init__.py @@ -273,8 +273,8 @@ async def to_code(config): await cg.register_component(var, config) # Add required libraries for ESP8266 if CORE.is_esp8266: - # https://github.com/OttoWinter/async-mqtt-client/blob/master/library.json - cg.add_library("ottowinter/AsyncMqttClient-esphome", "0.8.6") + # https://github.com/heman/async-mqtt-client/blob/master/library.json + cg.add_library("heman/AsyncMqttClient-esphome", "1.0.0") cg.add_define("USE_MQTT") cg.add_global(mqtt_ns.using) diff --git a/esphome/components/mqtt/mqtt_client.cpp b/esphome/components/mqtt/mqtt_client.cpp index 1d804170f6..0c6da42328 100644 --- a/esphome/components/mqtt/mqtt_client.cpp +++ b/esphome/components/mqtt/mqtt_client.cpp @@ -168,15 +168,10 @@ void MQTTClientComponent::start_dnslookup_() { case ERR_OK: { // Got IP immediately this->dns_resolved_ = true; -#ifdef USE_ESP32 #if LWIP_IPV6 this->ip_ = addr.u_addr.ip4.addr; #else this->ip_ = addr.addr; -#endif -#endif -#ifdef USE_ESP8266 - this->ip_ = addr.addr; #endif this->start_connect_(); return; @@ -228,15 +223,10 @@ void MQTTClientComponent::dns_found_callback(const char *name, const ip_addr_t * if (ipaddr == nullptr) { a_this->dns_resolve_error_ = true; } else { -#ifdef USE_ESP32 #if LWIP_IPV6 a_this->ip_ = ipaddr->u_addr.ip4.addr; #else a_this->ip_ = ipaddr->addr; -#endif -#endif // USE_ESP32 -#ifdef USE_ESP8266 - a_this->ip_ = ipaddr->addr; #endif a_this->dns_resolved_ = true; } diff --git a/esphome/components/network/__init__.py b/esphome/components/network/__init__.py index 83778e0bf4..dd1353f86f 100644 --- a/esphome/components/network/__init__.py +++ b/esphome/components/network/__init__.py @@ -15,22 +15,23 @@ IPAddress = network_ns.class_("IPAddress") CONFIG_SCHEMA = cv.Schema( { - cv.SplitDefault(CONF_ENABLE_IPV6, esp32=False): cv.All( - cv.only_on_esp32, cv.boolean - ), + cv.Optional(CONF_ENABLE_IPV6, default=False): cv.boolean, } ) async def to_code(config): - if CONF_ENABLE_IPV6 in config: - cg.add_define("ENABLE_IPV6", config[CONF_ENABLE_IPV6]) - if CORE.using_esp_idf: - add_idf_sdkconfig_option("CONFIG_LWIP_IPV6", config[CONF_ENABLE_IPV6]) - add_idf_sdkconfig_option( - "CONFIG_LWIP_IPV6_AUTOCONFIG", config[CONF_ENABLE_IPV6] - ) - else: - if config[CONF_ENABLE_IPV6]: - cg.add_build_flag("-DCONFIG_LWIP_IPV6") - cg.add_build_flag("-DCONFIG_LWIP_IPV6_AUTOCONFIG") + cg.add_define("ENABLE_IPV6", config[CONF_ENABLE_IPV6]) + if CORE.using_esp_idf: + add_idf_sdkconfig_option("CONFIG_LWIP_IPV6", config[CONF_ENABLE_IPV6]) + add_idf_sdkconfig_option( + "CONFIG_LWIP_IPV6_AUTOCONFIG", config[CONF_ENABLE_IPV6] + ) + else: + if config[CONF_ENABLE_IPV6]: + cg.add_build_flag("-DCONFIG_LWIP_IPV6") + cg.add_build_flag("-DCONFIG_LWIP_IPV6_AUTOCONFIG") + if CORE.is_rp2040: + cg.add_build_flag("-DPIO_FRAMEWORK_ARDUINO_ENABLE_IPV6") + if CORE.is_esp8266: + cg.add_build_flag("-DPIO_FRAMEWORK_ARDUINO_LWIP2_IPV6_LOW_MEMORY") diff --git a/esphome/components/socket/socket.cpp b/esphome/components/socket/socket.cpp index 4c78397873..824e04150b 100644 --- a/esphome/components/socket/socket.cpp +++ b/esphome/components/socket/socket.cpp @@ -60,7 +60,7 @@ socklen_t set_sockaddr_any(struct sockaddr *addr, socklen_t addrlen, uint16_t po memset(server, 0, sizeof(sockaddr_in6)); server->sin6_family = AF_INET6; server->sin6_port = htons(port); - server->sin6_addr = in6addr_any; + server->sin6_addr = IN6ADDR_ANY_INIT; return sizeof(sockaddr_in6); #else if (addrlen < sizeof(sockaddr_in)) { diff --git a/esphome/components/wifi/wifi_component_esp8266.cpp b/esphome/components/wifi/wifi_component_esp8266.cpp index a28aa8b858..1afa439567 100644 --- a/esphome/components/wifi/wifi_component_esp8266.cpp +++ b/esphome/components/wifi/wifi_component_esp8266.cpp @@ -19,6 +19,7 @@ extern "C" { #include "lwip/apps/sntp.h" #if LWIP_IPV6 #include "lwip/netif.h" // struct netif +#include #endif #if USE_ARDUINO_VERSION_CODE >= VERSION_CODE(3, 0, 0) #include "LwipDhcpServer.h" @@ -164,11 +165,11 @@ bool WiFiComponent::wifi_sta_ip_config_(optional manual_ip) { ip_addr_t dns; if (uint32_t(manual_ip->dns1) != 0) { - dns.addr = static_cast(manual_ip->dns1); + ip_addr_set_ip4_u32_val(dns, static_cast(manual_ip->dns1)); dns_setserver(0, &dns); } if (uint32_t(manual_ip->dns2) != 0) { - dns.addr = static_cast(manual_ip->dns2); + ip_addr_set_ip4_u32_val(dns, static_cast(manual_ip->dns2)); dns_setserver(1, &dns); } @@ -325,6 +326,18 @@ bool WiFiComponent::wifi_sta_connect_(const WiFiAP &ap) { return false; } +#if ENABLE_IPV6 + for (bool configured = false; !configured;) { + for (auto addr : addrList) { + ESP_LOGV(TAG, "Address %s", addr.toString().c_str()); + if ((configured = !addr.isLocal() && addr.isV6())) { + break; + } + } + delay(500); // NOLINT + } +#endif + if (ap.get_channel().has_value()) { ret = wifi_set_channel(*ap.get_channel()); if (!ret) { diff --git a/esphome/components/wifi/wifi_component_pico_w.cpp b/esphome/components/wifi/wifi_component_pico_w.cpp index 489ebc3699..149ca61cd5 100644 --- a/esphome/components/wifi/wifi_component_pico_w.cpp +++ b/esphome/components/wifi/wifi_component_pico_w.cpp @@ -175,7 +175,11 @@ network::IPAddress WiFiComponent::wifi_subnet_mask_() { return {WiFi.subnetMask( network::IPAddress WiFiComponent::wifi_gateway_ip_() { return {WiFi.gatewayIP()}; } network::IPAddress WiFiComponent::wifi_dns_ip_(int num) { const ip_addr_t *dns_ip = dns_getserver(num); +#ifdef PIO_FRAMEWORK_ARDUINO_ENABLE_IPV6 + return {dns_ip->u_addr.ip4.addr}; +#else return {dns_ip->addr}; +#endif } void WiFiComponent::wifi_loop_() { diff --git a/platformio.ini b/platformio.ini index aea164353d..73cd7c65c8 100644 --- a/platformio.ini +++ b/platformio.ini @@ -57,6 +57,7 @@ lib_deps = ${common.lib_deps} SPI ; spi (Arduino built-in) Wire ; i2c (Arduino built-int) + heman/AsyncMqttClient-esphome@1.0.0 ; mqtt esphome/ESPAsyncWebServer-esphome@2.1.0 ; web_server_base fastled/FastLED@3.3.2 ; fastled_base mikalhart/TinyGPSPlus@1.0.2 ; gps @@ -88,8 +89,7 @@ lib_deps = ${common:arduino.lib_deps} ESP8266WiFi ; wifi (Arduino built-in) Update ; ota (Arduino built-in) - ottowinter/AsyncMqttClient-esphome@0.8.6 ; mqtt - esphome/ESPAsyncTCP-esphome@1.2.3 ; async_tcp + esphome/ESPAsyncTCP-esphome@2.0.0 ; async_tcp ESP8266HTTPClient ; http_request (Arduino built-in) ESP8266mDNS ; mdns (Arduino built-in) DNSServer ; captive_portal (Arduino built-in)