From 9045a7da8322bb70a046f8b3b7ac1a6118e2f5bf Mon Sep 17 00:00:00 2001 From: s-hadinger <49731213+s-hadinger@users.noreply.github.com> Date: Mon, 15 Jan 2024 21:05:40 +0100 Subject: [PATCH] IP stack compatible with new Core3 IPv6 implementation (#20509) * IP stack compatible with new Core3 IPv6 implementation * Fix compilation * Forece CI --- CHANGELOG.md | 1 + .../ESP32-to-ESP8266-compat/src/ESP32Wifi.cpp | 22 +++-- .../berry_matter/src/be_matter_misc.cpp | 6 +- tasmota/tasmota_support/support_wifi.ino | 93 +++++++++++-------- tasmota/tasmota_xdrv_driver/xdrv_38_ping.ino | 4 +- .../xdrv_52_3_berry_mdns.ino | 15 +-- .../xdrv_52_3_berry_tcpclientasync.ino | 4 +- .../xdrv_52_3_berry_tcpserver.ino | 4 +- .../xdrv_52_3_berry_udp.ino | 10 +- .../xdrv_82_esp32_ethernet.ino | 25 ++++- 10 files changed, 115 insertions(+), 69 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index eac36086e..f5f5fff3d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -17,6 +17,7 @@ All notable changes to this project will be documented in this file. ### Breaking Changed ### Changed +- IP stack compatible with new Core3 IPv6 implementation () ### Fixed - Scripter memory leak in `>w x` (#20473) diff --git a/lib/libesp32/ESP32-to-ESP8266-compat/src/ESP32Wifi.cpp b/lib/libesp32/ESP32-to-ESP8266-compat/src/ESP32Wifi.cpp index ea288d547..c5cdedc3f 100644 --- a/lib/libesp32/ESP32-to-ESP8266-compat/src/ESP32Wifi.cpp +++ b/lib/libesp32/ESP32-to-ESP8266-compat/src/ESP32Wifi.cpp @@ -89,10 +89,12 @@ void WiFiClass32::scrubDNS(void) { const IPAddress ip_dns = IPAddress(dns_getserver(i)); // Step 1. save valid values from DNS if (!ip_addr_isany_val((const ip_addr_t &)ip_dns)) { - if (ip_dns.isV4() && has_v4) { - dns_save4[i] = (ip_addr_t) ip_dns; // dns entry is populated, save it in v4 slot - } else if (ip_dns.isV6() && has_v6) { - dns_save6[i] = (ip_addr_t) ip_dns; // dns entry is populated, save it in v6 slot + if (ip_dns.type() == IPv4 && has_v4) { + ip_dns.to_ip_addr_t(&dns_save4[i]); + // dns_save4[i] = (ip_addr_t) ip_dns; // dns entry is populated, save it in v4 slot + } else if (has_v6) { + ip_dns.to_ip_addr_t(&dns_save6[i]); + // dns_save6[i] = (ip_addr_t) ip_dns; // dns entry is populated, save it in v6 slot } } @@ -213,7 +215,7 @@ static void wifi32_dns_found_callback(const char *name, const ip_addr_t *ipaddr, } // We need this helper method to access protected methods from WiFiGeneric void WiFiClass32::dnsDone(void) { - setStatusBits(WIFI_DNS_DONE_BIT); + setStatusBits(NET_DNS_DONE_BIT); } /** @@ -231,7 +233,7 @@ int WiFiClass32::hostByName(const char* aHostname, IPAddress& aResult, int32_t t 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(WIFI_DNS_IDLE_BIT | WIFI_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; @@ -240,18 +242,18 @@ int WiFiClass32::hostByName(const char* aHostname, IPAddress& aResult, int32_t t // 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)) { #ifdef USE_IPV6 - aResult = dns_ipaddr; + aResult.from_ip_addr_t(&dns_ipaddr); #else // USE_IPV6 aResult = ip_addr_get_ip4_u32(&dns_ipaddr); #endif // USE_IPV6 } else if(err == ERR_INPROGRESS) { - waitStatusBits(WIFI_DNS_DONE_BIT, timer_ms); //real internal timeout in lwip library is 14[s] - clearStatusBits(WIFI_DNS_DONE_BIT); + waitStatusBits(NET_DNS_DONE_BIT, timer_ms); //real internal timeout in lwip library is 14[s] + clearStatusBits(NET_DNS_DONE_BIT); } if (!ip_addr_isany_val(dns_ipaddr)) { #ifdef USE_IPV6 - aResult = dns_ipaddr; + aResult.from_ip_addr_t(&dns_ipaddr); #else // USE_IPV6 aResult = ip_addr_get_ip4_u32(&dns_ipaddr); #endif // USE_IPV6 diff --git a/lib/libesp32/berry_matter/src/be_matter_misc.cpp b/lib/libesp32/berry_matter/src/be_matter_misc.cpp index 0e57c2aa5..32931d6c7 100644 --- a/lib/libesp32/berry_matter/src/be_matter_misc.cpp +++ b/lib/libesp32/berry_matter/src/be_matter_misc.cpp @@ -32,12 +32,14 @@ extern "C" const void* matter_get_ip_bytes(const char* ip_str, size_t* ret_len) IPAddress ip; if (ip.fromString(ip_str)) { #ifdef USE_IPV6 - if (ip.isV4()) { + if (ip.type() == IPv4) { uint32_t ip_32 = ip; memcpy(ip_bytes, &ip_32, 4); *ret_len = 4; } else { - memcpy(ip_bytes, ip.raw6(), 16); + ip_addr_t ip_addr; + ip.to_ip_addr_t(&ip_addr); + memcpy(ip_bytes, &ip_addr.u_addr.ip6, 16); *ret_len = 16; } #else diff --git a/tasmota/tasmota_support/support_wifi.ino b/tasmota/tasmota_support/support_wifi.ino index c76a278a1..fbf6dc1b1 100644 --- a/tasmota/tasmota_support/support_wifi.ino +++ b/tasmota/tasmota_support/support_wifi.ino @@ -209,7 +209,7 @@ void WifiBegin(uint8_t flag, uint8_t channel) { WiFi.persistent(false); // Solve possible wifi init errors (re-add at 6.2.1.16 #4044, #4083) #if defined(USE_IPV6) && defined(ESP32) - WiFi.IPv6(true); + WiFi.enableIPv6(true); #endif #ifdef USE_WIFI_RANGE_EXTENDER @@ -545,6 +545,11 @@ String EthernetGetIPv4Str(void) } #ifdef USE_IPV6 +bool IPv6isLocal(const IPAddress & ip) { + return ip.addr_type() == ESP_IP6_ADDR_IS_LINK_LOCAL; // TODO +} + +#include "lwip/netif.h" // // Scan through all interfaces to find a global or local IPv6 address // Arg: @@ -557,7 +562,7 @@ bool WifiFindIPv6(IPAddress *ip, bool is_local, const char * if_type = "st") { for (uint32_t i = 0; i < LWIP_IPV6_NUM_ADDRESSES; i++) { ip_addr_t *ipv6 = &intf->ip6_addr[i]; if (IP_IS_V6_VAL(*ipv6) && !ip_addr_isloopback(ipv6) && !ip_addr_isany(ipv6) && ((bool)ip_addr_islinklocal(ipv6) == is_local)) { - if (ip != nullptr) { *ip = *ipv6; } + if (ip != nullptr) { ip->from_ip_addr_t(ipv6); } return true; } } @@ -579,7 +584,7 @@ bool WifiHasIPv6(void) String WifiGetIPv6Str(void) { IPAddress ip; - return WifiGetIPv6(&ip) ? ip.toString() : String(); + return WifiGetIPv6(&ip) ? ip.toString(true) : String(); } bool WifiGetIPv6LinkLocal(IPAddress *ip) @@ -589,7 +594,7 @@ bool WifiGetIPv6LinkLocal(IPAddress *ip) String WifiGetIPv6LinkLocalStr(void) { IPAddress ip; - return WifiGetIPv6LinkLocal(&ip) ? ip.toString() : String(); + return WifiGetIPv6LinkLocal(&ip) ? ip.toString(true) : String(); } @@ -605,7 +610,7 @@ bool EthernetHasIPv6(void) String EthernetGetIPv6Str(void) { IPAddress ip; - return EthernetGetIPv6(&ip) ? ip.toString() : String(); + return EthernetGetIPv6(&ip) ? ip.toString(true) : String(); } bool EthernetGetIPv6LinkLocal(IPAddress *ip) @@ -619,7 +624,7 @@ bool EthernetHasIPv6LinkLocal(void) String EthernetGetIPv6LinkLocalStr(void) { IPAddress ip; - return EthernetGetIPv6LinkLocal(&ip) ? ip.toString() : String(); + return EthernetGetIPv6LinkLocal(&ip) ? ip.toString(true) : String(); } bool DNSGetIP(IPAddress *ip, uint32_t idx) @@ -629,16 +634,16 @@ bool DNSGetIP(IPAddress *ip, uint32_t idx) #endif const ip_addr_t *ip_dns = dns_getserver(idx); if (!ip_addr_isany(ip_dns)) { - if (ip != nullptr) { *ip = *ip_dns; } + if (ip != nullptr) { ip->from_ip_addr_t((ip_addr_t*)ip_dns); } return true; } - if (ip != nullptr) { *ip = *IP4_ADDR_ANY; } + if (ip != nullptr) { ip->from_ip_addr_t((ip_addr_t*)IP4_ADDR_ANY); } return false; } String DNSGetIPStr(uint32_t idx) { IPAddress ip; - return DNSGetIP(&ip, idx) ? ip.toString() : String(F("0.0.0.0")); + return DNSGetIP(&ip, idx) ? ip.toString(true) : String(F("0.0.0.0")); } // @@ -646,15 +651,15 @@ String DNSGetIPStr(uint32_t idx) void WifiDumpAddressesIPv6(void) { for (netif* intf = netif_list; intf != nullptr; intf = intf->next) { - if (!ip_addr_isany_val(intf->ip_addr)) AddLog(LOG_LEVEL_DEBUG, "WIF: '%c%c%i' IPv4 %s", intf->name[0], intf->name[1], intf->num, IPAddress(intf->ip_addr).toString().c_str()); + if (!ip_addr_isany_val(intf->ip_addr)) AddLog(LOG_LEVEL_DEBUG, "WIF: '%c%c%i' IPv4 %s", intf->name[0], intf->name[1], intf->num, IPAddress(&intf->ip_addr).toString(true).c_str()); for (uint32_t i = 0; i < LWIP_IPV6_NUM_ADDRESSES; i++) { if (!ip_addr_isany_val(intf->ip6_addr[i])) AddLog(LOG_LEVEL_DEBUG, "IP : '%c%c%i' IPv6 %s %s", intf->name[0], intf->name[1], intf->num, - IPAddress(intf->ip6_addr[i]).toString().c_str(), + IPAddress(&intf->ip6_addr[i]).toString(true).c_str(), ip_addr_islinklocal(&intf->ip6_addr[i]) ? "local" : ""); } } - AddLog(LOG_LEVEL_DEBUG, "IP : DNS: %s %s", IPAddress(dns_getserver(0)).toString().c_str(), IPAddress(dns_getserver(1)).toString().c_str()); + AddLog(LOG_LEVEL_DEBUG, "IP : DNS: %s %s", IPAddress(dns_getserver(0)).toString().c_str(), IPAddress(dns_getserver(1)).toString(true).c_str()); AddLog(LOG_LEVEL_DEBUG, "WIF: v4IP: %_I v6IP: %s mainIP: %s", (uint32_t) WiFi.localIP(), WifiGetIPv6Str().c_str(), WifiGetIPStr().c_str()); #if defined(ESP32) && CONFIG_IDF_TARGET_ESP32 && defined(USE_ETHERNET) AddLog(LOG_LEVEL_DEBUG, "ETH: v4IP %_I v6IP: %s mainIP: %s", (uint32_t) EthernetLocalIP(), EthernetGetIPv6Str().c_str(), EthernetGetIPStr().c_str()); @@ -680,8 +685,8 @@ bool IPGetListeningAddress(IPAddress * ip) IPAddress ip_eth; bool has_eth = EthernetGetIP(&ip_eth); if (has_wifi && has_eth) { - if (ip_eth.isV4()) { *ip = ip_eth; return true; } - if (ip_wifi.isV4()) { *ip = ip_wifi; return true; } + if (ip_eth.type() == IPv4) { *ip = ip_eth; return true; } + if (ip_wifi.type() == IPv4) { *ip = ip_wifi; return true; } // both addresses are v6, return ETH *ip = ip_eth; return true; @@ -707,11 +712,11 @@ bool IPGetListeningAddress(IPAddress * ip) String IPGetListeningAddressStr(void) { IPAddress ip; - if (IPGetListeningAddress(&ip)) { - return ip.toString(); - } else { - return String(); - } +#ifdef USE_IPV6 + return IPGetListeningAddress(&ip) ? ip.toString(true) : String(); +#else + return IPGetListeningAddress(&ip) ? ip.toString() : String(); +#endif } // Because of IPv6, we can't test an IP address agains (uint32_t)0L anymore @@ -732,11 +737,11 @@ inline bool IPIsValid(const IPAddress & ip) String IPForUrl(const IPAddress & ip) { #ifdef USE_IPV6 - if (ip.isV4()) { + if (ip.type() == IPv4) { return ip.toString().c_str(); } else { String s('['); - s += ip.toString().c_str(); + s += ip.toString(true).c_str(); s += ']'; return s; } @@ -789,7 +794,11 @@ bool WifiHasIP(void) { String WifiGetIPStr(void) { IPAddress ip; +#ifdef USE_IPV6 + return WifiGetIP(&ip) ? ip.toString(true) : String(); +#else return WifiGetIP(&ip) ? ip.toString() : String(); +#endif } // Has a routable IP, whether IPv4 or IPv6, Wifi or Ethernet @@ -809,9 +818,9 @@ void WifiCheckIp(void) { if (WL_CONNECTED == WiFi.status()) { #ifdef ESP32 if (!Wifi.ipv6_local_link_called) { - WiFi.enableIpV6(); + WiFi.enableIPv6(true); // TODO Wifi.ipv6_local_link_called = true; - // AddLog(LOG_LEVEL_DEBUG, PSTR("WIF: calling enableIpV6")); + // AddLog(LOG_LEVEL_DEBUG, PSTR("WIF: calling enableIPV6")); } #endif } @@ -1279,18 +1288,6 @@ bool WifiHostByName(const char* aHostname, IPAddress& aResult) { uint32_t dns_end = millis(); if (success) { // Host name resolved -#ifdef USE_IPV6 -#if ESP_IDF_VERSION_MAJOR >= 5 - // check if there is a zone-id - // look for '%' in string - const char *s = aHostname; - while (*s && *s != '%') { s++; } - if (*s == '%') { - // we have a zone id - aResult.setZone(netif_name_to_index(s + 1)); - } -#endif -#endif // USE_IPV6 if (0xFFFFFFFF != (uint32_t)aResult) { AddLog(LOG_LEVEL_DEBUG_MORE, PSTR(D_LOG_WIFI "DNS resolved '%s' (%s) in %i ms"), aHostname, aResult.toString().c_str(), dns_end - dns_start); return true; @@ -1376,7 +1373,11 @@ uint64_t WifiGetNtp(void) { uint32_t attempts = 3; while (attempts > 0) { uint32_t port = random(1025, 65535); // Create a random port for the UDP connection. +#ifdef USE_IPV6 + if (udp.begin(IPAddress(IPv6), port) != 0) { +#else if (udp.begin(port) != 0) { +#endif break; } attempts--; @@ -1454,6 +1455,8 @@ uint64_t WifiGetNtp(void) { // Respond to some Arduino/esp-idf events for better IPv6 support // -------------------------------------------------------------------------------- #ifdef ESP32 +extern esp_netif_t* get_esp_interface_netif(esp_interface_t interface); + // typedef void (*WiFiEventSysCb)(arduino_event_t *event); void WifiEvents(arduino_event_t *event) { switch (event->event_id) { @@ -1461,17 +1464,17 @@ void WifiEvents(arduino_event_t *event) { #ifdef USE_IPV6 case ARDUINO_EVENT_WIFI_STA_GOT_IP6: { - ip_addr_t ip_addr6; - ip_addr_copy_from_ip6(ip_addr6, event->event_info.got_ip6.ip6_info.ip); - IPAddress addr(ip_addr6); +// Serial.printf(">>> event ARDUINO_EVENT_WIFI_STA_GOT_IP6 \n"); + IPAddress addr(IPv6, (const uint8_t*)event->event_info.got_ip6.ip6_info.ip.addr, event->event_info.got_ip6.ip6_info.ip.zone); AddLog(LOG_LEVEL_DEBUG, PSTR("%s: IPv6 %s %s"), event->event_id == ARDUINO_EVENT_ETH_GOT_IP6 ? "ETH" : "WIF", - addr.isLocal() ? PSTR("Local") : PSTR("Global"), addr.toString().c_str()); + IPv6isLocal(addr) ? PSTR("Local") : PSTR("Global"), addr.toString(true).c_str()); } break; #endif // USE_IPV6 case ARDUINO_EVENT_WIFI_STA_GOT_IP: { +// Serial.printf(">>> event ARDUINO_EVENT_WIFI_STA_GOT_IP \n"); ip_addr_t ip_addr4; ip_addr_copy_from_ip4(ip_addr4, event->event_info.got_ip.ip_info.ip); AddLog(LOG_LEVEL_DEBUG, PSTR("WIF: IPv4 %_I, mask %_I, gateway %_I"), @@ -1482,6 +1485,18 @@ void WifiEvents(arduino_event_t *event) { break; case ARDUINO_EVENT_WIFI_STA_CONNECTED: + // 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 + while (esp_netif_create_ip6_linklocal(get_esp_interface_netif(ESP_IF_WIFI_STA)) != ESP_OK) { + delay(1); + if (i-- == 0) { + break; + } + } + } + + // WiFi.enableIPv6(); // AddLog(LOG_LEVEL_DEBUG, PSTR("WIF: Received ARDUINO_EVENT_WIFI_STA_CONNECTED")); Wifi.ipv6_local_link_called = false; // not sure if this is needed, make sure link-local is restored at each reconnect break; diff --git a/tasmota/tasmota_xdrv_driver/xdrv_38_ping.ino b/tasmota/tasmota_xdrv_driver/xdrv_38_ping.ino index 77e8c5b6a..4d76a439a 100644 --- a/tasmota/tasmota_xdrv_driver/xdrv_38_ping.ino +++ b/tasmota/tasmota_xdrv_driver/xdrv_38_ping.ino @@ -311,7 +311,7 @@ extern "C" { ip_addr_t ip; ip_addr_set_any_val(false, ip); #ifdef USE_IPV6 - ip = (ip_addr_t)ipfull; + ipfull.to_ip_addr_t(&ip); #else ip_addr_set_ip4_u32_val(ip, (uint32_t)ipfull); #endif @@ -384,7 +384,7 @@ void PingResponsePoll(void) { ping->hostname.c_str(), success ? PSTR("true") : PSTR("false"), #ifdef USE_IPV6 - IPAddress(ping->ip).toString().c_str(), + IPAddress(&ping->ip).toString(true).c_str(), #else IPAddress(ip_addr_get_ip4_u32(&ping->ip)).toString().c_str(), #endif diff --git a/tasmota/tasmota_xdrv_driver/xdrv_52_3_berry_mdns.ino b/tasmota/tasmota_xdrv_driver/xdrv_52_3_berry_mdns.ino index d9f59c756..cfa50cf73 100644 --- a/tasmota/tasmota_xdrv_driver/xdrv_52_3_berry_mdns.ino +++ b/tasmota/tasmota_xdrv_driver/xdrv_52_3_berry_mdns.ino @@ -239,12 +239,14 @@ extern "C" { #ifdef USE_IPV6 // - ip_addr_t *ip_addr = (ip_addr_t*) ip; - head->addr.type = ip_addr->type; - if (ip_addr->type == ESP_IPADDR_TYPE_V6) { - memcpy(head->addr.u_addr.ip6.addr, ip_addr->u_addr.ip6.addr, 16); + // ip_addr_t *ip_addr = (ip_addr_t*) ip; + ip_addr_t ip_addr; + ip.to_ip_addr_t(&ip_addr); + head->addr.type = ip_addr.type; + if (ip_addr.type == ESP_IPADDR_TYPE_V6) { + memcpy(head->addr.u_addr.ip6.addr, ip_addr.u_addr.ip6.addr, 16); } else { - head->addr.u_addr.ip4.addr = ip_addr->u_addr.ip4.addr; + head->addr.u_addr.ip4.addr = ip_addr.u_addr.ip4.addr; } #else head->addr.u_addr.ip4.addr = (uint32_t) ip; @@ -332,10 +334,11 @@ extern "C" { } else { continue; } + be_pushstring(vm, IPAddress(&ip_addr).toString(true).c_str()); #else uint32_t ip_addr = a->addr.u_addr.ip4.addr; - #endif be_pushstring(vm, IPAddress(ip_addr).toString().c_str()); + #endif be_data_push(vm, -2); be_pop(vm, 1); } diff --git a/tasmota/tasmota_xdrv_driver/xdrv_52_3_berry_tcpclientasync.ino b/tasmota/tasmota_xdrv_driver/xdrv_52_3_berry_tcpclientasync.ino index 3e2812c29..69341f1d3 100644 --- a/tasmota/tasmota_xdrv_driver/xdrv_52_3_berry_tcpclientasync.ino +++ b/tasmota/tasmota_xdrv_driver/xdrv_52_3_berry_tcpclientasync.ino @@ -504,10 +504,10 @@ extern "C" { tcp->update_local_addr_port(); if (tcp->local_port > 0) { be_map_insert_int(vm, "local_port", tcp->local_port); - be_map_insert_str(vm, "local_addr", tcp->local_addr.toString().c_str()); + be_map_insert_str(vm, "local_addr", tcp->local_addr.toString(true).c_str()); } be_map_insert_int(vm, "remote_port", tcp->remotePort()); - be_map_insert_str(vm, "remote_addr", tcp->remoteIP().toString().c_str()); + be_map_insert_str(vm, "remote_addr", tcp->remoteIP().toString(true).c_str()); } be_pop(vm, 1); be_return(vm); diff --git a/tasmota/tasmota_xdrv_driver/xdrv_52_3_berry_tcpserver.ino b/tasmota/tasmota_xdrv_driver/xdrv_52_3_berry_tcpserver.ino index b813dddc8..969ec9bd9 100644 --- a/tasmota/tasmota_xdrv_driver/xdrv_52_3_berry_tcpserver.ino +++ b/tasmota/tasmota_xdrv_driver/xdrv_52_3_berry_tcpserver.ino @@ -240,7 +240,7 @@ extern "C" { WiFiClient * client_ptr = nullptr; if (server_tcp->hasClient()) { WiFiClient new_client = server_tcp->available(); - AddLog(LOG_LEVEL_INFO, "BRY: Got connection from %s:%i local %s:%i", new_client.remoteIP().toString().c_str(), new_client.remotePort(), new_client.localIP().toString().c_str(), new_client.localPort()); + AddLog(LOG_LEVEL_INFO, "BRY: Got connection from %s:%i local %s:%i", new_client.remoteIP().toString(true).c_str(), new_client.remotePort(), new_client.localIP().toString().c_str(), new_client.localPort()); client_ptr = new WiFiClient(); *client_ptr = new_client; } else { @@ -254,7 +254,7 @@ extern "C" { AsyncTCPClient * client_ptr = nullptr; if (server_tcp->hasClient()) { client_ptr = server_tcp->availableAsync(); - AddLog(LOG_LEVEL_INFO, "BRY: Got connection from %s:%i local %s:%i", client_ptr->remoteIP().toString().c_str(), client_ptr->remotePort(), client_ptr->localIP().toString().c_str(), client_ptr->localPort()); + AddLog(LOG_LEVEL_INFO, "BRY: Got connection from %s:%i local %s:%i", client_ptr->remoteIP().toString(true).c_str(), client_ptr->remotePort(), client_ptr->localIP().toString().c_str(), client_ptr->localPort()); } else { be_raise(vm, "internal_error", "tcpserver has no client connected"); } diff --git a/tasmota/tasmota_xdrv_driver/xdrv_52_3_berry_udp.ino b/tasmota/tasmota_xdrv_driver/xdrv_52_3_berry_udp.ino index ab80735a7..0bdba475d 100644 --- a/tasmota/tasmota_xdrv_driver/xdrv_52_3_berry_udp.ino +++ b/tasmota/tasmota_xdrv_driver/xdrv_52_3_berry_udp.ino @@ -51,7 +51,11 @@ extern "C" { // udp.begin(interface:string, port:int) -> bool int32_t be_udp_begin_ntv(WiFiUDP *udp, const char *host, int32_t port) { +#ifdef USE_IPV6 + IPAddress addr(IPv6); +#else IPAddress addr; +#endif // if no host or host is "" then we defult to INADDR_ANY if(host && (*host != 0) && !WifiHostByName(host, addr)){ return 0; @@ -66,7 +70,11 @@ extern "C" { // udp.begin_multicast(address:string, port:int) -> nil int32_t be_udp_begin_mcast_ntv(WiFiUDP *udp, const char *host, int32_t port) { +#ifdef USE_IPV6 + IPAddress addr(IPv6); +#else IPAddress addr; +#endif if(!WifiHostByName(host, addr)){ return 0; } @@ -127,7 +135,7 @@ extern "C" { // set remotet ip IPAddress remote_ip = udp->remoteIP(); - be_pushstring(vm, remote_ip.toString().c_str()); + be_pushstring(vm, remote_ip.toString(true).c_str()); be_setmember(vm, 1, "remote_ip"); be_pop(vm, 1); diff --git a/tasmota/tasmota_xdrv_driver/xdrv_82_esp32_ethernet.ino b/tasmota/tasmota_xdrv_driver/xdrv_82_esp32_ethernet.ino index 8ae9c8d6a..63e1d7d51 100644 --- a/tasmota/tasmota_xdrv_driver/xdrv_82_esp32_ethernet.ino +++ b/tasmota/tasmota_xdrv_driver/xdrv_82_esp32_ethernet.ino @@ -85,6 +85,8 @@ char eth_hostname[sizeof(TasmotaGlobal.hostname)]; uint8_t eth_config_change; +extern esp_netif_t* get_esp_interface_netif(esp_interface_t interface); + void EthernetEvent(arduino_event_t *event); void EthernetEvent(arduino_event_t *event) { switch (event->event_id) { @@ -95,14 +97,27 @@ void EthernetEvent(arduino_event_t *event) { case ARDUINO_EVENT_ETH_CONNECTED: #ifdef USE_IPV6 - ETH.enableIpV6(); // enable Link-Local + ETH.enableIPv6(); // enable Link-Local + // 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 + while (esp_netif_create_ip6_linklocal(get_esp_interface_netif(ESP_IF_ETH)) != ESP_OK) { + delay(1); + if (i-- == 0) { + AddLog(LOG_LEVEL_INFO, ">>>> HELP"); + break; + } + } + AddLog(LOG_LEVEL_INFO, ">>>> ESP_IF_ETH i=%i", i); + } #endif // USE_IPV6 + AddLog(LOG_LEVEL_INFO, PSTR(D_LOG_ETH D_CONNECTED " at %dMbps%s, Mac %s, Hostname %s"), ETH.linkSpeed(), (ETH.fullDuplex()) ? " Full Duplex" : "", ETH.macAddress().c_str(), eth_hostname ); - // AddLog(LOG_LEVEL_DEBUG, D_LOG_ETH "ETH.enableIpV6() -> %i", ETH.enableIpV6()); + // AddLog(LOG_LEVEL_DEBUG, D_LOG_ETH "ETH.enableIPV6() -> %i", ETH.enableIPV6()); break; case ARDUINO_EVENT_ETH_GOT_IP: @@ -128,11 +143,11 @@ void EthernetEvent(arduino_event_t *event) { { ip_addr_t ip_addr6; ip_addr_copy_from_ip6(ip_addr6, event->event_info.got_ip6.ip6_info.ip); - IPAddress addr(ip_addr6); + IPAddress addr(&ip_addr6); AddLog(LOG_LEVEL_DEBUG, PSTR("%s: IPv6 %s %s"), event->event_id == ARDUINO_EVENT_ETH_GOT_IP6 ? "ETH" : "WIF", - addr.isLocal() ? PSTR("Local") : PSTR("Global"), addr.toString().c_str()); - if (!addr.isLocal()) { // declare network up on IPv6 + IPv6isLocal(addr) ? PSTR("Local") : PSTR("Global"), addr.toString().c_str()); + if (!IPv6isLocal(addr)) { // declare network up on IPv6 TasmotaGlobal.rules_flag.eth_connected = 1; TasmotaGlobal.global_state.eth_down = 0; }