diff --git a/libraries/ESP8266WiFi/keywords.txt b/libraries/ESP8266WiFi/keywords.txt index b24bfc598..16eea2422 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 ####################################### @@ -108,6 +109,9 @@ psk KEYWORD2 BSSID KEYWORD2 BSSIDstr KEYWORD2 RSSI KEYWORD2 +stationKeepAliveSetIntervalMs KEYWORD2 +stationKeepAliveStop KEYWORD2 +stationKeepAliveNow KEYWORD2 enableInsecureWEP KEYWORD2 getListenInterval KEYWORD2 isSleepLevelMax KEYWORD2 diff --git a/libraries/ESP8266WiFi/src/ESP8266WiFiGratuitous.cpp b/libraries/ESP8266WiFi/src/ESP8266WiFiGratuitous.cpp new file mode 100644 index 000000000..0465fbc4f --- /dev/null +++ b/libraries/ESP8266WiFi/src/ESP8266WiFiGratuitous.cpp @@ -0,0 +1,94 @@ +/* + 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 +*/ + +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 + +#include "ESP8266WiFiGratuitous.h" + +namespace experimental +{ + +ETSTimer* ESP8266WiFiGratuitous::_timer = 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; + } +} + +void ESP8266WiFiGratuitous::scheduleItForNextYieldOnce (void*) +{ + schedule_recurrent_function_us([]() + { + ESP8266WiFiGratuitous::stationKeepAliveNow(); + return false; + }, 0); +} + +bool ESP8266WiFiGratuitous::stationKeepAliveSetIntervalMs (uint32_t ms) +{ + if (_timer) + { + os_timer_disarm(_timer); + _timer = nullptr; + } + + if (ms) + { + // send one now + 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; +} + +}; // experimental:: diff --git a/libraries/ESP8266WiFi/src/ESP8266WiFiGratuitous.h b/libraries/ESP8266WiFi/src/ESP8266WiFiGratuitous.h new file mode 100644 index 000000000..d86426cd8 --- /dev/null +++ b/libraries/ESP8266WiFi/src/ESP8266WiFiGratuitous.h @@ -0,0 +1,54 @@ +/* + 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 +#include // ETSTimer + +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 void scheduleItForNextYieldOnce (void*); + + static ETSTimer* _timer; +}; + +}; // experimental:: + +#endif // ESP8266WIFIGRATUITOUS_H_ diff --git a/libraries/ESP8266WiFi/src/ESP8266WiFiSTA.cpp b/libraries/ESP8266WiFi/src/ESP8266WiFiSTA.cpp index 8f52942b7..26fb4b9d3 100644 --- a/libraries/ESP8266WiFi/src/ESP8266WiFiSTA.cpp +++ b/libraries/ESP8266WiFi/src/ESP8266WiFiSTA.cpp @@ -89,7 +89,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; } diff --git a/libraries/ESP8266WiFi/src/ESP8266WiFiSTA.h b/libraries/ESP8266WiFi/src/ESP8266WiFiSTA.h index 696ff1b39..cf38e1254 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); diff --git a/libraries/Ticker/src/Ticker.h b/libraries/Ticker/src/Ticker.h index 436a68ce8..07ce33c62 100644 --- a/libraries/Ticker/src/Ticker.h +++ b/libraries/Ticker/src/Ticker.h @@ -35,30 +35,42 @@ public: 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 @@ public: _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 @@ public: _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 @@ public: _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) { diff --git a/tests/host/common/MocklwIP.cpp b/tests/host/common/MocklwIP.cpp index bc5ae6ebc..f114572c1 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"