diff --git a/docs/en/api/wifi.rst b/docs/en/api/wifi.rst index 16d8a9d5666..e7ac3cbc690 100644 --- a/docs/en/api/wifi.rst +++ b/docs/en/api/wifi.rst @@ -61,7 +61,7 @@ Function pointer callback taking the event ID: .. code-block:: arduino typedef void (*WiFiEventCb)(arduino_event_id_t); - wifi_event_id_t onEvent(WiFiEventCb, arduino_event_id_t = ARDUINO_EVENT_MAX); + wifi_event_id_t onEvent(WiFiEventCb, arduino_event_id_t = ARDUINO_EVENT_ANY); Function pointer callback taking an event-ID-and-info struct: @@ -73,26 +73,26 @@ Function pointer callback taking an event-ID-and-info struct: } arduino_event_t; typedef void (*WiFiEventSysCb)(arduino_event_t *); - wifi_event_id_t onEvent(WiFiEventSysCb, arduino_event_id_t = ARDUINO_EVENT_MAX); + wifi_event_id_t onEvent(WiFiEventSysCb, arduino_event_id_t = ARDUINO_EVENT_ANY); Callback using ``std::function`` taking event ID and info separately: .. code-block:: arduino typedef std::function WiFiEventFuncCb; - wifi_event_id_t onEvent(WiFiEventFuncCb, arduino_event_id_t = ARDUINO_EVENT_MAX); + wifi_event_id_t onEvent(WiFiEventFuncCb, arduino_event_id_t = ARDUINO_EVENT_ANY); A similar set of functions are available to remove callbacks: .. code-block:: arduino - void removeEvent(WiFiEventCb, arduino_event_id_t = ARDUINO_EVENT_MAX); - void removeEvent(WiFiEventSysCb, arduino_event_id_t = ARDUINO_EVENT_MAX); - void removeEvent(wifi_event_id_t = ARDUINO_EVENT_MAX); + void removeEvent(WiFiEventCb, arduino_event_id_t = ARDUINO_EVENT_ANY); + void removeEvent(WiFiEventSysCb, arduino_event_id_t = ARDUINO_EVENT_ANY); + void removeEvent(wifi_event_id_t = ARDUINO_EVENT_ANY); In all cases, the subscribing function accepts an optional event type to invoke the callback only for that specific event; with the default -``ARDUINO_EVENT_MAX``, the callback will be invoked for all Wi-Fi events. +``ARDUINO_EVENT_ANY``, the callback will be invoked for all Wi-Fi events. Any callback function is given the event type in a parameter. Some of the possible callback function formats also take an diff --git a/libraries/Ethernet/src/ETH.cpp b/libraries/Ethernet/src/ETH.cpp index 542a7e2a218..21522148208 100644 --- a/libraries/Ethernet/src/ETH.cpp +++ b/libraries/Ethernet/src/ETH.cpp @@ -94,7 +94,7 @@ esp_eth_handle_t ETHClass::handle() const { void ETHClass::_onEthEvent(int32_t event_id, void *event_data) { arduino_event_t arduino_event; - arduino_event.event_id = ARDUINO_EVENT_MAX; + arduino_event.event_id = ARDUINO_EVENT_ANY; if (event_id == ETHERNET_EVENT_CONNECTED) { log_v("%s Connected", desc()); @@ -118,7 +118,7 @@ void ETHClass::_onEthEvent(int32_t event_id, void *event_data) { ); } - if (arduino_event.event_id < ARDUINO_EVENT_MAX) { + if (arduino_event.event_id != ARDUINO_EVENT_ANY) { Network.postEvent(&arduino_event); } } diff --git a/libraries/Network/src/NetworkEvents.cpp b/libraries/Network/src/NetworkEvents.cpp index 161e55c5d01..f97016894d2 100644 --- a/libraries/Network/src/NetworkEvents.cpp +++ b/libraries/Network/src/NetworkEvents.cpp @@ -3,39 +3,24 @@ * * SPDX-License-Identifier: Apache-2.0 */ +#include #include "NetworkEvents.h" -#include "NetworkManager.h" -#include "esp_task.h" #include "esp32-hal.h" -#ifndef ARDUINO_NETWORK_EVENT_TASK_STACK_SIZE -#define ARDUINO_NETWORK_EVENT_TASK_STACK_SIZE 4096 -#endif - -NetworkEvents::NetworkEvents() : _arduino_event_group(NULL), _arduino_event_queue(NULL), _arduino_event_task_handle(NULL) {} +ESP_EVENT_DEFINE_BASE(ARDUINO_EVENTS); NetworkEvents::~NetworkEvents() { - if (_arduino_event_task_handle != NULL) { - vTaskDelete(_arduino_event_task_handle); - _arduino_event_task_handle = NULL; - } if (_arduino_event_group != NULL) { vEventGroupDelete(_arduino_event_group); _arduino_event_group = NULL; } - if (_arduino_event_queue != NULL) { - arduino_event_t *event = NULL; - // consume queue - while (xQueueReceive(_arduino_event_queue, &event, 0) == pdTRUE) { - delete event; - } - vQueueDelete(_arduino_event_queue); - _arduino_event_queue = NULL; + // unregister event bus handler + if (_evt_handler){ + esp_event_handler_instance_unregister(ARDUINO_EVENTS, ESP_EVENT_ANY_ID, _evt_handler); + _evt_handler = nullptr; } } -static uint32_t _initial_bits = 0; - bool NetworkEvents::initNetworkEvents() { if (!_arduino_event_group) { _arduino_event_group = xEventGroupCreate(); @@ -46,108 +31,75 @@ bool NetworkEvents::initNetworkEvents() { xEventGroupSetBits(_arduino_event_group, _initial_bits); } - if (!_arduino_event_queue) { - _arduino_event_queue = xQueueCreate(32, sizeof(arduino_event_t *)); - if (!_arduino_event_queue) { - log_e("Network Event Queue Create Failed!"); - return false; - } - } - + // create default ESP event loop esp_err_t err = esp_event_loop_create_default(); if (err != ESP_OK && err != ESP_ERR_INVALID_STATE) { log_e("esp_event_loop_create_default failed!"); - return err; + return false; } - if (!_arduino_event_task_handle) { - xTaskCreateUniversal( - [](void *self) { - static_cast(self)->_checkForEvent(); - }, - "arduino_events", // label - ARDUINO_NETWORK_EVENT_TASK_STACK_SIZE, // event task's stack size - this, ESP_TASKD_EVENT_PRIO - 1, &_arduino_event_task_handle, ARDUINO_EVENT_RUNNING_CORE + // subscribe to default ESP event bus + if (!_evt_handler){ + ESP_ERROR_CHECK( + esp_event_handler_instance_register( + ARDUINO_EVENTS, ESP_EVENT_ANY_ID, + [](void* self, esp_event_base_t base, int32_t id, void* data) { static_cast(self)->_evt_picker(id, reinterpret_cast(data)); }, + this, + &_evt_handler + ) ); - if (!_arduino_event_task_handle) { - log_e("Network Event Task Start Failed!"); - return false; - } } - return true; } -bool NetworkEvents::postEvent(const arduino_event_t *data) { - if (data == NULL || _arduino_event_queue == NULL) { - return false; - } - arduino_event_t *event = new arduino_event_t(); - if (event == NULL) { - log_e("Arduino Event Malloc Failed!"); - return false; - } +bool NetworkEvents::postEvent(const arduino_event_t *data, TickType_t timeout) { + if (!data) return false; + esp_err_t err = esp_event_post(ARDUINO_EVENTS, static_cast(data->event_id), &data->event_info, sizeof(data->event_info), timeout); + if (err == ESP_OK) + return true; - memcpy(event, data, sizeof(arduino_event_t)); - if (xQueueSend(_arduino_event_queue, &event, portMAX_DELAY) != pdPASS) { - log_e("Arduino Event Send Failed!"); - delete event; // release mem on error - return false; - } - return true; + log_e("Arduino Event Send Failed!"); + return false; } -void NetworkEvents::_checkForEvent() { - // this task can't run without the queue - if (_arduino_event_queue == NULL) { - _arduino_event_task_handle = NULL; - vTaskDelete(NULL); - return; - } +bool NetworkEvents::postEvent(arduino_event_id_t event, const arduino_event_info_t *info, TickType_t timeout){ + if (info) + return esp_event_post(ARDUINO_EVENTS, static_cast(event), info, sizeof(arduino_event_info_t), timeout) == pdTRUE; + else + return esp_event_post(ARDUINO_EVENTS, static_cast(event), NULL, 0, timeout) == pdTRUE; +} - for (;;) { - arduino_event_t *event = NULL; - // wait for an event on a queue - if (xQueueReceive(_arduino_event_queue, &event, portMAX_DELAY) != pdTRUE) { - continue; - } - if (event == NULL) { - continue; - } - log_v("Network Event: %d - %s", event->event_id, eventName(event->event_id)); +void NetworkEvents::_evt_picker(int32_t id, arduino_event_info_t *info){ #if defined NETWORK_EVENTS_MUTEX && SOC_CPU_CORES_NUM > 1 - std::unique_lock lock(_mtx); + std::lock_guard lock(_mtx); #endif // defined NETWORK_EVENTS_MUTEX && SOC_CPU_CORES_NUM > 1 - // iterate over registered callbacks - for (auto &i : _cbEventList) { - if (i.cb || i.fcb || i.scb) { - if (i.event == (arduino_event_id_t)event->event_id || i.event == ARDUINO_EVENT_MAX) { - if (i.cb) { - i.cb((arduino_event_id_t)event->event_id); - continue; - } - - if (i.fcb) { - i.fcb((arduino_event_id_t)event->event_id, (arduino_event_info_t)event->event_info); - continue; - } - - i.scb(event); + // iterate over registered callbacks + for (auto &i : _cbEventList) { + if (i.event == ARDUINO_EVENT_ANY || i.event == static_cast(id)){ + + std::visit([id, info](auto&& arg){ + using T = std::decay_t; + if constexpr (std::is_same_v) + arg(static_cast(id), info); + else if constexpr (std::is_same_v) + arg(static_cast(id)); + else if constexpr (std::is_same_v) + if (info) + arg(static_cast(id), *info); + else + arg(static_cast(id), {}); + else if constexpr (std::is_same_v){ + // system event callback needs a ptr to struct + arduino_event_t event{static_cast(id), {}}; + if (info) + memcpy(&event.event_info, info, sizeof(arduino_event_info_t)); + arg(&event); } - } + }, i.cb_v); } - -#if defined NETWORK_EVENTS_MUTEX && SOC_CPU_CORES_NUM > 1 - lock.unlock(); -#endif // defined NETWORK_EVENTS_MUTEX && SOC_CPU_CORES_NUM > 1 - - // release the event object's memory - delete event; } - - vTaskDelete(NULL); } template static size_t getStdFunctionAddress(std::function f) { @@ -168,7 +120,7 @@ network_event_handle_t NetworkEvents::onEvent(NetworkEventCb cbEvent, arduino_ev std::lock_guard lock(_mtx); #endif // defined NETWORK_EVENTS_MUTEX && SOC_CPU_CORES_NUM > 1 - _cbEventList.emplace_back(++_current_id, cbEvent, nullptr, nullptr, event); + _cbEventList.emplace_back(++_current_id, cbEvent, event); return _cbEventList.back().id; } @@ -181,7 +133,7 @@ network_event_handle_t NetworkEvents::onEvent(NetworkEventFuncCb cbEvent, arduin std::lock_guard lock(_mtx); #endif // defined NETWORK_EVENTS_MUTEX && SOC_CPU_CORES_NUM > 1 - _cbEventList.emplace_back(++_current_id, nullptr, cbEvent, nullptr, event); + _cbEventList.emplace_back(++_current_id, cbEvent, event); return _cbEventList.back().id; } @@ -194,7 +146,7 @@ network_event_handle_t NetworkEvents::onEvent(NetworkEventSysCb cbEvent, arduino std::lock_guard lock(_mtx); #endif // defined NETWORK_EVENTS_MUTEX && SOC_CPU_CORES_NUM > 1 - _cbEventList.emplace_back(++_current_id, nullptr, nullptr, cbEvent, event); + _cbEventList.emplace_back(++_current_id, cbEvent, event); return _cbEventList.back().id; } @@ -207,7 +159,7 @@ network_event_handle_t NetworkEvents::onSysEvent(NetworkEventCb cbEvent, arduino std::lock_guard lock(_mtx); #endif // defined NETWORK_EVENTS_MUTEX && SOC_CPU_CORES_NUM > 1 - _cbEventList.emplace(_cbEventList.begin(), ++_current_id, cbEvent, nullptr, nullptr, event); + _cbEventList.emplace(_cbEventList.begin(), ++_current_id, cbEvent, event); return _cbEventList.front().id; } @@ -220,7 +172,7 @@ network_event_handle_t NetworkEvents::onSysEvent(NetworkEventFuncCb cbEvent, ard std::lock_guard lock(_mtx); #endif // defined NETWORK_EVENTS_MUTEX && SOC_CPU_CORES_NUM > 1 - _cbEventList.emplace(_cbEventList.begin(), ++_current_id, nullptr, cbEvent, nullptr, event); + _cbEventList.emplace(_cbEventList.begin(), ++_current_id, cbEvent, event); return _cbEventList.front().id; } @@ -233,7 +185,20 @@ network_event_handle_t NetworkEvents::onSysEvent(NetworkEventSysCb cbEvent, ardu std::lock_guard lock(_mtx); #endif // defined NETWORK_EVENTS_MUTEX && SOC_CPU_CORES_NUM > 1 - _cbEventList.emplace(_cbEventList.begin(), ++_current_id, nullptr, nullptr, cbEvent, event); + _cbEventList.emplace(_cbEventList.begin(), ++_current_id, cbEvent, event); + return _cbEventList.front().id; +} + +network_event_handle_t NetworkEvents::onSysEvent(NetworkEventReceiver cbEvent, arduino_event_id_t event){ + if (!cbEvent) { + return 0; + } + +#if defined NETWORK_EVENTS_MUTEX && SOC_CPU_CORES_NUM > 1 + std::lock_guard lock(_mtx); +#endif // defined NETWORK_EVENTS_MUTEX && SOC_CPU_CORES_NUM > 1 + + _cbEventList.emplace(_cbEventList.begin(), ++_current_id, cbEvent, event); return _cbEventList.front().id; } @@ -250,7 +215,11 @@ void NetworkEvents::removeEvent(NetworkEventCb cbEvent, arduino_event_id_t event std::remove_if( _cbEventList.begin(), _cbEventList.end(), [cbEvent, event](const NetworkEventCbList_t &e) { - return e.cb == cbEvent && e.event == event; + return e.event == event && std::visit([cbEvent](auto&& arg) -> bool { + if constexpr (std::is_same_v>) + return cbEvent == arg; + else return false; + }, e.cb_v); } ), _cbEventList.end() @@ -265,12 +234,15 @@ void NetworkEvents::removeEvent(NetworkEventFuncCb cbEvent, arduino_event_id_t e #if defined NETWORK_EVENTS_MUTEX && SOC_CPU_CORES_NUM > 1 std::lock_guard lock(_mtx); #endif // defined NETWORK_EVENTS_MUTEX && SOC_CPU_CORES_NUM > 1 - _cbEventList.erase( std::remove_if( _cbEventList.begin(), _cbEventList.end(), [cbEvent, event](const NetworkEventCbList_t &e) { - return getStdFunctionAddress(e.fcb) == getStdFunctionAddress(cbEvent) && e.event == event; + return e.event == event && std::visit([cbEvent](auto&& arg) -> bool { + if constexpr (std::is_same_v>) + return getStdFunctionAddress(cbEvent) == getStdFunctionAddress(arg); + else return false; + }, e.cb_v); } ), _cbEventList.end() @@ -290,7 +262,11 @@ void NetworkEvents::removeEvent(NetworkEventSysCb cbEvent, arduino_event_id_t ev std::remove_if( _cbEventList.begin(), _cbEventList.end(), [cbEvent, event](const NetworkEventCbList_t &e) { - return e.scb == cbEvent && e.event == event; + return e.event == event && std::visit([cbEvent](auto&& arg) -> bool { + if constexpr (std::is_same_v>) + return cbEvent == arg; + else return false; + }, e.cb_v); } ), _cbEventList.end() @@ -354,7 +330,6 @@ int NetworkEvents::waitStatusBits(int bits, uint32_t timeout_ms) { * @brief Convert arduino_event_id_t to a C string. * @param [in] id The event id to be converted. * @return A string representation of the event id. - * @note: arduino_event_id_t values as of Mar 2023 (arduino-esp32 r2.0.7) are: 0-39 (ARDUINO_EVENT_MAX=40) and are defined in WiFiGeneric.h. */ const char *NetworkEvents::eventName(arduino_event_id_t id) { switch (id) { diff --git a/libraries/Network/src/NetworkEvents.h b/libraries/Network/src/NetworkEvents.h index 34a54cab092..d78b9bd7c29 100644 --- a/libraries/Network/src/NetworkEvents.h +++ b/libraries/Network/src/NetworkEvents.h @@ -14,10 +14,8 @@ #include "esp_eth_driver.h" #endif #include +#include #include "freertos/FreeRTOS.h" -#include "freertos/task.h" -#include "freertos/queue.h" -#include "freertos/semphr.h" #include "freertos/event_groups.h" #if defined NETWORK_EVENTS_MUTEX && SOC_CPU_CORES_NUM > 1 #include @@ -39,8 +37,11 @@ constexpr int WIFI_SCAN_DONE_BIT = BIT1; #define NET_HAS_IP6_GLOBAL_BIT 0 ESP_EVENT_DECLARE_BASE(ARDUINO_EVENTS); +// backward compatibility +#define ARDUINO_EVENT_MAX ARDUINO_EVENT_ANY typedef enum { + ARDUINO_EVENT_ANY = ESP_EVENT_ANY_ID, // make all ARDUINO events compatibile with ANY ESP_EVENT ARDUINO_EVENT_NONE = 0, ARDUINO_EVENT_ETH_START, ARDUINO_EVENT_ETH_STOP, @@ -93,9 +94,9 @@ typedef enum { ARDUINO_EVENT_PPP_GOT_IP, ARDUINO_EVENT_PPP_LOST_IP, ARDUINO_EVENT_PPP_GOT_IP6, - ARDUINO_EVENT_MAX } arduino_event_id_t; + typedef union { ip_event_ap_staipassigned_t wifi_ap_staipassigned; ip_event_got_ip_t got_ip; @@ -134,10 +135,15 @@ struct arduino_event_t { }; // type aliases +using network_event_handle_t = size_t; +// static callback using NetworkEventCb = void (*)(arduino_event_id_t event); +// Generic Arduno NetworkEvent Functional Callback for events propagated via ESP Event loop +using NetworkEventReceiver = std::function; +// deprecated ones using NetworkEventFuncCb = std::function; using NetworkEventSysCb = void (*)(arduino_event_t *event); -using network_event_handle_t = size_t; + /** * @brief Class that provides network events callback handling @@ -148,9 +154,19 @@ using network_event_handle_t = size_t; */ class NetworkEvents { public: - NetworkEvents(); + NetworkEvents(){}; ~NetworkEvents(); + /** + * @brief register callback function to be executed on arduino event(s) + * @note if same handler is registered twice or more than same handler would be called twice or more times + * + * @param cbEvent functional callback + * @param event event to process, any event by default + * @return network_event_handle_t + */ + network_event_handle_t onEvent(NetworkEventReceiver cbEvent, arduino_event_id_t event = ARDUINO_EVENT_ANY); + /** * @brief register callback function to be executed on arduino event(s) * @note if same handler is registered twice or more than same handler would be called twice or more times @@ -159,30 +175,31 @@ class NetworkEvents { * @param event event to process, any event by default * @return network_event_handle_t */ - network_event_handle_t onEvent(NetworkEventCb cbEvent, arduino_event_id_t event = ARDUINO_EVENT_MAX); + network_event_handle_t onEvent(NetworkEventCb cbEvent, arduino_event_id_t event = ARDUINO_EVENT_ANY); /** * @brief register functional callback to be executed on arduino event(s) * also used for lambda callbacks * @note if same handler is registered twice or more than same handler would be called twice or more times * - * @param cbEvent static callback function + * @param cbEvent functional callback * @param event event to process, any event by default * @return network_event_handle_t */ - network_event_handle_t onEvent(NetworkEventFuncCb cbEvent, arduino_event_id_t event = ARDUINO_EVENT_MAX); + [[deprecated( "NetworkEventFuncCb deprecated, pls, use NetworkEventReceiver instead" )]] + network_event_handle_t onEvent(NetworkEventFuncCb cbEvent, arduino_event_id_t event = ARDUINO_EVENT_ANY); /** * @brief register static system callback to be executed on arduino event(s) * callback function would be supplied with a pointer to arduino_event_t structure as an argument - * * @note if same handler is registered twice or more than same handler would be called twice or more times * * @param cbEvent static callback function * @param event event to process, any event by default * @return network_event_handle_t */ - network_event_handle_t onEvent(NetworkEventSysCb cbEvent, arduino_event_id_t event = ARDUINO_EVENT_MAX); + [[deprecated( "NetworkEventSysCb deprecated, pls, use NetworkEventReceiver instead" )]] + network_event_handle_t onEvent(NetworkEventSysCb cbEvent, arduino_event_id_t event = ARDUINO_EVENT_ANY); /** * @brief unregister static function callback @@ -191,7 +208,7 @@ class NetworkEvents { * @param cbEvent static callback function * @param event event to process, any event by default */ - void removeEvent(NetworkEventCb cbEvent, arduino_event_id_t event = ARDUINO_EVENT_MAX); + void removeEvent(NetworkEventCb cbEvent, arduino_event_id_t event = ARDUINO_EVENT_ANY); /** * @brief unregister functional callback @@ -201,8 +218,8 @@ class NetworkEvents { * @param cbEvent functional callback * @param event event to process, any event by default */ - void removeEvent(NetworkEventFuncCb cbEvent, arduino_event_id_t event = ARDUINO_EVENT_MAX) - __attribute__((deprecated("removing functional callbacks via pointer is deprecated, use removeEvent(network_event_handle_t) instead"))); + [[deprecated( "removing functional callbacks via pointer is deprecated, use removeEvent(network_event_handle_t) instead" )]] + void removeEvent(NetworkEventFuncCb cbEvent, arduino_event_id_t event = ARDUINO_EVENT_ANY); /** * @brief unregister static system function callback @@ -211,13 +228,12 @@ class NetworkEvents { * @param cbEvent static callback function * @param event event to process, any event by default */ - void removeEvent(NetworkEventSysCb cbEvent, arduino_event_id_t event = ARDUINO_EVENT_MAX); + void removeEvent(NetworkEventSysCb cbEvent, arduino_event_id_t event = ARDUINO_EVENT_ANY); /** * @brief unregister event callback via handler * - * @param cbEvent static callback function - * @param event event to process, any event by default + * @param event_handle a handler to remove */ void removeEvent(network_event_handle_t event_handle); @@ -225,20 +241,22 @@ class NetworkEvents { * @brief get a human-readable name of an event by it's id * * @param id event id code - * @return const char* event name string */ static const char *eventName(arduino_event_id_t id); /** - * @brief post an event to the queue - * and propagade and event to subscribed handlers + * @brief post an event to the queue and propagade it to subscribed handlers * @note posting an event will trigger context switch from a lower priority task * * @param event a pointer to arduino_event_t struct + * @param info optional struct with side data related to event * @return true if event was queued susccessfuly - * @return false on memrory allocation error or queue is full + * @return false on memory allocation error or queue is full */ - bool postEvent(const arduino_event_t *event); + bool postEvent(arduino_event_id_t event, const arduino_event_info_t *info = nullptr, TickType_t timeout = portMAX_DELAY); + + [[deprecated( "posting arduino_event_t is deprecated, pls, use postEvent(arduino_event_id_t event, const arduino_event_info_t *info) instead" )]] + bool postEvent(const arduino_event_t *event, TickType_t timeout = portMAX_DELAY); int getStatusBits() const; int waitStatusBits(int bits, uint32_t timeout_ms); @@ -257,11 +275,15 @@ class NetworkEvents { protected: bool initNetworkEvents(); // same as onEvent() but places newly added handler at the beginning of registered events list - network_event_handle_t onSysEvent(NetworkEventCb cbEvent, arduino_event_id_t event = ARDUINO_EVENT_MAX); + network_event_handle_t onSysEvent(NetworkEventCb cbEvent, arduino_event_id_t event = ARDUINO_EVENT_ANY); + // same as onEvent() but places newly added handler at the beginning of registered events list + network_event_handle_t onSysEvent(NetworkEventReceiver cbEvent, arduino_event_id_t event = ARDUINO_EVENT_ANY); // same as onEvent() but places newly added handler at the beginning of registered events list - network_event_handle_t onSysEvent(NetworkEventFuncCb cbEvent, arduino_event_id_t event = ARDUINO_EVENT_MAX); + [[deprecated( "NetworkEventFuncCb deprecated, pls, use NetworkEventReceiver instead" )]] + network_event_handle_t onSysEvent(NetworkEventFuncCb cbEvent, arduino_event_id_t event = ARDUINO_EVENT_ANY); // same as onEvent() but places newly added handler at the beginning of registered events list - network_event_handle_t onSysEvent(NetworkEventSysCb cbEvent, arduino_event_id_t event = ARDUINO_EVENT_MAX); + [[deprecated( "NetworkEventSysCb deprecated, pls, use NetworkEventReceiver instead" )]] + network_event_handle_t onSysEvent(NetworkEventSysCb cbEvent, arduino_event_id_t event = ARDUINO_EVENT_ANY); private: /** @@ -273,24 +295,31 @@ class NetworkEvents { */ struct NetworkEventCbList_t { network_event_handle_t id; - NetworkEventCb cb; - NetworkEventFuncCb fcb; - NetworkEventSysCb scb; + std::variantcb_v; arduino_event_id_t event; - explicit NetworkEventCbList_t( - network_event_handle_t id, NetworkEventCb cb = nullptr, NetworkEventFuncCb fcb = nullptr, NetworkEventSysCb scb = nullptr, - arduino_event_id_t event = ARDUINO_EVENT_MAX - ) - : id(id), cb(cb), fcb(fcb), scb(scb), event(event) {} + explicit NetworkEventCbList_t(network_event_handle_t id, NetworkEventCb callback, arduino_event_id_t event = ARDUINO_EVENT_ANY ) + : id(id), cb_v(callback), event(event) {} + + explicit NetworkEventCbList_t(network_event_handle_t id, NetworkEventReceiver callback, arduino_event_id_t event = ARDUINO_EVENT_ANY ) + : id(id), cb_v(callback), event(event) {} + + explicit NetworkEventCbList_t(network_event_handle_t id, NetworkEventFuncCb callback, arduino_event_id_t event = ARDUINO_EVENT_ANY ) + : id(id), cb_v(callback), event(event) {} + + explicit NetworkEventCbList_t(network_event_handle_t id, NetworkEventSysCb callback, arduino_event_id_t event = ARDUINO_EVENT_ANY ) + : id(id), cb_v(callback), event(event) {} }; // define initial id's value network_event_handle_t _current_id{0}; + // EventGroup i.c. + uint32_t _initial_bits{0}; + + // ESP event bus handler + esp_event_handler_instance_t _evt_handler{nullptr}; - EventGroupHandle_t _arduino_event_group; - QueueHandle_t _arduino_event_queue; - TaskHandle_t _arduino_event_task_handle; + EventGroupHandle_t _arduino_event_group{nullptr}; // registered events callbacks container std::vector _cbEventList; @@ -300,9 +329,6 @@ class NetworkEvents { std::mutex _mtx; #endif // defined NETWORK_EVENTS_MUTEX && SOC_CPU_CORES_NUM > 1 - /** - * @brief task function that picks events from an event queue and calls registered callbacks - * - */ - void _checkForEvent(); + // ESP event bus callback function, picks events from an event queue and calls registered callbacks + void _evt_picker(int32_t id, arduino_event_info_t *info); }; diff --git a/libraries/Network/src/NetworkInterface.cpp b/libraries/Network/src/NetworkInterface.cpp index 01790ec2493..ba0a0fc4158 100644 --- a/libraries/Network/src/NetworkInterface.cpp +++ b/libraries/Network/src/NetworkInterface.cpp @@ -70,7 +70,7 @@ static void _ip_event_cb(void *arg, esp_event_base_t event_base, int32_t event_i void NetworkInterface::_onIpEvent(int32_t event_id, void *event_data) { arduino_event_t arduino_event; - arduino_event.event_id = ARDUINO_EVENT_MAX; + arduino_event.event_id = ARDUINO_EVENT_ANY; if (event_id == _got_ip_event_id) { setStatusBits(ESP_NETIF_HAS_IP_BIT); #if ARDUHAL_LOG_LEVEL >= ARDUHAL_LOG_LEVEL_VERBOSE @@ -151,7 +151,7 @@ void NetworkInterface::_onIpEvent(int32_t event_id, void *event_data) { #endif } - if (arduino_event.event_id < ARDUINO_EVENT_MAX) { + if (arduino_event.event_id != ARDUINO_EVENT_ANY) { Network.postEvent(&arduino_event); } } diff --git a/libraries/PPP/src/PPP.cpp b/libraries/PPP/src/PPP.cpp index 77b70d3969c..8d15f570cb4 100644 --- a/libraries/PPP/src/PPP.cpp +++ b/libraries/PPP/src/PPP.cpp @@ -128,7 +128,7 @@ void PPPClass::_onPppArduinoEvent(arduino_event_id_t event, arduino_event_info_t // PPP Driver Events Callback void PPPClass::_onPppEvent(int32_t event, void *event_data) { arduino_event_t arduino_event; - arduino_event.event_id = ARDUINO_EVENT_MAX; + arduino_event.event_id = ARDUINO_EVENT_ANY; log_v("PPP Driver Event %ld: %s", event, _ppp_event_name(event)); @@ -141,7 +141,7 @@ void PPPClass::_onPppEvent(int32_t event, void *event_data) { } } - if (arduino_event.event_id < ARDUINO_EVENT_MAX) { + if (arduino_event.event_id != ARDUINO_EVENT_ANY) { Network.postEvent(&arduino_event); } } diff --git a/libraries/WiFi/src/AP.cpp b/libraries/WiFi/src/AP.cpp index b713a6d3901..60b24ee4909 100644 --- a/libraries/WiFi/src/AP.cpp +++ b/libraries/WiFi/src/AP.cpp @@ -72,28 +72,19 @@ static bool softap_config_equal(const wifi_config_t &lhs, const wifi_config_t &r return true; } -static APClass *_ap_network_if = NULL; - -static esp_event_handler_instance_t _ap_ev_instance = NULL; -static void _ap_event_cb(void *arg, esp_event_base_t event_base, int32_t event_id, void *event_data) { - if (event_base == WIFI_EVENT) { - ((APClass *)arg)->_onApEvent(event_id, event_data); - } -} - -static void _onApArduinoEvent(arduino_event_t *ev) { - if (_ap_network_if == NULL || ev->event_id < ARDUINO_EVENT_WIFI_AP_START || ev->event_id > ARDUINO_EVENT_WIFI_AP_GOT_IP6) { +void APClass::_onApArduinoEvent(arduino_event_id_t event, const arduino_event_info_t *info) { + if (event < ARDUINO_EVENT_WIFI_AP_START || event > ARDUINO_EVENT_WIFI_AP_GOT_IP6) { return; } - log_v("Arduino AP Event: %d - %s", ev->event_id, Network.eventName(ev->event_id)); - if (ev->event_id == ARDUINO_EVENT_WIFI_AP_START) { + log_v("Arduino AP Event: %d - %s", event, NetworkEvents::eventName(event)); + if (event == ARDUINO_EVENT_WIFI_AP_START) { #if CONFIG_LWIP_IPV6 - if (_ap_network_if->getStatusBits() & ESP_NETIF_WANT_IP6_BIT) { - esp_err_t err = esp_netif_create_ip6_linklocal(_ap_network_if->netif()); + if (getStatusBits() & ESP_NETIF_WANT_IP6_BIT) { + esp_err_t err = esp_netif_create_ip6_linklocal(netif()); if (err != ESP_OK) { log_e("Failed to enable IPv6 Link Local on AP: 0x%x: %s", err, esp_err_to_name(err)); } else { - log_v("Enabled IPv6 Link Local on %s", _ap_network_if->desc()); + log_v("Enabled IPv6 Link Local on %s", desc()); } } #endif @@ -101,69 +92,85 @@ static void _onApArduinoEvent(arduino_event_t *ev) { } void APClass::_onApEvent(int32_t event_id, void *event_data) { - arduino_event_t arduino_event; - arduino_event.event_id = ARDUINO_EVENT_MAX; - - if (event_id == WIFI_EVENT_AP_START) { - log_v("AP Started"); - arduino_event.event_id = ARDUINO_EVENT_WIFI_AP_START; - setStatusBits(ESP_NETIF_STARTED_BIT); - } else if (event_id == WIFI_EVENT_AP_STOP) { - log_v("AP Stopped"); - arduino_event.event_id = ARDUINO_EVENT_WIFI_AP_STOP; - clearStatusBits(ESP_NETIF_STARTED_BIT | ESP_NETIF_CONNECTED_BIT | ESP_NETIF_HAS_IP_BIT | ESP_NETIF_HAS_LOCAL_IP6_BIT | ESP_NETIF_HAS_GLOBAL_IP6_BIT); - } else if (event_id == WIFI_EVENT_AP_PROBEREQRECVED) { -#if ARDUHAL_LOG_LEVEL >= ARDUHAL_LOG_LEVEL_VERBOSE - wifi_event_ap_probe_req_rx_t *event = (wifi_event_ap_probe_req_rx_t *)event_data; - log_v("AP Probe Request: RSSI: %d, MAC: " MACSTR, event->rssi, MAC2STR(event->mac)); -#endif - arduino_event.event_id = ARDUINO_EVENT_WIFI_AP_PROBEREQRECVED; - memcpy(&arduino_event.event_info.wifi_ap_probereqrecved, event_data, sizeof(wifi_event_ap_probe_req_rx_t)); - } else if (event_id == WIFI_EVENT_AP_STACONNECTED) { -#if ARDUHAL_LOG_LEVEL >= ARDUHAL_LOG_LEVEL_VERBOSE - wifi_event_ap_staconnected_t *event = (wifi_event_ap_staconnected_t *)event_data; - log_v("AP Station Connected: MAC: " MACSTR ", AID: %d", MAC2STR(event->mac), event->aid); -#endif - arduino_event.event_id = ARDUINO_EVENT_WIFI_AP_STACONNECTED; - memcpy(&arduino_event.event_info.wifi_ap_staconnected, event_data, sizeof(wifi_event_ap_staconnected_t)); - setStatusBits(ESP_NETIF_CONNECTED_BIT); - } else if (event_id == WIFI_EVENT_AP_STADISCONNECTED) { -#if ARDUHAL_LOG_LEVEL >= ARDUHAL_LOG_LEVEL_VERBOSE - wifi_event_ap_stadisconnected_t *event = (wifi_event_ap_stadisconnected_t *)event_data; - log_v("AP Station Disconnected: MAC: " MACSTR ", AID: %d", MAC2STR(event->mac), event->aid); -#endif - arduino_event.event_id = ARDUINO_EVENT_WIFI_AP_STADISCONNECTED; - memcpy(&arduino_event.event_info.wifi_ap_stadisconnected, event_data, sizeof(wifi_event_ap_stadisconnected_t)); - // If no more clients are left - wifi_sta_list_t clients; - if (esp_wifi_ap_get_sta_list(&clients) != ESP_OK || clients.num == 0) { - clearStatusBits(ESP_NETIF_CONNECTED_BIT); + switch (event_id){ + case WIFI_EVENT_AP_START : + log_v("AP Started"); + setStatusBits(ESP_NETIF_STARTED_BIT); + Network.postEvent(ARDUINO_EVENT_WIFI_AP_START); + return; + case WIFI_EVENT_AP_STOP : + log_v("AP Stopped"); + clearStatusBits(ESP_NETIF_STARTED_BIT | ESP_NETIF_CONNECTED_BIT | ESP_NETIF_HAS_IP_BIT | ESP_NETIF_HAS_LOCAL_IP6_BIT | ESP_NETIF_HAS_GLOBAL_IP6_BIT); + Network.postEvent(ARDUINO_EVENT_WIFI_AP_STOP); + return; + case WIFI_EVENT_AP_PROBEREQRECVED : { + #if ARDUHAL_LOG_LEVEL >= ARDUHAL_LOG_LEVEL_VERBOSE + wifi_event_ap_probe_req_rx_t *event = (wifi_event_ap_probe_req_rx_t *)event_data; + log_v("AP Probe Request: RSSI: %d, MAC: " MACSTR, event->rssi, MAC2STR(event->mac)); + #endif + arduino_event_info_t i; + memcpy(&i.wifi_ap_probereqrecved, event_data, sizeof(wifi_event_ap_probe_req_rx_t)); + Network.postEvent(ARDUINO_EVENT_WIFI_AP_PROBEREQRECVED, &i); + return; } - } else { - return; - } - - if (arduino_event.event_id < ARDUINO_EVENT_MAX) { - Network.postEvent(&arduino_event); + case WIFI_EVENT_AP_STACONNECTED : { + #if ARDUHAL_LOG_LEVEL >= ARDUHAL_LOG_LEVEL_VERBOSE + wifi_event_ap_staconnected_t *event = (wifi_event_ap_staconnected_t *)event_data; + log_v("AP Station Connected: MAC: " MACSTR ", AID: %d", MAC2STR(event->mac), event->aid); + #endif + setStatusBits(ESP_NETIF_CONNECTED_BIT); + arduino_event_info_t i; + memcpy(&i.wifi_ap_staconnected, event_data, sizeof(wifi_event_ap_staconnected_t)); + Network.postEvent(ARDUINO_EVENT_WIFI_AP_STACONNECTED, &i); + return; + } + case WIFI_EVENT_AP_STADISCONNECTED : { + #if ARDUHAL_LOG_LEVEL >= ARDUHAL_LOG_LEVEL_VERBOSE + wifi_event_ap_stadisconnected_t *event = (wifi_event_ap_stadisconnected_t *)event_data; + log_v("AP Station Disconnected: MAC: " MACSTR ", AID: %d", MAC2STR(event->mac), event->aid); + #endif + // If no more clients are left + wifi_sta_list_t clients; + if (esp_wifi_ap_get_sta_list(&clients) != ESP_OK || clients.num == 0) { + clearStatusBits(ESP_NETIF_CONNECTED_BIT); + } + arduino_event_info_t i; + memcpy(&i.wifi_ap_stadisconnected, event_data, sizeof(wifi_event_ap_stadisconnected_t)); + Network.postEvent(ARDUINO_EVENT_WIFI_AP_STADISCONNECTED, &i); + return; + } + default : + return; } } -APClass::APClass() { - _ap_network_if = this; -} +APClass::APClass() {} APClass::~APClass() { end(); - _ap_network_if = NULL; + Network.removeEvent(_evt_handle); + if (_ap_ev_instance != NULL) { + esp_event_handler_instance_unregister(WIFI_EVENT, ESP_EVENT_ANY_ID, _ap_ev_instance); + _ap_ev_instance = NULL; + } } bool APClass::onEnable() { - if (_ap_ev_instance == NULL && esp_event_handler_instance_register(WIFI_EVENT, ESP_EVENT_ANY_ID, &_ap_event_cb, this, &_ap_ev_instance)) { - log_e("event_handler_instance_register for WIFI_EVENT Failed!"); - return false; + if (!_ap_ev_instance){ + esp_err_t err = esp_event_handler_instance_register(WIFI_EVENT, ESP_EVENT_ANY_ID, + [](void* self, esp_event_base_t base, int32_t id, void* data) { static_cast(self)->_onApEvent(id, data); }, + this, + &_ap_ev_instance + ); + if (err){ + log_e("event_handler_instance_register for WIFI_EVENT Failed!"); + return false; + } } + if (_esp_netif == NULL) { - Network.onSysEvent(_onApArduinoEvent); + if (!_evt_handle) + _evt_handle = Network.onSysEvent([this](arduino_event_id_t event, const arduino_event_info_t *info){_onApArduinoEvent(event, info);}); _esp_netif = get_esp_interface_netif(ESP_IF_WIFI_AP); /* attach to receive events */ initNetif(ESP_NETIF_ID_AP); @@ -172,13 +179,14 @@ bool APClass::onEnable() { } bool APClass::onDisable() { - Network.removeEvent(_onApArduinoEvent); + Network.removeEvent(_evt_handle); + _evt_handle = 0; // we just set _esp_netif to NULL here, so destroyNetif() does not try to destroy it. // That would be done by WiFi.enableAP(false) if STA is not enabled, or when it gets disabled _esp_netif = NULL; destroyNetif(); if (_ap_ev_instance != NULL) { - esp_event_handler_unregister(WIFI_EVENT, ESP_EVENT_ANY_ID, &_ap_event_cb); + esp_event_handler_instance_unregister(WIFI_EVENT, ESP_EVENT_ANY_ID, _ap_ev_instance); _ap_ev_instance = NULL; } return true; diff --git a/libraries/WiFi/src/STA.cpp b/libraries/WiFi/src/STA.cpp index 547a27d1c47..2b954bbb63c 100644 --- a/libraries/WiFi/src/STA.cpp +++ b/libraries/WiFi/src/STA.cpp @@ -30,6 +30,7 @@ #include "esp_wpa2.h" #endif + esp_netif_t *get_esp_interface_netif(esp_interface_t interface); static size_t _wifi_strncpy(char *dst, const char *src, size_t dst_len) { @@ -46,15 +47,6 @@ static size_t _wifi_strncpy(char *dst, const char *src, size_t dst_len) { return src_len; } -static STAClass *_sta_network_if = NULL; - -static esp_event_handler_instance_t _sta_ev_instance = NULL; -static void _sta_event_cb(void *arg, esp_event_base_t event_base, int32_t event_id, void *event_data) { - if (event_base == WIFI_EVENT) { - ((STAClass *)arg)->_onStaEvent(event_id, event_data); - } -} - static bool _is_staReconnectableReason(uint8_t reason) { switch (reason) { case WIFI_REASON_UNSPECIFIED: @@ -102,139 +94,158 @@ static const char *auth_mode_str(int authmode) { } #endif -static void _onStaArduinoEvent(arduino_event_t *ev) { - if (_sta_network_if == NULL || ev->event_id < ARDUINO_EVENT_WIFI_STA_START || ev->event_id > ARDUINO_EVENT_WIFI_STA_LOST_IP) { +void STAClass::_onStaArduinoEvent(arduino_event_id_t event, const arduino_event_info_t *info) { + if (event < ARDUINO_EVENT_WIFI_STA_START || event > ARDUINO_EVENT_WIFI_STA_LOST_IP) { return; } static bool first_connect = true; - log_v("Arduino STA Event: %d - %s", ev->event_id, Network.eventName(ev->event_id)); + log_v("Arduino STA Event: %d - %s", event, NetworkEvents::eventName(event)); - if (ev->event_id == ARDUINO_EVENT_WIFI_STA_START) { - _sta_network_if->_setStatus(WL_DISCONNECTED); - if (esp_wifi_set_ps(WiFi.getSleep()) != ESP_OK) { - log_e("esp_wifi_set_ps failed"); - } - } else if (ev->event_id == ARDUINO_EVENT_WIFI_STA_STOP) { - _sta_network_if->_setStatus(WL_STOPPED); - } else if (ev->event_id == ARDUINO_EVENT_WIFI_STA_CONNECTED) { - _sta_network_if->_setStatus(WL_IDLE_STATUS); -#if CONFIG_LWIP_IPV6 - if (_sta_network_if->getStatusBits() & ESP_NETIF_WANT_IP6_BIT) { - esp_err_t err = esp_netif_create_ip6_linklocal(_sta_network_if->netif()); - if (err != ESP_OK) { - log_e("Failed to enable IPv6 Link Local on STA: 0x%x: %s", err, esp_err_to_name(err)); - } else { - log_v("Enabled IPv6 Link Local on %s", _sta_network_if->desc()); + switch (event){ + case ARDUINO_EVENT_WIFI_STA_START : + _setStatus(WL_DISCONNECTED); + if (esp_wifi_set_ps(WiFi.getSleep()) != ESP_OK) { + log_e("esp_wifi_set_ps failed"); } - } -#endif - } else if (ev->event_id == ARDUINO_EVENT_WIFI_STA_DISCONNECTED) { - uint8_t reason = ev->event_info.wifi_sta_disconnected.reason; - // Reason 0 causes crash, use reason 1 (UNSPECIFIED) instead - if (!reason) { - reason = WIFI_REASON_UNSPECIFIED; - } - log_w("Reason: %u - %s", reason, WiFi.STA.disconnectReasonName((wifi_err_reason_t)reason)); - if (reason == WIFI_REASON_NO_AP_FOUND) { - _sta_network_if->_setStatus(WL_NO_SSID_AVAIL); - } else if ((reason == WIFI_REASON_AUTH_FAIL) && !first_connect) { - _sta_network_if->_setStatus(WL_CONNECT_FAILED); - } else if (reason == WIFI_REASON_BEACON_TIMEOUT || reason == WIFI_REASON_HANDSHAKE_TIMEOUT) { - _sta_network_if->_setStatus(WL_CONNECTION_LOST); - } else if (reason == WIFI_REASON_AUTH_EXPIRE) { - - } else { - _sta_network_if->_setStatus(WL_DISCONNECTED); - } - - bool DoReconnect = false; - if (reason == WIFI_REASON_ASSOC_LEAVE) { //Voluntarily disconnected. Don't reconnect! - } else if (first_connect) { //Retry once for all failure reasons - first_connect = false; - DoReconnect = true; - log_d("WiFi Reconnect Running"); - } else if (_sta_network_if->getAutoReconnect() && _is_staReconnectableReason(reason)) { - DoReconnect = true; - log_d("WiFi AutoReconnect Running"); - } else if (reason == WIFI_REASON_ASSOC_FAIL) { - _sta_network_if->_setStatus(WL_CONNECT_FAILED); - } - if (DoReconnect) { - _sta_network_if->disconnect(); - _sta_network_if->connect(); - } - } else if (ev->event_id == ARDUINO_EVENT_WIFI_STA_GOT_IP) { -#if ARDUHAL_LOG_LEVEL >= ARDUHAL_LOG_LEVEL_VERBOSE - uint8_t *ip = (uint8_t *)&(ev->event_info.got_ip.ip_info.ip.addr); - uint8_t *mask = (uint8_t *)&(ev->event_info.got_ip.ip_info.netmask.addr); - uint8_t *gw = (uint8_t *)&(ev->event_info.got_ip.ip_info.gw.addr); - log_v( - "STA IP: %u.%u.%u.%u, MASK: %u.%u.%u.%u, GW: %u.%u.%u.%u", ip[0], ip[1], ip[2], ip[3], mask[0], mask[1], mask[2], mask[3], gw[0], gw[1], gw[2], gw[3] - ); -#endif - _sta_network_if->_setStatus(WL_CONNECTED); - } else if (ev->event_id == ARDUINO_EVENT_WIFI_STA_LOST_IP) { - _sta_network_if->_setStatus(WL_IDLE_STATUS); + return; + case ARDUINO_EVENT_WIFI_STA_STOP : + _setStatus(WL_STOPPED); + return; + case ARDUINO_EVENT_WIFI_STA_CONNECTED : + _setStatus(WL_IDLE_STATUS); + #if CONFIG_LWIP_IPV6 + if (getStatusBits() & ESP_NETIF_WANT_IP6_BIT) { + esp_err_t err = esp_netif_create_ip6_linklocal(netif()); + if (err != ESP_OK) { + log_e("Failed to enable IPv6 Link Local on STA: 0x%x: %s", err, esp_err_to_name(err)); + } else { + log_v("Enabled IPv6 Link Local on %s", desc()); + } + } + #endif + return; + case ARDUINO_EVENT_WIFI_STA_DISCONNECTED : { + if (!info) break; + uint8_t reason = info->wifi_sta_disconnected.reason; + // Reason 0 causes crash, use reason 1 (UNSPECIFIED) instead + if (!reason) { + reason = WIFI_REASON_UNSPECIFIED; + } + log_w("Reason: %u - %s", reason, WiFi.STA.disconnectReasonName((wifi_err_reason_t)reason)); + switch (reason){ + case WIFI_REASON_NO_AP_FOUND : + _setStatus(WL_NO_SSID_AVAIL); + break; + case WIFI_REASON_AUTH_FAIL : + if (!first_connect) + _setStatus(WL_CONNECT_FAILED); + break; + case WIFI_REASON_BEACON_TIMEOUT : + case WIFI_REASON_HANDSHAKE_TIMEOUT : + _setStatus(WL_CONNECTION_LOST); + break; + case WIFI_REASON_AUTH_EXPIRE : + break; + default: + _setStatus(WL_DISCONNECTED); + break; + } + + bool DoReconnect = false; + if (reason == WIFI_REASON_ASSOC_LEAVE) { //Voluntarily disconnected. Don't reconnect! + } else if (first_connect) { //Retry once for all failure reasons + first_connect = false; + DoReconnect = true; + log_d("WiFi Reconnect Running"); + } else if (getAutoReconnect() && _is_staReconnectableReason(reason)) { + DoReconnect = true; + log_d("WiFi AutoReconnect Running"); + } else if (reason == WIFI_REASON_ASSOC_FAIL) { + _setStatus(WL_CONNECT_FAILED); + } + if (DoReconnect) { + disconnect(); + connect(); + } + } case ARDUINO_EVENT_WIFI_STA_GOT_IP : + /* + // dublicate, similar logging is done in NetworkInterface::_onIpEvent + #if ARDUHAL_LOG_LEVEL >= ARDUHAL_LOG_LEVEL_VERBOSE + uint8_t *ip = (uint8_t *)&(ev->event_info.got_ip.ip_info.ip.addr); + uint8_t *mask = (uint8_t *)&(ev->event_info.got_ip.ip_info.netmask.addr); + uint8_t *gw = (uint8_t *)&(ev->event_info.got_ip.ip_info.gw.addr); + log_v( + "STA IP: %u.%u.%u.%u, MASK: %u.%u.%u.%u, GW: %u.%u.%u.%u", ip[0], ip[1], ip[2], ip[3], mask[0], mask[1], mask[2], mask[3], gw[0], gw[1], gw[2], gw[3] + ); + #endif + */ + _setStatus(WL_CONNECTED); + break; + case ARDUINO_EVENT_WIFI_STA_LOST_IP : + _setStatus(WL_IDLE_STATUS); + break; + + default: + return; } } void STAClass::_onStaEvent(int32_t event_id, void *event_data) { - arduino_event_t arduino_event; - arduino_event.event_id = ARDUINO_EVENT_MAX; - - if (event_id == WIFI_EVENT_STA_START) { - log_v("STA Started"); - arduino_event.event_id = ARDUINO_EVENT_WIFI_STA_START; - setStatusBits(ESP_NETIF_STARTED_BIT); - } else if (event_id == WIFI_EVENT_STA_STOP) { - log_v("STA Stopped"); - arduino_event.event_id = ARDUINO_EVENT_WIFI_STA_STOP; - clearStatusBits( - ESP_NETIF_STARTED_BIT | ESP_NETIF_CONNECTED_BIT | ESP_NETIF_HAS_IP_BIT | ESP_NETIF_HAS_LOCAL_IP6_BIT | ESP_NETIF_HAS_GLOBAL_IP6_BIT - | ESP_NETIF_HAS_STATIC_IP_BIT - ); - } else if (event_id == WIFI_EVENT_STA_AUTHMODE_CHANGE) { -#if ARDUHAL_LOG_LEVEL >= ARDUHAL_LOG_LEVEL_VERBOSE - wifi_event_sta_authmode_change_t *event = (wifi_event_sta_authmode_change_t *)event_data; - log_v("STA Auth Mode Changed: From: %s, To: %s", auth_mode_str(event->old_mode), auth_mode_str(event->new_mode)); -#endif - arduino_event.event_id = ARDUINO_EVENT_WIFI_STA_AUTHMODE_CHANGE; - memcpy(&arduino_event.event_info.wifi_sta_authmode_change, event_data, sizeof(wifi_event_sta_authmode_change_t)); - } else if (event_id == WIFI_EVENT_STA_CONNECTED) { -#if ARDUHAL_LOG_LEVEL >= ARDUHAL_LOG_LEVEL_VERBOSE - wifi_event_sta_connected_t *event = (wifi_event_sta_connected_t *)event_data; - log_v( - "STA Connected: SSID: %s, BSSID: " MACSTR ", Channel: %u, Auth: %s", event->ssid, MAC2STR(event->bssid), event->channel, auth_mode_str(event->authmode) - ); -#endif - arduino_event.event_id = ARDUINO_EVENT_WIFI_STA_CONNECTED; - memcpy(&arduino_event.event_info.wifi_sta_connected, event_data, sizeof(wifi_event_sta_connected_t)); - setStatusBits(ESP_NETIF_CONNECTED_BIT); - } else if (event_id == WIFI_EVENT_STA_DISCONNECTED) { -#if ARDUHAL_LOG_LEVEL >= ARDUHAL_LOG_LEVEL_VERBOSE - wifi_event_sta_disconnected_t *event = (wifi_event_sta_disconnected_t *)event_data; - log_v("STA Disconnected: SSID: %s, BSSID: " MACSTR ", Reason: %u", event->ssid, MAC2STR(event->bssid), event->reason); -#endif - arduino_event.event_id = ARDUINO_EVENT_WIFI_STA_DISCONNECTED; - memcpy(&arduino_event.event_info.wifi_sta_disconnected, event_data, sizeof(wifi_event_sta_disconnected_t)); - clearStatusBits(ESP_NETIF_CONNECTED_BIT | ESP_NETIF_HAS_IP_BIT | ESP_NETIF_HAS_LOCAL_IP6_BIT | ESP_NETIF_HAS_GLOBAL_IP6_BIT); - } else { - return; - } - - if (arduino_event.event_id < ARDUINO_EVENT_MAX) { - Network.postEvent(&arduino_event); + switch (event_id){ + case WIFI_EVENT_STA_START : + log_v("STA Started"); + setStatusBits(ESP_NETIF_STARTED_BIT); + Network.postEvent(ARDUINO_EVENT_WIFI_STA_START); + return; + case WIFI_EVENT_STA_STOP : + log_v("STA Stopped"); + clearStatusBits( + ESP_NETIF_STARTED_BIT | ESP_NETIF_CONNECTED_BIT | ESP_NETIF_HAS_IP_BIT | ESP_NETIF_HAS_LOCAL_IP6_BIT | ESP_NETIF_HAS_GLOBAL_IP6_BIT | ESP_NETIF_HAS_STATIC_IP_BIT + ); + Network.postEvent(ARDUINO_EVENT_WIFI_STA_STOP); + return; + case WIFI_EVENT_STA_AUTHMODE_CHANGE : { + #if ARDUHAL_LOG_LEVEL >= ARDUHAL_LOG_LEVEL_VERBOSE + wifi_event_sta_authmode_change_t *event = (wifi_event_sta_authmode_change_t *)event_data; + log_v("STA Auth Mode Changed: From: %s, To: %s", auth_mode_str(event->old_mode), auth_mode_str(event->new_mode)); + #endif + arduino_event_info_t i; + memcpy(&i.wifi_sta_authmode_change, event_data, sizeof(wifi_event_sta_authmode_change_t)); + Network.postEvent(ARDUINO_EVENT_WIFI_STA_AUTHMODE_CHANGE, &i); + return; + } + case WIFI_EVENT_STA_CONNECTED : { + #if ARDUHAL_LOG_LEVEL >= ARDUHAL_LOG_LEVEL_VERBOSE + wifi_event_sta_connected_t *event = (wifi_event_sta_connected_t *)event_data; + log_v("STA Connected: SSID: %s, BSSID: " MACSTR ", Channel: %u, Auth: %s", event->ssid, MAC2STR(event->bssid), event->channel, auth_mode_str(event->authmode)); + #endif + setStatusBits(ESP_NETIF_CONNECTED_BIT); + arduino_event_info_t i; + memcpy(&i.wifi_sta_connected, event_data, sizeof(wifi_event_sta_connected_t)); + Network.postEvent(ARDUINO_EVENT_WIFI_STA_CONNECTED, &i); + return; + } + case WIFI_EVENT_STA_DISCONNECTED : { + #if ARDUHAL_LOG_LEVEL >= ARDUHAL_LOG_LEVEL_VERBOSE + wifi_event_sta_disconnected_t *event = (wifi_event_sta_disconnected_t *)event_data; + log_v("STA Disconnected: SSID: %s, BSSID: " MACSTR ", Reason: %u", event->ssid, MAC2STR(event->bssid), event->reason); + #endif + clearStatusBits(ESP_NETIF_CONNECTED_BIT | ESP_NETIF_HAS_IP_BIT | ESP_NETIF_HAS_LOCAL_IP6_BIT | ESP_NETIF_HAS_GLOBAL_IP6_BIT); + arduino_event_info_t i; + memcpy(&i.wifi_sta_disconnected, event_data, sizeof(wifi_event_sta_disconnected_t)); + Network.postEvent(ARDUINO_EVENT_WIFI_STA_DISCONNECTED, &i); + return; + } + default:; } } STAClass::STAClass() - : _minSecurity(WIFI_AUTH_WPA2_PSK), _scanMethod(WIFI_FAST_SCAN), _sortMethod(WIFI_CONNECT_AP_BY_SIGNAL), _autoReconnect(true), _status(WL_STOPPED) { - _sta_network_if = this; -} + : _minSecurity(WIFI_AUTH_WPA2_PSK), _scanMethod(WIFI_FAST_SCAN), _sortMethod(WIFI_CONNECT_AP_BY_SIGNAL), _autoReconnect(true), _status(WL_STOPPED) {} STAClass::~STAClass() { end(); - _sta_network_if = NULL; + onDisable(); } wl_status_t STAClass::status() { @@ -265,9 +276,15 @@ bool STAClass::bandwidth(wifi_bandwidth_t bandwidth) { } bool STAClass::onEnable() { - if (_sta_ev_instance == NULL && esp_event_handler_instance_register(WIFI_EVENT, ESP_EVENT_ANY_ID, &_sta_event_cb, this, &_sta_ev_instance)) { - log_e("event_handler_instance_register for WIFI_EVENT Failed!"); - return false; + bool result{true}; + if (!_sta_ev_instance && esp_event_handler_instance_register( + WIFI_EVENT, + ESP_EVENT_ANY_ID, + [](void* self, esp_event_base_t base, int32_t id, void* data) { static_cast(self)->_onStaEvent(id, data); }, + this, + &_sta_ev_instance)) { + log_e("register for WIFI_EVENT Failed!"); + result = false; } if (_esp_netif == NULL) { _esp_netif = get_esp_interface_netif(ESP_IF_WIFI_STA); @@ -276,20 +293,22 @@ bool STAClass::onEnable() { return false; } /* attach to receive events */ - Network.onSysEvent(_onStaArduinoEvent); + if (!_evt_handle) + _evt_handle = Network.onSysEvent( [this](arduino_event_id_t e, const arduino_event_info_t *i){_onStaArduinoEvent(e, i);} ); initNetif(ESP_NETIF_ID_STA); } - return true; + return result; } bool STAClass::onDisable() { - Network.removeEvent(_onStaArduinoEvent); + Network.removeEvent(_evt_handle); + _evt_handle = 0; // we just set _esp_netif to NULL here, so destroyNetif() does not try to destroy it. // That would be done by WiFi.enableSTA(false) if AP is not enabled, or when it gets disabled _esp_netif = NULL; destroyNetif(); if (_sta_ev_instance != NULL) { - esp_event_handler_unregister(WIFI_EVENT, ESP_EVENT_ANY_ID, &_sta_event_cb); + esp_event_handler_instance_unregister(WIFI_EVENT, ESP_EVENT_ANY_ID, _sta_ev_instance); _sta_ev_instance = NULL; } return true; diff --git a/libraries/WiFi/src/WiFiAP.h b/libraries/WiFi/src/WiFiAP.h index e80f91fa26c..208af11cd2d 100644 --- a/libraries/WiFi/src/WiFiAP.h +++ b/libraries/WiFi/src/WiFiAP.h @@ -57,14 +57,23 @@ class APClass : public NetworkInterface { String SSID(void) const; uint8_t stationCount(); - void _onApEvent(int32_t event_id, void *event_data); - protected: size_t printDriverInfo(Print &out) const; friend class WiFiGenericClass; bool onEnable(); bool onDisable(); + +private: + // Arduino events + network_event_handle_t _evt_handle{0}; + // esp AP events + esp_event_handler_instance_t _ap_ev_instance{NULL}; + + // Arduino events + void _onApArduinoEvent(arduino_event_id_t event, const arduino_event_info_t *info); + // esp AP events + void _onApEvent(int32_t event_id, void *event_data); }; // ---------------------------------------------------------------------------------------------- diff --git a/libraries/WiFi/src/WiFiGeneric.cpp b/libraries/WiFi/src/WiFiGeneric.cpp index aa994963514..3c366943755 100644 --- a/libraries/WiFi/src/WiFiGeneric.cpp +++ b/libraries/WiFi/src/WiFiGeneric.cpp @@ -56,9 +56,16 @@ extern "C" { #include #include "sdkconfig.h" -ESP_EVENT_DEFINE_BASE(ARDUINO_EVENTS); - static esp_netif_t *esp_netifs[ESP_IF_MAX] = {NULL, NULL, NULL}; +// a static handle for event callback +static network_event_handle_t evt_handle{0}; +static esp_event_handler_instance_t evt_wifi_handle{nullptr}; +#if !CONFIG_ESP_WIFI_REMOTE_ENABLED +static esp_event_handler_instance_t evt_sc_handle{nullptr}; +#if CONFIG_NETWORK_PROV_NETWORK_TYPE_WIFI +static esp_event_handler_instance_t evt_nprov_handle{nullptr}; +#endif // CONFIG_NETWORK_PROV_NETWORK_TYPE_WIFI +#endif //!CONFIG_ESP_WIFI_REMOTE_ENABLED esp_netif_t *get_esp_interface_netif(esp_interface_t interface) { if (interface < ESP_IF_MAX) { @@ -68,152 +75,183 @@ esp_netif_t *get_esp_interface_netif(esp_interface_t interface) { } static void _arduino_event_cb(void *arg, esp_event_base_t event_base, int32_t event_id, void *event_data) { - arduino_event_t arduino_event; - arduino_event.event_id = ARDUINO_EVENT_MAX; - - /* - * SCAN - * */ - if (event_base == WIFI_EVENT && event_id == WIFI_EVENT_SCAN_DONE) { -#if ARDUHAL_LOG_LEVEL >= ARDUHAL_LOG_LEVEL_VERBOSE - wifi_event_sta_scan_done_t *event = (wifi_event_sta_scan_done_t *)event_data; - log_v("SCAN Done: ID: %u, Status: %u, Results: %u", event->scan_id, event->status, event->number); -#endif - arduino_event.event_id = ARDUINO_EVENT_WIFI_SCAN_DONE; - memcpy(&arduino_event.event_info.wifi_scan_done, event_data, sizeof(wifi_event_sta_scan_done_t)); - - /* - * WPS - * */ - } else if (event_base == WIFI_EVENT && event_id == WIFI_EVENT_STA_WPS_ER_SUCCESS) { - arduino_event.event_id = ARDUINO_EVENT_WPS_ER_SUCCESS; - } else if (event_base == WIFI_EVENT && event_id == WIFI_EVENT_STA_WPS_ER_FAILED) { - arduino_event.event_id = ARDUINO_EVENT_WPS_ER_FAILED; - memcpy(&arduino_event.event_info.wps_fail_reason, event_data, sizeof(wifi_event_sta_wps_fail_reason_t)); - } else if (event_base == WIFI_EVENT && event_id == WIFI_EVENT_STA_WPS_ER_TIMEOUT) { - arduino_event.event_id = ARDUINO_EVENT_WPS_ER_TIMEOUT; - } else if (event_base == WIFI_EVENT && event_id == WIFI_EVENT_STA_WPS_ER_PIN) { - arduino_event.event_id = ARDUINO_EVENT_WPS_ER_PIN; - memcpy(&arduino_event.event_info.wps_er_pin, event_data, sizeof(wifi_event_sta_wps_er_pin_t)); - } else if (event_base == WIFI_EVENT && event_id == WIFI_EVENT_STA_WPS_ER_PBC_OVERLAP) { - arduino_event.event_id = ARDUINO_EVENT_WPS_ER_PBC_OVERLAP; - - /* - * FTM - * */ - } else if (event_base == WIFI_EVENT && event_id == WIFI_EVENT_FTM_REPORT) { - arduino_event.event_id = ARDUINO_EVENT_WIFI_FTM_REPORT; - memcpy(&arduino_event.event_info.wifi_ftm_report, event_data, sizeof(wifi_event_ftm_report_t)); + if (event_base == WIFI_EVENT){ + switch (event_id){ + case WIFI_EVENT_STA_WPS_ER_SUCCESS : + Network.postEvent(ARDUINO_EVENT_WPS_ER_SUCCESS); + return; + case WIFI_EVENT_STA_WPS_ER_TIMEOUT : + Network.postEvent(ARDUINO_EVENT_WPS_ER_TIMEOUT); + return; + case WIFI_EVENT_STA_WPS_ER_PBC_OVERLAP : + Network.postEvent(ARDUINO_EVENT_WPS_ER_PBC_OVERLAP); + return; + case WIFI_EVENT_SCAN_DONE : { + #if ARDUHAL_LOG_LEVEL >= ARDUHAL_LOG_LEVEL_VERBOSE + wifi_event_sta_scan_done_t *event = (wifi_event_sta_scan_done_t *)event_data; + log_v("SCAN Done: ID: %u, Status: %u, Results: %u", event->scan_id, event->status, event->number); + #endif + arduino_event_info_t i; + memcpy(&i.wifi_scan_done, event_data, sizeof(wifi_event_sta_scan_done_t)); + Network.postEvent(ARDUINO_EVENT_WIFI_SCAN_DONE, &i); + return; + } + case WIFI_EVENT_STA_WPS_ER_FAILED : { + arduino_event_info_t i; + memcpy(&i.wps_fail_reason, event_data, sizeof(wifi_event_sta_wps_fail_reason_t)); + Network.postEvent(ARDUINO_EVENT_WPS_ER_FAILED, &i); + return; + } + case WIFI_EVENT_STA_WPS_ER_PIN : { + arduino_event_info_t i; + memcpy(&i.wps_fail_reason, event_data, sizeof(wifi_event_sta_wps_er_pin_t)); + Network.postEvent(ARDUINO_EVENT_WPS_ER_PIN, &i); + return; + } + case WIFI_EVENT_FTM_REPORT : { + arduino_event_info_t i; + memcpy(&i.wifi_ftm_report, event_data, sizeof(wifi_event_ftm_report_t)); + Network.postEvent(ARDUINO_EVENT_WIFI_FTM_REPORT, &i); + return; + } + default: + return; + } + } #if !CONFIG_ESP_WIFI_REMOTE_ENABLED - /* - * SMART CONFIG - * */ - } else if (event_base == SC_EVENT && event_id == SC_EVENT_SCAN_DONE) { - log_v("SC Scan Done"); - arduino_event.event_id = ARDUINO_EVENT_SC_SCAN_DONE; - } else if (event_base == SC_EVENT && event_id == SC_EVENT_FOUND_CHANNEL) { - log_v("SC Found Channel"); - arduino_event.event_id = ARDUINO_EVENT_SC_FOUND_CHANNEL; - } else if (event_base == SC_EVENT && event_id == SC_EVENT_GOT_SSID_PSWD) { -#if ARDUHAL_LOG_LEVEL >= ARDUHAL_LOG_LEVEL_VERBOSE - smartconfig_event_got_ssid_pswd_t *event = (smartconfig_event_got_ssid_pswd_t *)event_data; - log_v("SC: SSID: %s, Password: %s", (const char *)event->ssid, (const char *)event->password); -#endif - arduino_event.event_id = ARDUINO_EVENT_SC_GOT_SSID_PSWD; - memcpy(&arduino_event.event_info.sc_got_ssid_pswd, event_data, sizeof(smartconfig_event_got_ssid_pswd_t)); - - } else if (event_base == SC_EVENT && event_id == SC_EVENT_SEND_ACK_DONE) { - log_v("SC Send Ack Done"); - arduino_event.event_id = ARDUINO_EVENT_SC_SEND_ACK_DONE; + if (event_base == SC_EVENT){ + switch (event_id){ + case SC_EVENT_SCAN_DONE : + log_v("SC Scan Done"); + Network.postEvent(ARDUINO_EVENT_SC_SCAN_DONE); + return; + case SC_EVENT_FOUND_CHANNEL : + log_v("SC Found Channel"); + Network.postEvent(ARDUINO_EVENT_SC_FOUND_CHANNEL); + return; + case SC_EVENT_GOT_SSID_PSWD : { + #if ARDUHAL_LOG_LEVEL >= ARDUHAL_LOG_LEVEL_VERBOSE + smartconfig_event_got_ssid_pswd_t *event = (smartconfig_event_got_ssid_pswd_t *)event_data; + log_v("SC: SSID: %s, Password: %s", (const char *)event->ssid, (const char *)event->password); + #endif + arduino_event_info_t i; + memcpy(&i.sc_got_ssid_pswd, event_data, sizeof(smartconfig_event_got_ssid_pswd_t)); + Network.postEvent(ARDUINO_EVENT_SC_GOT_SSID_PSWD, &i); + return; + } + case SC_EVENT_SEND_ACK_DONE : + log_v("SC Send Ack Done"); + Network.postEvent(ARDUINO_EVENT_SC_SEND_ACK_DONE); + return; + default: + return; + } + } #if CONFIG_NETWORK_PROV_NETWORK_TYPE_WIFI - /* + /* * Provisioning - * */ - } else if (event_base == NETWORK_PROV_EVENT && event_id == NETWORK_PROV_INIT) { - log_v("Provisioning Initialized!"); - arduino_event.event_id = ARDUINO_EVENT_PROV_INIT; - } else if (event_base == NETWORK_PROV_EVENT && event_id == NETWORK_PROV_DEINIT) { - log_v("Provisioning Uninitialized!"); - arduino_event.event_id = ARDUINO_EVENT_PROV_DEINIT; - } else if (event_base == NETWORK_PROV_EVENT && event_id == NETWORK_PROV_START) { - log_v("Provisioning Start!"); - arduino_event.event_id = ARDUINO_EVENT_PROV_START; - } else if (event_base == NETWORK_PROV_EVENT && event_id == NETWORK_PROV_END) { - log_v("Provisioning End!"); - network_prov_mgr_deinit(); - arduino_event.event_id = ARDUINO_EVENT_PROV_END; - } else if (event_base == NETWORK_PROV_EVENT && event_id == NETWORK_PROV_WIFI_CRED_RECV) { -#if ARDUHAL_LOG_LEVEL >= ARDUHAL_LOG_LEVEL_VERBOSE - wifi_sta_config_t *event = (wifi_sta_config_t *)event_data; - log_v("Provisioned Credentials: SSID: %s, Password: %s", (const char *)event->ssid, (const char *)event->password); -#endif - arduino_event.event_id = ARDUINO_EVENT_PROV_CRED_RECV; - memcpy(&arduino_event.event_info.prov_cred_recv, event_data, sizeof(wifi_sta_config_t)); - } else if (event_base == NETWORK_PROV_EVENT && event_id == NETWORK_PROV_WIFI_CRED_FAIL) { -#if ARDUHAL_LOG_LEVEL >= ARDUHAL_LOG_LEVEL_ERROR - network_prov_wifi_sta_fail_reason_t *reason = (network_prov_wifi_sta_fail_reason_t *)event_data; - log_e("Provisioning Failed: Reason : %s", (*reason == NETWORK_PROV_WIFI_STA_AUTH_ERROR) ? "Authentication Failed" : "AP Not Found"); -#endif - arduino_event.event_id = ARDUINO_EVENT_PROV_CRED_FAIL; - memcpy(&arduino_event.event_info.prov_fail_reason, event_data, sizeof(network_prov_wifi_sta_fail_reason_t)); - } else if (event_base == NETWORK_PROV_EVENT && event_id == NETWORK_PROV_WIFI_CRED_SUCCESS) { - log_v("Provisioning Success!"); - arduino_event.event_id = ARDUINO_EVENT_PROV_CRED_SUCCESS; -#endif -#endif - } - - if (arduino_event.event_id < ARDUINO_EVENT_MAX) { - Network.postEvent(&arduino_event); + */ + if (event_base == NETWORK_PROV_EVENT){ + switch (event_id){ + case NETWORK_PROV_INIT : + log_v("Provisioning Initialized!"); + Network.postEvent(ARDUINO_EVENT_PROV_INIT); + return; + case NETWORK_PROV_DEINIT : + log_v("Provisioning Uninitialized!"); + Network.postEvent(ARDUINO_EVENT_PROV_DEINIT); + return; + case NETWORK_PROV_START : + log_v("Provisioning Start!"); + Network.postEvent(ARDUINO_EVENT_PROV_START); + return; + case NETWORK_PROV_END : + log_v("Provisioning End!"); + network_prov_mgr_deinit(); + Network.postEvent(ARDUINO_EVENT_PROV_END); + return; + case NETWORK_PROV_WIFI_CRED_RECV : { + #if ARDUHAL_LOG_LEVEL >= ARDUHAL_LOG_LEVEL_VERBOSE + wifi_sta_config_t *event = (wifi_sta_config_t *)event_data; + log_v("Provisioned Credentials: SSID: %s, Password: %s", (const char *)event->ssid, (const char *)event->password); + #endif + arduino_event_info_t i; + memcpy(&i.prov_cred_recv, event_data, sizeof(wifi_sta_config_t)); + Network.postEvent(ARDUINO_EVENT_PROV_CRED_RECV, &i); + return; + } + case NETWORK_PROV_WIFI_CRED_FAIL : { + #if ARDUHAL_LOG_LEVEL >= ARDUHAL_LOG_LEVEL_ERROR + network_prov_wifi_sta_fail_reason_t *reason = (network_prov_wifi_sta_fail_reason_t *)event_data; + log_e("Provisioning Failed: Reason : %s", (*reason == NETWORK_PROV_WIFI_STA_AUTH_ERROR) ? "Authentication Failed" : "AP Not Found"); + #endif + arduino_event_info_t i; + memcpy(&i.prov_fail_reason, event_data, sizeof(network_prov_wifi_sta_fail_reason_t)); + Network.postEvent(ARDUINO_EVENT_PROV_CRED_FAIL, &i); + return; + } + case NETWORK_PROV_WIFI_CRED_SUCCESS : + log_v("Provisioning Success!"); + Network.postEvent(ARDUINO_EVENT_PROV_CRED_SUCCESS); + return; + default: + return; + } } +#endif // CONFIG_NETWORK_PROV_NETWORK_TYPE_WIFI +#endif //!CONFIG_ESP_WIFI_REMOTE_ENABLED } static bool initWiFiEvents() { - if (esp_event_handler_instance_register(WIFI_EVENT, ESP_EVENT_ANY_ID, &_arduino_event_cb, NULL, NULL)) { - log_e("event_handler_instance_register for WIFI_EVENT Failed!"); - return false; + bool result{true}; + + if (!evt_wifi_handle && esp_event_handler_instance_register(WIFI_EVENT, ESP_EVENT_ANY_ID, &_arduino_event_cb, NULL, &evt_wifi_handle)) { + log_e("register for WIFI_EVENT Failed!"); + result = false; } #if !CONFIG_ESP_WIFI_REMOTE_ENABLED - if (esp_event_handler_instance_register(SC_EVENT, ESP_EVENT_ANY_ID, &_arduino_event_cb, NULL, NULL)) { - log_e("event_handler_instance_register for SC_EVENT Failed!"); - return false; + if (!evt_sc_handle && esp_event_handler_instance_register(SC_EVENT, ESP_EVENT_ANY_ID, &_arduino_event_cb, NULL, &evt_sc_handle)) { + log_e("register for SC_EVENT Failed!"); + result = false; } #if CONFIG_NETWORK_PROV_NETWORK_TYPE_WIFI - if (esp_event_handler_instance_register(NETWORK_PROV_EVENT, ESP_EVENT_ANY_ID, &_arduino_event_cb, NULL, NULL)) { - log_e("event_handler_instance_register for NETWORK_PROV_EVENT Failed!"); - return false; + if (!evt_nprov_handle && esp_event_handler_instance_register(NETWORK_PROV_EVENT, ESP_EVENT_ANY_ID, &_arduino_event_cb, NULL, &evt_nprov_handle)) { + log_e("register for NETWORK_PROV_EVENT Failed!"); + result = false; } #endif #endif - return true; + return result; } static bool deinitWiFiEvents() { - if (esp_event_handler_unregister(WIFI_EVENT, ESP_EVENT_ANY_ID, &_arduino_event_cb)) { - log_e("esp_event_handler_unregister for WIFI_EVENT Failed!"); - return false; + bool result{true}; + + if (evt_wifi_handle && esp_event_handler_instance_unregister(WIFI_EVENT, ESP_EVENT_ANY_ID, evt_wifi_handle)) { + log_e("unregister for WIFI_EVENT Failed!"); + result = false; } #if !CONFIG_ESP_WIFI_REMOTE_ENABLED - if (esp_event_handler_unregister(SC_EVENT, ESP_EVENT_ANY_ID, &_arduino_event_cb)) { - log_e("esp_event_handler_unregister for SC_EVENT Failed!"); - return false; + if (evt_sc_handle && esp_event_handler_instance_unregister(SC_EVENT, ESP_EVENT_ANY_ID, evt_sc_handle)) { + log_e("unregister for SC_EVENT Failed!"); + result = false; } #if CONFIG_NETWORK_PROV_NETWORK_TYPE_WIFI - if (esp_event_handler_unregister(NETWORK_PROV_EVENT, ESP_EVENT_ANY_ID, &_arduino_event_cb)) { - log_e("esp_event_handler_unregister for NETWORK_PROV_EVENT Failed!"); - return false; + if (evt_nprov_handle && esp_event_handler_instance_unregister(NETWORK_PROV_EVENT, ESP_EVENT_ANY_ID, evt_nprov_handle)) { + log_e("unregister for NETWORK_PROV_EVENT Failed!"); + result = false; } #endif #endif - return true; + return result; } /* @@ -350,9 +388,7 @@ static bool wifiLowLevelDeinit() { } lowLevelInitDone = !(esp_wifi_deinit() == ESP_OK); if (!lowLevelInitDone) { - arduino_event_t arduino_event; - arduino_event.event_id = ARDUINO_EVENT_WIFI_OFF; - Network.postEvent(&arduino_event); + Network.postEvent(ARDUINO_EVENT_WIFI_OFF); #if CONFIG_ESP_WIFI_REMOTE_ENABLED if (hosted_initialized && esp_hosted_deinit() == ESP_OK) { hosted_initialized = false; @@ -411,12 +447,13 @@ wifi_ps_type_t WiFiGenericClass::_sleepEnabled = WIFI_PS_MIN_MODEM; WiFiGenericClass::WiFiGenericClass() {} -const char *WiFiGenericClass::disconnectReasonName(wifi_err_reason_t reason) { - return WiFi.STA.disconnectReasonName(reason); +WiFiGenericClass::~WiFiGenericClass(){ + Network.removeEvent(evt_handle); + evt_handle = 0; } -const char *WiFiGenericClass::eventName(arduino_event_id_t id) { - return Network.eventName(id); +const char *WiFiGenericClass::disconnectReasonName(wifi_err_reason_t reason) { + return WiFi.STA.disconnectReasonName(reason); } const char *WiFiGenericClass::getHostname() { @@ -431,25 +468,22 @@ bool WiFiGenericClass::setHostname(const char *hostname) { * callback for WiFi events * @param arg */ -void WiFiGenericClass::_eventCallback(arduino_event_t *event) { - if (!event) { - return; //Null would crash this function - } - +void WiFiGenericClass::_eventCallback(arduino_event_id_t event, const arduino_event_info_t *info) { // log_d("Arduino Event: %d - %s", event->event_id, WiFi.eventName(event->event_id)); - if (event->event_id == ARDUINO_EVENT_WIFI_SCAN_DONE) { + if (event == ARDUINO_EVENT_WIFI_SCAN_DONE) { WiFiScanClass::_scanDone(); + } #if !CONFIG_ESP_WIFI_REMOTE_ENABLED - } else if (event->event_id == ARDUINO_EVENT_SC_GOT_SSID_PSWD) { + else if (event == ARDUINO_EVENT_SC_GOT_SSID_PSWD && info) { WiFi.begin( - (const char *)event->event_info.sc_got_ssid_pswd.ssid, (const char *)event->event_info.sc_got_ssid_pswd.password, 0, - ((event->event_info.sc_got_ssid_pswd.bssid_set == true) ? event->event_info.sc_got_ssid_pswd.bssid : NULL) + (const char *)info->sc_got_ssid_pswd.ssid, (const char *)info->sc_got_ssid_pswd.password, 0, + ((info->sc_got_ssid_pswd.bssid_set == true) ? info->sc_got_ssid_pswd.bssid : NULL) ); - } else if (event->event_id == ARDUINO_EVENT_SC_SEND_ACK_DONE) { + } else if (event == ARDUINO_EVENT_SC_SEND_ACK_DONE) { esp_smartconfig_stop(); WiFiSTAClass::_smartConfigDone = true; -#endif } +#endif } /** @@ -529,7 +563,8 @@ bool WiFiGenericClass::mode(wifi_mode_t m) { if (!wifiLowLevelInit(_persistent)) { return false; } - Network.onSysEvent(_eventCallback); + if (!evt_handle) + evt_handle = Network.onSysEvent(_eventCallback); } if (((m & WIFI_MODE_STA) != 0) && ((cm & WIFI_MODE_STA) == 0)) { @@ -554,7 +589,8 @@ bool WiFiGenericClass::mode(wifi_mode_t m) { // we are disabling AP interface WiFi.AP.onDisable(); } - Network.removeEvent(_eventCallback); + Network.removeEvent(evt_handle); + evt_handle = 0; return true; } diff --git a/libraries/WiFi/src/WiFiGeneric.h b/libraries/WiFi/src/WiFiGeneric.h index ed216229ed4..ba5681b1013 100644 --- a/libraries/WiFi/src/WiFiGeneric.h +++ b/libraries/WiFi/src/WiFiGeneric.h @@ -81,12 +81,13 @@ typedef enum { class WiFiGenericClass { public: WiFiGenericClass(); + virtual ~WiFiGenericClass(); - wifi_event_id_t onEvent(WiFiEventCb cbEvent, arduino_event_id_t event = ARDUINO_EVENT_MAX); - wifi_event_id_t onEvent(WiFiEventFuncCb cbEvent, arduino_event_id_t event = ARDUINO_EVENT_MAX); - wifi_event_id_t onEvent(WiFiEventSysCb cbEvent, arduino_event_id_t event = ARDUINO_EVENT_MAX); - void removeEvent(WiFiEventCb cbEvent, arduino_event_id_t event = ARDUINO_EVENT_MAX); - void removeEvent(WiFiEventSysCb cbEvent, arduino_event_id_t event = ARDUINO_EVENT_MAX); + wifi_event_id_t onEvent(WiFiEventCb cbEvent, arduino_event_id_t event = ARDUINO_EVENT_ANY); + wifi_event_id_t onEvent(WiFiEventFuncCb cbEvent, arduino_event_id_t event = ARDUINO_EVENT_ANY); + wifi_event_id_t onEvent(WiFiEventSysCb cbEvent, arduino_event_id_t event = ARDUINO_EVENT_ANY); + void removeEvent(WiFiEventCb cbEvent, arduino_event_id_t event = ARDUINO_EVENT_ANY); + void removeEvent(WiFiEventSysCb cbEvent, arduino_event_id_t event = ARDUINO_EVENT_ANY); void removeEvent(wifi_event_id_t id); static int getStatusBits(); @@ -131,9 +132,8 @@ class WiFiGenericClass { static uint8_t calculateSubnetCIDR(IPAddress subnetMask); const char *disconnectReasonName(wifi_err_reason_t reason); - const char *eventName(arduino_event_id_t id); + static const char *eventName(arduino_event_id_t id){ return NetworkEvents::eventName(id); }; - static void _eventCallback(arduino_event_t *event); protected: static bool _persistent; @@ -145,6 +145,8 @@ class WiFiGenericClass { static int setStatusBits(int bits); static int clearStatusBits(int bits); + static void _eventCallback(arduino_event_id_t event, const arduino_event_info_t *info); + friend class WiFiSTAClass; friend class WiFiScanClass; friend class WiFiAPClass; diff --git a/libraries/WiFi/src/WiFiSTA.h b/libraries/WiFi/src/WiFiSTA.h index 3c8adbd8502..0c8a6b93274 100644 --- a/libraries/WiFi/src/WiFiSTA.h +++ b/libraries/WiFi/src/WiFiSTA.h @@ -85,9 +85,6 @@ class STAClass : public NetworkInterface { const char *disconnectReasonName(wifi_err_reason_t reason); - // Private Use - void _setStatus(wl_status_t status); - void _onStaEvent(int32_t event_id, void *event_data); protected: wifi_auth_mode_t _minSecurity; @@ -101,6 +98,13 @@ class STAClass : public NetworkInterface { friend class WiFiGenericClass; bool onEnable(); bool onDisable(); + +private: + esp_event_handler_instance_t _sta_ev_instance{NULL}; + network_event_handle_t _evt_handle{0}; + void _onStaArduinoEvent(arduino_event_id_t event, const arduino_event_info_t *info); + void _setStatus(wl_status_t status); + void _onStaEvent(int32_t event_id, void *event_data); }; // ----------------------------------------------------------------------------------------------