Skip to content

Commit de166c9

Browse files
authored
WiFi event handling refactoring (#2119)
1 parent 7fd7ca6 commit de166c9

File tree

3 files changed

+258
-59
lines changed

3 files changed

+258
-59
lines changed

libraries/ESP8266WiFi/src/ESP8266WiFiGeneric.cpp

+143-43
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,8 @@
2222
2323
*/
2424

25+
#include <list>
26+
#include <string.h>
2527
#include "ESP8266WiFi.h"
2628
#include "ESP8266WiFiGeneric.h"
2729

@@ -40,68 +42,164 @@ extern "C" {
4042

4143
#include "WiFiClient.h"
4244
#include "WiFiUdp.h"
43-
4445
#include "debug.h"
4546

46-
#undef min
47-
#undef max
48-
#include <vector>
49-
5047
extern "C" void esp_schedule();
5148
extern "C" void esp_yield();
5249

50+
5351
// -----------------------------------------------------------------------------------------------------------------------
5452
// ------------------------------------------------- Generic WiFi function -----------------------------------------------
5553
// -----------------------------------------------------------------------------------------------------------------------
5654

57-
// arduino dont like std::vectors move static here
58-
static std::vector<WiFiEventCbList_t> cbEventList;
55+
struct WiFiEventHandlerOpaque
56+
{
57+
WiFiEventHandlerOpaque(WiFiEvent_t event, std::function<void(System_Event_t*)> handler)
58+
: mEvent(event), mHandler(handler)
59+
{
60+
}
61+
62+
void operator()(System_Event_t* e)
63+
{
64+
if (static_cast<WiFiEvent>(e->event) == mEvent || mEvent == WIFI_EVENT_ANY) {
65+
mHandler(e);
66+
}
67+
}
68+
69+
bool canExpire()
70+
{
71+
return mCanExpire;
72+
}
73+
74+
WiFiEvent_t mEvent;
75+
std::function<void(System_Event_t*)> mHandler;
76+
bool mCanExpire = true; /* stopgap solution to handle deprecated void onEvent(cb, evt) case */
77+
};
78+
79+
static std::list<WiFiEventHandler> sCbEventList;
5980

6081
bool ESP8266WiFiGenericClass::_persistent = true;
6182
WiFiMode_t ESP8266WiFiGenericClass::_forceSleepLastMode = WIFI_OFF;
6283

63-
ESP8266WiFiGenericClass::ESP8266WiFiGenericClass() {
84+
ESP8266WiFiGenericClass::ESP8266WiFiGenericClass()
85+
{
6486
wifi_set_event_handler_cb((wifi_event_handler_cb_t) &ESP8266WiFiGenericClass::_eventCallback);
6587
}
6688

67-
/**
68-
* set callback function
69-
* @param cbEvent WiFiEventCb
70-
* @param event optional filter (WIFI_EVENT_MAX is all events)
71-
*/
72-
void ESP8266WiFiGenericClass::onEvent(WiFiEventCb cbEvent, WiFiEvent_t event) {
73-
if(!cbEvent) {
74-
return;
75-
}
76-
WiFiEventCbList_t newEventHandler;
77-
newEventHandler.cb = cbEvent;
78-
newEventHandler.event = event;
79-
cbEventList.push_back(newEventHandler);
89+
void ESP8266WiFiGenericClass::onEvent(WiFiEventCb f, WiFiEvent_t event)
90+
{
91+
WiFiEventHandler handler = std::make_shared<WiFiEventHandlerOpaque>(event, [f](System_Event_t* e) {
92+
(*f)(static_cast<WiFiEvent>(e->event));
93+
});
94+
handler->mCanExpire = false;
8095
}
8196

82-
/**
83-
* removes a callback form event handler
84-
* @param cbEvent WiFiEventCb
85-
* @param event optional filter (WIFI_EVENT_MAX is all events)
86-
*/
87-
void ESP8266WiFiGenericClass::removeEvent(WiFiEventCb cbEvent, WiFiEvent_t event) {
88-
if(!cbEvent) {
89-
return;
90-
}
97+
WiFiEventHandler ESP8266WiFiGenericClass::onStationModeConnected(std::function<void(const WiFiEventStationModeConnected&)> f)
98+
{
99+
WiFiEventHandler handler = std::make_shared<WiFiEventHandlerOpaque>(WIFI_EVENT_STAMODE_CONNECTED, [f](System_Event_t* e) {
100+
auto& src = e->event_info.connected;
101+
WiFiEventStationModeConnected dst;
102+
dst.ssid = String(reinterpret_cast<char*>(src.ssid));
103+
memcpy(dst.bssid, src.bssid, 6);
104+
dst.channel = src.channel;
105+
f(dst);
106+
});
107+
sCbEventList.push_back(handler);
108+
return handler;
109+
}
91110

92-
for(uint32_t i = 0; i < cbEventList.size(); i++) {
93-
WiFiEventCbList_t entry = cbEventList[i];
94-
if(entry.cb == cbEvent && entry.event == event) {
95-
cbEventList.erase(cbEventList.begin() + i);
96-
}
97-
}
111+
WiFiEventHandler ESP8266WiFiGenericClass::onStationModeDisconnected(std::function<void(const WiFiEventStationModeDisconnected&)> f)
112+
{
113+
WiFiEventHandler handler = std::make_shared<WiFiEventHandlerOpaque>(WIFI_EVENT_STAMODE_DISCONNECTED, [f](System_Event_t* e){
114+
auto& src = e->event_info.disconnected;
115+
WiFiEventStationModeDisconnected dst;
116+
dst.ssid = String(reinterpret_cast<char*>(src.ssid));
117+
memcpy(dst.bssid, src.bssid, 6);
118+
dst.reason = static_cast<WiFiDisconnectReason>(src.reason);
119+
f(dst);
120+
});
121+
sCbEventList.push_back(handler);
122+
return handler;
123+
}
124+
125+
WiFiEventHandler ESP8266WiFiGenericClass::onStationModeAuthModeChanged(std::function<void(const WiFiEventStationModeAuthModeChanged&)> f)
126+
{
127+
WiFiEventHandler handler = std::make_shared<WiFiEventHandlerOpaque>(WIFI_EVENT_STAMODE_AUTHMODE_CHANGE, [f](System_Event_t* e){
128+
auto& src = e->event_info.auth_change;
129+
WiFiEventStationModeAuthModeChanged dst;
130+
dst.oldMode = src.old_mode;
131+
dst.newMode = src.new_mode;
132+
f(dst);
133+
});
134+
sCbEventList.push_back(handler);
135+
return handler;
136+
}
137+
138+
WiFiEventHandler ESP8266WiFiGenericClass::onStationModeGotIP(std::function<void(const WiFiEventStationModeGotIP&)> f)
139+
{
140+
WiFiEventHandler handler = std::make_shared<WiFiEventHandlerOpaque>(WIFI_EVENT_STAMODE_GOT_IP, [f](System_Event_t* e){
141+
auto& src = e->event_info.got_ip;
142+
WiFiEventStationModeGotIP dst;
143+
dst.ip = src.ip.addr;
144+
dst.mask = src.mask.addr;
145+
dst.gw = src.gw.addr;
146+
f(dst);
147+
});
148+
sCbEventList.push_back(handler);
149+
return handler;
98150
}
99151

152+
WiFiEventHandler onStationModeDHCPTimeout(std::function<void(void)> f)
153+
{
154+
WiFiEventHandler handler = std::make_shared<WiFiEventHandlerOpaque>(WIFI_EVENT_STAMODE_DHCP_TIMEOUT, [f](System_Event_t* e){
155+
f();
156+
});
157+
sCbEventList.push_back(handler);
158+
return handler;
159+
}
160+
161+
WiFiEventHandler ESP8266WiFiGenericClass::onSoftAPModeStationConnected(std::function<void(const WiFiEventSoftAPModeStationConnected&)> f)
162+
{
163+
WiFiEventHandler handler = std::make_shared<WiFiEventHandlerOpaque>(WIFI_EVENT_SOFTAPMODE_STACONNECTED, [f](System_Event_t* e){
164+
auto& src = e->event_info.sta_connected;
165+
WiFiEventSoftAPModeStationConnected dst;
166+
memcpy(dst.mac, src.mac, 6);
167+
dst.aid = src.aid;
168+
f(dst);
169+
});
170+
sCbEventList.push_back(handler);
171+
return handler;
172+
}
173+
174+
WiFiEventHandler ESP8266WiFiGenericClass::onSoftAPModeStationDisconnected(std::function<void(const WiFiEventSoftAPModeStationDisconnected&)> f)
175+
{
176+
WiFiEventHandler handler = std::make_shared<WiFiEventHandlerOpaque>(WIFI_EVENT_SOFTAPMODE_STADISCONNECTED, [f](System_Event_t* e){
177+
auto& src = e->event_info.sta_disconnected;
178+
WiFiEventSoftAPModeStationDisconnected dst;
179+
memcpy(dst.mac, src.mac, 6);
180+
dst.aid = src.aid;
181+
f(dst);
182+
});
183+
sCbEventList.push_back(handler);
184+
return handler;
185+
}
186+
187+
// WiFiEventHandler ESP8266WiFiGenericClass::onWiFiModeChange(std::function<void(const WiFiEventModeChange&)> f)
188+
// {
189+
// WiFiEventHandler handler = std::make_shared<WiFiEventHandlerOpaque>(WIFI_EVENT_MODE_CHANGE, [f](System_Event_t* e){
190+
// WiFiEventModeChange& dst = *reinterpret_cast<WiFiEventModeChange*>(&e->event_info);
191+
// f(dst);
192+
// });
193+
// sCbEventList.push_back(handler);
194+
// return handler;
195+
// }
196+
100197
/**
101198
* callback for WiFi events
102199
* @param arg
103200
*/
104-
void ESP8266WiFiGenericClass::_eventCallback(void* arg) {
201+
void ESP8266WiFiGenericClass::_eventCallback(void* arg)
202+
{
105203
System_Event_t* event = reinterpret_cast<System_Event_t*>(arg);
106204
DEBUG_WIFI("wifi evt: %d\n", event->event);
107205

@@ -110,12 +208,14 @@ void ESP8266WiFiGenericClass::_eventCallback(void* arg) {
110208
WiFiClient::stopAll();
111209
}
112210

113-
for(uint32_t i = 0; i < cbEventList.size(); i++) {
114-
WiFiEventCbList_t entry = cbEventList[i];
115-
if(entry.cb) {
116-
if(entry.event == (WiFiEvent_t) event->event || entry.event == WIFI_EVENT_MAX) {
117-
entry.cb((WiFiEvent_t) event->event);
118-
}
211+
for(auto it = std::begin(sCbEventList); it != std::end(sCbEventList); ) {
212+
WiFiEventHandler &handler = *it;
213+
if (handler->canExpire() && handler.unique()) {
214+
it = sCbEventList.erase(it);
215+
}
216+
else {
217+
(*handler)(event);
218+
++it;
119219
}
120220
}
121221
}

libraries/ESP8266WiFi/src/ESP8266WiFiGeneric.h

+17-8
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,8 @@
2424
#define ESP8266WIFIGENERIC_H_
2525

2626
#include "ESP8266WiFiType.h"
27+
#include <functional>
28+
#include <memory>
2729

2830
#ifdef DEBUG_ESP_WIFI
2931
#ifdef DEBUG_ESP_PORT
@@ -35,24 +37,31 @@
3537
#define DEBUG_WIFI_GENERIC(...)
3638
#endif
3739

38-
typedef void (*WiFiEventCb)(WiFiEvent_t event);
40+
struct WiFiEventHandlerOpaque;
41+
typedef std::shared_ptr<WiFiEventHandlerOpaque> WiFiEventHandler;
3942

40-
typedef struct {
41-
WiFiEventCb cb;
42-
WiFiEvent_t event;
43-
} WiFiEventCbList_t;
43+
typedef void (*WiFiEventCb)(WiFiEvent_t);
4444

4545
class ESP8266WiFiGenericClass {
4646
// ----------------------------------------------------------------------------------------------
4747
// -------------------------------------- Generic WiFi function ---------------------------------
4848
// ----------------------------------------------------------------------------------------------
4949

5050
public:
51-
5251
ESP8266WiFiGenericClass();
5352

54-
void onEvent(WiFiEventCb cbEvent, WiFiEvent_t event = WIFI_EVENT_MAX);
55-
void removeEvent(WiFiEventCb cbEvent, WiFiEvent_t event = WIFI_EVENT_MAX);
53+
// Note: this function is deprecated. Use one of the functions below instead.
54+
void onEvent(WiFiEventCb cb, WiFiEvent_t event = WIFI_EVENT_ANY) __attribute__((deprecated));
55+
56+
// Subscribe to specific event and get event information as an argument to the callback
57+
WiFiEventHandler onStationModeConnected(std::function<void(const WiFiEventStationModeConnected&)>);
58+
WiFiEventHandler onStationModeDisconnected(std::function<void(const WiFiEventStationModeDisconnected&)>);
59+
WiFiEventHandler onStationModeAuthModeChanged(std::function<void(const WiFiEventStationModeAuthModeChanged&)>);
60+
WiFiEventHandler onStationModeGotIP(std::function<void(const WiFiEventStationModeGotIP&)>);
61+
WiFiEventHandler onStationModeDHCPTimeout(std::function<void(void)>);
62+
WiFiEventHandler onSoftAPModeStationConnected(std::function<void(const WiFiEventSoftAPModeStationConnected&)>);
63+
WiFiEventHandler onSoftAPModeStationDisconnected(std::function<void(const WiFiEventSoftAPModeStationDisconnected&)>);
64+
// WiFiEventHandler onWiFiModeChange(std::function<void(const WiFiEventModeChange&)>);
5665

5766
int32_t channel(void);
5867

0 commit comments

Comments
 (0)