mirror of https://github.com/arendst/Tasmota.git
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:
parent
d0a9f0d15d
commit
9045a7da83
|
@ -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)
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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");
|
||||||
}
|
}
|
||||||
|
|
|
@ -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);
|
||||||
|
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue