From 602509650ebd974f95a59f98ecaf173dc4c2abb3 Mon Sep 17 00:00:00 2001 From: david gauchard Date: Sat, 7 Dec 2019 16:50:09 +0100 Subject: [PATCH 01/14] wifi: ARP gratuitous API for wifi station mode --- libraries/ESP8266WiFi/keywords.txt | 3 ++ libraries/ESP8266WiFi/src/ESP8266WiFiSTA.cpp | 56 +++++++++++++++++++- libraries/ESP8266WiFi/src/ESP8266WiFiSTA.h | 12 +++++ 3 files changed, 70 insertions(+), 1 deletion(-) diff --git a/libraries/ESP8266WiFi/keywords.txt b/libraries/ESP8266WiFi/keywords.txt index b24bfc598e..ca600820bb 100644 --- a/libraries/ESP8266WiFi/keywords.txt +++ b/libraries/ESP8266WiFi/keywords.txt @@ -108,6 +108,9 @@ psk KEYWORD2 BSSID KEYWORD2 BSSIDstr KEYWORD2 RSSI KEYWORD2 +stationKeepAliveSetupMs KEYWORD2 +stationKeepAliveStop KEYWORD2 +stationKeepAliveEnabled KEYWORD2 enableInsecureWEP KEYWORD2 getListenInterval KEYWORD2 isSleepLevelMax KEYWORD2 diff --git a/libraries/ESP8266WiFi/src/ESP8266WiFiSTA.cpp b/libraries/ESP8266WiFi/src/ESP8266WiFiSTA.cpp index 8f52942b74..d765992f64 100644 --- a/libraries/ESP8266WiFi/src/ESP8266WiFiSTA.cpp +++ b/libraries/ESP8266WiFi/src/ESP8266WiFiSTA.cpp @@ -34,6 +34,7 @@ #include "mem.h" #include "user_interface.h" #include "smartconfig.h" +#include "Schedule.h" extern "C" { #include "lwip/err.h" @@ -43,6 +44,11 @@ extern "C" { #if LWIP_IPV6 #include "lwip/netif.h" // struct netif #endif +#if LWIP_VERSION_MAJOR == 1 +#include "netif/etharp.h" // gratuitous arp +#else +#include "lwip/etharp.h" // gratuitous arp +#endif } #include "debug.h" @@ -89,7 +95,7 @@ static bool sta_config_equal(const station_config& lhs, const station_config& rh return false; } } - + if(lhs.threshold.rssi != rhs.threshold.rssi) { return false; } @@ -704,7 +710,55 @@ int32_t ESP8266WiFiSTAClass::RSSI(void) { return wifi_station_get_rssi(); } +bool ESP8266WiFiSTAClass::stationKeepAliveEnabled () +{ + return _keepStationAliveUs != 0; +} +void ESP8266WiFiSTAClass::stationKeepAliveStop () +{ + _keepStationAliveUs = -1; + // will be set to 0 at recurrent call +} + +bool ESP8266WiFiSTAClass::stationKeepAliveSetupMs (int ms) +{ + if (_keepStationAliveUs != 0 || ms <= 0) + return false; + _keepStationAliveUs = ms * 1000; + + schedule_recurrent_function_us([&]() + { + for (netif* interface = netif_list; interface != nullptr; interface = interface->next) + + if ( + (interface->flags & NETIF_FLAG_LINK_UP) + && (interface->flags & NETIF_FLAG_UP) +#if LWIP_VERSION_MAJOR == 1 + && (!ip_addr_isany(&interface->ip_addr)) +#else + && interface->num == STATION_IF /* lwip1 does not set num properly */ + && (!ip4_addr_isany_val(*netif_ip4_addr(interface))) +#endif + ) + { + etharp_gratuitous(interface); + break; + } + + if (_keepStationAliveUs > 0) + // continue + return true; + + // stop on user request (value < 0) + _keepStationAliveUs = 0; // stop acknowledged + // stop recurrent function + return false; + + }, _keepStationAliveUs); + + return true; +} // ----------------------------------------------------------------------------------------------------------------------- // -------------------------------------------------- STA remote configure ----------------------------------------------- diff --git a/libraries/ESP8266WiFi/src/ESP8266WiFiSTA.h b/libraries/ESP8266WiFi/src/ESP8266WiFiSTA.h index 696ff1b390..27ca713b77 100644 --- a/libraries/ESP8266WiFi/src/ESP8266WiFiSTA.h +++ b/libraries/ESP8266WiFi/src/ESP8266WiFiSTA.h @@ -83,10 +83,22 @@ class ESP8266WiFiSTAClass { int32_t RSSI(); + // enable automatic sending of Gratuitous ARP packets + // based on a time interval in milliseconds + // returns true on success + bool stationKeepAliveSetupMs (int ms = 1000); + + // request for stopping arp gratuitous packets + void stationKeepAliveStop (); + + // allows to check whether the gratuitous ARP service is still running + bool stationKeepAliveEnabled (); + static void enableInsecureWEP (bool enable = true) { _useInsecureWEP = enable; } protected: + int _keepStationAliveUs = 0; static bool _useStaticIp; static bool _useInsecureWEP; From c087e08ca9c303d254a5f216bce7c57c32b19bb4 Mon Sep 17 00:00:00 2001 From: david gauchard Date: Sat, 7 Dec 2019 17:03:39 +0100 Subject: [PATCH 02/14] fix with lwip1 --- libraries/ESP8266WiFi/src/ESP8266WiFiSTA.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/libraries/ESP8266WiFi/src/ESP8266WiFiSTA.cpp b/libraries/ESP8266WiFi/src/ESP8266WiFiSTA.cpp index d765992f64..e699ae2861 100644 --- a/libraries/ESP8266WiFi/src/ESP8266WiFiSTA.cpp +++ b/libraries/ESP8266WiFi/src/ESP8266WiFiSTA.cpp @@ -45,6 +45,7 @@ extern "C" { #include "lwip/netif.h" // struct netif #endif #if LWIP_VERSION_MAJOR == 1 +#include "netif/wlan_lwip_if.h" // eagle_lwip_getif() #include "netif/etharp.h" // gratuitous arp #else #include "lwip/etharp.h" // gratuitous arp @@ -730,11 +731,11 @@ bool ESP8266WiFiSTAClass::stationKeepAliveSetupMs (int ms) schedule_recurrent_function_us([&]() { for (netif* interface = netif_list; interface != nullptr; interface = interface->next) - if ( (interface->flags & NETIF_FLAG_LINK_UP) && (interface->flags & NETIF_FLAG_UP) #if LWIP_VERSION_MAJOR == 1 + && interface == eagle_lwip_getif(STATION_IF) && (!ip_addr_isany(&interface->ip_addr)) #else && interface->num == STATION_IF /* lwip1 does not set num properly */ From 93bc15e3726e1e7832e04f7f7edd88866ff0a509 Mon Sep 17 00:00:00 2001 From: david gauchard Date: Sat, 7 Dec 2019 17:05:03 +0100 Subject: [PATCH 03/14] update comment --- libraries/ESP8266WiFi/src/ESP8266WiFiSTA.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/libraries/ESP8266WiFi/src/ESP8266WiFiSTA.cpp b/libraries/ESP8266WiFi/src/ESP8266WiFiSTA.cpp index e699ae2861..0c450027cb 100644 --- a/libraries/ESP8266WiFi/src/ESP8266WiFiSTA.cpp +++ b/libraries/ESP8266WiFi/src/ESP8266WiFiSTA.cpp @@ -735,10 +735,10 @@ bool ESP8266WiFiSTAClass::stationKeepAliveSetupMs (int ms) (interface->flags & NETIF_FLAG_LINK_UP) && (interface->flags & NETIF_FLAG_UP) #if LWIP_VERSION_MAJOR == 1 - && interface == eagle_lwip_getif(STATION_IF) + && interface == eagle_lwip_getif(STATION_IF) /* lwip1 does not set num properly */ && (!ip_addr_isany(&interface->ip_addr)) #else - && interface->num == STATION_IF /* lwip1 does not set num properly */ + && interface->num == STATION_IF && (!ip4_addr_isany_val(*netif_ip4_addr(interface))) #endif ) From cbd217faa1c6c964a1420ebd2dbc4307708e1d14 Mon Sep 17 00:00:00 2001 From: david gauchard Date: Sun, 8 Dec 2019 01:39:05 +0100 Subject: [PATCH 04/14] update API to allow changing interval on the fly --- libraries/ESP8266WiFi/keywords.txt | 2 +- libraries/ESP8266WiFi/src/ESP8266WiFiSTA.cpp | 53 +++++++++----------- libraries/ESP8266WiFi/src/ESP8266WiFiSTA.h | 12 +++-- 3 files changed, 33 insertions(+), 34 deletions(-) diff --git a/libraries/ESP8266WiFi/keywords.txt b/libraries/ESP8266WiFi/keywords.txt index ca600820bb..e1af1be675 100644 --- a/libraries/ESP8266WiFi/keywords.txt +++ b/libraries/ESP8266WiFi/keywords.txt @@ -108,7 +108,7 @@ psk KEYWORD2 BSSID KEYWORD2 BSSIDstr KEYWORD2 RSSI KEYWORD2 -stationKeepAliveSetupMs KEYWORD2 +stationKeepAliveSetIntervalMs KEYWORD2 stationKeepAliveStop KEYWORD2 stationKeepAliveEnabled KEYWORD2 enableInsecureWEP KEYWORD2 diff --git a/libraries/ESP8266WiFi/src/ESP8266WiFiSTA.cpp b/libraries/ESP8266WiFi/src/ESP8266WiFiSTA.cpp index 0c450027cb..61d4a309cf 100644 --- a/libraries/ESP8266WiFi/src/ESP8266WiFiSTA.cpp +++ b/libraries/ESP8266WiFi/src/ESP8266WiFiSTA.cpp @@ -711,24 +711,9 @@ int32_t ESP8266WiFiSTAClass::RSSI(void) { return wifi_station_get_rssi(); } -bool ESP8266WiFiSTAClass::stationKeepAliveEnabled () +void ESP8266WiFiSTAClass::stationKeepAliveNow () { - return _keepStationAliveUs != 0; -} - -void ESP8266WiFiSTAClass::stationKeepAliveStop () -{ - _keepStationAliveUs = -1; - // will be set to 0 at recurrent call -} - -bool ESP8266WiFiSTAClass::stationKeepAliveSetupMs (int ms) -{ - if (_keepStationAliveUs != 0 || ms <= 0) - return false; - _keepStationAliveUs = ms * 1000; - - schedule_recurrent_function_us([&]() + if (_keepStationAliveUs > 0) { for (netif* interface = netif_list; interface != nullptr; interface = interface->next) if ( @@ -747,18 +732,30 @@ bool ESP8266WiFiSTAClass::stationKeepAliveSetupMs (int ms) break; } - if (_keepStationAliveUs > 0) - // continue - return true; - - // stop on user request (value < 0) - _keepStationAliveUs = 0; // stop acknowledged - // stop recurrent function - return false; - - }, _keepStationAliveUs); + // re/schedule with a possibly updated interval + schedule_recurrent_function_us([&]() + { + stationKeepAliveNow(); + return false; + }, _keepStationAliveUs); + } + else + // mark disabled (0) if user cancelled it (<0) + _keepStationAliveUs = 0; +} - return true; +void ESP8266WiFiSTAClass::stationKeepAliveSetIntervalMs (int ms) +{ + bool wasEnabled = (_keepStationAliveUs > 0); + int us = ms * 1000; + if (wasEnabled) + _keepStationAliveUs = ms <= 0? /*disable*/-1: /*update*/us; + else if (ms > 0) + { + _keepStationAliveUs = us; + // start + stationKeepAliveNow(); + } } // ----------------------------------------------------------------------------------------------------------------------- diff --git a/libraries/ESP8266WiFi/src/ESP8266WiFiSTA.h b/libraries/ESP8266WiFi/src/ESP8266WiFiSTA.h index 27ca713b77..171bbf7511 100644 --- a/libraries/ESP8266WiFi/src/ESP8266WiFiSTA.h +++ b/libraries/ESP8266WiFi/src/ESP8266WiFiSTA.h @@ -83,16 +83,16 @@ class ESP8266WiFiSTAClass { int32_t RSSI(); - // enable automatic sending of Gratuitous ARP packets + // enable or update automatic sending of Gratuitous ARP packets // based on a time interval in milliseconds - // returns true on success - bool stationKeepAliveSetupMs (int ms = 1000); + void stationKeepAliveSetIntervalMs (int ms = 1000); // request for stopping arp gratuitous packets - void stationKeepAliveStop (); + void stationKeepAliveStop () { stationKeepAliveSetIntervalMs(0); } // allows to check whether the gratuitous ARP service is still running - bool stationKeepAliveEnabled (); + bool stationKeepAliveEnabled () const { return _keepStationAliveUs != 0; } + static void enableInsecureWEP (bool enable = true) { _useInsecureWEP = enable; } @@ -102,6 +102,8 @@ class ESP8266WiFiSTAClass { static bool _useStaticIp; static bool _useInsecureWEP; + void stationKeepAliveNow (); + // ---------------------------------------------------------------------------------------------- // ------------------------------------ STA remote configure ----------------------------------- // ---------------------------------------------------------------------------------------------- From 8d433ca6d5c51df17d2c315feeaf43c43755692b Mon Sep 17 00:00:00 2001 From: david gauchard Date: Sun, 8 Dec 2019 21:58:20 +0100 Subject: [PATCH 05/14] update API --- libraries/ESP8266WiFi/keywords.txt | 2 +- libraries/ESP8266WiFi/src/ESP8266WiFiSTA.cpp | 77 +++++++++++--------- libraries/ESP8266WiFi/src/ESP8266WiFiSTA.h | 17 ++--- 3 files changed, 53 insertions(+), 43 deletions(-) diff --git a/libraries/ESP8266WiFi/keywords.txt b/libraries/ESP8266WiFi/keywords.txt index e1af1be675..3db3541a23 100644 --- a/libraries/ESP8266WiFi/keywords.txt +++ b/libraries/ESP8266WiFi/keywords.txt @@ -110,7 +110,7 @@ BSSIDstr KEYWORD2 RSSI KEYWORD2 stationKeepAliveSetIntervalMs KEYWORD2 stationKeepAliveStop KEYWORD2 -stationKeepAliveEnabled KEYWORD2 +stationKeepAliveNow KEYWORD2 enableInsecureWEP KEYWORD2 getListenInterval KEYWORD2 isSleepLevelMax KEYWORD2 diff --git a/libraries/ESP8266WiFi/src/ESP8266WiFiSTA.cpp b/libraries/ESP8266WiFi/src/ESP8266WiFiSTA.cpp index 61d4a309cf..7435848be7 100644 --- a/libraries/ESP8266WiFi/src/ESP8266WiFiSTA.cpp +++ b/libraries/ESP8266WiFi/src/ESP8266WiFiSTA.cpp @@ -713,48 +713,59 @@ int32_t ESP8266WiFiSTAClass::RSSI(void) { void ESP8266WiFiSTAClass::stationKeepAliveNow () { - if (_keepStationAliveUs > 0) - { - for (netif* interface = netif_list; interface != nullptr; interface = interface->next) - if ( - (interface->flags & NETIF_FLAG_LINK_UP) - && (interface->flags & NETIF_FLAG_UP) + for (netif* interface = netif_list; interface != nullptr; interface = interface->next) + if ( + (interface->flags & NETIF_FLAG_LINK_UP) + && (interface->flags & NETIF_FLAG_UP) #if LWIP_VERSION_MAJOR == 1 - && interface == eagle_lwip_getif(STATION_IF) /* lwip1 does not set num properly */ - && (!ip_addr_isany(&interface->ip_addr)) + && interface == eagle_lwip_getif(STATION_IF) /* lwip1 does not set if->num properly */ + && (!ip_addr_isany(&interface->ip_addr)) #else - && interface->num == STATION_IF - && (!ip4_addr_isany_val(*netif_ip4_addr(interface))) + && interface->num == STATION_IF + && (!ip4_addr_isany_val(*netif_ip4_addr(interface))) #endif - ) - { - etharp_gratuitous(interface); - break; - } - - // re/schedule with a possibly updated interval - schedule_recurrent_function_us([&]() - { - stationKeepAliveNow(); - return false; - }, _keepStationAliveUs); - } - else - // mark disabled (0) if user cancelled it (<0) - _keepStationAliveUs = 0; + ) + { + etharp_gratuitous(interface); + break; + } } void ESP8266WiFiSTAClass::stationKeepAliveSetIntervalMs (int ms) { - bool wasEnabled = (_keepStationAliveUs > 0); - int us = ms * 1000; - if (wasEnabled) - _keepStationAliveUs = ms <= 0? /*disable*/-1: /*update*/us; - else if (ms > 0) + int us; + if (ms > std::numeric_limits::max() / 1000) + // for sanity only, 24 days is not really meaningful + us = std::numeric_limits::max(); + else + us = ms * 1000; + + // cancel possibly already scheduled future events + _keepStationState++; + + if (us) { - _keepStationAliveUs = us; - // start + // send one now stationKeepAliveNow(); + + // schedule next ones + int checkState = _keepStationState; + schedule_recurrent_function_us([&, checkState]() + { +Serial.printf("--- %d %d\n", checkState, this->_keepStationState); + // this recurring scheduled function will be cancelled + // when this->_keepStationState != checkState + if (checkState != this->_keepStationState) + // cancel this recurring event + return false; + +Serial.printf("--- SEND\n"); + // send gratuitous ARP + this->stationKeepAliveNow(); + + // keep on with next event + return true; + }, us); } } diff --git a/libraries/ESP8266WiFi/src/ESP8266WiFiSTA.h b/libraries/ESP8266WiFi/src/ESP8266WiFiSTA.h index 171bbf7511..024a391f0a 100644 --- a/libraries/ESP8266WiFi/src/ESP8266WiFiSTA.h +++ b/libraries/ESP8266WiFi/src/ESP8266WiFiSTA.h @@ -41,8 +41,8 @@ class ESP8266WiFiSTAClass { wl_status_t begin(const String& ssid, const String& passphrase = emptyString, int32_t channel = 0, const uint8_t* bssid = NULL, bool connect = true); wl_status_t begin(); - //The argument order for ESP is not the same as for Arduino. However, there is compatibility code under the hood - //to detect Arduino arg order, and handle it correctly. Be aware that the Arduino default value handling doesn't + //The argument order for ESP is not the same as for Arduino. However, there is compatibility code under the hood + //to detect Arduino arg order, and handle it correctly. Be aware that the Arduino default value handling doesn't //work here (see Arduino docs for gway/subnet defaults). In other words: at least 3 args must always be given. bool config(IPAddress local_ip, IPAddress gateway, IPAddress subnet, IPAddress dns1 = (uint32_t)0x00000000, IPAddress dns2 = (uint32_t)0x00000000); @@ -83,26 +83,25 @@ class ESP8266WiFiSTAClass { int32_t RSSI(); - // enable or update automatic sending of Gratuitous ARP packets - // based on a time interval in milliseconds + // disable(0) or enable/update automatic sending of Gratuitous ARP packets + // a gratuitous ARP packet is sent at start, then + // based on a time interval in milliseconds, default 1s void stationKeepAliveSetIntervalMs (int ms = 1000); // request for stopping arp gratuitous packets void stationKeepAliveStop () { stationKeepAliveSetIntervalMs(0); } - // allows to check whether the gratuitous ARP service is still running - bool stationKeepAliveEnabled () const { return _keepStationAliveUs != 0; } - + // immediately send one gratuitous ARP from STA + static void stationKeepAliveNow (); static void enableInsecureWEP (bool enable = true) { _useInsecureWEP = enable; } protected: - int _keepStationAliveUs = 0; static bool _useStaticIp; static bool _useInsecureWEP; - void stationKeepAliveNow (); + int _keepStationState = 0; // ---------------------------------------------------------------------------------------------- // ------------------------------------ STA remote configure ----------------------------------- From 716baecf2f281dde27755ab253bee6af425d62ca Mon Sep 17 00:00:00 2001 From: david gauchard Date: Sun, 8 Dec 2019 22:03:23 +0100 Subject: [PATCH 06/14] remove debug lines --- libraries/ESP8266WiFi/src/ESP8266WiFiSTA.cpp | 2 -- 1 file changed, 2 deletions(-) diff --git a/libraries/ESP8266WiFi/src/ESP8266WiFiSTA.cpp b/libraries/ESP8266WiFi/src/ESP8266WiFiSTA.cpp index 7435848be7..076fe23ffa 100644 --- a/libraries/ESP8266WiFi/src/ESP8266WiFiSTA.cpp +++ b/libraries/ESP8266WiFi/src/ESP8266WiFiSTA.cpp @@ -752,14 +752,12 @@ void ESP8266WiFiSTAClass::stationKeepAliveSetIntervalMs (int ms) int checkState = _keepStationState; schedule_recurrent_function_us([&, checkState]() { -Serial.printf("--- %d %d\n", checkState, this->_keepStationState); // this recurring scheduled function will be cancelled // when this->_keepStationState != checkState if (checkState != this->_keepStationState) // cancel this recurring event return false; -Serial.printf("--- SEND\n"); // send gratuitous ARP this->stationKeepAliveNow(); From 2885ac46dfb3c76b71a0a2a01035fd061051a36e Mon Sep 17 00:00:00 2001 From: david gauchard Date: Sun, 8 Dec 2019 22:31:34 +0100 Subject: [PATCH 07/14] mock lwIP's etharp_request() --- tests/host/common/MocklwIP.cpp | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/tests/host/common/MocklwIP.cpp b/tests/host/common/MocklwIP.cpp index bc5ae6ebc4..f114572c14 100644 --- a/tests/host/common/MocklwIP.cpp +++ b/tests/host/common/MocklwIP.cpp @@ -26,4 +26,11 @@ const ip_addr_t* sntp_getserver(u8_t) return IP_ADDR_ANY; } +err_t etharp_request(struct netif *netif, const ip4_addr_t *ipaddr) +{ + (void)netif; + (void)ipaddr; + return ERR_OK; +} + } // extern "C" From 338c3df9c8d21cf706fed4b83eed713f9e99dbfe Mon Sep 17 00:00:00 2001 From: david gauchard Date: Mon, 9 Dec 2019 22:26:52 +0100 Subject: [PATCH 08/14] unsigned interval --- libraries/ESP8266WiFi/src/ESP8266WiFiSTA.cpp | 10 +++++----- libraries/ESP8266WiFi/src/ESP8266WiFiSTA.h | 2 +- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/libraries/ESP8266WiFi/src/ESP8266WiFiSTA.cpp b/libraries/ESP8266WiFi/src/ESP8266WiFiSTA.cpp index 076fe23ffa..7e1f2dd2f7 100644 --- a/libraries/ESP8266WiFi/src/ESP8266WiFiSTA.cpp +++ b/libraries/ESP8266WiFi/src/ESP8266WiFiSTA.cpp @@ -731,12 +731,12 @@ void ESP8266WiFiSTAClass::stationKeepAliveNow () } } -void ESP8266WiFiSTAClass::stationKeepAliveSetIntervalMs (int ms) +void ESP8266WiFiSTAClass::stationKeepAliveSetIntervalMs (uint32_t ms) { - int us; - if (ms > std::numeric_limits::max() / 1000) - // for sanity only, 24 days is not really meaningful - us = std::numeric_limits::max(); + uint32_t us; + if (ms > std::numeric_limits::max() / 1000) + // for sanity only, 49 days is not really meaningful + us = std::numeric_limits::max(); else us = ms * 1000; diff --git a/libraries/ESP8266WiFi/src/ESP8266WiFiSTA.h b/libraries/ESP8266WiFi/src/ESP8266WiFiSTA.h index 024a391f0a..6d5f97513c 100644 --- a/libraries/ESP8266WiFi/src/ESP8266WiFiSTA.h +++ b/libraries/ESP8266WiFi/src/ESP8266WiFiSTA.h @@ -86,7 +86,7 @@ class ESP8266WiFiSTAClass { // disable(0) or enable/update automatic sending of Gratuitous ARP packets // a gratuitous ARP packet is sent at start, then // based on a time interval in milliseconds, default 1s - void stationKeepAliveSetIntervalMs (int ms = 1000); + void stationKeepAliveSetIntervalMs (uint32_t ms = 1000); // request for stopping arp gratuitous packets void stationKeepAliveStop () { stationKeepAliveSetIntervalMs(0); } From 55370eb1b94d57fbe89f3498e3ab6be6f80680b8 Mon Sep 17 00:00:00 2001 From: david gauchard Date: Wed, 8 Apr 2020 19:11:59 +0200 Subject: [PATCH 09/14] use scheduled ticker --- libraries/ESP8266WiFi/src/ESP8266WiFiSTA.cpp | 40 +++++++------------- libraries/ESP8266WiFi/src/ESP8266WiFiSTA.h | 12 +++--- 2 files changed, 20 insertions(+), 32 deletions(-) diff --git a/libraries/ESP8266WiFi/src/ESP8266WiFiSTA.cpp b/libraries/ESP8266WiFi/src/ESP8266WiFiSTA.cpp index 7e1f2dd2f7..98c7e86ea2 100644 --- a/libraries/ESP8266WiFi/src/ESP8266WiFiSTA.cpp +++ b/libraries/ESP8266WiFi/src/ESP8266WiFiSTA.cpp @@ -731,40 +731,28 @@ void ESP8266WiFiSTAClass::stationKeepAliveNow () } } -void ESP8266WiFiSTAClass::stationKeepAliveSetIntervalMs (uint32_t ms) +bool ESP8266WiFiSTAClass::stationKeepAliveSetIntervalMs (uint32_t ms) { - uint32_t us; - if (ms > std::numeric_limits::max() / 1000) - // for sanity only, 49 days is not really meaningful - us = std::numeric_limits::max(); - else - us = ms * 1000; - - // cancel possibly already scheduled future events - _keepStationState++; + if (_keepalive) { + delete _keepalive; + _keepalive = nullptr; + } - if (us) - { + if (ms) { // send one now stationKeepAliveNow(); - // schedule next ones - int checkState = _keepStationState; - schedule_recurrent_function_us([&, checkState]() - { - // this recurring scheduled function will be cancelled - // when this->_keepStationState != checkState - if (checkState != this->_keepStationState) - // cancel this recurring event - return false; + _keepalive = new (std::nothrow) Ticker; + if (_keepalive == nullptr) + return false; - // send gratuitous ARP + _keepalive->attach_ms_scheduled(ms, [&]() + { this->stationKeepAliveNow(); - - // keep on with next event - return true; - }, us); + }); } + + return true; } // ----------------------------------------------------------------------------------------------------------------------- diff --git a/libraries/ESP8266WiFi/src/ESP8266WiFiSTA.h b/libraries/ESP8266WiFi/src/ESP8266WiFiSTA.h index 6d5f97513c..ac21f50628 100644 --- a/libraries/ESP8266WiFi/src/ESP8266WiFiSTA.h +++ b/libraries/ESP8266WiFi/src/ESP8266WiFiSTA.h @@ -23,7 +23,7 @@ #ifndef ESP8266WIFISTA_H_ #define ESP8266WIFISTA_H_ - +#include #include "ESP8266WiFiType.h" #include "ESP8266WiFiGeneric.h" #include "user_interface.h" @@ -83,13 +83,13 @@ class ESP8266WiFiSTAClass { int32_t RSSI(); - // disable(0) or enable/update automatic sending of Gratuitous ARP packets - // a gratuitous ARP packet is sent at start, then + // disable(0) or enable/update automatic sending of Gratuitous ARP packets. + // A gratuitous ARP packet is immediately sent when calling this function, then // based on a time interval in milliseconds, default 1s - void stationKeepAliveSetIntervalMs (uint32_t ms = 1000); + bool stationKeepAliveSetIntervalMs (uint32_t ms = 1000); // request for stopping arp gratuitous packets - void stationKeepAliveStop () { stationKeepAliveSetIntervalMs(0); } + void stationKeepAliveStop () { (void)stationKeepAliveSetIntervalMs(0); } // immediately send one gratuitous ARP from STA static void stationKeepAliveNow (); @@ -101,7 +101,7 @@ class ESP8266WiFiSTAClass { static bool _useStaticIp; static bool _useInsecureWEP; - int _keepStationState = 0; + Ticker* _keepalive; // ---------------------------------------------------------------------------------------------- // ------------------------------------ STA remote configure ----------------------------------- From 817f3b78aa51a26d8efc24a419ffef15cb9eab4d Mon Sep 17 00:00:00 2001 From: david gauchard Date: Wed, 8 Apr 2020 22:54:00 +0200 Subject: [PATCH 10/14] ticker: +attach_ms_scheduled_accurate ticker: +comment gratuitous: use attach_ms_scheduled_accurate --- libraries/ESP8266WiFi/src/ESP8266WiFiSTA.cpp | 3 +-- libraries/Ticker/src/Ticker.h | 19 +++++++++++++++++++ 2 files changed, 20 insertions(+), 2 deletions(-) diff --git a/libraries/ESP8266WiFi/src/ESP8266WiFiSTA.cpp b/libraries/ESP8266WiFi/src/ESP8266WiFiSTA.cpp index 98c7e86ea2..c88105d1f9 100644 --- a/libraries/ESP8266WiFi/src/ESP8266WiFiSTA.cpp +++ b/libraries/ESP8266WiFi/src/ESP8266WiFiSTA.cpp @@ -746,8 +746,7 @@ bool ESP8266WiFiSTAClass::stationKeepAliveSetIntervalMs (uint32_t ms) if (_keepalive == nullptr) return false; - _keepalive->attach_ms_scheduled(ms, [&]() - { + _keepalive->attach_ms_scheduled_accurate(ms, [&]() { this->stationKeepAliveNow(); }); } diff --git a/libraries/Ticker/src/Ticker.h b/libraries/Ticker/src/Ticker.h index 436a68ce8e..07ce33c623 100644 --- a/libraries/Ticker/src/Ticker.h +++ b/libraries/Ticker/src/Ticker.h @@ -35,30 +35,42 @@ class Ticker typedef void (*callback_with_arg_t)(void*); typedef std::function callback_function_t; + // callback will be called at following loop() after ticker fires void attach_scheduled(float seconds, callback_function_t callback) { _callback_function = [callback]() { schedule_function(callback); }; _attach_ms(1000UL * seconds, true); } + // callback will be called in SYS ctx when ticker fires void attach(float seconds, callback_function_t callback) { _callback_function = std::move(callback); _attach_ms(1000UL * seconds, true); } + // callback will be called at following loop() after ticker fires void attach_ms_scheduled(uint32_t milliseconds, callback_function_t callback) { _callback_function = [callback]() { schedule_function(callback); }; _attach_ms(milliseconds, true); } + // callback will be called at following yield() after ticker fires + void attach_ms_scheduled_accurate(uint32_t milliseconds, callback_function_t callback) + { + _callback_function = [callback]() { schedule_recurrent_function_us([callback]() { callback(); return false; }, 0); }; + _attach_ms(milliseconds, true); + } + + // callback will be called in SYS ctx when ticker fires void attach_ms(uint32_t milliseconds, callback_function_t callback) { _callback_function = std::move(callback); _attach_ms(milliseconds, true); } + // callback will be called in SYS ctx when ticker fires template void attach(float seconds, void (*callback)(TArg), TArg arg) { @@ -66,6 +78,7 @@ class Ticker _attach_ms(1000UL * seconds, true, reinterpret_cast(callback), reinterpret_cast(arg)); } + // callback will be called in SYS ctx when ticker fires template void attach_ms(uint32_t milliseconds, void (*callback)(TArg), TArg arg) { @@ -73,30 +86,35 @@ class Ticker _attach_ms(milliseconds, true, reinterpret_cast(callback), reinterpret_cast(arg)); } + // callback will be called at following loop() after ticker fires void once_scheduled(float seconds, callback_function_t callback) { _callback_function = [callback]() { schedule_function(callback); }; _attach_ms(1000UL * seconds, false); } + // callback will be called in SYS ctx when ticker fires void once(float seconds, callback_function_t callback) { _callback_function = std::move(callback); _attach_ms(1000UL * seconds, false); } + // callback will be called at following loop() after ticker fires void once_ms_scheduled(uint32_t milliseconds, callback_function_t callback) { _callback_function = [callback]() { schedule_function(callback); }; _attach_ms(milliseconds, false); } + // callback will be called in SYS ctx when ticker fires void once_ms(uint32_t milliseconds, callback_function_t callback) { _callback_function = std::move(callback); _attach_ms(milliseconds, false); } + // callback will be called in SYS ctx when ticker fires template void once(float seconds, void (*callback)(TArg), TArg arg) { @@ -104,6 +122,7 @@ class Ticker _attach_ms(1000UL * seconds, false, reinterpret_cast(callback), reinterpret_cast(arg)); } + // callback will be called in SYS ctx when ticker fires template void once_ms(uint32_t milliseconds, void (*callback)(TArg), TArg arg) { From 8f04314abc9246ff2e5437528c33717ae2b1cfe5 Mon Sep 17 00:00:00 2001 From: david gauchard Date: Wed, 8 Apr 2020 23:23:08 +0200 Subject: [PATCH 11/14] move to experimental namespace --- libraries/ESP8266WiFi/keywords.txt | 1 + .../ESP8266WiFi/src/ESP8266WiFiGratuitous.cpp | 82 +++++++++++++++++++ .../ESP8266WiFi/src/ESP8266WiFiGratuitous.h | 53 ++++++++++++ libraries/ESP8266WiFi/src/ESP8266WiFiSTA.cpp | 48 ----------- libraries/ESP8266WiFi/src/ESP8266WiFiSTA.h | 15 +--- 5 files changed, 137 insertions(+), 62 deletions(-) create mode 100644 libraries/ESP8266WiFi/src/ESP8266WiFiGratuitous.cpp create mode 100644 libraries/ESP8266WiFi/src/ESP8266WiFiGratuitous.h diff --git a/libraries/ESP8266WiFi/keywords.txt b/libraries/ESP8266WiFi/keywords.txt index 3db3541a23..16eea24227 100644 --- a/libraries/ESP8266WiFi/keywords.txt +++ b/libraries/ESP8266WiFi/keywords.txt @@ -26,6 +26,7 @@ PublicKey KEYWORD1 CertStoreSPIFFSBearSSL KEYWORD1 CertStoreSDBearSSL KEYWORD1 Session KEYWORD1 +ESP8266WiFiGratuitous KEYWORD1 ####################################### diff --git a/libraries/ESP8266WiFi/src/ESP8266WiFiGratuitous.cpp b/libraries/ESP8266WiFi/src/ESP8266WiFiGratuitous.cpp new file mode 100644 index 0000000000..a2108a4b09 --- /dev/null +++ b/libraries/ESP8266WiFi/src/ESP8266WiFiGratuitous.cpp @@ -0,0 +1,82 @@ +/* + ESP8266WiFiGratuitous.cpp - esp8266 Wifi support + copyright esp8266/arduino + + 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 "lwip/init.h" // LWIP_VERSION_* +#if LWIP_VERSION_MAJOR == 1 +#include "netif/wlan_lwip_if.h" // eagle_lwip_getif() +#include "netif/etharp.h" // gratuitous arp +#else +#include "lwip/etharp.h" // gratuitous arp +#endif + +#include "ESP8266WiFiGratuitous.h" + +namespace experimental +{ + +Ticker* ESP8266WiFiGratuitous::_keepalive = nullptr; + +void ESP8266WiFiGratuitous::stationKeepAliveNow () +{ + for (netif* interface = netif_list; interface != nullptr; interface = interface->next) + if ( + (interface->flags & NETIF_FLAG_LINK_UP) + && (interface->flags & NETIF_FLAG_UP) +#if LWIP_VERSION_MAJOR == 1 + && interface == eagle_lwip_getif(STATION_IF) /* lwip1 does not set if->num properly */ + && (!ip_addr_isany(&interface->ip_addr)) +#else + && interface->num == STATION_IF + && (!ip4_addr_isany_val(*netif_ip4_addr(interface))) +#endif + ) + { + etharp_gratuitous(interface); + break; + } +} + +bool ESP8266WiFiGratuitous::stationKeepAliveSetIntervalMs (uint32_t ms) +{ + if (_keepalive) + { + delete _keepalive; + _keepalive = nullptr; + } + + if (ms) { + // send one now + stationKeepAliveNow(); + + _keepalive = new (std::nothrow) Ticker; + if (_keepalive != nullptr) + { + _keepalive->attach_ms_scheduled_accurate(ms, []() + { + stationKeepAliveNow(); + }); + } + } + + return true; +} + +}; // experimental:: diff --git a/libraries/ESP8266WiFi/src/ESP8266WiFiGratuitous.h b/libraries/ESP8266WiFi/src/ESP8266WiFiGratuitous.h new file mode 100644 index 0000000000..a0640d35b2 --- /dev/null +++ b/libraries/ESP8266WiFi/src/ESP8266WiFiGratuitous.h @@ -0,0 +1,53 @@ +/* + ESP8266WiFiGratuitous.h - esp8266 Wifi support + copyright esp8266/arduino + + 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 +*/ + +#ifndef ESP8266WIFIGRATUITOUS_H_ +#define ESP8266WIFIGRATUITOUS_H_ + +#include // uint32_t + +class Ticker; + +namespace experimental +{ + +class ESP8266WiFiGratuitous +{ +public: + + // disable(0) or enable/update automatic sending of Gratuitous ARP packets. + // A gratuitous ARP packet is immediately sent when calling this function, then + // based on a time interval in milliseconds, default = 1s + // return value: true when started, false otherwise + static bool stationKeepAliveSetIntervalMs (uint32_t ms = 1000); + + // request for stopping arp gratuitous packets + static void stationKeepAliveStop () { (void)stationKeepAliveSetIntervalMs(0); } + + // immediately send one gratuitous ARP from STA + static void stationKeepAliveNow (); + +protected: + + static Ticker* _keepalive; +}; + +}; // experimental:: + +#endif // ESP8266WIFIGRATUITOUS_H_ diff --git a/libraries/ESP8266WiFi/src/ESP8266WiFiSTA.cpp b/libraries/ESP8266WiFi/src/ESP8266WiFiSTA.cpp index c88105d1f9..26fb4b9d37 100644 --- a/libraries/ESP8266WiFi/src/ESP8266WiFiSTA.cpp +++ b/libraries/ESP8266WiFi/src/ESP8266WiFiSTA.cpp @@ -34,7 +34,6 @@ #include "mem.h" #include "user_interface.h" #include "smartconfig.h" -#include "Schedule.h" extern "C" { #include "lwip/err.h" @@ -44,12 +43,6 @@ extern "C" { #if LWIP_IPV6 #include "lwip/netif.h" // struct netif #endif -#if LWIP_VERSION_MAJOR == 1 -#include "netif/wlan_lwip_if.h" // eagle_lwip_getif() -#include "netif/etharp.h" // gratuitous arp -#else -#include "lwip/etharp.h" // gratuitous arp -#endif } #include "debug.h" @@ -711,48 +704,7 @@ int32_t ESP8266WiFiSTAClass::RSSI(void) { return wifi_station_get_rssi(); } -void ESP8266WiFiSTAClass::stationKeepAliveNow () -{ - for (netif* interface = netif_list; interface != nullptr; interface = interface->next) - if ( - (interface->flags & NETIF_FLAG_LINK_UP) - && (interface->flags & NETIF_FLAG_UP) -#if LWIP_VERSION_MAJOR == 1 - && interface == eagle_lwip_getif(STATION_IF) /* lwip1 does not set if->num properly */ - && (!ip_addr_isany(&interface->ip_addr)) -#else - && interface->num == STATION_IF - && (!ip4_addr_isany_val(*netif_ip4_addr(interface))) -#endif - ) - { - etharp_gratuitous(interface); - break; - } -} -bool ESP8266WiFiSTAClass::stationKeepAliveSetIntervalMs (uint32_t ms) -{ - if (_keepalive) { - delete _keepalive; - _keepalive = nullptr; - } - - if (ms) { - // send one now - stationKeepAliveNow(); - - _keepalive = new (std::nothrow) Ticker; - if (_keepalive == nullptr) - return false; - - _keepalive->attach_ms_scheduled_accurate(ms, [&]() { - this->stationKeepAliveNow(); - }); - } - - return true; -} // ----------------------------------------------------------------------------------------------------------------------- // -------------------------------------------------- STA remote configure ----------------------------------------------- diff --git a/libraries/ESP8266WiFi/src/ESP8266WiFiSTA.h b/libraries/ESP8266WiFi/src/ESP8266WiFiSTA.h index ac21f50628..cf38e1254e 100644 --- a/libraries/ESP8266WiFi/src/ESP8266WiFiSTA.h +++ b/libraries/ESP8266WiFi/src/ESP8266WiFiSTA.h @@ -23,7 +23,7 @@ #ifndef ESP8266WIFISTA_H_ #define ESP8266WIFISTA_H_ -#include + #include "ESP8266WiFiType.h" #include "ESP8266WiFiGeneric.h" #include "user_interface.h" @@ -83,17 +83,6 @@ class ESP8266WiFiSTAClass { int32_t RSSI(); - // disable(0) or enable/update automatic sending of Gratuitous ARP packets. - // A gratuitous ARP packet is immediately sent when calling this function, then - // based on a time interval in milliseconds, default 1s - bool stationKeepAliveSetIntervalMs (uint32_t ms = 1000); - - // request for stopping arp gratuitous packets - void stationKeepAliveStop () { (void)stationKeepAliveSetIntervalMs(0); } - - // immediately send one gratuitous ARP from STA - static void stationKeepAliveNow (); - static void enableInsecureWEP (bool enable = true) { _useInsecureWEP = enable; } protected: @@ -101,8 +90,6 @@ class ESP8266WiFiSTAClass { static bool _useStaticIp; static bool _useInsecureWEP; - Ticker* _keepalive; - // ---------------------------------------------------------------------------------------------- // ------------------------------------ STA remote configure ----------------------------------- // ---------------------------------------------------------------------------------------------- From 2ce8df5f6cd548e59f14fff4e897ecd017df1d6b Mon Sep 17 00:00:00 2001 From: david gauchard Date: Wed, 8 Apr 2020 23:48:55 +0200 Subject: [PATCH 12/14] fix for lwIP-v1.4 --- libraries/ESP8266WiFi/src/ESP8266WiFiGratuitous.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/libraries/ESP8266WiFi/src/ESP8266WiFiGratuitous.cpp b/libraries/ESP8266WiFi/src/ESP8266WiFiGratuitous.cpp index a2108a4b09..31db896ba4 100644 --- a/libraries/ESP8266WiFi/src/ESP8266WiFiGratuitous.cpp +++ b/libraries/ESP8266WiFi/src/ESP8266WiFiGratuitous.cpp @@ -19,13 +19,17 @@ #include +extern "C" +{ #include "lwip/init.h" // LWIP_VERSION_* #if LWIP_VERSION_MAJOR == 1 #include "netif/wlan_lwip_if.h" // eagle_lwip_getif() #include "netif/etharp.h" // gratuitous arp +#include "user_interface.h" #else #include "lwip/etharp.h" // gratuitous arp #endif +} // extern "C" #include "ESP8266WiFiGratuitous.h" From 4c5cc0227a2bdbf4aece823ee445f68314710e81 Mon Sep 17 00:00:00 2001 From: david gauchard Date: Thu, 9 Apr 2020 09:54:47 +0200 Subject: [PATCH 13/14] attempt to make pio happy --- libraries/ESP8266WiFi/src/ESP8266WiFiGratuitous.cpp | 2 -- libraries/ESP8266WiFi/src/ESP8266WiFiGratuitous.h | 2 +- 2 files changed, 1 insertion(+), 3 deletions(-) diff --git a/libraries/ESP8266WiFi/src/ESP8266WiFiGratuitous.cpp b/libraries/ESP8266WiFi/src/ESP8266WiFiGratuitous.cpp index 31db896ba4..3c157f6e01 100644 --- a/libraries/ESP8266WiFi/src/ESP8266WiFiGratuitous.cpp +++ b/libraries/ESP8266WiFi/src/ESP8266WiFiGratuitous.cpp @@ -17,8 +17,6 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ -#include - extern "C" { #include "lwip/init.h" // LWIP_VERSION_* diff --git a/libraries/ESP8266WiFi/src/ESP8266WiFiGratuitous.h b/libraries/ESP8266WiFi/src/ESP8266WiFiGratuitous.h index a0640d35b2..228ed0cb1b 100644 --- a/libraries/ESP8266WiFi/src/ESP8266WiFiGratuitous.h +++ b/libraries/ESP8266WiFi/src/ESP8266WiFiGratuitous.h @@ -22,7 +22,7 @@ #include // uint32_t -class Ticker; +#include namespace experimental { From 6801b3c5c0d5963a5910180a0cdb69bd2dfa442c Mon Sep 17 00:00:00 2001 From: david gauchard Date: Thu, 9 Apr 2020 15:38:23 +0200 Subject: [PATCH 14/14] use directly ETSTimer instead of Ticker --- .../ESP8266WiFi/src/ESP8266WiFiGratuitous.cpp | 36 ++++++++++++------- .../ESP8266WiFi/src/ESP8266WiFiGratuitous.h | 9 ++--- 2 files changed, 28 insertions(+), 17 deletions(-) diff --git a/libraries/ESP8266WiFi/src/ESP8266WiFiGratuitous.cpp b/libraries/ESP8266WiFi/src/ESP8266WiFiGratuitous.cpp index 3c157f6e01..0465fbc4f8 100644 --- a/libraries/ESP8266WiFi/src/ESP8266WiFiGratuitous.cpp +++ b/libraries/ESP8266WiFi/src/ESP8266WiFiGratuitous.cpp @@ -29,12 +29,14 @@ extern "C" #endif } // extern "C" +#include + #include "ESP8266WiFiGratuitous.h" namespace experimental { -Ticker* ESP8266WiFiGratuitous::_keepalive = nullptr; +ETSTimer* ESP8266WiFiGratuitous::_timer = nullptr; void ESP8266WiFiGratuitous::stationKeepAliveNow () { @@ -56,26 +58,34 @@ void ESP8266WiFiGratuitous::stationKeepAliveNow () } } +void ESP8266WiFiGratuitous::scheduleItForNextYieldOnce (void*) +{ + schedule_recurrent_function_us([]() + { + ESP8266WiFiGratuitous::stationKeepAliveNow(); + return false; + }, 0); +} + bool ESP8266WiFiGratuitous::stationKeepAliveSetIntervalMs (uint32_t ms) { - if (_keepalive) + if (_timer) { - delete _keepalive; - _keepalive = nullptr; + os_timer_disarm(_timer); + _timer = nullptr; } - if (ms) { + if (ms) + { // send one now stationKeepAliveNow(); - _keepalive = new (std::nothrow) Ticker; - if (_keepalive != nullptr) - { - _keepalive->attach_ms_scheduled_accurate(ms, []() - { - stationKeepAliveNow(); - }); - } + _timer = (ETSTimer*)malloc(sizeof(ETSTimer)); + if (_timer == nullptr) + return false; + + os_timer_setfn(_timer, ESP8266WiFiGratuitous::scheduleItForNextYieldOnce, nullptr); + os_timer_arm(_timer, ms, true); } return true; diff --git a/libraries/ESP8266WiFi/src/ESP8266WiFiGratuitous.h b/libraries/ESP8266WiFi/src/ESP8266WiFiGratuitous.h index 228ed0cb1b..d86426cd87 100644 --- a/libraries/ESP8266WiFi/src/ESP8266WiFiGratuitous.h +++ b/libraries/ESP8266WiFi/src/ESP8266WiFiGratuitous.h @@ -20,9 +20,8 @@ #ifndef ESP8266WIFIGRATUITOUS_H_ #define ESP8266WIFIGRATUITOUS_H_ -#include // uint32_t - -#include +#include // uint32_t +#include // ETSTimer namespace experimental { @@ -45,7 +44,9 @@ class ESP8266WiFiGratuitous protected: - static Ticker* _keepalive; + static void scheduleItForNextYieldOnce (void*); + + static ETSTimer* _timer; }; }; // experimental:: pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy