mirror of
https://github.com/esp8266/Arduino.git
synced 2025-07-07 06:01:35 +03:00
WiFi event handling refactoring (#2119)
This commit is contained in:
@ -22,6 +22,8 @@
|
||||
|
||||
*/
|
||||
|
||||
#include <list>
|
||||
#include <string.h>
|
||||
#include "ESP8266WiFi.h"
|
||||
#include "ESP8266WiFiGeneric.h"
|
||||
|
||||
@ -40,68 +42,164 @@ extern "C" {
|
||||
|
||||
#include "WiFiClient.h"
|
||||
#include "WiFiUdp.h"
|
||||
|
||||
#include "debug.h"
|
||||
|
||||
#undef min
|
||||
#undef max
|
||||
#include <vector>
|
||||
|
||||
extern "C" void esp_schedule();
|
||||
extern "C" void esp_yield();
|
||||
|
||||
|
||||
// -----------------------------------------------------------------------------------------------------------------------
|
||||
// ------------------------------------------------- Generic WiFi function -----------------------------------------------
|
||||
// -----------------------------------------------------------------------------------------------------------------------
|
||||
|
||||
// arduino dont like std::vectors move static here
|
||||
static std::vector<WiFiEventCbList_t> cbEventList;
|
||||
struct WiFiEventHandlerOpaque
|
||||
{
|
||||
WiFiEventHandlerOpaque(WiFiEvent_t event, std::function<void(System_Event_t*)> handler)
|
||||
: mEvent(event), mHandler(handler)
|
||||
{
|
||||
}
|
||||
|
||||
void operator()(System_Event_t* e)
|
||||
{
|
||||
if (static_cast<WiFiEvent>(e->event) == mEvent || mEvent == WIFI_EVENT_ANY) {
|
||||
mHandler(e);
|
||||
}
|
||||
}
|
||||
|
||||
bool canExpire()
|
||||
{
|
||||
return mCanExpire;
|
||||
}
|
||||
|
||||
WiFiEvent_t mEvent;
|
||||
std::function<void(System_Event_t*)> mHandler;
|
||||
bool mCanExpire = true; /* stopgap solution to handle deprecated void onEvent(cb, evt) case */
|
||||
};
|
||||
|
||||
static std::list<WiFiEventHandler> sCbEventList;
|
||||
|
||||
bool ESP8266WiFiGenericClass::_persistent = true;
|
||||
WiFiMode_t ESP8266WiFiGenericClass::_forceSleepLastMode = WIFI_OFF;
|
||||
|
||||
ESP8266WiFiGenericClass::ESP8266WiFiGenericClass() {
|
||||
ESP8266WiFiGenericClass::ESP8266WiFiGenericClass()
|
||||
{
|
||||
wifi_set_event_handler_cb((wifi_event_handler_cb_t) &ESP8266WiFiGenericClass::_eventCallback);
|
||||
}
|
||||
|
||||
/**
|
||||
* set callback function
|
||||
* @param cbEvent WiFiEventCb
|
||||
* @param event optional filter (WIFI_EVENT_MAX is all events)
|
||||
*/
|
||||
void ESP8266WiFiGenericClass::onEvent(WiFiEventCb cbEvent, WiFiEvent_t event) {
|
||||
if(!cbEvent) {
|
||||
return;
|
||||
}
|
||||
WiFiEventCbList_t newEventHandler;
|
||||
newEventHandler.cb = cbEvent;
|
||||
newEventHandler.event = event;
|
||||
cbEventList.push_back(newEventHandler);
|
||||
void ESP8266WiFiGenericClass::onEvent(WiFiEventCb f, WiFiEvent_t event)
|
||||
{
|
||||
WiFiEventHandler handler = std::make_shared<WiFiEventHandlerOpaque>(event, [f](System_Event_t* e) {
|
||||
(*f)(static_cast<WiFiEvent>(e->event));
|
||||
});
|
||||
handler->mCanExpire = false;
|
||||
}
|
||||
|
||||
/**
|
||||
* removes a callback form event handler
|
||||
* @param cbEvent WiFiEventCb
|
||||
* @param event optional filter (WIFI_EVENT_MAX is all events)
|
||||
*/
|
||||
void ESP8266WiFiGenericClass::removeEvent(WiFiEventCb cbEvent, WiFiEvent_t event) {
|
||||
if(!cbEvent) {
|
||||
return;
|
||||
}
|
||||
|
||||
for(uint32_t i = 0; i < cbEventList.size(); i++) {
|
||||
WiFiEventCbList_t entry = cbEventList[i];
|
||||
if(entry.cb == cbEvent && entry.event == event) {
|
||||
cbEventList.erase(cbEventList.begin() + i);
|
||||
}
|
||||
}
|
||||
WiFiEventHandler ESP8266WiFiGenericClass::onStationModeConnected(std::function<void(const WiFiEventStationModeConnected&)> f)
|
||||
{
|
||||
WiFiEventHandler handler = std::make_shared<WiFiEventHandlerOpaque>(WIFI_EVENT_STAMODE_CONNECTED, [f](System_Event_t* e) {
|
||||
auto& src = e->event_info.connected;
|
||||
WiFiEventStationModeConnected dst;
|
||||
dst.ssid = String(reinterpret_cast<char*>(src.ssid));
|
||||
memcpy(dst.bssid, src.bssid, 6);
|
||||
dst.channel = src.channel;
|
||||
f(dst);
|
||||
});
|
||||
sCbEventList.push_back(handler);
|
||||
return handler;
|
||||
}
|
||||
|
||||
WiFiEventHandler ESP8266WiFiGenericClass::onStationModeDisconnected(std::function<void(const WiFiEventStationModeDisconnected&)> f)
|
||||
{
|
||||
WiFiEventHandler handler = std::make_shared<WiFiEventHandlerOpaque>(WIFI_EVENT_STAMODE_DISCONNECTED, [f](System_Event_t* e){
|
||||
auto& src = e->event_info.disconnected;
|
||||
WiFiEventStationModeDisconnected dst;
|
||||
dst.ssid = String(reinterpret_cast<char*>(src.ssid));
|
||||
memcpy(dst.bssid, src.bssid, 6);
|
||||
dst.reason = static_cast<WiFiDisconnectReason>(src.reason);
|
||||
f(dst);
|
||||
});
|
||||
sCbEventList.push_back(handler);
|
||||
return handler;
|
||||
}
|
||||
|
||||
WiFiEventHandler ESP8266WiFiGenericClass::onStationModeAuthModeChanged(std::function<void(const WiFiEventStationModeAuthModeChanged&)> f)
|
||||
{
|
||||
WiFiEventHandler handler = std::make_shared<WiFiEventHandlerOpaque>(WIFI_EVENT_STAMODE_AUTHMODE_CHANGE, [f](System_Event_t* e){
|
||||
auto& src = e->event_info.auth_change;
|
||||
WiFiEventStationModeAuthModeChanged dst;
|
||||
dst.oldMode = src.old_mode;
|
||||
dst.newMode = src.new_mode;
|
||||
f(dst);
|
||||
});
|
||||
sCbEventList.push_back(handler);
|
||||
return handler;
|
||||
}
|
||||
|
||||
WiFiEventHandler ESP8266WiFiGenericClass::onStationModeGotIP(std::function<void(const WiFiEventStationModeGotIP&)> f)
|
||||
{
|
||||
WiFiEventHandler handler = std::make_shared<WiFiEventHandlerOpaque>(WIFI_EVENT_STAMODE_GOT_IP, [f](System_Event_t* e){
|
||||
auto& src = e->event_info.got_ip;
|
||||
WiFiEventStationModeGotIP dst;
|
||||
dst.ip = src.ip.addr;
|
||||
dst.mask = src.mask.addr;
|
||||
dst.gw = src.gw.addr;
|
||||
f(dst);
|
||||
});
|
||||
sCbEventList.push_back(handler);
|
||||
return handler;
|
||||
}
|
||||
|
||||
WiFiEventHandler onStationModeDHCPTimeout(std::function<void(void)> f)
|
||||
{
|
||||
WiFiEventHandler handler = std::make_shared<WiFiEventHandlerOpaque>(WIFI_EVENT_STAMODE_DHCP_TIMEOUT, [f](System_Event_t* e){
|
||||
f();
|
||||
});
|
||||
sCbEventList.push_back(handler);
|
||||
return handler;
|
||||
}
|
||||
|
||||
WiFiEventHandler ESP8266WiFiGenericClass::onSoftAPModeStationConnected(std::function<void(const WiFiEventSoftAPModeStationConnected&)> f)
|
||||
{
|
||||
WiFiEventHandler handler = std::make_shared<WiFiEventHandlerOpaque>(WIFI_EVENT_SOFTAPMODE_STACONNECTED, [f](System_Event_t* e){
|
||||
auto& src = e->event_info.sta_connected;
|
||||
WiFiEventSoftAPModeStationConnected dst;
|
||||
memcpy(dst.mac, src.mac, 6);
|
||||
dst.aid = src.aid;
|
||||
f(dst);
|
||||
});
|
||||
sCbEventList.push_back(handler);
|
||||
return handler;
|
||||
}
|
||||
|
||||
WiFiEventHandler ESP8266WiFiGenericClass::onSoftAPModeStationDisconnected(std::function<void(const WiFiEventSoftAPModeStationDisconnected&)> f)
|
||||
{
|
||||
WiFiEventHandler handler = std::make_shared<WiFiEventHandlerOpaque>(WIFI_EVENT_SOFTAPMODE_STADISCONNECTED, [f](System_Event_t* e){
|
||||
auto& src = e->event_info.sta_disconnected;
|
||||
WiFiEventSoftAPModeStationDisconnected dst;
|
||||
memcpy(dst.mac, src.mac, 6);
|
||||
dst.aid = src.aid;
|
||||
f(dst);
|
||||
});
|
||||
sCbEventList.push_back(handler);
|
||||
return handler;
|
||||
}
|
||||
|
||||
// WiFiEventHandler ESP8266WiFiGenericClass::onWiFiModeChange(std::function<void(const WiFiEventModeChange&)> f)
|
||||
// {
|
||||
// WiFiEventHandler handler = std::make_shared<WiFiEventHandlerOpaque>(WIFI_EVENT_MODE_CHANGE, [f](System_Event_t* e){
|
||||
// WiFiEventModeChange& dst = *reinterpret_cast<WiFiEventModeChange*>(&e->event_info);
|
||||
// f(dst);
|
||||
// });
|
||||
// sCbEventList.push_back(handler);
|
||||
// return handler;
|
||||
// }
|
||||
|
||||
/**
|
||||
* callback for WiFi events
|
||||
* @param arg
|
||||
*/
|
||||
void ESP8266WiFiGenericClass::_eventCallback(void* arg) {
|
||||
void ESP8266WiFiGenericClass::_eventCallback(void* arg)
|
||||
{
|
||||
System_Event_t* event = reinterpret_cast<System_Event_t*>(arg);
|
||||
DEBUG_WIFI("wifi evt: %d\n", event->event);
|
||||
|
||||
@ -110,12 +208,14 @@ void ESP8266WiFiGenericClass::_eventCallback(void* arg) {
|
||||
WiFiClient::stopAll();
|
||||
}
|
||||
|
||||
for(uint32_t i = 0; i < cbEventList.size(); i++) {
|
||||
WiFiEventCbList_t entry = cbEventList[i];
|
||||
if(entry.cb) {
|
||||
if(entry.event == (WiFiEvent_t) event->event || entry.event == WIFI_EVENT_MAX) {
|
||||
entry.cb((WiFiEvent_t) event->event);
|
||||
}
|
||||
for(auto it = std::begin(sCbEventList); it != std::end(sCbEventList); ) {
|
||||
WiFiEventHandler &handler = *it;
|
||||
if (handler->canExpire() && handler.unique()) {
|
||||
it = sCbEventList.erase(it);
|
||||
}
|
||||
else {
|
||||
(*handler)(event);
|
||||
++it;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user