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-
5047extern " C" void esp_schedule ();
5148extern " 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
6081bool ESP8266WiFiGenericClass::_persistent = true ;
6182WiFiMode_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}
0 commit comments