1
0
mirror of https://github.com/esp8266/Arduino.git synced 2025-04-19 23:22:16 +03:00

WiFi: ARP gratuitous API for wifi station mode (#6889)

* wifi: ARP gratuitous API for wifi station mode

* fix with lwip1

* update comment

* update API to allow changing interval on the fly

* update API

* remove debug lines

* mock lwIP's etharp_request()

* unsigned interval

* use scheduled ticker

* ticker: +attach_ms_scheduled_accurate
ticker: +comment
gratuitous: use attach_ms_scheduled_accurate

* move to experimental namespace

* fix for lwIP-v1.4

* attempt to make pio happy

* use directly ETSTimer instead of Ticker
This commit is contained in:
david gauchard 2020-04-09 16:19:15 +02:00 committed by GitHub
parent d600cc7fa6
commit bc170e6d63
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 181 additions and 3 deletions

View File

@ -26,6 +26,7 @@ PublicKey KEYWORD1
CertStoreSPIFFSBearSSL KEYWORD1 CertStoreSPIFFSBearSSL KEYWORD1
CertStoreSDBearSSL KEYWORD1 CertStoreSDBearSSL KEYWORD1
Session KEYWORD1 Session KEYWORD1
ESP8266WiFiGratuitous KEYWORD1
####################################### #######################################
@ -108,6 +109,9 @@ psk KEYWORD2
BSSID KEYWORD2 BSSID KEYWORD2
BSSIDstr KEYWORD2 BSSIDstr KEYWORD2
RSSI KEYWORD2 RSSI KEYWORD2
stationKeepAliveSetIntervalMs KEYWORD2
stationKeepAliveStop KEYWORD2
stationKeepAliveNow KEYWORD2
enableInsecureWEP KEYWORD2 enableInsecureWEP KEYWORD2
getListenInterval KEYWORD2 getListenInterval KEYWORD2
isSleepLevelMax KEYWORD2 isSleepLevelMax KEYWORD2

View File

@ -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 <Schedule.h>
#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::

View File

@ -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 <stdint.h> // uint32_t
#include <ets_sys.h> // 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_

View File

@ -35,30 +35,42 @@ public:
typedef void (*callback_with_arg_t)(void*); typedef void (*callback_with_arg_t)(void*);
typedef std::function<void(void)> callback_function_t; typedef std::function<void(void)> callback_function_t;
// callback will be called at following loop() after ticker fires
void attach_scheduled(float seconds, callback_function_t callback) void attach_scheduled(float seconds, callback_function_t callback)
{ {
_callback_function = [callback]() { schedule_function(callback); }; _callback_function = [callback]() { schedule_function(callback); };
_attach_ms(1000UL * seconds, true); _attach_ms(1000UL * seconds, true);
} }
// callback will be called in SYS ctx when ticker fires
void attach(float seconds, callback_function_t callback) void attach(float seconds, callback_function_t callback)
{ {
_callback_function = std::move(callback); _callback_function = std::move(callback);
_attach_ms(1000UL * seconds, true); _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) void attach_ms_scheduled(uint32_t milliseconds, callback_function_t callback)
{ {
_callback_function = [callback]() { schedule_function(callback); }; _callback_function = [callback]() { schedule_function(callback); };
_attach_ms(milliseconds, true); _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) void attach_ms(uint32_t milliseconds, callback_function_t callback)
{ {
_callback_function = std::move(callback); _callback_function = std::move(callback);
_attach_ms(milliseconds, true); _attach_ms(milliseconds, true);
} }
// callback will be called in SYS ctx when ticker fires
template<typename TArg> template<typename TArg>
void attach(float seconds, void (*callback)(TArg), TArg arg) void attach(float seconds, void (*callback)(TArg), TArg arg)
{ {
@ -66,6 +78,7 @@ public:
_attach_ms(1000UL * seconds, true, reinterpret_cast<callback_with_arg_t>(callback), reinterpret_cast<void*>(arg)); _attach_ms(1000UL * seconds, true, reinterpret_cast<callback_with_arg_t>(callback), reinterpret_cast<void*>(arg));
} }
// callback will be called in SYS ctx when ticker fires
template<typename TArg> template<typename TArg>
void attach_ms(uint32_t milliseconds, void (*callback)(TArg), TArg arg) void attach_ms(uint32_t milliseconds, void (*callback)(TArg), TArg arg)
{ {
@ -73,30 +86,35 @@ public:
_attach_ms(milliseconds, true, reinterpret_cast<callback_with_arg_t>(callback), reinterpret_cast<void*>(arg)); _attach_ms(milliseconds, true, reinterpret_cast<callback_with_arg_t>(callback), reinterpret_cast<void*>(arg));
} }
// callback will be called at following loop() after ticker fires
void once_scheduled(float seconds, callback_function_t callback) void once_scheduled(float seconds, callback_function_t callback)
{ {
_callback_function = [callback]() { schedule_function(callback); }; _callback_function = [callback]() { schedule_function(callback); };
_attach_ms(1000UL * seconds, false); _attach_ms(1000UL * seconds, false);
} }
// callback will be called in SYS ctx when ticker fires
void once(float seconds, callback_function_t callback) void once(float seconds, callback_function_t callback)
{ {
_callback_function = std::move(callback); _callback_function = std::move(callback);
_attach_ms(1000UL * seconds, false); _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) void once_ms_scheduled(uint32_t milliseconds, callback_function_t callback)
{ {
_callback_function = [callback]() { schedule_function(callback); }; _callback_function = [callback]() { schedule_function(callback); };
_attach_ms(milliseconds, false); _attach_ms(milliseconds, false);
} }
// callback will be called in SYS ctx when ticker fires
void once_ms(uint32_t milliseconds, callback_function_t callback) void once_ms(uint32_t milliseconds, callback_function_t callback)
{ {
_callback_function = std::move(callback); _callback_function = std::move(callback);
_attach_ms(milliseconds, false); _attach_ms(milliseconds, false);
} }
// callback will be called in SYS ctx when ticker fires
template<typename TArg> template<typename TArg>
void once(float seconds, void (*callback)(TArg), TArg arg) void once(float seconds, void (*callback)(TArg), TArg arg)
{ {
@ -104,6 +122,7 @@ public:
_attach_ms(1000UL * seconds, false, reinterpret_cast<callback_with_arg_t>(callback), reinterpret_cast<void*>(arg)); _attach_ms(1000UL * seconds, false, reinterpret_cast<callback_with_arg_t>(callback), reinterpret_cast<void*>(arg));
} }
// callback will be called in SYS ctx when ticker fires
template<typename TArg> template<typename TArg>
void once_ms(uint32_t milliseconds, void (*callback)(TArg), TArg arg) void once_ms(uint32_t milliseconds, void (*callback)(TArg), TArg arg)
{ {

View File

@ -26,4 +26,11 @@ const ip_addr_t* sntp_getserver(u8_t)
return IP_ADDR_ANY; 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" } // extern "C"