mirror of
https://github.com/esp8266/Arduino.git
synced 2025-07-27 18:02:17 +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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -24,6 +24,8 @@
|
||||
#define ESP8266WIFIGENERIC_H_
|
||||
|
||||
#include "ESP8266WiFiType.h"
|
||||
#include <functional>
|
||||
#include <memory>
|
||||
|
||||
#ifdef DEBUG_ESP_WIFI
|
||||
#ifdef DEBUG_ESP_PORT
|
||||
@ -35,12 +37,10 @@
|
||||
#define DEBUG_WIFI_GENERIC(...)
|
||||
#endif
|
||||
|
||||
typedef void (*WiFiEventCb)(WiFiEvent_t event);
|
||||
struct WiFiEventHandlerOpaque;
|
||||
typedef std::shared_ptr<WiFiEventHandlerOpaque> WiFiEventHandler;
|
||||
|
||||
typedef struct {
|
||||
WiFiEventCb cb;
|
||||
WiFiEvent_t event;
|
||||
} WiFiEventCbList_t;
|
||||
typedef void (*WiFiEventCb)(WiFiEvent_t);
|
||||
|
||||
class ESP8266WiFiGenericClass {
|
||||
// ----------------------------------------------------------------------------------------------
|
||||
@ -48,11 +48,20 @@ class ESP8266WiFiGenericClass {
|
||||
// ----------------------------------------------------------------------------------------------
|
||||
|
||||
public:
|
||||
|
||||
ESP8266WiFiGenericClass();
|
||||
|
||||
void onEvent(WiFiEventCb cbEvent, WiFiEvent_t event = WIFI_EVENT_MAX);
|
||||
void removeEvent(WiFiEventCb cbEvent, WiFiEvent_t event = WIFI_EVENT_MAX);
|
||||
// Note: this function is deprecated. Use one of the functions below instead.
|
||||
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);
|
||||
|
||||
|
@ -28,23 +28,28 @@
|
||||
#define WIFI_SCAN_RUNNING (-1)
|
||||
#define WIFI_SCAN_FAILED (-2)
|
||||
|
||||
// Note:
|
||||
// this enums need to be in sync with the SDK!
|
||||
// Note: these 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
|
||||
} WiFiMode_t;
|
||||
|
||||
typedef enum {
|
||||
typedef enum WiFiPhyMode
|
||||
{
|
||||
WIFI_PHY_MODE_11B = 1, WIFI_PHY_MODE_11G = 2, WIFI_PHY_MODE_11N = 3
|
||||
} WiFiPhyMode_t;
|
||||
|
||||
typedef enum {
|
||||
WIFI_NONE_SLEEP = 0, WIFI_LIGHT_SLEEP =1, WIFI_MODEM_SLEEP = 2
|
||||
typedef enum WiFiSleepType
|
||||
{
|
||||
WIFI_NONE_SLEEP = 0, WIFI_LIGHT_SLEEP = 1, WIFI_MODEM_SLEEP = 2
|
||||
} WiFiSleepType_t;
|
||||
|
||||
|
||||
typedef enum {
|
||||
typedef enum WiFiEvent
|
||||
{
|
||||
WIFI_EVENT_STAMODE_CONNECTED = 0,
|
||||
WIFI_EVENT_STAMODE_DISCONNECTED,
|
||||
WIFI_EVENT_STAMODE_AUTHMODE_CHANGE,
|
||||
@ -53,9 +58,94 @@ typedef enum {
|
||||
WIFI_EVENT_SOFTAPMODE_STACONNECTED,
|
||||
WIFI_EVENT_SOFTAPMODE_STADISCONNECTED,
|
||||
WIFI_EVENT_SOFTAPMODE_PROBEREQRECVED,
|
||||
WIFI_EVENT_MAX
|
||||
WIFI_EVENT_MAX,
|
||||
WIFI_EVENT_ANY = WIFI_EVENT_MAX,
|
||||
WIFI_EVENT_MODE_CHANGE
|
||||
} 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" {
|
||||
|
Reference in New Issue
Block a user