Skip to content

Commit

Permalink
refactor(NetworkEvents) code polishing and comments
Browse files Browse the repository at this point in the history
- rename NetworkEvents::cbEventList as private member NetworkEvents_cbEventList
- NetworkEvents::getStatusBits() add const qualifier
- turn statics into constexpr
- add indexes to enum::arduino_event_id_t to make events indexing consistent for SOCs with/without WiFi
  also leave some index gaps to minimize renumbering on adding new events
- add doxygen help to NetworkEvents:: methods
- declare NetworkEvents::eventName() as static, that could be used without creating class scope
- potential mem leak in postEvent
  • Loading branch information
vortigont committed Sep 26, 2024
1 parent c8a0c49 commit 06bf619
Show file tree
Hide file tree
Showing 2 changed files with 128 additions and 40 deletions.
48 changes: 25 additions & 23 deletions libraries/Network/src/NetworkEvents.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@
#include "esp_task.h"
#include "esp32-hal.h"


NetworkEvents::NetworkEvents() : _arduino_event_group(NULL), _arduino_event_queue(NULL), _arduino_event_task_handle(NULL) {}

NetworkEvents::~NetworkEvents() {
Expand All @@ -22,8 +21,9 @@ NetworkEvents::~NetworkEvents() {
}
if (_arduino_event_queue != NULL) {
arduino_event_t *event = NULL;
// consume queue
while (xQueueReceive(_arduino_event_queue, &event, 0) == pdTRUE) {
free(event);
delete event;
}
vQueueDelete(_arduino_event_queue);
_arduino_event_queue = NULL;
Expand Down Expand Up @@ -73,18 +73,20 @@ bool NetworkEvents::initNetworkEvents() {
return true;
}

bool NetworkEvents::postEvent(arduino_event_t *data) {
bool NetworkEvents::postEvent(const arduino_event_t *data) {
if (data == NULL || _arduino_event_queue == NULL) {
return false;
}
arduino_event_t *event = (arduino_event_t *)malloc(sizeof(arduino_event_t));
arduino_event_t *event = new arduino_event_t();
if (event == NULL) {
log_e("Arduino Event Malloc Failed!");
return false;
}

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;
Expand All @@ -110,7 +112,7 @@ void NetworkEvents::_checkForEvent() {
log_v("Network Event: %d - %s", event->event_id, eventName(event->event_id));

// iterate over registered callbacks
for (auto &i : cbEventList){
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) {
Expand All @@ -129,7 +131,7 @@ void NetworkEvents::_checkForEvent() {
}

// release the event object's memory
free(event);
delete event;
}

vTaskDelete(NULL);
Expand All @@ -149,81 +151,81 @@ network_event_handle_t NetworkEvents::onEvent(NetworkEventCb cbEvent, arduino_ev
return 0;
}

cbEventList.emplace_back(++_current_id, cbEvent, nullptr, nullptr, event);
return cbEventList.back().id;
_cbEventList.emplace_back(++_current_id, cbEvent, nullptr, nullptr, event);
return _cbEventList.back().id;
}

network_event_handle_t NetworkEvents::onEvent(NetworkEventFuncCb cbEvent, arduino_event_id_t event) {
if (!cbEvent) {
return 0;
}

cbEventList.emplace_back(++_current_id, nullptr, cbEvent, nullptr, event);
return cbEventList.back().id;
_cbEventList.emplace_back(++_current_id, nullptr, cbEvent, nullptr, event);
return _cbEventList.back().id;
}

network_event_handle_t NetworkEvents::onEvent(NetworkEventSysCb cbEvent, arduino_event_id_t event) {
if (!cbEvent) {
return 0;
}

cbEventList.emplace_back(++_current_id, nullptr, nullptr, cbEvent, event);
return cbEventList.back().id;
_cbEventList.emplace_back(++_current_id, nullptr, nullptr, cbEvent, event);
return _cbEventList.back().id;
}

network_event_handle_t NetworkEvents::onSysEvent(NetworkEventCb cbEvent, arduino_event_id_t event) {
if (!cbEvent) {
return 0;
}

cbEventList.emplace(cbEventList.begin(), ++_current_id, cbEvent, nullptr, nullptr, event);
return cbEventList.front().id;
_cbEventList.emplace(_cbEventList.begin(), ++_current_id, cbEvent, nullptr, nullptr, event);
return _cbEventList.front().id;
}

network_event_handle_t NetworkEvents::onSysEvent(NetworkEventFuncCb cbEvent, arduino_event_id_t event) {
if (!cbEvent) {
return 0;
}

cbEventList.emplace(cbEventList.begin(), ++_current_id, nullptr, cbEvent, nullptr, event);
return cbEventList.front().id;
_cbEventList.emplace(_cbEventList.begin(), ++_current_id, nullptr, cbEvent, nullptr, event);
return _cbEventList.front().id;
}

network_event_handle_t NetworkEvents::onSysEvent(NetworkEventSysCb cbEvent, arduino_event_id_t event) {
if (!cbEvent) {
return 0;
}

cbEventList.emplace(cbEventList.begin(), ++_current_id, nullptr, nullptr, cbEvent, event);
return cbEventList.front().id;
_cbEventList.emplace(_cbEventList.begin(), ++_current_id, nullptr, nullptr, cbEvent, event);
return _cbEventList.front().id;
}

void NetworkEvents::removeEvent(NetworkEventCb cbEvent, arduino_event_id_t event) {
if (!cbEvent) {
return;
}

cbEventList.erase(std::remove_if(cbEventList.begin(), cbEventList.end(), [cbEvent, event](const NetworkEventCbList_t& e) { return e.cb == cbEvent && e.event == event; }), cbEventList.end());
_cbEventList.erase(std::remove_if(_cbEventList.begin(), _cbEventList.end(), [cbEvent, event](const NetworkEventCbList_t& e) { return e.cb == cbEvent && e.event == event; }), _cbEventList.end());
}

void NetworkEvents::removeEvent(NetworkEventFuncCb cbEvent, arduino_event_id_t event) {
if (!cbEvent) {
return;
}

cbEventList.erase(std::remove_if(cbEventList.begin(), cbEventList.end(), [cbEvent, event](const NetworkEventCbList_t& e) { return getStdFunctionAddress(e.fcb) == getStdFunctionAddress(cbEvent) && e.event == event; }), cbEventList.end());
_cbEventList.erase(std::remove_if(_cbEventList.begin(), _cbEventList.end(), [cbEvent, event](const NetworkEventCbList_t& e) { return getStdFunctionAddress(e.fcb) == getStdFunctionAddress(cbEvent) && e.event == event; }), _cbEventList.end());
}

void NetworkEvents::removeEvent(NetworkEventSysCb cbEvent, arduino_event_id_t event) {
if (!cbEvent) {
return;
}

cbEventList.erase(std::remove_if(cbEventList.begin(), cbEventList.end(), [cbEvent, event](const NetworkEventCbList_t& e) { return e.scb == cbEvent && e.event == event; }), cbEventList.end());
_cbEventList.erase(std::remove_if(_cbEventList.begin(), _cbEventList.end(), [cbEvent, event](const NetworkEventCbList_t& e) { return e.scb == cbEvent && e.event == event; }), _cbEventList.end());
}

void NetworkEvents::removeEvent(network_event_handle_t id) {
cbEventList.erase(std::remove_if(cbEventList.begin(), cbEventList.end(), [id](const NetworkEventCbList_t& e) { return e.id == id; }), cbEventList.end());
_cbEventList.erase(std::remove_if(_cbEventList.begin(), _cbEventList.end(), [id](const NetworkEventCbList_t& e) { return e.id == id; }), _cbEventList.end());
}

int NetworkEvents::setStatusBits(int bits) {
Expand All @@ -242,7 +244,7 @@ int NetworkEvents::clearStatusBits(int bits) {
return xEventGroupClearBits(_arduino_event_group, bits);
}

int NetworkEvents::getStatusBits() {
int NetworkEvents::getStatusBits() const {
if (!_arduino_event_group) {
return _initial_bits;
}
Expand Down
120 changes: 103 additions & 17 deletions libraries/Network/src/NetworkEvents.h
Original file line number Diff line number Diff line change
Expand Up @@ -24,16 +24,16 @@
#endif

#if SOC_WIFI_SUPPORTED
static const int WIFI_SCANNING_BIT = BIT0;
static const int WIFI_SCAN_DONE_BIT = BIT1;
constexpr int WIFI_SCANNING_BIT = BIT0;
constexpr int WIFI_SCAN_DONE_BIT = BIT1;
#endif

#define NET_HAS_IP6_GLOBAL_BIT 0

ESP_EVENT_DECLARE_BASE(ARDUINO_EVENTS);

typedef enum {
ARDUINO_EVENT_NONE,
ARDUINO_EVENT_NONE = 0,
ARDUINO_EVENT_ETH_START,
ARDUINO_EVENT_ETH_STOP,
ARDUINO_EVENT_ETH_CONNECTED,
Expand All @@ -42,43 +42,43 @@ typedef enum {
ARDUINO_EVENT_ETH_LOST_IP,
ARDUINO_EVENT_ETH_GOT_IP6,
#if SOC_WIFI_SUPPORTED
ARDUINO_EVENT_WIFI_OFF,
ARDUINO_EVENT_WIFI_OFF = 100,
ARDUINO_EVENT_WIFI_READY,
ARDUINO_EVENT_WIFI_SCAN_DONE,
ARDUINO_EVENT_WIFI_STA_START,
ARDUINO_EVENT_WIFI_FTM_REPORT,
ARDUINO_EVENT_WIFI_STA_START = 110,
ARDUINO_EVENT_WIFI_STA_STOP,
ARDUINO_EVENT_WIFI_STA_CONNECTED,
ARDUINO_EVENT_WIFI_STA_DISCONNECTED,
ARDUINO_EVENT_WIFI_STA_AUTHMODE_CHANGE,
ARDUINO_EVENT_WIFI_STA_GOT_IP,
ARDUINO_EVENT_WIFI_STA_GOT_IP6,
ARDUINO_EVENT_WIFI_STA_LOST_IP,
ARDUINO_EVENT_WIFI_AP_START,
ARDUINO_EVENT_WIFI_AP_START = 130,
ARDUINO_EVENT_WIFI_AP_STOP,
ARDUINO_EVENT_WIFI_AP_STACONNECTED,
ARDUINO_EVENT_WIFI_AP_STADISCONNECTED,
ARDUINO_EVENT_WIFI_AP_STAIPASSIGNED,
ARDUINO_EVENT_WIFI_AP_PROBEREQRECVED,
ARDUINO_EVENT_WIFI_AP_GOT_IP6,
ARDUINO_EVENT_WIFI_FTM_REPORT,
ARDUINO_EVENT_WPS_ER_SUCCESS,
ARDUINO_EVENT_WPS_ER_SUCCESS = 140,
ARDUINO_EVENT_WPS_ER_FAILED,
ARDUINO_EVENT_WPS_ER_TIMEOUT,
ARDUINO_EVENT_WPS_ER_PIN,
ARDUINO_EVENT_WPS_ER_PBC_OVERLAP,
ARDUINO_EVENT_SC_SCAN_DONE,
ARDUINO_EVENT_SC_SCAN_DONE = 150,
ARDUINO_EVENT_SC_FOUND_CHANNEL,
ARDUINO_EVENT_SC_GOT_SSID_PSWD,
ARDUINO_EVENT_SC_SEND_ACK_DONE,
ARDUINO_EVENT_PROV_INIT,
ARDUINO_EVENT_PROV_INIT = 160,
ARDUINO_EVENT_PROV_DEINIT,
ARDUINO_EVENT_PROV_START,
ARDUINO_EVENT_PROV_END,
ARDUINO_EVENT_PROV_CRED_RECV,
ARDUINO_EVENT_PROV_CRED_FAIL,
ARDUINO_EVENT_PROV_CRED_SUCCESS,
#endif
ARDUINO_EVENT_PPP_START,
ARDUINO_EVENT_PPP_START = 200,
ARDUINO_EVENT_PPP_STOP,
ARDUINO_EVENT_PPP_CONNECTED,
ARDUINO_EVENT_PPP_DISCONNECTED,
Expand Down Expand Up @@ -125,24 +125,107 @@ using NetworkEventFuncCb = std::function<void(arduino_event_id_t event, arduino_
using NetworkEventSysCb = void(*)(arduino_event_t *event);
using network_event_handle_t = size_t;

/**
* @brief Class that provides network events callback handling
* it registers user callback functions for event handling,
* maintans the queue of events and propagates the event amoung subscribed callbacks
* callback are called in the context of a dedicated task consuming the queue
*
*/
class NetworkEvents {
public:
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 static callback function
* @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);

/**
* @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 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);

/**
* @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);

/**
* @brief unregister static function callback
* @note a better way to unregister callbacks is to save/unregister via network_event_handle_t
*
* @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(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 event_handle) instead")));

/**
* @brief unregister functional callback
* @note a better way to unregister callbacks is to save/unregister via network_event_handle_t
* @note this does not work for lambda's! Do unregister via network_event_handle_t
*
* @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")));

/**
* @brief unregister static system function callback
* @note a better way to unregister callbacks is to save/unregister via network_event_handle_t
*
* @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);

/**
* @brief unregister event callback via handler
*
* @param cbEvent static callback function
* @param event event to process, any event by default
*/
void removeEvent(network_event_handle_t event_handle);

const char *eventName(arduino_event_id_t id);
/**
* @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);

bool postEvent(arduino_event_t *event);
/**
* @brief post an event to the queue
* and propagade and event 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
* @return true if event was queued susccessfuly
* @return false on memrory allocation error or queue is full
*/
bool postEvent(const arduino_event_t *event);

int getStatusBits();
int getStatusBits() const;
int waitStatusBits(int bits, uint32_t timeout_ms);
int setStatusBits(int bits);
int clearStatusBits(int bits);
Expand All @@ -158,8 +241,11 @@ class NetworkEvents {

protected:
bool initNetworkEvents();
// same as onEvent() but places newly added handler at the begining of registered events list
network_event_handle_t onSysEvent(NetworkEventCb cbEvent, arduino_event_id_t event = ARDUINO_EVENT_MAX);
// same as onEvent() but places newly added handler at the begining of registered events list
network_event_handle_t onSysEvent(NetworkEventFuncCb cbEvent, arduino_event_id_t event = ARDUINO_EVENT_MAX);
// same as onEvent() but places newly added handler at the begining of registered events list
network_event_handle_t onSysEvent(NetworkEventSysCb cbEvent, arduino_event_id_t event = ARDUINO_EVENT_MAX);

private:
Expand Down Expand Up @@ -189,10 +275,10 @@ class NetworkEvents {
TaskHandle_t _arduino_event_task_handle;

// registred events callbacks containter
std::vector<NetworkEventCbList_t> cbEventList;
std::vector<NetworkEventCbList_t> _cbEventList;

/**
* @brief task that picks events from a event queue and calls registered callbacks
* @brief task function that picks events from an event queue and calls registered callbacks
*
*/
void _checkForEvent();
Expand Down

0 comments on commit 06bf619

Please sign in to comment.