1
0
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:
Ivan Grokhotkov
2016-06-10 07:46:10 +08:00
committed by GitHub
parent 7fd7ca6834
commit de166c9dd7
3 changed files with 259 additions and 60 deletions

View File

@ -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;
}
}
}