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
3634esp_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-
6150static 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
184193void 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
233243STAClass::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
238246STAClass::~STAClass () {
239247 end ();
240- _sta_network_if = NULL ;
241- Network.removeEvent (evt_handle);
242- evt_handle = 0 ;
248+ onDisable ();
243249}
244250
245251wl_status_t STAClass::status () {
@@ -270,9 +276,15 @@ bool STAClass::bandwidth(wifi_bandwidth_t bandwidth) {
270276}
271277
272278bool 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
291303bool 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 ;
0 commit comments