44
55const char * const TAG = " WiFiManager" ;
66
7+ #include < freertos/queue.h>
78#include < freertos/task.h>
89
910#include < esp_wifi.h>
@@ -29,6 +30,16 @@ const uint32_t OPENSHOCK_WIFI_SCAN_MIN_MS_PER_CHANNEL = 100;
2930const uint32_t OPENSHOCK_WIFI_SCAN_MAX_MS_PER_CHANNEL = 300 ; // Adjusting this value will affect the scan rate, but may also affect the scan results
3031const uint32_t OPENSHOCK_WIFI_SCAN_TIMEOUT_MS = 10 * 1000 ;
3132
33+ const uint32_t OPENSHOCK_DNS_MAIN = 0x01010101 ; // 1.1.1.1
34+ const uint32_t OPENSHOCK_DNS_BACKUP = 0x08080808 ; // 8.8.8.8
35+ const uint32_t OPENSHOCK_DNS_FALLBACK = 0x09090909 ; // 9.9.9.9
36+
37+ enum class WiFiTaskNotification : uint8_t {
38+ None,
39+ ScanFailed,
40+ ScanCompleted
41+ }
42+
3243enum class WiFiState : uint8_t {
3344 Disconnected = 0 ,
3445 Scanning = 1 << 0 ,
@@ -38,17 +49,18 @@ enum class WiFiState : uint8_t {
3849
3950struct ScanResult {
4051 uint8_t scanId;
41- uint8_t size;
42- uint8_t capacity;
52+ uint16_t size;
53+ uint16_t capacity;
4354 wifi_ap_record_t * records;
4455};
4556
57+ static QueueHandle_t s_event_queue = nullptr ;
4658static esp_netif_t * s_wifi_sta = nullptr ;
4759static esp_netif_t * s_wifi_ap = nullptr ;
4860static WiFiState s_state = WiFiState::Disconnected;
4961static uint8_t s_target_creds = 0 ;
50- static uint8_t s_scan_current_ch = 0 ;
51- static ScanResult s_scan_results [OPENSHOCK_WIFI_SCAN_MAX_CHANNEL] = {};
62+ static uint8_t s_scan_channel_current = 0 ;
63+ static ScanResult s_scan_channel [OPENSHOCK_WIFI_SCAN_MAX_CHANNEL] = {};
5264
5365template <std::size_t N>
5466static bool is_zero (const uint8_t (&array)[N])
@@ -83,23 +95,23 @@ static bool configure_sta_dns()
8395 esp_netif_dns_info_t dns;
8496 dns.ip .type = ESP_IPADDR_TYPE_V4;
8597
86- dns.ip .u_addr .ip4 .addr = 0x01010101 ; // 1.1.1.1
98+ dns.ip .u_addr .ip4 .addr = OPENSHOCK_DNS_MAIN;
8799
88100 err = esp_netif_set_dns_info (s_wifi_sta, ESP_NETIF_DNS_MAIN, &dns);
89101 if (err != ERR_OK) {
90102 OS_LOGE (TAG, " Failed to set Main DNS: %d" , err);
91103 return false ;
92104 }
93105
94- dns.ip .u_addr .ip4 .addr = 0x08080808 ; // 8.8.8.8
106+ dns.ip .u_addr .ip4 .addr = OPENSHOCK_DNS_BACKUP;
95107
96108 err = esp_netif_set_dns_info (s_wifi_sta, ESP_NETIF_DNS_BACKUP, &dns);
97109 if (err != ERR_OK) {
98110 OS_LOGE (TAG, " Failed to set Backup DNS: %d" , err);
99111 return false ;
100112 }
101113
102- dns.ip .u_addr .ip4 .addr = 0x09090909 ; // 9.9.9.9
114+ dns.ip .u_addr .ip4 .addr = OPENSHOCK_DNS_FALLBACK;
103115
104116 err = esp_netif_set_dns_info (s_wifi_sta, ESP_NETIF_DNS_FALLBACK, &dns);
105117 if (err != ERR_OK) {
@@ -171,71 +183,6 @@ static bool mark_network_as_attempted(const uint8_t (&bssid)[6])
171183 return true ;
172184}
173185
174- static void wifi_event_wifi_ready_handler (void * event_data)
175- {
176- OS_LOGV (TAG, " WiFi Ready!" );
177- }
178-
179- static void wifi_event_scan_done_handler (void * event_data)
180- {
181- auto data = reinterpret_cast <wifi_event_sta_scan_done_t *>(event_data);
182-
183- if (data->status == 1 ) {
184- // TODO: what to do?
185- OS_LOGE (TAG, " WiFi Scan failed!" );
186- return ;
187- }
188-
189- if (s_scan_current_ch <= 0 || s_scan_current_ch >= OPENSHOCK_WIFI_SCAN_MAX_CHANNEL) {
190- // TODO: what to do?
191- OS_LOGE (TAG, " WiFi Scanned channel is invalid!" );
192- return ;
193- }
194-
195- OS_LOGD (TAG, " WiFi scan completed, results: %hhu scan id: %hhu" , data->number , data->scan_id );
196-
197- ScanResult* result = s_scan_results[s_scan_current_ch];
198-
199- result->scanId = data->scan_id ;
200- result->size = data->number ;
201-
202- if (result->records == nullptr || result->capacity < data->number ) {
203- OS_LOGD (TAG, " Initializing scan results at %hhu to %hhu elements" , s_scan_current_ch, data->number );
204- result->capacity = data->number ;
205- result->records = reinterpret_cast <wifi_ap_record_t *>(malloc (data->number * sizeof (wifi_ap_record_t )));
206- } else if (result->capacity < data->number ) {
207- OS_LOGD (TAG, " Resizing scan results at %hhu from %hhu to %hhu elements" , s_scan_current_ch, data->number );
208- free (result->records );
209- result->capacity = data->number ;
210- result->records = reinterpret_cast <wifi_ap_record_t *>(malloc (data->number * sizeof (wifi_ap_record_t )));
211- }
212-
213- esp_err_t err = esp_wifi_scan_get_ap_records (result->size , result->records );
214- if (err != nullptr ) {
215- OS_LOGE (TAG, " Failed to get scan results: %d" , err);
216- return ;
217- }
218-
219- // TODO: Check if scan is finished, start next channel scan if not.
220- }
221-
222- static void wifi_event_handler (void * event_handler_arg, esp_event_base_t event_base, int32_t event_id, void * event_data)
223- {
224- (void )event_handler_arg;
225- (void )event_base;
226-
227- switch (event_id) {
228- case WIFI_EVENT_WIFI_READY:
229- wifi_event_wifi_ready_handler (event_data);
230- break ;
231- case WIFI_EVENT_SCAN_DONE:
232- wifi_event_scan_done_handler (event_data);
233- break ;
234- default :
235- break ;
236- }
237- }
238-
239186static bool get_next_network (OpenShock::Config::WiFiCredentials& creds)
240187{
241188 return find_network ([&creds](const OpenShock::WiFiNetwork& net) {
@@ -255,7 +202,7 @@ static bool get_next_network(OpenShock::Config::WiFiCredentials& creds)
255202 }) != s_wifiNetworks.end ();
256203}
257204
258- static bool wifi_start_scan (uint8_t channel = OPENSHOCK_WIFI_SCAN_MAX_CHANNEL)
205+ static bool wifi_scan_start (uint8_t channel = OPENSHOCK_WIFI_SCAN_MAX_CHANNEL)
259206{
260207 wifi_scan_config_t scan_cfg = {
261208 .ssid = nullptr ,
@@ -272,9 +219,16 @@ static bool wifi_start_scan(uint8_t channel = OPENSHOCK_WIFI_SCAN_MAX_CHANNEL)
272219 .home_chan_dwell_time = OPENSHOCK_WIFI_SCAN_DWELL_PER_CHANNEL,
273220 };
274221
222+ uint8_t lastChannel = s_scan_channel_current;
223+ s_scan_channel_current = channel;
224+
275225 esp_err_t err = esp_wifi_scan_start (&scan_cfg, /* block: */ false );
276226 if (err != ERR_OK) {
227+ // Restore previous variable ASAP
228+ s_scan_channel_current = lastChannel;
229+
277230 OS_LOGE (TAG, " Failed to start scan: %d" , err);
231+
278232 return false ;
279233 }
280234
@@ -330,7 +284,7 @@ static bool wifi_start_connect(std::string_view ssid, std::string_view password,
330284 err = esp_wifi_connect ();
331285 if (err != ERR_OK) {
332286 s_state = WiFiState::Disconnected;
333- OS_LOGE (TAG, " Failed to stat wifi connect : %d" , err);
287+ OS_LOGE (TAG, " Failed to stat wifi conhuhnect : %d" , err);
334288 return false ;
335289 }
336290
@@ -364,22 +318,154 @@ static bool wifi_connect_target_or_next()
364318 return wifi_start_connect (creds.ssid , creds.password , nullptr );
365319}
366320
367- static void wifi_task (void *)
321+ static void task_handle_scan_failed ()
322+ {
323+ // TODO: Wtf to do here?
324+ }
325+
326+ static void task_handle_scan_completed ()
327+ {
328+ }
329+
330+ static void task_handle_disconnected ()
331+ {
332+ static int64_t lastScanRequest = 0 ;
333+ if (wifi_connect_target_or_next ()) return ;
334+
335+ int64_t now = OpenShock::millis ();
336+
337+ if (lastScanRequest == 0 || now - lastScanRequest > 30'000 ) {
338+ lastScanRequest = now;
339+
340+ OS_LOGV (TAG, " No networks to connect to, starting scan..." );
341+ wifi_scan_start ();
342+ }
343+ }
344+
345+ static void task_main (void *)
368346{
369- int64_t lastScanRequest = 0 ;
347+ bool isScanning = false ;
370348 while (true ) {
371- if (s_state == WiFiState::Disconnected) {
372- if (!wifi_connect_target_or_next ()) {
373- int64_t now = OpenShock::millis ();
374- if (lastScanRequest == 0 || now - lastScanRequest > 30'000 ) {
375- lastScanRequest = now;
376-
377- OS_LOGV (TAG, " No networks to connect to, starting scan..." );
378- wifi_start_scan ();
379- }
349+ WiFiTaskNotification eventType;
350+ if (xQueueReceive (s_event_queue, &eventType, portMAX_DELAY) == pdTRUE) {
351+ switch (eventType) {
352+ case WiFiTaskNotification::ScanFailed:
353+ task_handle_scan_failed ();
354+ break ;
355+ case WiFiTaskNotification::ScanCompleted:
356+ task_handle_scan_completed ();
357+ break ;
358+ default :
359+ break ;
380360 }
381361 }
382- vTaskDelay (pdMS_TO_TICKS (1000 ));
362+ }
363+ }
364+
365+ static void event_notify_task (WiFiTaskNotification notification)
366+ {
367+ if (xQueueSend (s_event_queue, ¬ification, portMAX_DELAY) != pdTRUE) {
368+ OS_PANIC (TAG, " Unable to queue wifi event!" );
369+ }
370+ }
371+
372+ static void event_wifi_ready_handler (void * event_data)
373+ {
374+ OS_LOGV (TAG, " WiFi Ready!" );
375+ }
376+
377+ static void event_wifi_scan_done_handler (void * event_data)
378+ {
379+ auto data = reinterpret_cast <wifi_event_sta_scan_done_t *>(event_data);
380+
381+ if (data->status == 1 ) {
382+ OS_LOGE (TAG, " WiFi Scan failed!" );
383+ event_notify_task (WiFiTaskNotification::ScanFailed);
384+ return ;
385+ }
386+
387+ if (s_scan_channel_current <= 0 || s_scan_channel_current > OPENSHOCK_WIFI_SCAN_MAX_CHANNEL) {
388+ OS_LOGE (TAG, " WiFi Scanned channel is invalid!" );
389+ event_notify_task (WiFiTaskNotification::ScanFailed);
390+ return ;
391+ }
392+
393+ OS_LOGD (TAG, " WiFi scan completed, results: %hhu scan id: %hhu" , data->number , data->scan_id );
394+
395+ ScanResult& result = s_scan_channel[s_scan_channel_current];
396+
397+ esp_err_t err;
398+
399+ uint16_t numRecords;
400+ err = esp_wifi_scan_get_ap_num (&numRecords);
401+ if (err != ERR_OK) {
402+ OS_LOGE (TAG, " Failed to get scan result count: %d" , err);
403+ event_notify_task (WiFiTaskNotification::ScanFailed);
404+ return ;
405+ }
406+
407+ OS_LOGI (TAG, " Values: %hhu <-> %hu" , data->number , numRecords);
408+
409+ result.scanId = data->scan_id ;
410+ result.size = numRecords;
411+
412+ if (result.records == nullptr || result.capacity < numRecords) {
413+ OS_LOGD (TAG, " Initializing scan results at %hhu to %hhu elements" , s_scan_channel_current, numRecords);
414+ result.capacity = numRecords;
415+ result.records = reinterpret_cast <wifi_ap_record_t *>(malloc (numRecords * sizeof (wifi_ap_record_t )));
416+ } else if (result.capacity < numRecords) {
417+ OS_LOGD (TAG, " Resizing scan results at %hhu from %hhu to %hhu elements" , s_scan_channel_current, numRecords);
418+ free (result.records );
419+ result.capacity = numRecords;
420+ result.records = reinterpret_cast <wifi_ap_record_t *>(malloc (numRecords * sizeof (wifi_ap_record_t )));
421+ }
422+
423+ err = esp_wifi_scan_get_ap_records (&result.size , result.records );
424+ if (err != ERR_OK) {
425+ OS_LOGE (TAG, " Failed to get scan results: %d" , err);
426+ event_notify_task (WiFiTaskNotification::ScanFailed);
427+ return ;
428+ }
429+
430+ if (--s_scan_channel_current == 0 ) {
431+ event_notify_task (WiFiTaskNotification::ScanCompleted);
432+ return ;
433+ }
434+
435+ wifi_scan_start (s_scan_channel_current);
436+ }
437+
438+ static void event_wifi_handler (void * event_handler_arg, esp_event_base_t event_base, int32_t event_id, void * event_data)
439+ {
440+ (void )event_handler_arg;
441+ (void )event_base;
442+
443+ switch (event_id) {
444+ case WIFI_EVENT_WIFI_READY:
445+ event_wifi_ready_handler (event_data);
446+ break ;
447+ case WIFI_EVENT_SCAN_DONE:
448+ event_wifi_scan_done_handler (event_data);
449+ break ;
450+ case WIFI_EVENT_STA_START:
451+ break ;
452+ case WIFI_EVENT_STA_STOP:
453+ break ;
454+ case WIFI_EVENT_STA_CONNECTED:
455+ break ;
456+ case WIFI_EVENT_STA_DISCONNECTED:
457+ break ;
458+ case WIFI_EVENT_AP_START:
459+ break ;
460+ case WIFI_EVENT_AP_STOP:
461+ break ;
462+ case WIFI_EVENT_AP_STACONNECTED:
463+ break ;
464+ case WIFI_EVENT_AP_STADISCONNECTED:
465+ break ;
466+ default :
467+ OS_LOGW (TAG, " Received unknown event with ID: %i" , event_id);
468+ break ;
383469 }
384470}
385471
@@ -392,9 +478,14 @@ bool OpenShock::WiFiManager::Init()
392478
393479 esp_err_t err;
394480
395- memset (s_scan_results, 0 , sizeof (ScanResult) * OPENSHOCK_WIFI_SCAN_MAX_CHANNEL);
481+ s_event_queue = xQueueCreate (32 , sizeof (WiFiTaskNotification));
482+ if (s_event_queue == nullptr ) {
483+ OS_PANIC (TAG, " Failed to allocate event queue, probably out of memory!" );
484+ }
485+
486+ memset (s_scan_channel, 0 , sizeof (ScanResult) * OPENSHOCK_WIFI_SCAN_MAX_CHANNEL);
396487
397- err = esp_event_handler_register (WIFI_EVENT, ESP_EVENT_ANY_ID, wifi_event_handler , nullptr );
488+ err = esp_event_handler_register (WIFI_EVENT, ESP_EVENT_ANY_ID, event_wifi_handler , nullptr );
398489 if (err != ERR_OK) {
399490 OS_LOGE (TAG, " Failed to subscribe to WiFi events: %d" , err);
400491 return false ;
0 commit comments