Skip to content

Commit 63a2641

Browse files
committed
refactor STAClass events handling
- make event handlers and callbacks as class members, remove static pointer to class instance - replace legacy esp_event_handler_unregister() with instance/hamdler via esp_event_handler_instance_unregister() - replace a bunch of if's with switch/case for better readability - removed mandatory struct arduino_event_t when sending arduino events, use post(event_id,*data)
1 parent 3fa0131 commit 63a2641

File tree

2 files changed

+157
-141
lines changed

2 files changed

+157
-141
lines changed

Diff for: libraries/WiFi/src/STA.cpp

+150-138
Original file line numberDiff line numberDiff line change
@@ -30,8 +30,6 @@
3030
#include "esp_wpa2.h"
3131
#endif
3232

33-
// a static handle for event callback
34-
static network_event_handle_t evt_handle{0};
3533

3634
esp_netif_t *get_esp_interface_netif(esp_interface_t interface);
3735

@@ -49,15 +47,6 @@ static size_t _wifi_strncpy(char *dst, const char *src, size_t dst_len) {
4947
return src_len;
5048
}
5149

52-
static STAClass *_sta_network_if = NULL;
53-
54-
static esp_event_handler_instance_t _sta_ev_instance = NULL;
55-
static void _sta_event_cb(void *arg, esp_event_base_t event_base, int32_t event_id, void *event_data) {
56-
if (event_base == WIFI_EVENT) {
57-
((STAClass *)arg)->_onStaEvent(event_id, event_data);
58-
}
59-
}
60-
6150
static bool _is_staReconnectableReason(uint8_t reason) {
6251
switch (reason) {
6352
case WIFI_REASON_UNSPECIFIED:
@@ -105,141 +94,158 @@ static const char *auth_mode_str(int authmode) {
10594
}
10695
#endif
10796

108-
static void _onStaArduinoEvent(arduino_event_t *ev) {
109-
if (_sta_network_if == NULL || ev->event_id < ARDUINO_EVENT_WIFI_STA_START || ev->event_id > ARDUINO_EVENT_WIFI_STA_LOST_IP) {
97+
void STAClass::_onStaArduinoEvent(arduino_event_id_t event, const arduino_event_info_t *info) {
98+
if (event < ARDUINO_EVENT_WIFI_STA_START || event > ARDUINO_EVENT_WIFI_STA_LOST_IP) {
11099
return;
111100
}
112101
static bool first_connect = true;
113-
log_v("Arduino STA Event: %d - %s", ev->event_id, NetworkEvents::eventName(ev->event_id));
102+
log_v("Arduino STA Event: %d - %s", event, NetworkEvents::eventName(event));
114103

115-
if (ev->event_id == ARDUINO_EVENT_WIFI_STA_START) {
116-
_sta_network_if->_setStatus(WL_DISCONNECTED);
117-
if (esp_wifi_set_ps(WiFi.getSleep()) != ESP_OK) {
118-
log_e("esp_wifi_set_ps failed");
119-
}
120-
} else if (ev->event_id == ARDUINO_EVENT_WIFI_STA_STOP) {
121-
_sta_network_if->_setStatus(WL_STOPPED);
122-
} else if (ev->event_id == ARDUINO_EVENT_WIFI_STA_CONNECTED) {
123-
_sta_network_if->_setStatus(WL_IDLE_STATUS);
124-
#if CONFIG_LWIP_IPV6
125-
if (_sta_network_if->getStatusBits() & ESP_NETIF_WANT_IP6_BIT) {
126-
esp_err_t err = esp_netif_create_ip6_linklocal(_sta_network_if->netif());
127-
if (err != ESP_OK) {
128-
log_e("Failed to enable IPv6 Link Local on STA: 0x%x: %s", err, esp_err_to_name(err));
129-
} else {
130-
log_v("Enabled IPv6 Link Local on %s", _sta_network_if->desc());
104+
switch (event){
105+
case ARDUINO_EVENT_WIFI_STA_START :
106+
_setStatus(WL_DISCONNECTED);
107+
if (esp_wifi_set_ps(WiFi.getSleep()) != ESP_OK) {
108+
log_e("esp_wifi_set_ps failed");
131109
}
132-
}
133-
#endif
134-
} else if (ev->event_id == ARDUINO_EVENT_WIFI_STA_DISCONNECTED) {
135-
uint8_t reason = ev->event_info.wifi_sta_disconnected.reason;
136-
// Reason 0 causes crash, use reason 1 (UNSPECIFIED) instead
137-
if (!reason) {
138-
reason = WIFI_REASON_UNSPECIFIED;
139-
}
140-
log_w("Reason: %u - %s", reason, WiFi.STA.disconnectReasonName((wifi_err_reason_t)reason));
141-
if (reason == WIFI_REASON_NO_AP_FOUND) {
142-
_sta_network_if->_setStatus(WL_NO_SSID_AVAIL);
143-
} else if ((reason == WIFI_REASON_AUTH_FAIL) && !first_connect) {
144-
_sta_network_if->_setStatus(WL_CONNECT_FAILED);
145-
} else if (reason == WIFI_REASON_BEACON_TIMEOUT || reason == WIFI_REASON_HANDSHAKE_TIMEOUT) {
146-
_sta_network_if->_setStatus(WL_CONNECTION_LOST);
147-
} else if (reason == WIFI_REASON_AUTH_EXPIRE) {
148-
149-
} else {
150-
_sta_network_if->_setStatus(WL_DISCONNECTED);
151-
}
152-
153-
bool DoReconnect = false;
154-
if (reason == WIFI_REASON_ASSOC_LEAVE) { //Voluntarily disconnected. Don't reconnect!
155-
} else if (first_connect) { //Retry once for all failure reasons
156-
first_connect = false;
157-
DoReconnect = true;
158-
log_d("WiFi Reconnect Running");
159-
} else if (_sta_network_if->getAutoReconnect() && _is_staReconnectableReason(reason)) {
160-
DoReconnect = true;
161-
log_d("WiFi AutoReconnect Running");
162-
} else if (reason == WIFI_REASON_ASSOC_FAIL) {
163-
_sta_network_if->_setStatus(WL_CONNECT_FAILED);
164-
}
165-
if (DoReconnect) {
166-
_sta_network_if->disconnect();
167-
_sta_network_if->connect();
168-
}
169-
} else if (ev->event_id == ARDUINO_EVENT_WIFI_STA_GOT_IP) {
170-
#if ARDUHAL_LOG_LEVEL >= ARDUHAL_LOG_LEVEL_VERBOSE
171-
uint8_t *ip = (uint8_t *)&(ev->event_info.got_ip.ip_info.ip.addr);
172-
uint8_t *mask = (uint8_t *)&(ev->event_info.got_ip.ip_info.netmask.addr);
173-
uint8_t *gw = (uint8_t *)&(ev->event_info.got_ip.ip_info.gw.addr);
174-
log_v(
175-
"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]
176-
);
177-
#endif
178-
_sta_network_if->_setStatus(WL_CONNECTED);
179-
} else if (ev->event_id == ARDUINO_EVENT_WIFI_STA_LOST_IP) {
180-
_sta_network_if->_setStatus(WL_IDLE_STATUS);
110+
return;
111+
case ARDUINO_EVENT_WIFI_STA_STOP :
112+
_setStatus(WL_STOPPED);
113+
return;
114+
case ARDUINO_EVENT_WIFI_STA_CONNECTED :
115+
_setStatus(WL_IDLE_STATUS);
116+
#if CONFIG_LWIP_IPV6
117+
if (getStatusBits() & ESP_NETIF_WANT_IP6_BIT) {
118+
esp_err_t err = esp_netif_create_ip6_linklocal(netif());
119+
if (err != ESP_OK) {
120+
log_e("Failed to enable IPv6 Link Local on STA: 0x%x: %s", err, esp_err_to_name(err));
121+
} else {
122+
log_v("Enabled IPv6 Link Local on %s", desc());
123+
}
124+
}
125+
#endif
126+
return;
127+
case ARDUINO_EVENT_WIFI_STA_DISCONNECTED : {
128+
if (!info) break;
129+
uint8_t reason = info->wifi_sta_disconnected.reason;
130+
// Reason 0 causes crash, use reason 1 (UNSPECIFIED) instead
131+
if (!reason) {
132+
reason = WIFI_REASON_UNSPECIFIED;
133+
}
134+
log_w("Reason: %u - %s", reason, WiFi.STA.disconnectReasonName((wifi_err_reason_t)reason));
135+
switch (reason){
136+
case WIFI_REASON_NO_AP_FOUND :
137+
_setStatus(WL_NO_SSID_AVAIL);
138+
break;
139+
case WIFI_REASON_AUTH_FAIL :
140+
if (!first_connect)
141+
_setStatus(WL_CONNECT_FAILED);
142+
break;
143+
case WIFI_REASON_BEACON_TIMEOUT :
144+
case WIFI_REASON_HANDSHAKE_TIMEOUT :
145+
_setStatus(WL_CONNECTION_LOST);
146+
break;
147+
case WIFI_REASON_AUTH_EXPIRE :
148+
break;
149+
default:
150+
_setStatus(WL_DISCONNECTED);
151+
break;
152+
}
153+
154+
bool DoReconnect = false;
155+
if (reason == WIFI_REASON_ASSOC_LEAVE) { //Voluntarily disconnected. Don't reconnect!
156+
} else if (first_connect) { //Retry once for all failure reasons
157+
first_connect = false;
158+
DoReconnect = true;
159+
log_d("WiFi Reconnect Running");
160+
} else if (getAutoReconnect() && _is_staReconnectableReason(reason)) {
161+
DoReconnect = true;
162+
log_d("WiFi AutoReconnect Running");
163+
} else if (reason == WIFI_REASON_ASSOC_FAIL) {
164+
_setStatus(WL_CONNECT_FAILED);
165+
}
166+
if (DoReconnect) {
167+
disconnect();
168+
connect();
169+
}
170+
} case ARDUINO_EVENT_WIFI_STA_GOT_IP :
171+
/*
172+
// dublicate, similar logging is done in NetworkInterface::_onIpEvent
173+
#if ARDUHAL_LOG_LEVEL >= ARDUHAL_LOG_LEVEL_VERBOSE
174+
uint8_t *ip = (uint8_t *)&(ev->event_info.got_ip.ip_info.ip.addr);
175+
uint8_t *mask = (uint8_t *)&(ev->event_info.got_ip.ip_info.netmask.addr);
176+
uint8_t *gw = (uint8_t *)&(ev->event_info.got_ip.ip_info.gw.addr);
177+
log_v(
178+
"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]
179+
);
180+
#endif
181+
*/
182+
_setStatus(WL_CONNECTED);
183+
break;
184+
case ARDUINO_EVENT_WIFI_STA_LOST_IP :
185+
_setStatus(WL_IDLE_STATUS);
186+
break;
187+
188+
default:
189+
return;
181190
}
182191
}
183192

184193
void STAClass::_onStaEvent(int32_t event_id, void *event_data) {
185-
arduino_event_t arduino_event;
186-
arduino_event.event_id = ARDUINO_EVENT_ANY;
187-
188-
if (event_id == WIFI_EVENT_STA_START) {
189-
log_v("STA Started");
190-
arduino_event.event_id = ARDUINO_EVENT_WIFI_STA_START;
191-
setStatusBits(ESP_NETIF_STARTED_BIT);
192-
} else if (event_id == WIFI_EVENT_STA_STOP) {
193-
log_v("STA Stopped");
194-
arduino_event.event_id = ARDUINO_EVENT_WIFI_STA_STOP;
195-
clearStatusBits(
196-
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
197-
| ESP_NETIF_HAS_STATIC_IP_BIT
198-
);
199-
} else if (event_id == WIFI_EVENT_STA_AUTHMODE_CHANGE) {
200-
#if ARDUHAL_LOG_LEVEL >= ARDUHAL_LOG_LEVEL_VERBOSE
201-
wifi_event_sta_authmode_change_t *event = (wifi_event_sta_authmode_change_t *)event_data;
202-
log_v("STA Auth Mode Changed: From: %s, To: %s", auth_mode_str(event->old_mode), auth_mode_str(event->new_mode));
203-
#endif
204-
arduino_event.event_id = ARDUINO_EVENT_WIFI_STA_AUTHMODE_CHANGE;
205-
memcpy(&arduino_event.event_info.wifi_sta_authmode_change, event_data, sizeof(wifi_event_sta_authmode_change_t));
206-
} else if (event_id == WIFI_EVENT_STA_CONNECTED) {
207-
#if ARDUHAL_LOG_LEVEL >= ARDUHAL_LOG_LEVEL_VERBOSE
208-
wifi_event_sta_connected_t *event = (wifi_event_sta_connected_t *)event_data;
209-
log_v(
210-
"STA Connected: SSID: %s, BSSID: " MACSTR ", Channel: %u, Auth: %s", event->ssid, MAC2STR(event->bssid), event->channel, auth_mode_str(event->authmode)
211-
);
212-
#endif
213-
arduino_event.event_id = ARDUINO_EVENT_WIFI_STA_CONNECTED;
214-
memcpy(&arduino_event.event_info.wifi_sta_connected, event_data, sizeof(wifi_event_sta_connected_t));
215-
setStatusBits(ESP_NETIF_CONNECTED_BIT);
216-
} else if (event_id == WIFI_EVENT_STA_DISCONNECTED) {
217-
#if ARDUHAL_LOG_LEVEL >= ARDUHAL_LOG_LEVEL_VERBOSE
218-
wifi_event_sta_disconnected_t *event = (wifi_event_sta_disconnected_t *)event_data;
219-
log_v("STA Disconnected: SSID: %s, BSSID: " MACSTR ", Reason: %u", event->ssid, MAC2STR(event->bssid), event->reason);
220-
#endif
221-
arduino_event.event_id = ARDUINO_EVENT_WIFI_STA_DISCONNECTED;
222-
memcpy(&arduino_event.event_info.wifi_sta_disconnected, event_data, sizeof(wifi_event_sta_disconnected_t));
223-
clearStatusBits(ESP_NETIF_CONNECTED_BIT | ESP_NETIF_HAS_IP_BIT | ESP_NETIF_HAS_LOCAL_IP6_BIT | ESP_NETIF_HAS_GLOBAL_IP6_BIT);
224-
} else {
225-
return;
226-
}
227-
228-
if (arduino_event.event_id != ARDUINO_EVENT_ANY) {
229-
Network.postEvent(&arduino_event);
194+
switch (event_id){
195+
case WIFI_EVENT_STA_START :
196+
log_v("STA Started");
197+
setStatusBits(ESP_NETIF_STARTED_BIT);
198+
Network.postEvent(ARDUINO_EVENT_WIFI_STA_START);
199+
return;
200+
case WIFI_EVENT_STA_STOP :
201+
log_v("STA Stopped");
202+
clearStatusBits(
203+
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
204+
);
205+
Network.postEvent(ARDUINO_EVENT_WIFI_STA_STOP);
206+
return;
207+
case WIFI_EVENT_STA_AUTHMODE_CHANGE : {
208+
#if ARDUHAL_LOG_LEVEL >= ARDUHAL_LOG_LEVEL_VERBOSE
209+
wifi_event_sta_authmode_change_t *event = (wifi_event_sta_authmode_change_t *)event_data;
210+
log_v("STA Auth Mode Changed: From: %s, To: %s", auth_mode_str(event->old_mode), auth_mode_str(event->new_mode));
211+
#endif
212+
arduino_event_info_t i;
213+
memcpy(&i.wifi_sta_authmode_change, event_data, sizeof(wifi_event_sta_authmode_change_t));
214+
Network.postEvent(ARDUINO_EVENT_WIFI_STA_AUTHMODE_CHANGE, &i);
215+
return;
216+
}
217+
case WIFI_EVENT_STA_CONNECTED : {
218+
#if ARDUHAL_LOG_LEVEL >= ARDUHAL_LOG_LEVEL_VERBOSE
219+
wifi_event_sta_connected_t *event = (wifi_event_sta_connected_t *)event_data;
220+
log_v("STA Connected: SSID: %s, BSSID: " MACSTR ", Channel: %u, Auth: %s", event->ssid, MAC2STR(event->bssid), event->channel, auth_mode_str(event->authmode));
221+
#endif
222+
setStatusBits(ESP_NETIF_CONNECTED_BIT);
223+
arduino_event_info_t i;
224+
memcpy(&i.wifi_sta_connected, event_data, sizeof(wifi_event_sta_connected_t));
225+
Network.postEvent(ARDUINO_EVENT_WIFI_STA_CONNECTED, &i);
226+
return;
227+
}
228+
case WIFI_EVENT_STA_DISCONNECTED : {
229+
#if ARDUHAL_LOG_LEVEL >= ARDUHAL_LOG_LEVEL_VERBOSE
230+
wifi_event_sta_disconnected_t *event = (wifi_event_sta_disconnected_t *)event_data;
231+
log_v("STA Disconnected: SSID: %s, BSSID: " MACSTR ", Reason: %u", event->ssid, MAC2STR(event->bssid), event->reason);
232+
#endif
233+
clearStatusBits(ESP_NETIF_CONNECTED_BIT | ESP_NETIF_HAS_IP_BIT | ESP_NETIF_HAS_LOCAL_IP6_BIT | ESP_NETIF_HAS_GLOBAL_IP6_BIT);
234+
arduino_event_info_t i;
235+
memcpy(&i.wifi_sta_disconnected, event_data, sizeof(wifi_event_sta_disconnected_t));
236+
Network.postEvent(ARDUINO_EVENT_WIFI_STA_DISCONNECTED, &i);
237+
return;
238+
}
239+
default:;
230240
}
231241
}
232242

233243
STAClass::STAClass()
234-
: _minSecurity(WIFI_AUTH_WPA2_PSK), _scanMethod(WIFI_FAST_SCAN), _sortMethod(WIFI_CONNECT_AP_BY_SIGNAL), _autoReconnect(true), _status(WL_STOPPED) {
235-
_sta_network_if = this;
236-
}
244+
: _minSecurity(WIFI_AUTH_WPA2_PSK), _scanMethod(WIFI_FAST_SCAN), _sortMethod(WIFI_CONNECT_AP_BY_SIGNAL), _autoReconnect(true), _status(WL_STOPPED) {}
237245

238246
STAClass::~STAClass() {
239247
end();
240-
_sta_network_if = NULL;
241-
Network.removeEvent(evt_handle);
242-
evt_handle = 0;
248+
onDisable();
243249
}
244250

245251
wl_status_t STAClass::status() {
@@ -270,9 +276,15 @@ bool STAClass::bandwidth(wifi_bandwidth_t bandwidth) {
270276
}
271277

272278
bool STAClass::onEnable() {
273-
if (_sta_ev_instance == NULL && esp_event_handler_instance_register(WIFI_EVENT, ESP_EVENT_ANY_ID, &_sta_event_cb, this, &_sta_ev_instance)) {
274-
log_e("event_handler_instance_register for WIFI_EVENT Failed!");
275-
return false;
279+
bool result{true};
280+
if (!_sta_ev_instance && esp_event_handler_instance_register(
281+
WIFI_EVENT,
282+
ESP_EVENT_ANY_ID,
283+
[](void* self, esp_event_base_t base, int32_t id, void* data) { static_cast<STAClass*>(self)->_onStaEvent(id, data); },
284+
this,
285+
&_sta_ev_instance)) {
286+
log_e("register for WIFI_EVENT Failed!");
287+
result = false;
276288
}
277289
if (_esp_netif == NULL) {
278290
_esp_netif = get_esp_interface_netif(ESP_IF_WIFI_STA);
@@ -281,22 +293,22 @@ bool STAClass::onEnable() {
281293
return false;
282294
}
283295
/* attach to receive events */
284-
if (!evt_handle)
285-
evt_handle = Network.onSysEvent(_onStaArduinoEvent);
296+
if (!_evt_handle)
297+
_evt_handle = Network.onSysEvent( [this](arduino_event_id_t e, const arduino_event_info_t *i){_onStaArduinoEvent(e, i);} );
286298
initNetif(ESP_NETIF_ID_STA);
287299
}
288300
return true;
289301
}
290302

291303
bool STAClass::onDisable() {
292-
Network.removeEvent(evt_handle);
293-
evt_handle = 0;
304+
Network.removeEvent(_evt_handle);
305+
_evt_handle = 0;
294306
// we just set _esp_netif to NULL here, so destroyNetif() does not try to destroy it.
295307
// That would be done by WiFi.enableSTA(false) if AP is not enabled, or when it gets disabled
296308
_esp_netif = NULL;
297309
destroyNetif();
298310
if (_sta_ev_instance != NULL) {
299-
esp_event_handler_unregister(WIFI_EVENT, ESP_EVENT_ANY_ID, &_sta_event_cb);
311+
esp_event_handler_instance_unregister(WIFI_EVENT, ESP_EVENT_ANY_ID, _sta_ev_instance);
300312
_sta_ev_instance = NULL;
301313
}
302314
return true;

Diff for: libraries/WiFi/src/WiFiSTA.h

+7-3
Original file line numberDiff line numberDiff line change
@@ -85,9 +85,6 @@ class STAClass : public NetworkInterface {
8585

8686
const char *disconnectReasonName(wifi_err_reason_t reason);
8787

88-
// Private Use
89-
void _setStatus(wl_status_t status);
90-
void _onStaEvent(int32_t event_id, void *event_data);
9188

9289
protected:
9390
wifi_auth_mode_t _minSecurity;
@@ -101,6 +98,13 @@ class STAClass : public NetworkInterface {
10198
friend class WiFiGenericClass;
10299
bool onEnable();
103100
bool onDisable();
101+
102+
private:
103+
esp_event_handler_instance_t _sta_ev_instance{NULL};
104+
network_event_handle_t _evt_handle{0};
105+
void _onStaArduinoEvent(arduino_event_id_t event, const arduino_event_info_t *info);
106+
void _setStatus(wl_status_t status);
107+
void _onStaEvent(int32_t event_id, void *event_data);
104108
};
105109

106110
// ----------------------------------------------------------------------------------------------

0 commit comments

Comments
 (0)