1
0
mirror of https://github.com/esp8266/Arduino.git synced 2025-07-30 16:24:09 +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 "ESP8266WiFi.h"
#include "ESP8266WiFiGeneric.h" #include "ESP8266WiFiGeneric.h"
@ -40,68 +42,164 @@ extern "C" {
#include "WiFiClient.h" #include "WiFiClient.h"
#include "WiFiUdp.h" #include "WiFiUdp.h"
#include "debug.h" #include "debug.h"
#undef min
#undef max
#include <vector>
extern "C" void esp_schedule(); extern "C" void esp_schedule();
extern "C" void esp_yield(); extern "C" void esp_yield();
// ----------------------------------------------------------------------------------------------------------------------- // -----------------------------------------------------------------------------------------------------------------------
// ------------------------------------------------- Generic WiFi function ----------------------------------------------- // ------------------------------------------------- Generic WiFi function -----------------------------------------------
// ----------------------------------------------------------------------------------------------------------------------- // -----------------------------------------------------------------------------------------------------------------------
// arduino dont like std::vectors move static here struct WiFiEventHandlerOpaque
static std::vector<WiFiEventCbList_t> cbEventList; {
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; bool ESP8266WiFiGenericClass::_persistent = true;
WiFiMode_t ESP8266WiFiGenericClass::_forceSleepLastMode = WIFI_OFF; WiFiMode_t ESP8266WiFiGenericClass::_forceSleepLastMode = WIFI_OFF;
ESP8266WiFiGenericClass::ESP8266WiFiGenericClass() { ESP8266WiFiGenericClass::ESP8266WiFiGenericClass()
{
wifi_set_event_handler_cb((wifi_event_handler_cb_t) &ESP8266WiFiGenericClass::_eventCallback); wifi_set_event_handler_cb((wifi_event_handler_cb_t) &ESP8266WiFiGenericClass::_eventCallback);
} }
/** void ESP8266WiFiGenericClass::onEvent(WiFiEventCb f, WiFiEvent_t event)
* set callback function {
* @param cbEvent WiFiEventCb WiFiEventHandler handler = std::make_shared<WiFiEventHandlerOpaque>(event, [f](System_Event_t* e) {
* @param event optional filter (WIFI_EVENT_MAX is all events) (*f)(static_cast<WiFiEvent>(e->event));
*/ });
void ESP8266WiFiGenericClass::onEvent(WiFiEventCb cbEvent, WiFiEvent_t event) { handler->mCanExpire = false;
if(!cbEvent) {
return;
}
WiFiEventCbList_t newEventHandler;
newEventHandler.cb = cbEvent;
newEventHandler.event = event;
cbEventList.push_back(newEventHandler);
} }
/** WiFiEventHandler ESP8266WiFiGenericClass::onStationModeConnected(std::function<void(const WiFiEventStationModeConnected&)> f)
* removes a callback form event handler {
* @param cbEvent WiFiEventCb WiFiEventHandler handler = std::make_shared<WiFiEventHandlerOpaque>(WIFI_EVENT_STAMODE_CONNECTED, [f](System_Event_t* e) {
* @param event optional filter (WIFI_EVENT_MAX is all events) auto& src = e->event_info.connected;
*/ WiFiEventStationModeConnected dst;
void ESP8266WiFiGenericClass::removeEvent(WiFiEventCb cbEvent, WiFiEvent_t event) { dst.ssid = String(reinterpret_cast<char*>(src.ssid));
if(!cbEvent) { memcpy(dst.bssid, src.bssid, 6);
return; dst.channel = src.channel;
} f(dst);
});
for(uint32_t i = 0; i < cbEventList.size(); i++) { sCbEventList.push_back(handler);
WiFiEventCbList_t entry = cbEventList[i]; return handler;
if(entry.cb == cbEvent && entry.event == event) {
cbEventList.erase(cbEventList.begin() + i);
}
}
} }
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 * callback for WiFi events
* @param arg * @param arg
*/ */
void ESP8266WiFiGenericClass::_eventCallback(void* arg) { void ESP8266WiFiGenericClass::_eventCallback(void* arg)
{
System_Event_t* event = reinterpret_cast<System_Event_t*>(arg); System_Event_t* event = reinterpret_cast<System_Event_t*>(arg);
DEBUG_WIFI("wifi evt: %d\n", event->event); DEBUG_WIFI("wifi evt: %d\n", event->event);
@ -110,12 +208,14 @@ void ESP8266WiFiGenericClass::_eventCallback(void* arg) {
WiFiClient::stopAll(); WiFiClient::stopAll();
} }
for(uint32_t i = 0; i < cbEventList.size(); i++) { for(auto it = std::begin(sCbEventList); it != std::end(sCbEventList); ) {
WiFiEventCbList_t entry = cbEventList[i]; WiFiEventHandler &handler = *it;
if(entry.cb) { if (handler->canExpire() && handler.unique()) {
if(entry.event == (WiFiEvent_t) event->event || entry.event == WIFI_EVENT_MAX) { it = sCbEventList.erase(it);
entry.cb((WiFiEvent_t) event->event); }
} else {
(*handler)(event);
++it;
} }
} }
} }

View File

@ -24,6 +24,8 @@
#define ESP8266WIFIGENERIC_H_ #define ESP8266WIFIGENERIC_H_
#include "ESP8266WiFiType.h" #include "ESP8266WiFiType.h"
#include <functional>
#include <memory>
#ifdef DEBUG_ESP_WIFI #ifdef DEBUG_ESP_WIFI
#ifdef DEBUG_ESP_PORT #ifdef DEBUG_ESP_PORT
@ -35,12 +37,10 @@
#define DEBUG_WIFI_GENERIC(...) #define DEBUG_WIFI_GENERIC(...)
#endif #endif
typedef void (*WiFiEventCb)(WiFiEvent_t event); struct WiFiEventHandlerOpaque;
typedef std::shared_ptr<WiFiEventHandlerOpaque> WiFiEventHandler;
typedef struct { typedef void (*WiFiEventCb)(WiFiEvent_t);
WiFiEventCb cb;
WiFiEvent_t event;
} WiFiEventCbList_t;
class ESP8266WiFiGenericClass { class ESP8266WiFiGenericClass {
// ---------------------------------------------------------------------------------------------- // ----------------------------------------------------------------------------------------------
@ -48,11 +48,20 @@ class ESP8266WiFiGenericClass {
// ---------------------------------------------------------------------------------------------- // ----------------------------------------------------------------------------------------------
public: public:
ESP8266WiFiGenericClass(); ESP8266WiFiGenericClass();
void onEvent(WiFiEventCb cbEvent, WiFiEvent_t event = WIFI_EVENT_MAX); // Note: this function is deprecated. Use one of the functions below instead.
void removeEvent(WiFiEventCb cbEvent, WiFiEvent_t event = WIFI_EVENT_MAX); void onEvent(WiFiEventCb cb, WiFiEvent_t event = WIFI_EVENT_ANY) __attribute__((deprecated));
// Subscribe to specific event and get event information as an argument to the callback
WiFiEventHandler onStationModeConnected(std::function<void(const WiFiEventStationModeConnected&)>);
WiFiEventHandler onStationModeDisconnected(std::function<void(const WiFiEventStationModeDisconnected&)>);
WiFiEventHandler onStationModeAuthModeChanged(std::function<void(const WiFiEventStationModeAuthModeChanged&)>);
WiFiEventHandler onStationModeGotIP(std::function<void(const WiFiEventStationModeGotIP&)>);
WiFiEventHandler onStationModeDHCPTimeout(std::function<void(void)>);
WiFiEventHandler onSoftAPModeStationConnected(std::function<void(const WiFiEventSoftAPModeStationConnected&)>);
WiFiEventHandler onSoftAPModeStationDisconnected(std::function<void(const WiFiEventSoftAPModeStationDisconnected&)>);
// WiFiEventHandler onWiFiModeChange(std::function<void(const WiFiEventModeChange&)>);
int32_t channel(void); int32_t channel(void);

View File

@ -28,23 +28,28 @@
#define WIFI_SCAN_RUNNING (-1) #define WIFI_SCAN_RUNNING (-1)
#define WIFI_SCAN_FAILED (-2) #define WIFI_SCAN_FAILED (-2)
// Note: // Note: these enums need to be in sync with the SDK!
// this enums need to be in sync with the SDK!
typedef enum WiFiMode { // TODO: replace/deprecate/remove enum typedefs ending with _t below
typedef enum WiFiMode
{
WIFI_OFF = 0, WIFI_STA = 1, WIFI_AP = 2, WIFI_AP_STA = 3 WIFI_OFF = 0, WIFI_STA = 1, WIFI_AP = 2, WIFI_AP_STA = 3
} WiFiMode_t; } WiFiMode_t;
typedef enum { typedef enum WiFiPhyMode
{
WIFI_PHY_MODE_11B = 1, WIFI_PHY_MODE_11G = 2, WIFI_PHY_MODE_11N = 3 WIFI_PHY_MODE_11B = 1, WIFI_PHY_MODE_11G = 2, WIFI_PHY_MODE_11N = 3
} WiFiPhyMode_t; } WiFiPhyMode_t;
typedef enum { typedef enum WiFiSleepType
WIFI_NONE_SLEEP = 0, WIFI_LIGHT_SLEEP =1, WIFI_MODEM_SLEEP = 2 {
WIFI_NONE_SLEEP = 0, WIFI_LIGHT_SLEEP = 1, WIFI_MODEM_SLEEP = 2
} WiFiSleepType_t; } WiFiSleepType_t;
typedef enum { typedef enum WiFiEvent
{
WIFI_EVENT_STAMODE_CONNECTED = 0, WIFI_EVENT_STAMODE_CONNECTED = 0,
WIFI_EVENT_STAMODE_DISCONNECTED, WIFI_EVENT_STAMODE_DISCONNECTED,
WIFI_EVENT_STAMODE_AUTHMODE_CHANGE, WIFI_EVENT_STAMODE_AUTHMODE_CHANGE,
@ -53,9 +58,94 @@ typedef enum {
WIFI_EVENT_SOFTAPMODE_STACONNECTED, WIFI_EVENT_SOFTAPMODE_STACONNECTED,
WIFI_EVENT_SOFTAPMODE_STADISCONNECTED, WIFI_EVENT_SOFTAPMODE_STADISCONNECTED,
WIFI_EVENT_SOFTAPMODE_PROBEREQRECVED, WIFI_EVENT_SOFTAPMODE_PROBEREQRECVED,
WIFI_EVENT_MAX WIFI_EVENT_MAX,
WIFI_EVENT_ANY = WIFI_EVENT_MAX,
WIFI_EVENT_MODE_CHANGE
} WiFiEvent_t; } WiFiEvent_t;
enum WiFiDisconnectReason
{
WIFI_DISCONNECT_REASON_UNSPECIFIED = 1,
WIFI_DISCONNECT_REASON_AUTH_EXPIRE = 2,
WIFI_DISCONNECT_REASON_AUTH_LEAVE = 3,
WIFI_DISCONNECT_REASON_ASSOC_EXPIRE = 4,
WIFI_DISCONNECT_REASON_ASSOC_TOOMANY = 5,
WIFI_DISCONNECT_REASON_NOT_AUTHED = 6,
WIFI_DISCONNECT_REASON_NOT_ASSOCED = 7,
WIFI_DISCONNECT_REASON_ASSOC_LEAVE = 8,
WIFI_DISCONNECT_REASON_ASSOC_NOT_AUTHED = 9,
WIFI_DISCONNECT_REASON_DISASSOC_PWRCAP_BAD = 10, /* 11h */
WIFI_DISCONNECT_REASON_DISASSOC_SUPCHAN_BAD = 11, /* 11h */
WIFI_DISCONNECT_REASON_IE_INVALID = 13, /* 11i */
WIFI_DISCONNECT_REASON_MIC_FAILURE = 14, /* 11i */
WIFI_DISCONNECT_REASON_4WAY_HANDSHAKE_TIMEOUT = 15, /* 11i */
WIFI_DISCONNECT_REASON_GROUP_KEY_UPDATE_TIMEOUT = 16, /* 11i */
WIFI_DISCONNECT_REASON_IE_IN_4WAY_DIFFERS = 17, /* 11i */
WIFI_DISCONNECT_REASON_GROUP_CIPHER_INVALID = 18, /* 11i */
WIFI_DISCONNECT_REASON_PAIRWISE_CIPHER_INVALID = 19, /* 11i */
WIFI_DISCONNECT_REASON_AKMP_INVALID = 20, /* 11i */
WIFI_DISCONNECT_REASON_UNSUPP_RSN_IE_VERSION = 21, /* 11i */
WIFI_DISCONNECT_REASON_INVALID_RSN_IE_CAP = 22, /* 11i */
WIFI_DISCONNECT_REASON_802_1X_AUTH_FAILED = 23, /* 11i */
WIFI_DISCONNECT_REASON_CIPHER_SUITE_REJECTED = 24, /* 11i */
WIFI_DISCONNECT_REASON_BEACON_TIMEOUT = 200,
WIFI_DISCONNECT_REASON_NO_AP_FOUND = 201,
WIFI_DISCONNECT_REASON_AUTH_FAIL = 202,
WIFI_DISCONNECT_REASON_ASSOC_FAIL = 203,
WIFI_DISCONNECT_REASON_HANDSHAKE_TIMEOUT = 204,
};
struct WiFiEventModeChange
{
WiFiMode oldMode;
WiFiMode newMode;
};
struct WiFiEventStationModeConnected
{
String ssid;
uint8 bssid[6];
uint8 channel;
};
struct WiFiEventStationModeDisconnected
{
String ssid;
uint8 bssid[6];
WiFiDisconnectReason reason;
};
struct WiFiEventStationModeAuthModeChanged
{
uint8 oldMode;
uint8 newMode;
};
struct WiFiEventStationModeGotIP
{
IPAddress ip;
IPAddress mask;
IPAddress gw;
};
struct WiFiEventSoftAPModeStationConnected
{
uint8 mac[6];
uint8 aid;
};
struct WiFiEventSoftAPModeStationDisconnected
{
uint8 mac[6];
uint8 aid;
};
struct WiFiEventSoftAPModeProbeRequestReceived
{
int rssi;
uint8 mac[6];
};
extern "C" { extern "C" {