From 4a32623a5130b8fbd2769f53b437799805926bb3 Mon Sep 17 00:00:00 2001 From: Stephan Hadinger Date: Sat, 10 Dec 2022 13:44:16 +0100 Subject: [PATCH] IPv6 improvements --- .../ESP32-to-ESP8266-compat/src/AddrList46.h | 216 ----------- .../src/IPAddress46.cpp | 331 ----------------- .../ESP32-to-ESP8266-compat/src/IPAddress46.h | 198 ----------- .../ESP32-to-ESP8266-compat/src/Udp46.h | 93 ----- .../ESP32-to-ESP8266-compat/src/WiFiUdp46.cpp | 335 ------------------ .../ESP32-to-ESP8266-compat/src/WiFiUdp46.h | 77 ---- .../src/esp8266toEsp32.h | 2 - lib/libesp32/berry_tasmota/src/be_udp_lib.cpp | 34 +- tasmota/my_user_config.h | 6 + tasmota/tasmota.ino | 9 +- tasmota/tasmota_support/support_command.ino | 20 +- tasmota/tasmota_support/support_wifi.ino | 43 +-- .../xdrv_01_9_webserver.ino | 12 +- .../tasmota_xdrv_driver/xdrv_02_9_mqtt.ino | 4 +- .../xdrv_52_3_berry_tasmota.ino | 14 +- .../xdrv_82_esp32_ethernet.ino | 6 +- 16 files changed, 75 insertions(+), 1325 deletions(-) delete mode 100644 lib/libesp32/ESP32-to-ESP8266-compat/src/AddrList46.h delete mode 100644 lib/libesp32/ESP32-to-ESP8266-compat/src/IPAddress46.cpp delete mode 100644 lib/libesp32/ESP32-to-ESP8266-compat/src/IPAddress46.h delete mode 100644 lib/libesp32/ESP32-to-ESP8266-compat/src/Udp46.h delete mode 100644 lib/libesp32/ESP32-to-ESP8266-compat/src/WiFiUdp46.cpp delete mode 100644 lib/libesp32/ESP32-to-ESP8266-compat/src/WiFiUdp46.h diff --git a/lib/libesp32/ESP32-to-ESP8266-compat/src/AddrList46.h b/lib/libesp32/ESP32-to-ESP8266-compat/src/AddrList46.h deleted file mode 100644 index bc2d07a398b9..000000000000 --- a/lib/libesp32/ESP32-to-ESP8266-compat/src/AddrList46.h +++ /dev/null @@ -1,216 +0,0 @@ -/* - AddrList.h - cycle through lwIP netif's ip addresses like a c++ list - Copyright (c) 2018 david gauchard. All right reserved. - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2.1 of the License, or (at your option) any later version. - - This library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with this library; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -/* - This class allows to explore all configured IP addresses - in lwIP netifs, with that kind of c++ loop: - - for (auto a: addrList) - out.printf("IF='%s' index=%d legacy=%d IPv4=%d local=%d hostname='%s' addr= %s\n", - a.iface().c_str(), - a.ifnumber(), - a.addr().isLegacy(), - a.addr().isV4(), - a.addr().isLocal(), - a.hostname().c_str(), - a.addr().toString().c_str()); - - This loop: - - while (WiFi.status() != WL_CONNECTED()) { - Serial.print('.'); - delay(500); - } - - can be replaced by: - - for (bool configured = false; !configured; ) { - for (auto iface: addrList) - if ((configured = !iface.addr().isLocal()) - break; - Serial.print('.'); - delay(500); - } - - waiting for an IPv6 global address: - - for (bool configured = false; !configured; ) { - for (auto iface: addrList) - if ((configured = ( !iface.addr().isV4() - && !iface.addr().isLocal()))) - break; - Serial.print('.'); - delay(500); - } - - waiting for an IPv6 global address, on a specific interface: - - for (bool configured = false; !configured; ) { - for (auto iface: addrList) - if ((configured = ( !iface.addr().isV4() - && !iface.addr().isLocal() - && iface.ifnumber() == STATION_IF))) - break; - Serial.print('.'); - delay(500); - } -*/ - -#ifndef __ADDRLIST_H -#define __ADDRLIST_H - -#include -#include -#include "IPAddress46.h" - -#if LWIP_IPV6 -#define IF_NUM_ADDRESSES (1 + LWIP_IPV6_NUM_ADDRESSES) -#else -#define IF_NUM_ADDRESSES (1) -#endif - -namespace esp8266 -{ -namespace AddressListImplementation -{ -struct netifWrapper -{ - netifWrapper (netif* netif) : _netif(netif), _num(-1) {} - netifWrapper (const netifWrapper& o) : _netif(o._netif), _num(o._num) {} - - netifWrapper& operator= (const netifWrapper& o) - { - _netif = o._netif; - _num = o._num; - return *this; - } - - bool equal(const netifWrapper& o) - { - return _netif == o._netif && (!_netif || _num == o._num); - } - - IPAddress46 addr () const { return ipFromNetifNum(); } - bool isLegacy () const { return _num == 0; } - bool isLocal () const { return addr().isLocal(); } - bool isV4 () const { return addr().isV4(); } - bool isV6 () const { return !addr().isV4(); } - String toString() const { return addr().toString(); } - - // related to legacy address (_num=0, ipv4) - IPAddress46 ipv4 () const { return _netif->ip_addr; } - IPAddress46 netmask () const { return _netif->netmask; } - IPAddress46 gw () const { return _netif->gw; } - - // common to all addresses of this interface - String ifname () const { return String(_netif->name[0]) + _netif->name[1]; } - const char* ifhostname () const { return _netif->hostname?: emptyString.c_str(); } - const char* ifmac () const { return (const char*)_netif->hwaddr; } - int ifnumber () const { return _netif->num; } - bool ifUp () const { return !!(_netif->flags & NETIF_FLAG_UP); } - const netif* interface () const { return _netif; } - - const ip_addr_t* ipFromNetifNum () const - { -#if LWIP_IPV6 - return _num ? &_netif->ip6_addr[_num - 1] : &_netif->ip_addr; -#else - return &_netif->ip_addr; -#endif - } - - // lwIP interface - netif* _netif; - - // address index within interface - // 0: legacy address (IPv4) - // n>0: (_num-1) is IPv6 index for netif->ip6_addr[] - int _num; -}; - - -class AddressListIterator -{ -public: - AddressListIterator (const netifWrapper& o) : netIf(o) {} - AddressListIterator (netif* netif) : netIf(netif) - { - // This constructor is called with lwIP's global netif_list, or - // nullptr. operator++() is designed to loop through _configured_ - // addresses. That's why netIf's _num is initialized to -1 to allow - // returning the first usable address to AddressList::begin(). - (void)operator++(); - } - - const netifWrapper& operator* () const { return netIf; } - const netifWrapper* operator-> () const { return &netIf; } - - bool operator== (AddressListIterator& o) { return netIf.equal(*o); } - bool operator!= (AddressListIterator& o) { return !netIf.equal(*o); } - - AddressListIterator operator++ (int) - { - AddressListIterator ret = *this; - (void)operator++(); - return ret; - } - - AddressListIterator& operator++ () - { - while (netIf._netif) - { - if (++netIf._num == IF_NUM_ADDRESSES) - { - // all addresses from current interface were iterated, - // switching to next interface - netIf = netifWrapper(netIf._netif->next); - continue; - } - if (!ip_addr_isany(netIf.ipFromNetifNum())) - // found an initialized address - break; - } - return *this; - } - - netifWrapper netIf; -}; - - -class AddressList -{ -public: - using const_iterator = const AddressListIterator; - - const_iterator begin () const { return const_iterator(netif_list); } - const_iterator end () const { return const_iterator(nullptr); } - -}; - -inline AddressList::const_iterator begin (const AddressList& a) { return a.begin(); } -inline AddressList::const_iterator end (const AddressList& a) { return a.end(); } - - -} // namespace AddressListImplementation -} // namespace esp8266 - -extern esp8266::AddressListImplementation::AddressList addrList; - - -#endif diff --git a/lib/libesp32/ESP32-to-ESP8266-compat/src/IPAddress46.cpp b/lib/libesp32/ESP32-to-ESP8266-compat/src/IPAddress46.cpp deleted file mode 100644 index 365ab58014c7..000000000000 --- a/lib/libesp32/ESP32-to-ESP8266-compat/src/IPAddress46.cpp +++ /dev/null @@ -1,331 +0,0 @@ -/* - IPAddress46.cpp - IPv6 support for ESP32 - - This class is copied from ESP8266 Arduino framework and provides - temporary support for IPv6 on ESP32. - - Copyright (C) 2021 Theo Arends and Stephan Hadinger - - This program is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see . -*/ - -/* - IPAddress.cpp - Base class that provides IPAddress - - Copyright (c) 2011 Adrian McEwen. All right reserved. - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2.1 of the License, or (at your option) any later version. - - This library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with this library; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include -#include -#include -#include - -// Tasmota Logging -extern void AddLog(uint32_t loglevel, PGM_P formatP, ...); -enum LoggingLevels {LOG_LEVEL_NONE, LOG_LEVEL_ERROR, LOG_LEVEL_INFO, LOG_LEVEL_DEBUG, LOG_LEVEL_DEBUG_MORE}; - -IPAddress46::IPAddress46(const IPAddress46& from) -{ - ip_addr_copy(_ip, from._ip); -} - -IPAddress46::IPAddress46() { -#if LWIP_IPV6 - _ip = *IP6_ADDR_ANY; -#else - _ip = *IP_ADDR_ANY; -#endif - // _ip = *IP_ANY_TYPE; // lwIP's v4-or-v6 generic address -} - -bool IPAddress46::isSet () const { - return !IP_IS_ANY_TYPE_VAL(_ip); - // return !ip_addr_isany(&_ip) && ((*this) != IPADDR_NONE); -} - -IPAddress46::IPAddress46(uint8_t first_octet, uint8_t second_octet, uint8_t third_octet, uint8_t fourth_octet) { - setV4(); - (*this)[0] = first_octet; - (*this)[1] = second_octet; - (*this)[2] = third_octet; - (*this)[3] = fourth_octet; -} - -void IPAddress46::ctor32(uint32_t address) { - setV4(); - v4() = address; -} - -IPAddress46::IPAddress46(const uint8_t *address) { - setV4(); - (*this)[0] = address[0]; - (*this)[1] = address[1]; - (*this)[2] = address[2]; - (*this)[3] = address[3]; -} - -bool IPAddress46::fromString(const char *address) { - if (!fromString4(address)) { -#if LWIP_IPV6 - return fromString6(address); -#else - return false; -#endif - } - return true; -} - -bool IPAddress46::fromString4(const char *address) { - // TODO: (IPv4) add support for "a", "a.b", "a.b.c" formats - - uint16_t acc = 0; // Accumulator - uint8_t dots = 0; - - while (*address) - { - char c = *address++; - if (c >= '0' && c <= '9') - { - acc = acc * 10 + (c - '0'); - if (acc > 255) { - // Value out of [0..255] range - return false; - } - } - else if (c == '.') - { - if (dots == 3) { - // Too much dots (there must be 3 dots) - return false; - } - (*this)[dots++] = acc; - acc = 0; - } - else - { - // Invalid char - return false; - } - } - - if (dots != 3) { - // Too few dots (there must be 3 dots) - return false; - } - (*this)[3] = acc; - - setV4(); - return true; -} - -IPAddress46& IPAddress46::operator=(const uint8_t *address) { - setV4(); - v4() = *reinterpret_cast(address); - return *this; -} - -IPAddress46& IPAddress46::operator=(uint32_t address) { - setV4(); - v4() = address; - return *this; -} - -bool IPAddress46::operator==(const uint8_t* addr) const { - return isV4() && v4() == *reinterpret_cast(addr); -} - -size_t IPAddress46::printTo(Print& p) const { - size_t n = 0; - - // if (!isSet()) - // return p.print(F("(IP unset)")); - -#if LWIP_IPV6 - if (isV6()) { - int count0 = 0; - for (int i = 0; i < 8; i++) { - uint16_t bit = PP_NTOHS(raw6()[i]); - if (bit || count0 < 0) { - n += p.printf("%x", bit); - if (count0 > 0) - // no more hiding 0 - count0 = -8; - } else - count0++; - if ((i != 7 && count0 < 2) || count0 == 7) - n += p.print(':'); - } - return n; - } -#endif - - for(int i = 0; i < 4; i++) { - n += p.print((*this)[i], DEC); - if (i != 3) - n += p.print('.'); - } - return n; -} - -String IPAddress46::toString() const -{ - StreamString sstr; -#if LWIP_IPV6 - if (isV6()) - sstr.reserve(40); // 8 shorts x 4 chars each + 7 colons + nullterm - else -#endif - sstr.reserve(16); // 4 bytes with 3 chars max + 3 dots + nullterm, or '(IP unset)' - printTo(sstr); - return sstr; -} - -bool IPAddress46::isValid(const String& arg) { - return IPAddress46().fromString(arg); -} - -bool IPAddress46::isValid(const char* arg) { - return IPAddress46().fromString(arg); -} - -const IPAddress46 INADDR46_ANY; // generic "0.0.0.0" for IPv4 & IPv6 -const IPAddress46 INADDR46_NONE(255,255,255,255); - -void IPAddress46::clear() { - (*this) = INADDR46_ANY; -} - -/**************************************/ - -#if LWIP_IPV6 - -bool IPAddress46::fromString6(const char *address) { - // TODO: test test test - - uint32_t acc = 0; // Accumulator - int dots = 0, doubledots = -1; - - while (*address) - { - char c = tolower(*address++); - if (isalnum(c)) { - if (c >= 'a') - c -= 'a' - '0' - 10; - acc = acc * 16 + (c - '0'); - if (acc > 0xffff) - // Value out of range - return false; - } - else if (c == ':') { - if (*address == ':') { - if (doubledots >= 0) - // :: allowed once - return false; - // remember location - doubledots = dots + !!acc; - address++; - } - if (dots == 7) - // too many separators - return false; - raw6()[dots++] = PP_HTONS(acc); - acc = 0; - } - else - // Invalid char - return false; - } - - if (doubledots == -1 && dots != 7) - // Too few separators - return false; - raw6()[dots++] = PP_HTONS(acc); - - if (doubledots != -1) { - for (int i = dots - doubledots - 1; i >= 0; i--) - raw6()[8 - dots + doubledots + i] = raw6()[doubledots + i]; - for (int i = doubledots; i < 8 - dots + doubledots; i++) - raw6()[i] = 0; - } - - setV6(); - return true; -} - -// -------------------------------------------------- -// Get host by name working for IPv6 -// -------------------------------------------------- -#include "lwip/dns.h" - -/** - * DNS callback - * @param name - * @param ipaddr - * @param callback_arg - */ -static void wifi_dns_found_callback(const char *name, const ip_addr_t *ipaddr, void *callback_arg) -{ - if(ipaddr) { - (*reinterpret_cast(callback_arg)) = IPAddress46(ipaddr); - } - WiFiGeneric46::DnsDone(); - // xEventGroupSetBits(_arduino_event_group, WIFI_DNS_DONE_BIT); -} - -int WiFiGeneric46::hostByName(const char* aHostname, IPAddress46& aResult) { - ip_addr_t addr; - aResult = static_cast(INADDR_NONE); - waitStatusBits(WIFI_DNS_IDLE_BIT, 16000); - clearStatusBits(WIFI_DNS_IDLE_BIT | WIFI_DNS_DONE_BIT); - err_t err = dns_gethostbyname_addrtype(aHostname, &addr, &wifi_dns_found_callback, &aResult, LWIP_DNS_ADDRTYPE_DEFAULT); - AddLog(LOG_LEVEL_DEBUG, "WIF: WiFiGeneric46::hostByName err=%i", err); - - if(err == ERR_OK) { - aResult = IPAddress46(&addr); - - if (!aResult.isSet()) { -#if LWIP_IPV6 - aResult.setV6(); -#else - aResult.setV4(); -#endif - } - } else if(err == ERR_INPROGRESS) { - waitStatusBits(WIFI_DNS_DONE_BIT, 15000); //real internal timeout in lwip library is 14[s] - clearStatusBits(WIFI_DNS_DONE_BIT); - } - setStatusBits(WIFI_DNS_IDLE_BIT); - - if(err == ERR_OK) { - AddLog(LOG_LEVEL_DEBUG, "WIF: WiFiGeneric46::hostByName Host: %s IP: %s", aHostname ? aHostname : "", aResult.toString().c_str()); - return 1; - } - return 0; -} - -#endif diff --git a/lib/libesp32/ESP32-to-ESP8266-compat/src/IPAddress46.h b/lib/libesp32/ESP32-to-ESP8266-compat/src/IPAddress46.h deleted file mode 100644 index 8aeff20156ca..000000000000 --- a/lib/libesp32/ESP32-to-ESP8266-compat/src/IPAddress46.h +++ /dev/null @@ -1,198 +0,0 @@ -/* - IPAddress46.h - IPv6 support for ESP32 - - This class is copied from ESP8266 Arduino framework and provides - temporary support for IPv6 on ESP32. - - Copyright (C) 2021 Theo Arends and Stephan Hadinger - - This program is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see . -*/ - -#ifndef __IPADDRESS46_H -#define __IPADDRESS46_H - -#include -#include -#include - -class IPAddress46: public Printable { - private: - - ip_addr_t _ip; - - // Access the raw byte array containing the address. Because this returns a pointer - // to the internal structure rather than a copy of the address this function should only - // be used when you know that the usage of the returned uint8_t* will be transient and not - // stored. - uint8_t* raw_address() { - return reinterpret_cast(&v4()); - } - const uint8_t* raw_address() const { - return reinterpret_cast(&v4()); - } - - void ctor32 (uint32_t); - - public: - // Constructors - IPAddress46(); - IPAddress46(const IPAddress46& from); - IPAddress46(uint8_t first_octet, uint8_t second_octet, uint8_t third_octet, uint8_t fourth_octet); - IPAddress46(uint32_t address) { ctor32(address); } - IPAddress46(unsigned long address) { ctor32(address); } - IPAddress46(int address) { ctor32(address); } - IPAddress46(const uint8_t *address); - - bool fromString(const char *address); - bool fromString(const String &address) { return fromString(address.c_str()); } - - // Overloaded cast operator to allow IPAddress46 objects to be used where a pointer - // to a four-byte uint8_t array is expected - operator uint32_t() const { return isV4()? v4(): (uint32_t)0; } - operator uint32_t() { return isV4()? v4(): (uint32_t)0; } - - bool isSet () const; - operator bool () const { return isSet(); } // <- - operator bool () { return isSet(); } // <- both are needed - - // generic IPv4 wrapper to uint32-view like arduino loves to see it - const uint32_t& v4() const { return ip_2_ip4(&_ip)->addr; } // for raw_address(const) - uint32_t& v4() { return ip_2_ip4(&_ip)->addr; } - - bool operator==(const IPAddress46& addr) const { - return ip_addr_cmp(&_ip, &addr._ip); - } - bool operator!=(const IPAddress46& addr) const { - return !ip_addr_cmp(&_ip, &addr._ip); - } - bool operator==(uint32_t addr) const { - return isV4() && v4() == addr; - } - bool operator==(unsigned long addr) const { - return isV4() && v4() == (uint32_t)addr; - } - bool operator!=(uint32_t addr) const { - return !(isV4() && v4() == addr); - } - bool operator!=(unsigned long addr) const { - return isV4() && v4() != (uint32_t)addr; - } - bool operator==(const uint8_t* addr) const; - - int operator>>(int n) const { - return isV4()? v4() >> n: 0; - } - - // Overloaded index operator to allow getting and setting individual octets of the address - uint8_t operator[](int index) const { - return isV4()? *(raw_address() + index): 0; - } - uint8_t& operator[](int index) { - setV4(); - return *(raw_address() + index); - } - - // Overloaded copy operators to allow initialisation of IPAddress46 objects from other types - IPAddress46& operator=(const uint8_t *address); - IPAddress46& operator=(uint32_t address); - IPAddress46& operator=(const IPAddress46&) = default; - - virtual size_t printTo(Print& p) const; - String toString() const; - - void clear(); - - /* - check if input string(arg) is a valid IPV4 address or not. - return true on valid. - return false on invalid. - */ - static bool isValid(const String& arg); - static bool isValid(const char* arg); - - friend class EthernetClass; - friend class UDP46; - friend class Client; - friend class Server; - friend class DhcpClass; - friend class DNSClient; - - operator ip_addr_t () const { return _ip; } - operator const ip_addr_t*() const { return &_ip; } - operator ip_addr_t*() { return &_ip; } - - bool isV4() const { return IP_IS_V4_VAL(_ip); } - void setV4() { IP_SET_TYPE_VAL(_ip, IPADDR_TYPE_V4); } - - bool isLocal () const { return ip_addr_islinklocal(&_ip); } - -#if LWIP_IPV6 - IPAddress46(const ip_addr_t& lwip_addr) { ip_addr_copy(_ip, lwip_addr); } - IPAddress46(const ip_addr_t* lwip_addr) { ip_addr_copy(_ip, *lwip_addr); } - - IPAddress46& operator=(const ip_addr_t& lwip_addr) { ip_addr_copy(_ip, lwip_addr); return *this; } - IPAddress46& operator=(const ip_addr_t* lwip_addr) { ip_addr_copy(_ip, *lwip_addr); return *this; } - - uint16_t* raw6() - { - setV6(); - return reinterpret_cast(ip_2_ip6(&_ip)); - } - - const uint16_t* raw6() const - { - return isV6()? reinterpret_cast(ip_2_ip6(&_ip)): nullptr; - } - - // when not IPv6, ip_addr_t == ip4_addr_t so this one would be ambiguous - // required otherwise - operator const ip4_addr_t*() const { return isV4()? ip_2_ip4(&_ip): nullptr; } - - bool isV6() const { return IP_IS_V6_VAL(_ip); } - void setV6() { IP_SET_TYPE_VAL(_ip, IPADDR_TYPE_V6); } - - protected: - bool fromString6(const char *address); - -#else - - // allow portable code when IPv6 is not enabled - - uint16_t* raw6() { return nullptr; } - const uint16_t* raw6() const { return nullptr; } - bool isV6() const { return false; } - void setV6() { } - -#endif - - protected: - bool fromString4(const char *address); -}; - -// -------------------------------------------------------------------------------- -// We need to create a subclass of WiFiGenericClass to access protected methods -// -------------------------------------------------------------------------------- -#include "WiFiGeneric.h" - -class WiFiGeneric46 : public WiFiGenericClass -{ - public: - WiFiGeneric46() {}; - - static int hostByName(const char *aHostname, IPAddress46 &aResult); - static void DnsDone(void) { setStatusBits(WIFI_DNS_DONE_BIT); }; -}; - -#endif // __IPADDRESS46_H diff --git a/lib/libesp32/ESP32-to-ESP8266-compat/src/Udp46.h b/lib/libesp32/ESP32-to-ESP8266-compat/src/Udp46.h deleted file mode 100644 index 85e891797f2b..000000000000 --- a/lib/libesp32/ESP32-to-ESP8266-compat/src/Udp46.h +++ /dev/null @@ -1,93 +0,0 @@ -/* - * Udp.cpp: Library to send/receive UDP packets. - * - * NOTE: UDP is fast, but has some important limitations (thanks to Warren Gray for mentioning these) - * 1) UDP does not guarantee the order in which assembled UDP packets are received. This - * might not happen often in practice, but in larger network topologies, a UDP - * packet can be received out of sequence. - * 2) UDP does not guard against lost packets - so packets *can* disappear without the sender being - * aware of it. Again, this may not be a concern in practice on small local networks. - * For more information, see http://www.cafeaulait.org/course/week12/35.html - * - * MIT License: - * Copyright (c) 2008 Bjoern Hartmann - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - * - * bjoern@cs.stanford.edu 12/30/2008 - */ - -#ifndef udp46_h -#define udp46_h - -#include -#include - -class UDP46: public Stream -{ - -public: - virtual uint8_t begin(uint16_t) =0; // initialize, start listening on specified port. Returns 1 if successful, 0 if there are no sockets available to use - virtual uint8_t beginMulticast(IPAddress46, uint16_t) { return 0; } // initialize, start listening on specified multicast IP address and port. Returns 1 if successful, 0 on failure - virtual void stop() =0; // Finish with the UDP socket - - // Sending UDP packets - - // Start building up a packet to send to the remote host specific in ip and port - // Returns 1 if successful, 0 if there was a problem with the supplied IP address or port - virtual int beginPacket(IPAddress46 ip, uint16_t port) =0; - // Start building up a packet to send to the remote host specific in host and port - // Returns 1 if successful, 0 if there was a problem resolving the hostname or port - virtual int beginPacket(const char *host, uint16_t port) =0; - // Finish off this packet and send it - // Returns 1 if the packet was sent successfully, 0 if there was an error - virtual int endPacket() =0; - // Write a single byte into the packet - virtual size_t write(uint8_t) =0; - // Write size bytes from buffer into the packet - virtual size_t write(const uint8_t *buffer, size_t size) =0; - - // Start processing the next available incoming packet - // Returns the size of the packet in bytes, or 0 if no packets are available - virtual int parsePacket() =0; - // Number of bytes remaining in the current packet - virtual int available() =0; - // Read a single byte from the current packet - virtual int read() =0; - // Read up to len bytes from the current packet and place them into buffer - // Returns the number of bytes read, or 0 if none are available - virtual int read(unsigned char* buffer, size_t len) =0; - // Read up to len characters from the current packet and place them into buffer - // Returns the number of characters read, or 0 if none are available - virtual int read(char* buffer, size_t len) =0; - // Return the next byte from the current packet without moving on to the next byte - virtual int peek() =0; - virtual void flush() =0; // Finish reading the current packet - - // Return the IP address of the host who sent the current incoming packet - virtual IPAddress46 remoteIP() =0; - // Return the port of the host who sent the current incoming packet - virtual uint16_t remotePort() =0; -protected: - uint8_t* rawIPAddress(IPAddress46& addr) - { - return addr.raw_address(); - } -}; - -#endif diff --git a/lib/libesp32/ESP32-to-ESP8266-compat/src/WiFiUdp46.cpp b/lib/libesp32/ESP32-to-ESP8266-compat/src/WiFiUdp46.cpp deleted file mode 100644 index 79c34f94fe24..000000000000 --- a/lib/libesp32/ESP32-to-ESP8266-compat/src/WiFiUdp46.cpp +++ /dev/null @@ -1,335 +0,0 @@ -/* - Udp.cpp - UDP class for Raspberry Pi - Copyright (c) 2016 Hristo Gochkov All right reserved. - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2.1 of the License, or (at your option) any later version. - - This library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with this library; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA -*/ -#include "WiFiUdp46.h" -#include -#include -#include - -#undef write -#undef read - -// Tasmota Logging -extern void AddLog(uint32_t loglevel, PGM_P formatP, ...); -enum LoggingLevels {LOG_LEVEL_NONE, LOG_LEVEL_ERROR, LOG_LEVEL_INFO, LOG_LEVEL_DEBUG, LOG_LEVEL_DEBUG_MORE}; - -WiFiUDP46::WiFiUDP46() -: udp_server(-1) -, server_port(0) -, remote_port(0) -, tx_buffer(0) -, tx_buffer_len(0) -, rx_buffer(0) -{} - -WiFiUDP46::~WiFiUDP46(){ - stop(); -} - -uint8_t WiFiUDP46::begin(IPAddress46 address, uint16_t port){ - stop(); - server_port = port; - - tx_buffer = new char[1460]; - if(!tx_buffer){ - log_e("could not create tx buffer: %d", errno); - return 0; - } - -#if LWIP_IPV6 - if ((udp_server=socket(AF_INET6, SOCK_DGRAM, 0)) == -1){ -#else - if ((udp_server=socket(AF_INET, SOCK_DGRAM, 0)) == -1){ -#endif - log_e("could not create socket: %d", errno); - return 0; - } - - // AddLog(LOG_LEVEL_DEBUG, "WiFiUDP46::begin socket called"); - int yes = 1; - if (setsockopt(udp_server,SOL_SOCKET,SO_REUSEADDR,&yes,sizeof(yes)) < 0) { - log_e("could not set socket option: %d", errno); - stop(); - return 0; - } - - //AddLog(LOG_LEVEL_DEBUG, "WiFiUDP46::begin setsockopt called"); - - struct sockaddr* sock_addr = NULL; - size_t sock_size = 0; - struct sockaddr_in addr; -#if LWIP_IPV6 - struct sockaddr_in6 addr6; - if (address.isV6()) { - // AddLog(LOG_LEVEL_DEBUG, "WiFiUDP46::begin set IPv6"); - memset((char *) &addr6, 0, sizeof(sockaddr_in6)); - addr6.sin6_len = sizeof(sockaddr_in6); - addr6.sin6_family = AF_INET6; - addr6.sin6_port = htons(server_port); - addr6.sin6_addr = *(in6_addr*)(ip_addr_t*)address; - addr6.sin6_addr = in6addr_any; - addr6.sin6_flowinfo = 0; - sock_addr = (struct sockaddr*)&addr6; - sock_size = sizeof(sockaddr_in6); - - // AddLog(LOG_LEVEL_DEBUG, "SOCK_ADDR_TYPE_MATCH(name, sock)=%i", SOCK_ADDR_TYPE_MATCH(sock_addr, sock_size)); - } else -#endif - if (1) { - memset((char *) &addr, 0, sizeof(sockaddr_in)); - addr.sin_family = AF_INET; - addr.sin_port = htons(server_port); - addr.sin_addr.s_addr = (in_addr_t)address; - sock_addr = (struct sockaddr*)&addr; - sock_size = sizeof(sockaddr_in); - } - //AddLog(LOG_LEVEL_DEBUG, "WiFiUDP46::begin udp_server=%p sock_addr=%p sock_size=%i", udp_server, sock_addr, sock_size); - if(bind(udp_server , sock_addr, sock_size) == -1){ - AddLog(LOG_LEVEL_DEBUG, "WIF: WiFiUDP46::begin bind error=%o", errno); - log_e("could not bind socket: %d", errno); - stop(); - return 0; - } - fcntl(udp_server, F_SETFL, O_NONBLOCK); - return 1; -} - -uint8_t WiFiUDP46::begin(uint16_t p){ - return begin(IPAddress46(), p); -} - -uint8_t WiFiUDP46::beginMulticast(IPAddress46 a, uint16_t p){ - if(begin(IPAddress46(), p)){ - if(!ip_addr_isany((ip_addr_t*)a)){ - struct ip_mreq mreq; - mreq.imr_multiaddr.s_addr = (in_addr_t)a; - mreq.imr_interface.s_addr = INADDR_ANY; - if (setsockopt(udp_server, IPPROTO_IP, IP_ADD_MEMBERSHIP, &mreq, sizeof(mreq)) < 0) { - log_e("could not join igmp: %d", errno); - stop(); - return 0; - } - multicast_ip = a; - } - return 1; - } - return 0; -} - -void WiFiUDP46::stop(){ - if(tx_buffer){ - delete[] tx_buffer; - tx_buffer = NULL; - } - tx_buffer_len = 0; - if(rx_buffer){ - cbuf *b = rx_buffer; - rx_buffer = NULL; - delete b; - } - if(udp_server == -1) - return; - if(!ip_addr_isany((ip_addr_t*)multicast_ip)){ - struct ip_mreq mreq; - mreq.imr_multiaddr.s_addr = (in_addr_t)multicast_ip; - mreq.imr_interface.s_addr = (in_addr_t)0; -#if LWIP_IPV6 - setsockopt(udp_server, IPPROTO_IPV6, IP_DROP_MEMBERSHIP, &mreq, sizeof(mreq)); -#else - setsockopt(udp_server, IPPROTO_IP, IP_DROP_MEMBERSHIP, &mreq, sizeof(mreq)); -#endif - multicast_ip = IPAddress46(INADDR_ANY); - } - close(udp_server); - udp_server = -1; -} - -int WiFiUDP46::beginMulticastPacket(){ - if(!server_port || multicast_ip == IPAddress46(INADDR_ANY)) - return 0; - remote_ip = multicast_ip; - remote_port = server_port; - return beginPacket(); -} - -int WiFiUDP46::beginPacket(){ - if(!remote_port) - return 0; - - // allocate tx_buffer if is necessary - if(!tx_buffer){ - tx_buffer = new char[1460]; - if(!tx_buffer){ - log_e("could not create tx buffer: %d", errno); - return 0; - } - } - - tx_buffer_len = 0; - - // check whereas socket is already open - if (udp_server != -1) - return 1; - - if ((udp_server=socket(AF_INET, SOCK_DGRAM, 0)) == -1){ - log_e("could not create socket: %d", errno); - return 0; - } - - fcntl(udp_server, F_SETFL, O_NONBLOCK); - - return 1; -} - -int WiFiUDP46::beginPacket(IPAddress46 ip, uint16_t port){ - remote_ip = ip; - remote_port = port; - return beginPacket(); -} - -int WiFiUDP46::beginPacket(const char *host, uint16_t port){ - struct hostent *server; - server = gethostbyname(host); - if (server == NULL){ - log_e("could not get host from dns: %d", errno); - return 0; - } - return beginPacket(IPAddress46((const uint8_t *)(server->h_addr_list[0])), port); -} - -int WiFiUDP46::endPacket(){ - if (remote_ip.isV4()) { - struct sockaddr_in recipient; - recipient.sin_len = sizeof(sockaddr_in); - recipient.sin_addr.s_addr = (uint32_t)remote_ip; - recipient.sin_family = AF_INET; - recipient.sin_port = htons(remote_port); - int sent = sendto(udp_server, tx_buffer, tx_buffer_len, 0, (struct sockaddr*) &recipient, sizeof(recipient)); - if(sent < 0){ - log_e("could not send data: %d", errno); - return 0; - } - } else { - struct sockaddr_in6 recipient; - recipient.sin6_len = sizeof(sockaddr_in6); - recipient.sin6_flowinfo = 0; - recipient.sin6_addr = *(in6_addr*)(ip_addr_t*)remote_ip; - // recipient.sin6_family = AF_INET6; - recipient.sin6_port = htons(remote_port); - int sent = sendto(udp_server, tx_buffer, tx_buffer_len, 0, (struct sockaddr*) &recipient, sizeof(recipient)); - if(sent < 0){ - log_e("could not send data: %d", errno); - return 0; - } - } - return 1; -} - -size_t WiFiUDP46::write(uint8_t data){ - if(tx_buffer_len == 1460){ - endPacket(); - tx_buffer_len = 0; - } - tx_buffer[tx_buffer_len++] = data; - return 1; -} - -size_t WiFiUDP46::write(const uint8_t *buffer, size_t size){ - size_t i; - for(i=0;i 0) { - rx_buffer = new cbuf(len); - rx_buffer->write(buf, len); - } - delete[] buf; - return len; -} - -int WiFiUDP46::available(){ - if(!rx_buffer) return 0; - return rx_buffer->available(); -} - -int WiFiUDP46::read(){ - if(!rx_buffer) return -1; - int out = rx_buffer->read(); - if(!rx_buffer->available()){ - cbuf *b = rx_buffer; - rx_buffer = 0; - delete b; - } - return out; -} - -int WiFiUDP46::read(unsigned char* buffer, size_t len){ - return read((char *)buffer, len); -} - -int WiFiUDP46::read(char* buffer, size_t len){ - if(!rx_buffer) return 0; - int out = rx_buffer->read(buffer, len); - if(!rx_buffer->available()){ - cbuf *b = rx_buffer; - rx_buffer = 0; - delete b; - } - return out; -} - -int WiFiUDP46::peek(){ - if(!rx_buffer) return -1; - return rx_buffer->peek(); -} - -void WiFiUDP46::flush(){ - if(!rx_buffer) return; - cbuf *b = rx_buffer; - rx_buffer = 0; - delete b; -} - -IPAddress46 WiFiUDP46::remoteIP(){ - return remote_ip; -} - -uint16_t WiFiUDP46::remotePort(){ - return remote_port; -} diff --git a/lib/libesp32/ESP32-to-ESP8266-compat/src/WiFiUdp46.h b/lib/libesp32/ESP32-to-ESP8266-compat/src/WiFiUdp46.h deleted file mode 100644 index d0436c51e03d..000000000000 --- a/lib/libesp32/ESP32-to-ESP8266-compat/src/WiFiUdp46.h +++ /dev/null @@ -1,77 +0,0 @@ -/* - * Udp.cpp: Library to send/receive UDP packets. - * - * NOTE: UDP is fast, but has some important limitations (thanks to Warren Gray for mentioning these) - * 1) UDP does not guarantee the order in which assembled UDP packets are received. This - * might not happen often in practice, but in larger network topologies, a UDP - * packet can be received out of sequence. - * 2) UDP does not guard against lost packets - so packets *can* disappear without the sender being - * aware of it. Again, this may not be a concern in practice on small local networks. - * For more information, see http://www.cafeaulait.org/course/week12/35.html - * - * MIT License: - * Copyright (c) 2008 Bjoern Hartmann - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - * - * bjoern@cs.stanford.edu 12/30/2008 - */ - -#ifndef _WIFIUDP46_H_ -#define _WIFIUDP46_H_ - -#include -#include -#include - -class WiFiUDP46 : public UDP46 { -private: - int udp_server; - IPAddress46 multicast_ip; - IPAddress46 remote_ip; - uint16_t server_port; - uint16_t remote_port; - char * tx_buffer; - size_t tx_buffer_len; - cbuf * rx_buffer; -public: - WiFiUDP46(); - ~WiFiUDP46(); - uint8_t begin(IPAddress46 a, uint16_t p); - uint8_t begin(uint16_t p); - uint8_t beginMulticast(IPAddress46 a, uint16_t p); - void stop(); - int beginMulticastPacket(); - int beginPacket(); - int beginPacket(IPAddress46 ip, uint16_t port); - int beginPacket(const char *host, uint16_t port); - int endPacket(); - size_t write(uint8_t); - size_t write(const uint8_t *buffer, size_t size); - int parsePacket(); - int available(); - int read(); - int read(unsigned char* buffer, size_t len); - int read(char* buffer, size_t len); - int peek(); - void flush(); - IPAddress46 remoteIP(); - uint16_t remotePort(); -}; - -#endif /* _WIFIUDP46_H_ */ diff --git a/lib/libesp32/ESP32-to-ESP8266-compat/src/esp8266toEsp32.h b/lib/libesp32/ESP32-to-ESP8266-compat/src/esp8266toEsp32.h index f6a6338c622e..23ed7f1b4abf 100644 --- a/lib/libesp32/ESP32-to-ESP8266-compat/src/esp8266toEsp32.h +++ b/lib/libesp32/ESP32-to-ESP8266-compat/src/esp8266toEsp32.h @@ -137,8 +137,6 @@ typedef int SerialConfig; //#define PortUdp_writestr(log_data) PortUdp.write((const uint8_t *)(log_data), strlen(log_data)) #define PortUdp_write(log_data, n) PortUdp.write((const uint8_t *)(log_data), n) -#undef LWIP_IPV6 - #define REASON_DEFAULT_RST 0 // "Power on" normal startup by power on #define REASON_WDT_RST 1 // "Hardware Watchdog" hardware watch dog reset #define REASON_EXCEPTION_RST 2 // "Exception" exception reset, GPIO status won’t change diff --git a/lib/libesp32/berry_tasmota/src/be_udp_lib.cpp b/lib/libesp32/berry_tasmota/src/be_udp_lib.cpp index 9110be68cc64..f6084b04994f 100644 --- a/lib/libesp32/berry_tasmota/src/be_udp_lib.cpp +++ b/lib/libesp32/berry_tasmota/src/be_udp_lib.cpp @@ -15,7 +15,7 @@ #include #include -#include +#include #include "be_mapping.h" // Tasmota Logging @@ -25,15 +25,15 @@ enum LoggingLevels {LOG_LEVEL_NONE, LOG_LEVEL_ERROR, LOG_LEVEL_INFO, LOG_LEVEL_D extern "C" { // init() - WiFiUDP46 *be_udp_init_ntv(void) { - return new WiFiUDP46(); + WiFiUDP *be_udp_init_ntv(void) { + return new WiFiUDP(); } int32_t be_udp_init(struct bvm *vm) { return be_call_c_func(vm, (void*) &be_udp_init_ntv, "+.p", ""); } // deinit() - void *be_udp_deinit_ntv(WiFiUDP46 *udp) { + void *be_udp_deinit_ntv(WiFiUDP *udp) { if (udp != nullptr) { delete udp; } return nullptr; } @@ -42,8 +42,8 @@ extern "C" { } // udp.begin(address:string, port:int) -> bool - int32_t be_udp_begin_ntv(WiFiUDP46 *udp, int32_t port) { - IPAddress46 addr; + int32_t be_udp_begin_ntv(WiFiUDP *udp, int32_t port) { + IPAddress addr; // AddLog(LOG_LEVEL_DEBUG, "BRY: udp.begin listening to '%s'", addr.toString().c_str()); return udp->begin(addr, port); } @@ -57,7 +57,7 @@ extern "C" { } // udp.stop() -> nil - void be_udp_stop_ntv(WiFiUDP46 *udp) { + void be_udp_stop_ntv(WiFiUDP *udp) { udp->stop(); } int32_t be_udp_stop(struct bvm *vm) { @@ -65,21 +65,21 @@ extern "C" { } // udp.begin_multicast(address:string, port:int) -> nil - int32_t be_udp_begin_mcast_ntv(WiFiUDP46 *udp, const char *host, int32_t port) { - IPAddress46 addr; - if(!WiFiGeneric46::hostByName(host, addr)){ + int32_t be_udp_begin_mcast_ntv(WiFiUDP *udp, const char *host, int32_t port) { + IPAddress addr; + if(!WiFiGenericClass::hostByName(host, addr)){ return 0; } - return udp->WiFiUDP46::beginMulticast(addr, port); + return udp->WiFiUDP::beginMulticast(addr, port); } int32_t be_udp_begin_mcast(struct bvm *vm) { return be_call_c_func(vm, (void*) &be_udp_begin_mcast_ntv, "b", ".si"); } // udp.send(address:string, port:int, payload:bytes) -> bool - int32_t be_udp_send_ntv(WiFiUDP46 *udp, const char *host, int32_t port, const uint8_t* buf, int32_t len) { - IPAddress46 addr; - if (!WiFiGeneric46::hostByName(host, addr)){ + int32_t be_udp_send_ntv(WiFiUDP *udp, const char *host, int32_t port, const uint8_t* buf, int32_t len) { + IPAddress addr; + if (!WiFiGenericClass::hostByName(host, addr)){ return 0; } // AddLog(LOG_LEVEL_DEBUG, "BRY: udp.begin got host '%s'", addr.toString().c_str()); @@ -94,7 +94,7 @@ extern "C" { } // udp.send_multicast(payload:bytes) -> bool - int32_t be_udp_send_mcast_ntv(WiFiUDP46 *udp, const uint8_t* buf, int32_t len) { + int32_t be_udp_send_mcast_ntv(WiFiUDP *udp, const uint8_t* buf, int32_t len) { if (!udp->beginMulticastPacket()) { return 0; } int bw = udp->write(buf, len); if (!bw) { return 0; } @@ -107,7 +107,7 @@ extern "C" { // udp.read() -> bytes or nil int32_t be_udp_read(struct bvm *vm) { - WiFiUDP46 *udp = (WiFiUDP46*) be_convert_single_elt(vm, 1, NULL, NULL); + WiFiUDP *udp = (WiFiUDP*) be_convert_single_elt(vm, 1, NULL, NULL); if (udp->parsePacket()) { int btr = udp->available(); // btr contains the size of bytes_to_read @@ -135,7 +135,7 @@ extern "C" { int32_t btr2 = udp->read(buf, btr); // set remotet ip - IPAddress46 remote_ip = udp->remoteIP(); + IPAddress remote_ip = udp->remoteIP(); be_pushstring(vm, remote_ip.toString().c_str()); be_setmember(vm, 1, "remote_ip"); be_pop(vm, 1); diff --git a/tasmota/my_user_config.h b/tasmota/my_user_config.h index e89a34b93851..b73e0ff80e84 100644 --- a/tasmota/my_user_config.h +++ b/tasmota/my_user_config.h @@ -405,6 +405,12 @@ #define WIFI_SOFT_AP_CHANNEL 1 // Soft Access Point Channel number between 1 and 13 as used by Wi-Fi Manager web GUI #define USE_IMPROV // Add support for IMPROV serial protocol as used by esp-web-tools (+2k code) +// -- IPv6 support ------------------------------- +// #define USE_IPV6 // Enable IPv6 support (if the underlying esp-idf is also configured to support it) + // Code size increase: + // ESP8266: tbd + // ESP32: tbd + // -- ESP-NOW ------------------------------------- //#define USE_TASMESH // Enable Tasmota Mesh using ESP-NOW (+11k code) diff --git a/tasmota/tasmota.ino b/tasmota/tasmota.ino index b5e98c07d6ad..479dce33a30e 100644 --- a/tasmota/tasmota.ino +++ b/tasmota/tasmota.ino @@ -32,6 +32,13 @@ #include "include/i18n.h" // Language support configured by my_user_config.h #include "include/tasmota_template.h" // Hardware configuration +// ------------------------------------------------------------------------------------------ +// If IPv6 is not support by the underlying esp-idf, disable it +// ------------------------------------------------------------------------------------------ +#if !LWIP_IPV6 + #undef USE_IPV6 +#endif + // Libraries #include // Ota #include // Ota @@ -494,7 +501,7 @@ void setup(void) { #ifdef ESP32 AddLog(LOG_LEVEL_INFO, PSTR("HDW: %s %s"), GetDeviceHardware().c_str(), FoundPSRAM() ? (CanUsePSRAM() ? "(PSRAM)" : "(PSRAM disabled)") : "" ); - AddLog(LOG_LEVEL_DEBUG, PSTR("HDW: FoundPSRAM=%i CanUsePSRAM=%i"), FoundPSRAM(), CanUsePSRAM()); + // AddLog(LOG_LEVEL_DEBUG, PSTR("HDW: FoundPSRAM=%i CanUsePSRAM=%i"), FoundPSRAM(), CanUsePSRAM()); #if !defined(HAS_PSRAM_FIX) if (FoundPSRAM() && !CanUsePSRAM()) { AddLog(LOG_LEVEL_INFO, PSTR("HDW: PSRAM is disabled, requires specific compilation on this hardware (see doc)")); diff --git a/tasmota/tasmota_support/support_command.ino b/tasmota/tasmota_support/support_command.ino index 7144351eda68..07fba6fe4bc6 100644 --- a/tasmota/tasmota_support/support_command.ino +++ b/tasmota/tasmota_support/support_command.ino @@ -802,24 +802,24 @@ void CmndStatus(void) } if ((0 == payload) || (5 == payload)) { -#if LWIP_IPV6 +#ifdef USE_IPV6 if (5 == payload) { WifiDumpAddressesIPv6(); } -#endif // LWIP_IPV6 +#endif // USE_IPV6 Response_P(PSTR("{\"" D_CMND_STATUS D_STATUS5_NETWORK "\":{\"" D_CMND_HOSTNAME "\":\"%s\",\"" D_CMND_IPADDRESS "\":\"%_I\",\"" D_JSON_GATEWAY "\":\"%_I\",\"" D_JSON_SUBNETMASK "\":\"%_I\",\"" D_JSON_DNSSERVER "1\":\"%_I\",\"" D_JSON_DNSSERVER "2\":\"%_I\",\"" D_JSON_MAC "\":\"%s\"" -#if LWIP_IPV6 +#ifdef USE_IPV6 ",\"" D_JSON_IP6_GLOBAL "\":\"%s\",\"" D_JSON_IP6_LOCAL "\":\"%s\"" -#endif // LWIP_IPV6 +#endif // USE_IPV6 ), TasmotaGlobal.hostname, (uint32_t)WiFi.localIP(), Settings->ipv4_address[1], Settings->ipv4_address[2], Settings->ipv4_address[3], Settings->ipv4_address[4], WiFi.macAddress().c_str() -#if LWIP_IPV6 +#ifdef USE_IPV6 ,WifiGetIPv6().c_str(), WifiGetIPv6LinkLocal().c_str() -#endif // LWIP_IPV6 +#endif // USE_IPV6 ); #ifdef USE_TASMESH ResponseAppend_P(PSTR(",\"SoftAPMac\":\"%s\""), WiFi.softAPmacAddress().c_str()); @@ -830,17 +830,17 @@ void CmndStatus(void) D_JSON_DNSSERVER "1\":\"%_I\",\"" D_JSON_DNSSERVER "2\":\"%_I\",\"" D_JSON_MAC "\":\"%s\"" -#if LWIP_IPV6 +#ifdef USE_IPV6 ",\"" D_JSON_IP6_GLOBAL "\":\"%s\",\"" D_JSON_IP6_LOCAL "\":\"%s\"" -#endif // LWIP_IPV6 +#endif // USE_IPV6 "}"), EthernetHostname(), (uint32_t)EthernetLocalIP(), Settings->eth_ipv4_address[1], Settings->eth_ipv4_address[2], Settings->eth_ipv4_address[3], Settings->eth_ipv4_address[4], EthernetMacAddress().c_str() -#if LWIP_IPV6 +#ifdef USE_IPV6 ,EthernetGetIPv6().c_str(), EthernetGetIPv6LinkLocal().c_str() -#endif // LWIP_IPV6 +#endif // USE_IPV6 ); #endif // USE_ETHERNET ResponseAppend_P(PSTR(",\"" D_CMND_WEBSERVER "\":%d,\"HTTP_API\":%d,\"" D_CMND_WIFICONFIG "\":%d,\"" D_CMND_WIFIPOWER "\":%s}}"), diff --git a/tasmota/tasmota_support/support_wifi.ino b/tasmota/tasmota_support/support_wifi.ino index 6c2914d8a30b..b72c309cde29 100644 --- a/tasmota/tasmota_support/support_wifi.ino +++ b/tasmota/tasmota_support/support_wifi.ino @@ -41,13 +41,6 @@ const uint8_t WIFI_CHECK_SEC = 20; // seconds const uint8_t WIFI_RETRY_OFFSET_SEC = WIFI_RETRY_SECONDS; // seconds #include // Wifi, MQTT, Ota, WifiManager -#if LWIP_IPV6 - #ifdef ESP8266 - #include // IPv6 DualStack - #else - #include // IPv6 DualStack - #endif -#endif // LWIP_IPV6=1 int WifiGetRssiAsQuality(int rssi) { int quality = 0; @@ -213,7 +206,7 @@ void WifiBegin(uint8_t flag, uint8_t channel) { #endif // USE_EMULATION WiFi.persistent(false); // Solve possible wifi init errors (re-add at 6.2.1.16 #4044, #4083) -#if LWIP_IPV6 && defined(ESP32) +#if defined(USE_IPV6) && defined(ESP32) WiFi.IPv6(true); #endif @@ -465,7 +458,7 @@ void WifiSetState(uint8_t state) } } -#if LWIP_IPV6 +#ifdef USE_IPV6 // // Scan through all interfaces to find a global or local IPv6 address // Arg: @@ -476,8 +469,8 @@ static String WifiFindIPv6(bool is_local, const char * if_type = "st") { if (intf->name[0] == if_type[0] && intf->name[1] == if_type[1]) { 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) && ((bool)ip_addr_islinklocal(ipv6) == is_local)) { - return IPAddress46(ipv6).toString(); + if (IP_IS_V6_VAL(*ipv6) && !ip_addr_isloopback(ipv6) && !ip_addr_isany(ipv6) && ((bool)ip_addr_islinklocal(ipv6) == is_local)) { + return IPAddress(ipv6).toString(); } } } @@ -510,33 +503,28 @@ void CreateLinkLocalIPv6(void) 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' IPv4 %s", intf->name[0], intf->name[1], IPAddress46(intf->ip_addr).toString().c_str()); + if (!ip_addr_isany_val(intf->ip_addr)) AddLog(LOG_LEVEL_DEBUG, "WIF: '%c%c' IPv4 %s", intf->name[0], intf->name[1], IPAddress(intf->ip_addr).toString().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, "WIF: '%c%c' IPv6 %s %s", intf->name[0], intf->name[1], - IPAddress46(intf->ip6_addr[i]).toString().c_str(), + IPAddress(intf->ip6_addr[i]).toString().c_str(), ip_addr_islinklocal(&intf->ip6_addr[i]) ? "local" : ""); } } } -#endif // LWIP_IPV6=1 +#endif // USE_IPV6 // Check to see if we have any routable IP address bool WifiHasIP(void) { -#if LWIP_IPV6 - for (auto a : addrList) { - if(!ip_addr_isloopback((ip_addr_t*)a.addr()) && !a.isLocal()) { - return true; - } - } - return false; +#ifdef USE_IPV6 + return !WiFi.localIP().isAny(); #else return (uint32_t)WiFi.localIP() != 0; -#endif +#endif // USE_IPV6 } void WifiCheckIp(void) { -#if LWIP_IPV6 +#ifdef USE_IPV6 if (WL_CONNECTED == WiFi.status()) { if (!Wifi.ipv6_local_link_called) { WiFi.enableIpV6(); @@ -545,7 +533,7 @@ void WifiCheckIp(void) { } } -#endif +#endif // USE_IPV6 if ((WL_CONNECTED == WiFi.status()) && WifiHasIP()) { WifiSetState(1); @@ -1081,24 +1069,23 @@ uint64_t WifiGetNtp(void) { // Respond to some Arduino/esp-idf events for better IPv6 support // -------------------------------------------------------------------------------- #ifdef ESP32 -#include "IPAddress46.h" // typedef void (*WiFiEventSysCb)(arduino_event_t *event); void WifiEvents(arduino_event_t *event) { switch (event->event_id) { -#if LWIP_IPV6 +#ifdef USE_IPV6 case ARDUINO_EVENT_WIFI_STA_GOT_IP6: case ARDUINO_EVENT_ETH_GOT_IP6: { ip_addr_t ip_addr6; ip_addr_copy_from_ip6(ip_addr6, event->event_info.got_ip6.ip6_info.ip); - IPAddress46 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()); } break; -#endif // LWIP_IPV6 +#endif // USE_IPV6 case ARDUINO_EVENT_WIFI_STA_GOT_IP: case ARDUINO_EVENT_ETH_GOT_IP: { diff --git a/tasmota/tasmota_xdrv_driver/xdrv_01_9_webserver.ino b/tasmota/tasmota_xdrv_driver/xdrv_01_9_webserver.ino index ffc691eca5bc..94eaf5d27145 100644 --- a/tasmota/tasmota_xdrv_driver/xdrv_01_9_webserver.ino +++ b/tasmota/tasmota_xdrv_driver/xdrv_01_9_webserver.ino @@ -610,7 +610,7 @@ void StartWebserver(int type, IPAddress ipweb) Webserver->begin(); // Web server start } if (Web.state != type) { -#if LWIP_IPV6 +#ifdef USE_IPV6 String ipv6_addr = WifiGetIPv6(); if (ipv6_addr!="") { AddLog(LOG_LEVEL_INFO, PSTR(D_LOG_HTTP D_WEBSERVER_ACTIVE_ON " %s%s " D_WITH_IP_ADDRESS " %_I and IPv6 global address %s "), @@ -622,7 +622,7 @@ void StartWebserver(int type, IPAddress ipweb) #else AddLog(LOG_LEVEL_INFO, PSTR(D_LOG_HTTP D_WEBSERVER_ACTIVE_ON " %s%s " D_WITH_IP_ADDRESS " %_I"), NetworkHostname(), (Mdns.begun) ? PSTR(".local") : "", (uint32_t)ipweb); -#endif // LWIP_IPV6 = 1 +#endif // USE_IPV6 TasmotaGlobal.rules_flag.http_init = 1; Web.state = type; } @@ -2359,7 +2359,7 @@ void HandleInformation(void) int32_t rssi = WiFi.RSSI(); WSContentSend_P(PSTR("}1" D_AP "%d " D_SSID " (" D_RSSI ")}2%s (%d%%, %d dBm) 11%c"), Settings->sta_active +1, HtmlEscape(SettingsText(SET_STASSID1 + Settings->sta_active)).c_str(), WifiGetRssiAsQuality(rssi), rssi, pgm_read_byte(&kWifiPhyMode[WiFi.getPhyMode() & 0x3]) ); WSContentSend_P(PSTR("}1" D_HOSTNAME "}2%s%s"), TasmotaGlobal.hostname, (Mdns.begun) ? PSTR(".local") : ""); -#if LWIP_IPV6 +#ifdef USE_IPV6 String ipv6_addr = WifiGetIPv6(); if (ipv6_addr != "") { WSContentSend_P(PSTR("}1 IPv6 Global (wifi)}2%s"), ipv6_addr.c_str()); @@ -2368,7 +2368,7 @@ void HandleInformation(void) if (ipv6_addr != "") { WSContentSend_P(PSTR("}1 IPv6 Local (wifi)}2%s"), ipv6_addr.c_str()); } -#endif // LWIP_IPV6 = 1 +#endif // USE_IPV6 if (static_cast(WiFi.localIP()) != 0) { WSContentSend_P(PSTR("}1" D_MAC_ADDRESS "}2%s"), WiFi.macAddress().c_str()); WSContentSend_P(PSTR("}1" D_IP_ADDRESS " (wifi)}2%_I"), (uint32_t)WiFi.localIP()); @@ -2387,7 +2387,7 @@ void HandleInformation(void) WSContentSend_P(PSTR("}1
}2
")); } WSContentSend_P(PSTR("}1" D_HOSTNAME "}2%s%s"), EthernetHostname(), (Mdns.begun) ? PSTR(".local") : ""); -#if LWIP_IPV6 +#ifdef USE_IPV6 String ipv6_eth_addr = EthernetGetIPv6(); if (ipv6_eth_addr != "") { WSContentSend_P(PSTR("}1 IPv6 Global (eth)}2%s"), ipv6_eth_addr.c_str()); @@ -2396,7 +2396,7 @@ void HandleInformation(void) if (ipv6_eth_addr != "") { WSContentSend_P(PSTR("}1 IPv6 Local (eth)}2%s"), ipv6_eth_addr.c_str()); } -#endif // LWIP_IPV6 = 1 +#endif // USE_IPV6 WSContentSend_P(PSTR("}1" D_MAC_ADDRESS "}2%s"), EthernetMacAddress().c_str()); WSContentSend_P(PSTR("}1" D_IP_ADDRESS " (eth)}2%_I"), (uint32_t)EthernetLocalIP()); } diff --git a/tasmota/tasmota_xdrv_driver/xdrv_02_9_mqtt.ino b/tasmota/tasmota_xdrv_driver/xdrv_02_9_mqtt.ino index fdd2e3703f63..950085016009 100644 --- a/tasmota/tasmota_xdrv_driver/xdrv_02_9_mqtt.ino +++ b/tasmota/tasmota_xdrv_driver/xdrv_02_9_mqtt.ino @@ -971,10 +971,10 @@ void MqttConnected(void) { if (static_cast(WiFi.localIP()) != 0) { ResponseAppend_P(PSTR(",\"" D_CMND_HOSTNAME "\":\"%s\",\"" D_CMND_IPADDRESS "\":\"%_I\""), TasmotaGlobal.hostname, (uint32_t)WiFi.localIP()); -#if LWIP_IPV6 +#ifdef USE_IPV6 ResponseAppend_P(PSTR(",\"" D_JSON_IP6_GLOBAL "\":\"%s\""), WifiGetIPv6().c_str()); ResponseAppend_P(PSTR(",\"" D_JSON_IP6_LOCAL "\":\"%s\""), WifiGetIPv6LinkLocal().c_str()); -#endif // LWIP_IPV6 = 1 +#endif // USE_IPV6 } #if defined(ESP32) && CONFIG_IDF_TARGET_ESP32 && defined(USE_ETHERNET) if (static_cast(EthernetLocalIP()) != 0) { diff --git a/tasmota/tasmota_xdrv_driver/xdrv_52_3_berry_tasmota.ino b/tasmota/tasmota_xdrv_driver/xdrv_52_3_berry_tasmota.ino index c2327b73fe4c..c42f6e0037b9 100644 --- a/tasmota/tasmota_xdrv_driver/xdrv_52_3_berry_tasmota.ino +++ b/tasmota/tasmota_xdrv_driver/xdrv_52_3_berry_tasmota.ino @@ -214,7 +214,7 @@ extern "C" { if (Settings->flag4.network_wifi) { int32_t rssi = WiFi.RSSI(); bool show_rssi = false; -#if LWIP_IPV6 +#ifdef USE_IPV6 String ipv6_addr = WifiGetIPv6(); if (ipv6_addr != "") { be_map_insert_str(vm, "ip6", ipv6_addr.c_str()); @@ -225,10 +225,10 @@ extern "C" { be_map_insert_str(vm, "ip6local", ipv6_addr.c_str()); show_rssi = true; } -#endif +#endif // USE_IPV6 if (static_cast(WiFi.localIP()) != 0) { be_map_insert_str(vm, "mac", WiFi.macAddress().c_str()); - be_map_insert_str(vm, "ip", IPAddress46((uint32_t)WiFi.localIP()).toString().c_str()); // quick fix for IPAddress bug + be_map_insert_str(vm, "ip", IPAddress((uint32_t)WiFi.localIP()).toString().c_str()); // quick fix for IPAddress bug show_rssi = true; } if (show_rssi) { @@ -252,9 +252,9 @@ extern "C" { #ifdef USE_ETHERNET if (static_cast(EthernetLocalIP()) != 0) { be_map_insert_str(vm, "mac", EthernetMacAddress().c_str()); - be_map_insert_str(vm, "ip", IPAddress46((uint32_t)EthernetLocalIP()).toString().c_str()); // quick fix for IPAddress bug + be_map_insert_str(vm, "ip", IPAddress((uint32_t)EthernetLocalIP()).toString().c_str()); // quick fix for IPAddress bug } -#if LWIP_IPV6 +#ifdef USE_IPV6 String ipv6_addr = EthernetGetIPv6(); if (ipv6_addr != "") { be_map_insert_str(vm, "ip6", ipv6_addr.c_str()); @@ -263,8 +263,8 @@ extern "C" { if (ipv6_addr != "") { be_map_insert_str(vm, "ip6local", ipv6_addr.c_str()); } -#endif -#endif +#endif // USE_IPV6 +#endif // USE_ETHERNET be_pop(vm, 1); be_return(vm); } diff --git a/tasmota/tasmota_xdrv_driver/xdrv_82_esp32_ethernet.ino b/tasmota/tasmota_xdrv_driver/xdrv_82_esp32_ethernet.ino index 8e962d22c222..406d3f94f856 100644 --- a/tasmota/tasmota_xdrv_driver/xdrv_82_esp32_ethernet.ino +++ b/tasmota/tasmota_xdrv_driver/xdrv_82_esp32_ethernet.ino @@ -94,9 +94,9 @@ void EthernetEvent(arduino_event_t *event) { break; case ARDUINO_EVENT_ETH_CONNECTED: -#if LWIP_IPV6 +#ifdef USE_IPV6 ETH.enableIpV6(); // enable Link-Local -#endif +#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 @@ -143,6 +143,7 @@ void EthernetSetIp(void) { Settings->eth_ipv4_address[4]); // IPAddress dns2 } +#ifdef USE_IPV6 // Returns only IPv6 global address (no loopback and no link-local) String EthernetGetIPv6(void) { @@ -153,6 +154,7 @@ String EthernetGetIPv6LinkLocal(void) { return WifiFindIPv6(true, "en"); } +#endif // USE_IPV6 void EthernetInit(void) { if (!Settings->flag4.network_ethernet) { return; }