IP stack compatible with new Core3 IPv6 implementation (#20509)

* IP stack compatible with new Core3 IPv6 implementation

* Fix compilation

* Forece CI
This commit is contained in:
s-hadinger 2024-01-15 21:05:40 +01:00 committed by GitHub
parent d0a9f0d15d
commit 9045a7da83
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
10 changed files with 115 additions and 69 deletions

View File

@ -17,6 +17,7 @@ All notable changes to this project will be documented in this file.
### Breaking Changed ### Breaking Changed
### Changed ### Changed
- IP stack compatible with new Core3 IPv6 implementation ()
### Fixed ### Fixed
- Scripter memory leak in `>w x` (#20473) - Scripter memory leak in `>w x` (#20473)

View File

@ -89,10 +89,12 @@ void WiFiClass32::scrubDNS(void) {
const IPAddress ip_dns = IPAddress(dns_getserver(i)); const IPAddress ip_dns = IPAddress(dns_getserver(i));
// Step 1. save valid values from DNS // Step 1. save valid values from DNS
if (!ip_addr_isany_val((const ip_addr_t &)ip_dns)) { if (!ip_addr_isany_val((const ip_addr_t &)ip_dns)) {
if (ip_dns.isV4() && has_v4) { if (ip_dns.type() == IPv4 && has_v4) {
dns_save4[i] = (ip_addr_t) ip_dns; // dns entry is populated, save it in v4 slot ip_dns.to_ip_addr_t(&dns_save4[i]);
} else if (ip_dns.isV6() && has_v6) { // dns_save4[i] = (ip_addr_t) ip_dns; // dns entry is populated, save it in v4 slot
dns_save6[i] = (ip_addr_t) ip_dns; // dns entry is populated, save it in v6 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 // We need this helper method to access protected methods from WiFiGeneric
void WiFiClass32::dnsDone(void) { 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 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 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; uint8_t v4v6priority = LWIP_DNS_ADDRTYPE_IPV4;
#ifdef USE_IPV6 #ifdef USE_IPV6
v4v6priority = WifiDNSGetIPv6Priority() ? LWIP_DNS_ADDRTYPE_IPV6_IPV4 : LWIP_DNS_ADDRTYPE_IPV4_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); // 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)) { if(err == ERR_OK && !ip_addr_isany_val(dns_ipaddr)) {
#ifdef USE_IPV6 #ifdef USE_IPV6
aResult = dns_ipaddr; aResult.from_ip_addr_t(&dns_ipaddr);
#else // USE_IPV6 #else // USE_IPV6
aResult = ip_addr_get_ip4_u32(&dns_ipaddr); aResult = ip_addr_get_ip4_u32(&dns_ipaddr);
#endif // USE_IPV6 #endif // USE_IPV6
} else if(err == ERR_INPROGRESS) { } else if(err == ERR_INPROGRESS) {
waitStatusBits(WIFI_DNS_DONE_BIT, timer_ms); //real internal timeout in lwip library is 14[s] waitStatusBits(NET_DNS_DONE_BIT, timer_ms); //real internal timeout in lwip library is 14[s]
clearStatusBits(WIFI_DNS_DONE_BIT); clearStatusBits(NET_DNS_DONE_BIT);
} }
if (!ip_addr_isany_val(dns_ipaddr)) { if (!ip_addr_isany_val(dns_ipaddr)) {
#ifdef USE_IPV6 #ifdef USE_IPV6
aResult = dns_ipaddr; aResult.from_ip_addr_t(&dns_ipaddr);
#else // USE_IPV6 #else // USE_IPV6
aResult = ip_addr_get_ip4_u32(&dns_ipaddr); aResult = ip_addr_get_ip4_u32(&dns_ipaddr);
#endif // USE_IPV6 #endif // USE_IPV6

View File

@ -32,12 +32,14 @@ extern "C" const void* matter_get_ip_bytes(const char* ip_str, size_t* ret_len)
IPAddress ip; IPAddress ip;
if (ip.fromString(ip_str)) { if (ip.fromString(ip_str)) {
#ifdef USE_IPV6 #ifdef USE_IPV6
if (ip.isV4()) { if (ip.type() == IPv4) {
uint32_t ip_32 = ip; uint32_t ip_32 = ip;
memcpy(ip_bytes, &ip_32, 4); memcpy(ip_bytes, &ip_32, 4);
*ret_len = 4; *ret_len = 4;
} else { } 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; *ret_len = 16;
} }
#else #else

View File

@ -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) WiFi.persistent(false); // Solve possible wifi init errors (re-add at 6.2.1.16 #4044, #4083)
#if defined(USE_IPV6) && defined(ESP32) #if defined(USE_IPV6) && defined(ESP32)
WiFi.IPv6(true); WiFi.enableIPv6(true);
#endif #endif
#ifdef USE_WIFI_RANGE_EXTENDER #ifdef USE_WIFI_RANGE_EXTENDER
@ -545,6 +545,11 @@ String EthernetGetIPv4Str(void)
} }
#ifdef USE_IPV6 #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 // Scan through all interfaces to find a global or local IPv6 address
// Arg: // 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++) { for (uint32_t i = 0; i < LWIP_IPV6_NUM_ADDRESSES; i++) {
ip_addr_t *ipv6 = &intf->ip6_addr[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_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; return true;
} }
} }
@ -579,7 +584,7 @@ bool WifiHasIPv6(void)
String WifiGetIPv6Str(void) String WifiGetIPv6Str(void)
{ {
IPAddress ip; IPAddress ip;
return WifiGetIPv6(&ip) ? ip.toString() : String(); return WifiGetIPv6(&ip) ? ip.toString(true) : String();
} }
bool WifiGetIPv6LinkLocal(IPAddress *ip) bool WifiGetIPv6LinkLocal(IPAddress *ip)
@ -589,7 +594,7 @@ bool WifiGetIPv6LinkLocal(IPAddress *ip)
String WifiGetIPv6LinkLocalStr(void) String WifiGetIPv6LinkLocalStr(void)
{ {
IPAddress ip; 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) String EthernetGetIPv6Str(void)
{ {
IPAddress ip; IPAddress ip;
return EthernetGetIPv6(&ip) ? ip.toString() : String(); return EthernetGetIPv6(&ip) ? ip.toString(true) : String();
} }
bool EthernetGetIPv6LinkLocal(IPAddress *ip) bool EthernetGetIPv6LinkLocal(IPAddress *ip)
@ -619,7 +624,7 @@ bool EthernetHasIPv6LinkLocal(void)
String EthernetGetIPv6LinkLocalStr(void) String EthernetGetIPv6LinkLocalStr(void)
{ {
IPAddress ip; IPAddress ip;
return EthernetGetIPv6LinkLocal(&ip) ? ip.toString() : String(); return EthernetGetIPv6LinkLocal(&ip) ? ip.toString(true) : String();
} }
bool DNSGetIP(IPAddress *ip, uint32_t idx) bool DNSGetIP(IPAddress *ip, uint32_t idx)
@ -629,16 +634,16 @@ bool DNSGetIP(IPAddress *ip, uint32_t idx)
#endif #endif
const ip_addr_t *ip_dns = dns_getserver(idx); const ip_addr_t *ip_dns = dns_getserver(idx);
if (!ip_addr_isany(ip_dns)) { 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; 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; return false;
} }
String DNSGetIPStr(uint32_t idx) String DNSGetIPStr(uint32_t idx)
{ {
IPAddress ip; 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) void WifiDumpAddressesIPv6(void)
{ {
for (netif* intf = netif_list; intf != nullptr; intf = intf->next) { 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++) { for (uint32_t i = 0; i < LWIP_IPV6_NUM_ADDRESSES; i++) {
if (!ip_addr_isany_val(intf->ip6_addr[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, 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" : ""); 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()); 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) #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()); 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; IPAddress ip_eth;
bool has_eth = EthernetGetIP(&ip_eth); bool has_eth = EthernetGetIP(&ip_eth);
if (has_wifi && has_eth) { if (has_wifi && has_eth) {
if (ip_eth.isV4()) { *ip = ip_eth; return true; } if (ip_eth.type() == IPv4) { *ip = ip_eth; return true; }
if (ip_wifi.isV4()) { *ip = ip_wifi; return true; } if (ip_wifi.type() == IPv4) { *ip = ip_wifi; return true; }
// both addresses are v6, return ETH // both addresses are v6, return ETH
*ip = ip_eth; *ip = ip_eth;
return true; return true;
@ -707,11 +712,11 @@ bool IPGetListeningAddress(IPAddress * ip)
String IPGetListeningAddressStr(void) String IPGetListeningAddressStr(void)
{ {
IPAddress ip; IPAddress ip;
if (IPGetListeningAddress(&ip)) { #ifdef USE_IPV6
return ip.toString(); return IPGetListeningAddress(&ip) ? ip.toString(true) : String();
} else { #else
return String(); return IPGetListeningAddress(&ip) ? ip.toString() : String();
} #endif
} }
// Because of IPv6, we can't test an IP address agains (uint32_t)0L anymore // 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) String IPForUrl(const IPAddress & ip)
{ {
#ifdef USE_IPV6 #ifdef USE_IPV6
if (ip.isV4()) { if (ip.type() == IPv4) {
return ip.toString().c_str(); return ip.toString().c_str();
} else { } else {
String s('['); String s('[');
s += ip.toString().c_str(); s += ip.toString(true).c_str();
s += ']'; s += ']';
return s; return s;
} }
@ -789,7 +794,11 @@ bool WifiHasIP(void) {
String WifiGetIPStr(void) String WifiGetIPStr(void)
{ {
IPAddress ip; IPAddress ip;
#ifdef USE_IPV6
return WifiGetIP(&ip) ? ip.toString(true) : String();
#else
return WifiGetIP(&ip) ? ip.toString() : String(); return WifiGetIP(&ip) ? ip.toString() : String();
#endif
} }
// Has a routable IP, whether IPv4 or IPv6, Wifi or Ethernet // Has a routable IP, whether IPv4 or IPv6, Wifi or Ethernet
@ -809,9 +818,9 @@ void WifiCheckIp(void) {
if (WL_CONNECTED == WiFi.status()) { if (WL_CONNECTED == WiFi.status()) {
#ifdef ESP32 #ifdef ESP32
if (!Wifi.ipv6_local_link_called) { if (!Wifi.ipv6_local_link_called) {
WiFi.enableIpV6(); WiFi.enableIPv6(true); // TODO
Wifi.ipv6_local_link_called = true; Wifi.ipv6_local_link_called = true;
// AddLog(LOG_LEVEL_DEBUG, PSTR("WIF: calling enableIpV6")); // AddLog(LOG_LEVEL_DEBUG, PSTR("WIF: calling enableIPV6"));
} }
#endif #endif
} }
@ -1279,18 +1288,6 @@ bool WifiHostByName(const char* aHostname, IPAddress& aResult) {
uint32_t dns_end = millis(); uint32_t dns_end = millis();
if (success) { if (success) {
// Host name resolved // 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) { 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); 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; return true;
@ -1376,7 +1373,11 @@ uint64_t WifiGetNtp(void) {
uint32_t attempts = 3; uint32_t attempts = 3;
while (attempts > 0) { while (attempts > 0) {
uint32_t port = random(1025, 65535); // Create a random port for the UDP connection. 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) { if (udp.begin(port) != 0) {
#endif
break; break;
} }
attempts--; attempts--;
@ -1454,6 +1455,8 @@ uint64_t WifiGetNtp(void) {
// Respond to some Arduino/esp-idf events for better IPv6 support // Respond to some Arduino/esp-idf events for better IPv6 support
// -------------------------------------------------------------------------------- // --------------------------------------------------------------------------------
#ifdef ESP32 #ifdef ESP32
extern esp_netif_t* get_esp_interface_netif(esp_interface_t interface);
// typedef void (*WiFiEventSysCb)(arduino_event_t *event); // typedef void (*WiFiEventSysCb)(arduino_event_t *event);
void WifiEvents(arduino_event_t *event) { void WifiEvents(arduino_event_t *event) {
switch (event->event_id) { switch (event->event_id) {
@ -1461,17 +1464,17 @@ void WifiEvents(arduino_event_t *event) {
#ifdef USE_IPV6 #ifdef USE_IPV6
case ARDUINO_EVENT_WIFI_STA_GOT_IP6: case ARDUINO_EVENT_WIFI_STA_GOT_IP6:
{ {
ip_addr_t ip_addr6; // Serial.printf(">>> event ARDUINO_EVENT_WIFI_STA_GOT_IP6 \n");
ip_addr_copy_from_ip6(ip_addr6, event->event_info.got_ip6.ip6_info.ip); IPAddress addr(IPv6, (const uint8_t*)event->event_info.got_ip6.ip6_info.ip.addr, event->event_info.got_ip6.ip6_info.ip.zone);
IPAddress addr(ip_addr6);
AddLog(LOG_LEVEL_DEBUG, PSTR("%s: IPv6 %s %s"), AddLog(LOG_LEVEL_DEBUG, PSTR("%s: IPv6 %s %s"),
event->event_id == ARDUINO_EVENT_ETH_GOT_IP6 ? "ETH" : "WIF", 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; break;
#endif // USE_IPV6 #endif // USE_IPV6
case ARDUINO_EVENT_WIFI_STA_GOT_IP: case ARDUINO_EVENT_WIFI_STA_GOT_IP:
{ {
// Serial.printf(">>> event ARDUINO_EVENT_WIFI_STA_GOT_IP \n");
ip_addr_t ip_addr4; ip_addr_t ip_addr4;
ip_addr_copy_from_ip4(ip_addr4, event->event_info.got_ip.ip_info.ip); 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"), AddLog(LOG_LEVEL_DEBUG, PSTR("WIF: IPv4 %_I, mask %_I, gateway %_I"),
@ -1482,6 +1485,18 @@ void WifiEvents(arduino_event_t *event) {
break; break;
case ARDUINO_EVENT_WIFI_STA_CONNECTED: 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")); // 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 Wifi.ipv6_local_link_called = false; // not sure if this is needed, make sure link-local is restored at each reconnect
break; break;

View File

@ -311,7 +311,7 @@ extern "C" {
ip_addr_t ip; ip_addr_t ip;
ip_addr_set_any_val(false, ip); ip_addr_set_any_val(false, ip);
#ifdef USE_IPV6 #ifdef USE_IPV6
ip = (ip_addr_t)ipfull; ipfull.to_ip_addr_t(&ip);
#else #else
ip_addr_set_ip4_u32_val(ip, (uint32_t)ipfull); ip_addr_set_ip4_u32_val(ip, (uint32_t)ipfull);
#endif #endif
@ -384,7 +384,7 @@ void PingResponsePoll(void) {
ping->hostname.c_str(), ping->hostname.c_str(),
success ? PSTR("true") : PSTR("false"), success ? PSTR("true") : PSTR("false"),
#ifdef USE_IPV6 #ifdef USE_IPV6
IPAddress(ping->ip).toString().c_str(), IPAddress(&ping->ip).toString(true).c_str(),
#else #else
IPAddress(ip_addr_get_ip4_u32(&ping->ip)).toString().c_str(), IPAddress(ip_addr_get_ip4_u32(&ping->ip)).toString().c_str(),
#endif #endif

View File

@ -239,12 +239,14 @@ extern "C" {
#ifdef USE_IPV6 #ifdef USE_IPV6
// //
ip_addr_t *ip_addr = (ip_addr_t*) ip; // ip_addr_t *ip_addr = (ip_addr_t*) ip;
head->addr.type = ip_addr->type; ip_addr_t ip_addr;
if (ip_addr->type == ESP_IPADDR_TYPE_V6) { ip.to_ip_addr_t(&ip_addr);
memcpy(head->addr.u_addr.ip6.addr, ip_addr->u_addr.ip6.addr, 16); 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 { } 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 #else
head->addr.u_addr.ip4.addr = (uint32_t) ip; head->addr.u_addr.ip4.addr = (uint32_t) ip;
@ -332,10 +334,11 @@ extern "C" {
} else { } else {
continue; continue;
} }
be_pushstring(vm, IPAddress(&ip_addr).toString(true).c_str());
#else #else
uint32_t ip_addr = a->addr.u_addr.ip4.addr; uint32_t ip_addr = a->addr.u_addr.ip4.addr;
#endif
be_pushstring(vm, IPAddress(ip_addr).toString().c_str()); be_pushstring(vm, IPAddress(ip_addr).toString().c_str());
#endif
be_data_push(vm, -2); be_data_push(vm, -2);
be_pop(vm, 1); be_pop(vm, 1);
} }

View File

@ -504,10 +504,10 @@ extern "C" {
tcp->update_local_addr_port(); tcp->update_local_addr_port();
if (tcp->local_port > 0) { if (tcp->local_port > 0) {
be_map_insert_int(vm, "local_port", tcp->local_port); 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_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_pop(vm, 1);
be_return(vm); be_return(vm);

View File

@ -240,7 +240,7 @@ extern "C" {
WiFiClient * client_ptr = nullptr; WiFiClient * client_ptr = nullptr;
if (server_tcp->hasClient()) { if (server_tcp->hasClient()) {
WiFiClient new_client = server_tcp->available(); 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 WiFiClient();
*client_ptr = new_client; *client_ptr = new_client;
} else { } else {
@ -254,7 +254,7 @@ extern "C" {
AsyncTCPClient * client_ptr = nullptr; AsyncTCPClient * client_ptr = nullptr;
if (server_tcp->hasClient()) { if (server_tcp->hasClient()) {
client_ptr = server_tcp->availableAsync(); 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 { } else {
be_raise(vm, "internal_error", "tcpserver has no client connected"); be_raise(vm, "internal_error", "tcpserver has no client connected");
} }

View File

@ -51,7 +51,11 @@ extern "C" {
// udp.begin(interface:string, port:int) -> bool // udp.begin(interface:string, port:int) -> bool
int32_t be_udp_begin_ntv(WiFiUDP *udp, const char *host, int32_t port) { int32_t be_udp_begin_ntv(WiFiUDP *udp, const char *host, int32_t port) {
#ifdef USE_IPV6
IPAddress addr(IPv6);
#else
IPAddress addr; IPAddress addr;
#endif
// if no host or host is "" then we defult to INADDR_ANY // if no host or host is "" then we defult to INADDR_ANY
if(host && (*host != 0) && !WifiHostByName(host, addr)){ if(host && (*host != 0) && !WifiHostByName(host, addr)){
return 0; return 0;
@ -66,7 +70,11 @@ extern "C" {
// udp.begin_multicast(address:string, port:int) -> nil // udp.begin_multicast(address:string, port:int) -> nil
int32_t be_udp_begin_mcast_ntv(WiFiUDP *udp, const char *host, int32_t port) { int32_t be_udp_begin_mcast_ntv(WiFiUDP *udp, const char *host, int32_t port) {
#ifdef USE_IPV6
IPAddress addr(IPv6);
#else
IPAddress addr; IPAddress addr;
#endif
if(!WifiHostByName(host, addr)){ if(!WifiHostByName(host, addr)){
return 0; return 0;
} }
@ -127,7 +135,7 @@ extern "C" {
// set remotet ip // set remotet ip
IPAddress remote_ip = udp->remoteIP(); 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_setmember(vm, 1, "remote_ip");
be_pop(vm, 1); be_pop(vm, 1);

View File

@ -85,6 +85,8 @@
char eth_hostname[sizeof(TasmotaGlobal.hostname)]; char eth_hostname[sizeof(TasmotaGlobal.hostname)];
uint8_t eth_config_change; 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);
void EthernetEvent(arduino_event_t *event) { void EthernetEvent(arduino_event_t *event) {
switch (event->event_id) { switch (event->event_id) {
@ -95,14 +97,27 @@ void EthernetEvent(arduino_event_t *event) {
case ARDUINO_EVENT_ETH_CONNECTED: case ARDUINO_EVENT_ETH_CONNECTED:
#ifdef USE_IPV6 #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 #endif // USE_IPV6
AddLog(LOG_LEVEL_INFO, PSTR(D_LOG_ETH D_CONNECTED " at %dMbps%s, Mac %s, Hostname %s"), AddLog(LOG_LEVEL_INFO, PSTR(D_LOG_ETH D_CONNECTED " at %dMbps%s, Mac %s, Hostname %s"),
ETH.linkSpeed(), (ETH.fullDuplex()) ? " Full Duplex" : "", ETH.linkSpeed(), (ETH.fullDuplex()) ? " Full Duplex" : "",
ETH.macAddress().c_str(), eth_hostname 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; break;
case ARDUINO_EVENT_ETH_GOT_IP: case ARDUINO_EVENT_ETH_GOT_IP:
@ -128,11 +143,11 @@ void EthernetEvent(arduino_event_t *event) {
{ {
ip_addr_t ip_addr6; ip_addr_t ip_addr6;
ip_addr_copy_from_ip6(ip_addr6, event->event_info.got_ip6.ip6_info.ip); 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"), AddLog(LOG_LEVEL_DEBUG, PSTR("%s: IPv6 %s %s"),
event->event_id == ARDUINO_EVENT_ETH_GOT_IP6 ? "ETH" : "WIF", 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().c_str());
if (!addr.isLocal()) { // declare network up on IPv6 if (!IPv6isLocal(addr)) { // declare network up on IPv6
TasmotaGlobal.rules_flag.eth_connected = 1; TasmotaGlobal.rules_flag.eth_connected = 1;
TasmotaGlobal.global_state.eth_down = 0; TasmotaGlobal.global_state.eth_down = 0;
} }