Skip to content

Commit bc170e6

Browse files
authored
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
1 parent d600cc7 commit bc170e6

File tree

7 files changed

+181
-3
lines changed

7 files changed

+181
-3
lines changed

libraries/ESP8266WiFi/keywords.txt

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ PublicKey KEYWORD1
2626
CertStoreSPIFFSBearSSL KEYWORD1
2727
CertStoreSDBearSSL KEYWORD1
2828
Session KEYWORD1
29+
ESP8266WiFiGratuitous KEYWORD1
2930

3031

3132
#######################################
@@ -108,6 +109,9 @@ psk KEYWORD2
108109
BSSID KEYWORD2
109110
BSSIDstr KEYWORD2
110111
RSSI KEYWORD2
112+
stationKeepAliveSetIntervalMs KEYWORD2
113+
stationKeepAliveStop KEYWORD2
114+
stationKeepAliveNow KEYWORD2
111115
enableInsecureWEP KEYWORD2
112116
getListenInterval KEYWORD2
113117
isSleepLevelMax KEYWORD2
Lines changed: 94 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,94 @@
1+
/*
2+
ESP8266WiFiGratuitous.cpp - esp8266 Wifi support
3+
copyright esp8266/arduino
4+
5+
This library is free software; you can redistribute it and/or
6+
modify it under the terms of the GNU Lesser General Public
7+
License as published by the Free Software Foundation; either
8+
version 2.1 of the License, or (at your option) any later version.
9+
10+
This library is distributed in the hope that it will be useful,
11+
but WITHOUT ANY WARRANTY; without even the implied warranty of
12+
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13+
Lesser General Public License for more details.
14+
15+
You should have received a copy of the GNU Lesser General Public
16+
License along with this library; if not, write to the Free Software
17+
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
18+
*/
19+
20+
extern "C"
21+
{
22+
#include "lwip/init.h" // LWIP_VERSION_*
23+
#if LWIP_VERSION_MAJOR == 1
24+
#include "netif/wlan_lwip_if.h" // eagle_lwip_getif()
25+
#include "netif/etharp.h" // gratuitous arp
26+
#include "user_interface.h"
27+
#else
28+
#include "lwip/etharp.h" // gratuitous arp
29+
#endif
30+
} // extern "C"
31+
32+
#include <Schedule.h>
33+
34+
#include "ESP8266WiFiGratuitous.h"
35+
36+
namespace experimental
37+
{
38+
39+
ETSTimer* ESP8266WiFiGratuitous::_timer = nullptr;
40+
41+
void ESP8266WiFiGratuitous::stationKeepAliveNow ()
42+
{
43+
for (netif* interface = netif_list; interface != nullptr; interface = interface->next)
44+
if (
45+
(interface->flags & NETIF_FLAG_LINK_UP)
46+
&& (interface->flags & NETIF_FLAG_UP)
47+
#if LWIP_VERSION_MAJOR == 1
48+
&& interface == eagle_lwip_getif(STATION_IF) /* lwip1 does not set if->num properly */
49+
&& (!ip_addr_isany(&interface->ip_addr))
50+
#else
51+
&& interface->num == STATION_IF
52+
&& (!ip4_addr_isany_val(*netif_ip4_addr(interface)))
53+
#endif
54+
)
55+
{
56+
etharp_gratuitous(interface);
57+
break;
58+
}
59+
}
60+
61+
void ESP8266WiFiGratuitous::scheduleItForNextYieldOnce (void*)
62+
{
63+
schedule_recurrent_function_us([]()
64+
{
65+
ESP8266WiFiGratuitous::stationKeepAliveNow();
66+
return false;
67+
}, 0);
68+
}
69+
70+
bool ESP8266WiFiGratuitous::stationKeepAliveSetIntervalMs (uint32_t ms)
71+
{
72+
if (_timer)
73+
{
74+
os_timer_disarm(_timer);
75+
_timer = nullptr;
76+
}
77+
78+
if (ms)
79+
{
80+
// send one now
81+
stationKeepAliveNow();
82+
83+
_timer = (ETSTimer*)malloc(sizeof(ETSTimer));
84+
if (_timer == nullptr)
85+
return false;
86+
87+
os_timer_setfn(_timer, ESP8266WiFiGratuitous::scheduleItForNextYieldOnce, nullptr);
88+
os_timer_arm(_timer, ms, true);
89+
}
90+
91+
return true;
92+
}
93+
94+
}; // experimental::
Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
/*
2+
ESP8266WiFiGratuitous.h - esp8266 Wifi support
3+
copyright esp8266/arduino
4+
5+
This library is free software; you can redistribute it and/or
6+
modify it under the terms of the GNU Lesser General Public
7+
License as published by the Free Software Foundation; either
8+
version 2.1 of the License, or (at your option) any later version.
9+
10+
This library is distributed in the hope that it will be useful,
11+
but WITHOUT ANY WARRANTY; without even the implied warranty of
12+
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13+
Lesser General Public License for more details.
14+
15+
You should have received a copy of the GNU Lesser General Public
16+
License along with this library; if not, write to the Free Software
17+
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
18+
*/
19+
20+
#ifndef ESP8266WIFIGRATUITOUS_H_
21+
#define ESP8266WIFIGRATUITOUS_H_
22+
23+
#include <stdint.h> // uint32_t
24+
#include <ets_sys.h> // ETSTimer
25+
26+
namespace experimental
27+
{
28+
29+
class ESP8266WiFiGratuitous
30+
{
31+
public:
32+
33+
// disable(0) or enable/update automatic sending of Gratuitous ARP packets.
34+
// A gratuitous ARP packet is immediately sent when calling this function, then
35+
// based on a time interval in milliseconds, default = 1s
36+
// return value: true when started, false otherwise
37+
static bool stationKeepAliveSetIntervalMs (uint32_t ms = 1000);
38+
39+
// request for stopping arp gratuitous packets
40+
static void stationKeepAliveStop () { (void)stationKeepAliveSetIntervalMs(0); }
41+
42+
// immediately send one gratuitous ARP from STA
43+
static void stationKeepAliveNow ();
44+
45+
protected:
46+
47+
static void scheduleItForNextYieldOnce (void*);
48+
49+
static ETSTimer* _timer;
50+
};
51+
52+
}; // experimental::
53+
54+
#endif // ESP8266WIFIGRATUITOUS_H_

libraries/ESP8266WiFi/src/ESP8266WiFiSTA.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -89,7 +89,7 @@ static bool sta_config_equal(const station_config& lhs, const station_config& rh
8989
return false;
9090
}
9191
}
92-
92+
9393
if(lhs.threshold.rssi != rhs.threshold.rssi) {
9494
return false;
9595
}

libraries/ESP8266WiFi/src/ESP8266WiFiSTA.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -41,8 +41,8 @@ class ESP8266WiFiSTAClass {
4141
wl_status_t begin(const String& ssid, const String& passphrase = emptyString, int32_t channel = 0, const uint8_t* bssid = NULL, bool connect = true);
4242
wl_status_t begin();
4343

44-
//The argument order for ESP is not the same as for Arduino. However, there is compatibility code under the hood
45-
//to detect Arduino arg order, and handle it correctly. Be aware that the Arduino default value handling doesn't
44+
//The argument order for ESP is not the same as for Arduino. However, there is compatibility code under the hood
45+
//to detect Arduino arg order, and handle it correctly. Be aware that the Arduino default value handling doesn't
4646
//work here (see Arduino docs for gway/subnet defaults). In other words: at least 3 args must always be given.
4747
bool config(IPAddress local_ip, IPAddress gateway, IPAddress subnet, IPAddress dns1 = (uint32_t)0x00000000, IPAddress dns2 = (uint32_t)0x00000000);
4848

libraries/Ticker/src/Ticker.h

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,75 +35,94 @@ class Ticker
3535
typedef void (*callback_with_arg_t)(void*);
3636
typedef std::function<void(void)> callback_function_t;
3737

38+
// callback will be called at following loop() after ticker fires
3839
void attach_scheduled(float seconds, callback_function_t callback)
3940
{
4041
_callback_function = [callback]() { schedule_function(callback); };
4142
_attach_ms(1000UL * seconds, true);
4243
}
4344

45+
// callback will be called in SYS ctx when ticker fires
4446
void attach(float seconds, callback_function_t callback)
4547
{
4648
_callback_function = std::move(callback);
4749
_attach_ms(1000UL * seconds, true);
4850
}
4951

52+
// callback will be called at following loop() after ticker fires
5053
void attach_ms_scheduled(uint32_t milliseconds, callback_function_t callback)
5154
{
5255
_callback_function = [callback]() { schedule_function(callback); };
5356
_attach_ms(milliseconds, true);
5457
}
5558

59+
// callback will be called at following yield() after ticker fires
60+
void attach_ms_scheduled_accurate(uint32_t milliseconds, callback_function_t callback)
61+
{
62+
_callback_function = [callback]() { schedule_recurrent_function_us([callback]() { callback(); return false; }, 0); };
63+
_attach_ms(milliseconds, true);
64+
}
65+
66+
// callback will be called in SYS ctx when ticker fires
5667
void attach_ms(uint32_t milliseconds, callback_function_t callback)
5768
{
5869
_callback_function = std::move(callback);
5970
_attach_ms(milliseconds, true);
6071
}
6172

73+
// callback will be called in SYS ctx when ticker fires
6274
template<typename TArg>
6375
void attach(float seconds, void (*callback)(TArg), TArg arg)
6476
{
6577
static_assert(sizeof(TArg) <= sizeof(void*), "attach() callback argument size must be <= sizeof(void*)");
6678
_attach_ms(1000UL * seconds, true, reinterpret_cast<callback_with_arg_t>(callback), reinterpret_cast<void*>(arg));
6779
}
6880

81+
// callback will be called in SYS ctx when ticker fires
6982
template<typename TArg>
7083
void attach_ms(uint32_t milliseconds, void (*callback)(TArg), TArg arg)
7184
{
7285
static_assert(sizeof(TArg) <= sizeof(void*), "attach() callback argument size must be <= sizeof(void*)");
7386
_attach_ms(milliseconds, true, reinterpret_cast<callback_with_arg_t>(callback), reinterpret_cast<void*>(arg));
7487
}
7588

89+
// callback will be called at following loop() after ticker fires
7690
void once_scheduled(float seconds, callback_function_t callback)
7791
{
7892
_callback_function = [callback]() { schedule_function(callback); };
7993
_attach_ms(1000UL * seconds, false);
8094
}
8195

96+
// callback will be called in SYS ctx when ticker fires
8297
void once(float seconds, callback_function_t callback)
8398
{
8499
_callback_function = std::move(callback);
85100
_attach_ms(1000UL * seconds, false);
86101
}
87102

103+
// callback will be called at following loop() after ticker fires
88104
void once_ms_scheduled(uint32_t milliseconds, callback_function_t callback)
89105
{
90106
_callback_function = [callback]() { schedule_function(callback); };
91107
_attach_ms(milliseconds, false);
92108
}
93109

110+
// callback will be called in SYS ctx when ticker fires
94111
void once_ms(uint32_t milliseconds, callback_function_t callback)
95112
{
96113
_callback_function = std::move(callback);
97114
_attach_ms(milliseconds, false);
98115
}
99116

117+
// callback will be called in SYS ctx when ticker fires
100118
template<typename TArg>
101119
void once(float seconds, void (*callback)(TArg), TArg arg)
102120
{
103121
static_assert(sizeof(TArg) <= sizeof(void*), "attach() callback argument size must be <= sizeof(void*)");
104122
_attach_ms(1000UL * seconds, false, reinterpret_cast<callback_with_arg_t>(callback), reinterpret_cast<void*>(arg));
105123
}
106124

125+
// callback will be called in SYS ctx when ticker fires
107126
template<typename TArg>
108127
void once_ms(uint32_t milliseconds, void (*callback)(TArg), TArg arg)
109128
{

tests/host/common/MocklwIP.cpp

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,4 +26,11 @@ const ip_addr_t* sntp_getserver(u8_t)
2626
return IP_ADDR_ANY;
2727
}
2828

29+
err_t etharp_request(struct netif *netif, const ip4_addr_t *ipaddr)
30+
{
31+
(void)netif;
32+
(void)ipaddr;
33+
return ERR_OK;
34+
}
35+
2936
} // extern "C"

0 commit comments

Comments
 (0)
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