16 wifi_ap_record_t *accessp_records; ///< [MAX_AP_NUM] records array with scan results. |
17 wifi_ap_record_t *accessp_records; ///< [MAX_AP_NUM] records array with scan results. |
17 wifi_config_t *task_wifi_ConfigSTA = NULL; ///< Current STA configuration. |
18 wifi_config_t *task_wifi_ConfigSTA = NULL; ///< Current STA configuration. |
18 WIFI_State *wifi_state = NULL; ///< Public state for other tasks. |
19 WIFI_State *wifi_state = NULL; ///< Public state for other tasks. |
19 esp_netif_t *sta_netif = NULL; ///< Station interface |
20 esp_netif_t *sta_netif = NULL; ///< Station interface |
20 |
21 |
21 extern wifiStation_t wifiStation; |
22 |
22 extern strConfig_t config; |
23 wifi_scan_config_t scan_config = { ///< WiFi scanner configuration. |
23 |
24 .ssid = (uint8_t *)CONFIG_ESP_WIFI_SSID, |
24 |
25 .bssid = 0, |
25 wifi_scan_config_t scan_config = { |
26 .channel = 0, |
26 .ssid = 0, |
27 .show_hidden = false |
27 .bssid = 0, |
28 }; |
28 .channel = 0, |
29 |
29 .show_hidden = false, |
|
30 .scan_time.passive = 130 ///< Beacons are usually sent every 100 mSec. |
|
31 }; ///< WiFi scanner configuration. |
|
32 |
|
33 uint8_t _wifi_ssid[33]; ///< Current SSID |
|
34 bool _wifi_ScanAPs = false; ///< Scanning |
|
35 bool _wifi_ScanDone = false; ///< Scan ready |
30 bool _wifi_ScanDone = false; ///< Scan ready |
|
31 bool _wifi_BetterAP = false; ///< If better AP available. |
|
32 int8_t _wifi_RSSI = -127; ///< Latest RSSI level. |
36 uint16_t _wifi_Scanned = 0; ///< Total scanned APs. |
33 uint16_t _wifi_Scanned = 0; ///< Total scanned APs. |
|
34 |
|
35 extern char hostname[]; ///< Generated hostname |
|
36 |
37 |
37 |
38 |
38 |
39 const int TASK_WIFI_REQUEST_STA_DISCONNECT = BIT0; ///< When set, means a client requested to disconnect from currently connected AP. |
39 const int TASK_WIFI_REQUEST_STA_DISCONNECT = BIT0; ///< When set, means a client requested to disconnect from currently connected AP. |
40 const int TASK_WIFI_REQUEST_STA_CONNECT = BIT1; ///< When set, means a client requested to connect to an access point. |
40 const int TASK_WIFI_REQUEST_STA_CONNECT = BIT1; ///< When set, means a client requested to connect to an access point. |
41 const int TASK_WIFI_REQUEST_STA_STATUS = BIT2; ///< When set, means a client requested to update the connection status. |
41 const int TASK_WIFI_REQUEST_STA_SCAN = BIT2; ///< When set, means a client requested a AP scan. |
42 |
42 const int TASK_WIFI_REQUEST_STA_STATUS = BIT3; ///< When set, means a client requested to update the connection status. |
43 const int TASK_WIFI_HAS_IP = BIT3; ///< Indicate that we have an IP address |
43 |
44 const int TASK_WIFI_STA_FAILED = BIT4; ///< Indicate that we could not get a connection to AP as station. |
44 const int TASK_WIFI_HAS_IP = BIT4; ///< Indicate that we have an IP address |
45 const int TASK_WIFI_STA_DISCONNECTED = BIT5; ///< Indicate that we are disconnected from an ap station. |
45 const int TASK_WIFI_STA_FAILED = BIT5; ///< Indicate that we could not get a connection to AP as station. |
46 const int TASK_WIFI_STA_CONNECTED = BIT6; ///< Indicate that we are connected to AP as station, flip of BIT5. |
46 const int TASK_WIFI_STA_DISCONNECTED = BIT6; ///< Indicate that we are disconnected from an ap station. |
|
47 const int TASK_WIFI_STA_CONNECTED = BIT7; ///< Indicate that we are connected to AP as station, flip of BIT5. |
47 |
48 |
48 |
49 |
49 |
50 |
50 /** |
51 /** |
51 * @brief Array with AP security names |
52 * @brief Array with AP security names |
76 { |
77 { |
77 xEventGroupSetBits(xEventGroupWifi, TASK_WIFI_REQUEST_STA_CONNECT); |
78 xEventGroupSetBits(xEventGroupWifi, TASK_WIFI_REQUEST_STA_CONNECT); |
78 } |
79 } |
79 |
80 |
80 |
81 |
|
82 void scan_WiFi(void) |
|
83 { |
|
84 xEventGroupSetBits(xEventGroupWifi, TASK_WIFI_REQUEST_STA_SCAN); |
|
85 } |
|
86 |
|
87 |
|
88 void disconnect_WiFi(void) |
|
89 { |
|
90 xEventGroupSetBits(xEventGroupWifi, TASK_WIFI_REQUEST_STA_DISCONNECT); |
|
91 xEventGroupClearBits(xEventGroupWifi, TASK_WIFI_REQUEST_STA_CONNECT); |
|
92 } |
|
93 |
|
94 |
81 |
95 |
82 static void wifi_event_handler(void* arg, esp_event_base_t event_base, int32_t event_id, void* event_data) |
96 static void wifi_event_handler(void* arg, esp_event_base_t event_base, int32_t event_id, void* event_data) |
83 { |
97 { |
84 switch (event_id) { |
98 switch (event_id) { |
85 |
99 |
86 case WIFI_EVENT_SCAN_DONE: |
100 case WIFI_EVENT_SCAN_DONE: |
87 // Get the results so the memory used is freed. |
101 { |
88 ESP_ERROR_CHECK(esp_wifi_scan_get_ap_records(&ap_num, accessp_records)); |
102 /* Get the results so the memory used is freed. */ |
89 _wifi_Scanned = ap_num; |
103 ESP_ERROR_CHECK(esp_wifi_scan_get_ap_records(&ap_num, accessp_records)); |
90 _wifi_ScanDone = true; |
104 ESP_LOGI(TAG, "Event wifi Scane done, %d records", ap_num); |
91 break; |
105 for (int i = 0; i < ap_num; i++) { |
|
106 wifi_ap_record_t ap = accessp_records[i]; |
|
107 ESP_LOGI(TAG, "AP:%d bssid:%02x:%02x:%02x:%02x:%02x:%02x ssid:%s ch:%d rssi:%d", |
|
108 i, ap.bssid[0], ap.bssid[1], ap.bssid[2], ap.bssid[3], ap.bssid[4], ap.bssid[5], |
|
109 ap.ssid, ap.primary, ap.rssi); |
|
110 if (ap.rssi > CONFIG_ESP_WIFI_ROAMING_LEVEL && ap.rssi > (_wifi_RSSI + 3)) { |
|
111 _wifi_BetterAP = true; |
|
112 ESP_LOGI(TAG, "AP:%d is a better AP", i); |
|
113 } |
|
114 } |
|
115 _wifi_Scanned = ap_num; |
|
116 _wifi_ScanDone = true; |
|
117 break; |
|
118 } |
92 |
119 |
93 case WIFI_EVENT_STA_START: |
120 case WIFI_EVENT_STA_START: |
|
121 { |
94 ESP_LOGI(TAG, "Event wifi START"); |
122 ESP_LOGI(TAG, "Event wifi START"); |
95 // Set the configured hostname for the dhcp client. |
123 // Set the configured hostname for the dhcp client. |
96 ESP_ERROR_CHECK(esp_netif_set_hostname(sta_netif, config.hostname)); |
124 ESP_ERROR_CHECK(esp_netif_set_hostname(sta_netif, hostname)); |
97 esp_wifi_connect(); |
125 esp_wifi_connect(); |
98 break; |
126 _wifi_BetterAP = false; |
|
127 break; |
|
128 } |
99 |
129 |
100 case WIFI_EVENT_STA_CONNECTED: |
130 case WIFI_EVENT_STA_CONNECTED: |
101 { |
131 { |
102 wifi_event_sta_connected_t* event = (wifi_event_sta_connected_t*) event_data; |
132 wifi_event_sta_connected_t* event = (wifi_event_sta_connected_t*) event_data; |
103 wifi_ap_record_t ap_info; |
133 wifi_ap_record_t ap_info; |
198 /* event handler and event group for the wifi driver */ |
231 /* event handler and event group for the wifi driver */ |
199 xEventGroupWifi = xEventGroupCreate(); |
232 xEventGroupWifi = xEventGroupCreate(); |
200 /* initialize the tcp stack */ |
233 /* initialize the tcp stack */ |
201 ESP_ERROR_CHECK(esp_netif_init()); |
234 ESP_ERROR_CHECK(esp_netif_init()); |
202 ESP_ERROR_CHECK(esp_event_loop_create_default()); |
235 ESP_ERROR_CHECK(esp_event_loop_create_default()); |
|
236 |
|
237 wifi_init_config_t cfg = WIFI_INIT_CONFIG_DEFAULT(); |
|
238 ESP_ERROR_CHECK(esp_wifi_init(&cfg)); |
|
239 |
203 sta_netif = esp_netif_create_default_wifi_sta(); |
240 sta_netif = esp_netif_create_default_wifi_sta(); |
204 assert(sta_netif); |
241 assert(sta_netif); |
205 |
242 |
206 /* |
243 /* |
207 * memory allocation of objects used by the task |
244 * memory allocation of objects used by the task |
208 */ |
245 */ |
209 accessp_records = (wifi_ap_record_t*)malloc(sizeof(wifi_ap_record_t) * MAX_AP_NUM); |
246 accessp_records = (wifi_ap_record_t*)malloc(sizeof(wifi_ap_record_t) * MAX_AP_NUM); |
210 task_wifi_ConfigSTA = (wifi_config_t*)malloc(sizeof(wifi_config_t)); |
|
211 memset(task_wifi_ConfigSTA, 0x00, sizeof(wifi_config_t)); |
|
212 |
|
213 xSemaphoreWiFi = xSemaphoreCreateMutex(); |
247 xSemaphoreWiFi = xSemaphoreCreateMutex(); |
214 wifi_state = malloc(sizeof(WIFI_State)); |
248 wifi_state = malloc(sizeof(WIFI_State)); |
215 memset(wifi_state, 0x00, sizeof(WIFI_State)); |
249 memset(wifi_state, 0x00, sizeof(WIFI_State)); |
216 |
250 |
217 /* |
251 /* |
218 * init wifi as station |
252 * init wifi as station |
219 */ |
253 */ |
220 wifi_init_config_t wifi_init_config = WIFI_INIT_CONFIG_DEFAULT(); |
|
221 ESP_ERROR_CHECK(esp_wifi_init(&wifi_init_config)); |
|
222 |
|
223 esp_event_handler_instance_t instance_any_id; |
254 esp_event_handler_instance_t instance_any_id; |
224 esp_event_handler_instance_t instance_got_ip; |
255 esp_event_handler_instance_t instance_got_ip; |
225 ESP_ERROR_CHECK( esp_event_handler_instance_register(WIFI_EVENT, ESP_EVENT_ANY_ID, &wifi_event_handler, NULL, &instance_any_id) ); |
256 ESP_ERROR_CHECK( esp_event_handler_instance_register(WIFI_EVENT, ESP_EVENT_ANY_ID, &wifi_event_handler, NULL, &instance_any_id) ); |
226 ESP_ERROR_CHECK( esp_event_handler_instance_register(IP_EVENT, ESP_EVENT_ANY_ID, &got_ip_event_handler, NULL, &instance_got_ip) ); |
257 ESP_ERROR_CHECK( esp_event_handler_instance_register(IP_EVENT, ESP_EVENT_ANY_ID, &got_ip_event_handler, NULL, &instance_got_ip) ); |
227 |
258 |
228 ESP_ERROR_CHECK(esp_wifi_set_storage(WIFI_STORAGE_RAM)); |
259 wifi_config_t wifi_config = { |
|
260 .sta = { |
|
261 .ssid = CONFIG_ESP_WIFI_SSID, |
|
262 .password = CONFIG_ESP_WIFI_PASSWORD, |
|
263 #if CONFIG_WIFI_ALL_CHANNEL_SCAN |
|
264 .scan_method = WIFI_ALL_CHANNEL_SCAN, |
|
265 #elif CONFIG_WIFI_FAST_SCAN |
|
266 .scan_method = WIFI_FAST_SCAN, |
|
267 #endif |
|
268 .failure_retry_cnt = 3, |
|
269 .sort_method = WIFI_CONNECT_AP_BY_SIGNAL, |
|
270 .threshold.rssi = CONFIG_ESP_FAST_SCAN_MINIMUM_SIGNAL, |
|
271 .threshold.authmode = WIFI_AUTH_WPA2_PSK, |
|
272 }, |
|
273 }; |
229 ESP_ERROR_CHECK(esp_wifi_set_mode(WIFI_MODE_STA)); |
274 ESP_ERROR_CHECK(esp_wifi_set_mode(WIFI_MODE_STA)); |
|
275 ESP_ERROR_CHECK(esp_wifi_set_config(WIFI_IF_STA, &wifi_config)); |
230 ESP_ERROR_CHECK(esp_wifi_start()); |
276 ESP_ERROR_CHECK(esp_wifi_start()); |
|
277 |
|
278 // ESP_ERROR_CHECK(esp_wifi_set_storage(WIFI_STORAGE_RAM)); |
231 |
279 |
232 xEventGroupSetBits(xEventGroupWifi, TASK_WIFI_REQUEST_STA_CONNECT); |
280 xEventGroupSetBits(xEventGroupWifi, TASK_WIFI_REQUEST_STA_CONNECT); |
233 xEventGroupClearBits(xEventGroupWifi, TASK_WIFI_STA_CONNECTED); |
281 xEventGroupClearBits(xEventGroupWifi, TASK_WIFI_STA_CONNECTED); |
234 xEventGroupSetBits(xEventGroupWifi, TASK_WIFI_STA_DISCONNECTED); |
282 xEventGroupSetBits(xEventGroupWifi, TASK_WIFI_STA_DISCONNECTED); |
235 EventBits_t uxBits; |
283 EventBits_t uxBits; |
236 |
284 |
237 for(;;) { |
285 for(;;) { |
238 |
286 |
239 /* actions that can trigger: request a connection, a scan, or a disconnection */ |
287 /* actions that can trigger: request a connection, a scan, or a disconnection */ |
240 uxBits = xEventGroupWaitBits(xEventGroupWifi, |
288 uxBits = xEventGroupWaitBits(xEventGroupWifi, |
241 TASK_WIFI_REQUEST_STA_CONNECT | TASK_WIFI_REQUEST_STA_DISCONNECT | TASK_WIFI_REQUEST_STA_STATUS, |
289 TASK_WIFI_REQUEST_STA_CONNECT | TASK_WIFI_REQUEST_STA_DISCONNECT | TASK_WIFI_REQUEST_STA_SCAN | TASK_WIFI_REQUEST_STA_STATUS, |
242 pdFALSE, pdFALSE, portMAX_DELAY ); |
290 pdFALSE, pdFALSE, portMAX_DELAY ); |
243 |
291 |
244 if (uxBits & TASK_WIFI_REQUEST_STA_DISCONNECT) { |
292 if (uxBits & TASK_WIFI_REQUEST_STA_DISCONNECT) { |
245 /* |
293 /* |
246 * user requested a disconnect, this will in effect disconnect the wifi |
294 * user requested a disconnect, this will in effect disconnect the wifi |
247 */ |
295 */ |
248 connect_mqtt(false); |
296 ESP_LOGI(TAG, "Request STA disconnect"); |
249 ESP_LOGD(TAG, "Request STA disconnect"); |
|
250 ESP_ERROR_CHECK(esp_wifi_disconnect()); |
297 ESP_ERROR_CHECK(esp_wifi_disconnect()); |
251 xEventGroupWaitBits(xEventGroupWifi, TASK_WIFI_STA_DISCONNECTED, pdFALSE, pdTRUE, portMAX_DELAY ); |
298 xEventGroupWaitBits(xEventGroupWifi, TASK_WIFI_STA_DISCONNECTED, pdFALSE, pdTRUE, portMAX_DELAY ); |
252 |
299 |
253 /* finally: release the scan request bit */ |
300 /* finally: release the scan request bit */ |
254 xEventGroupClearBits(xEventGroupWifi, TASK_WIFI_REQUEST_STA_DISCONNECT); |
301 xEventGroupClearBits(xEventGroupWifi, TASK_WIFI_REQUEST_STA_DISCONNECT); |
|
302 ESP_LOGI(TAG, "Request STA disconnect is done"); |
255 |
303 |
256 } else if (uxBits & TASK_WIFI_REQUEST_STA_CONNECT) { |
304 } else if (uxBits & TASK_WIFI_REQUEST_STA_CONNECT) { |
257 |
305 |
258 ESP_LOGD(TAG, "Request STA connect"); |
306 ESP_LOGI(TAG, "Request STA connect"); |
259 xEventGroupClearBits(xEventGroupWifi, TASK_WIFI_STA_FAILED); |
307 xEventGroupClearBits(xEventGroupWifi, TASK_WIFI_STA_FAILED); |
260 _wifi_ScanAPs = true; |
308 xEventGroupClearBits(xEventGroupWifi, TASK_WIFI_REQUEST_STA_CONNECT); |
261 _wifi_ScanDone = false; |
309 |
262 ap_num = MAX_AP_NUM; |
310 ESP_LOGI(TAG, "Connecting to `%s'", CONFIG_ESP_WIFI_SSID); |
263 ESP_ERROR_CHECK(esp_wifi_scan_start(&scan_config, false)); |
311 esp_err_t wifierror = esp_wifi_connect(); |
264 while (_wifi_ScanDone == false) { |
312 if (wifierror != ESP_OK) { |
265 vTaskDelay(10 / portTICK_PERIOD_MS); |
313 ESP_LOGE(TAG, "esp_wifi_connect() `%s' rc=%04x", CONFIG_ESP_WIFI_SSID, (int)wifierror); |
266 } |
314 xEventGroupSetBits(xEventGroupWifi, TASK_WIFI_STA_FAILED); |
267 ESP_LOGI(TAG, "Scan done %d APs", _wifi_Scanned); |
315 } |
268 bool found = false; |
316 uxBits = xEventGroupWaitBits(xEventGroupWifi, TASK_WIFI_STA_CONNECTED | TASK_WIFI_STA_FAILED, pdFALSE, pdFALSE, 5000 / portTICK_PERIOD_MS); |
269 |
317 // if (uxBits & TASK_WIFI_STA_CONNECTED) |
270 // Available Access Points. |
318 // xEventGroupClearBits(xEventGroupWifi, TASK_WIFI_REQUEST_STA_CONNECT); // Only clear when connected. |
271 for (int i = 0; i < _wifi_Scanned; i++) { |
319 |
272 wifi_ap_record_t ap = accessp_records[i]; |
|
273 // Check if we know this AP in the database. |
|
274 ESP_LOGD(TAG, "%d %-20s ch: %2d rssi: %d %s", i, ap.ssid, ap.primary, ap.rssi, apsec[ap.authmode]); |
|
275 if ((read_station(ap.ssid) >= 0)) { |
|
276 /* ssid */ |
|
277 size_t sz = sizeof(task_wifi_ConfigSTA->sta.ssid); |
|
278 memcpy(task_wifi_ConfigSTA->sta.ssid, wifiStation.SSID, sz); |
|
279 /* password */ |
|
280 sz = sizeof(task_wifi_ConfigSTA->sta.password); |
|
281 memcpy(task_wifi_ConfigSTA->sta.password, wifiStation.Password, sz); |
|
282 found = true; |
|
283 break; |
|
284 } |
|
285 } |
|
286 if (found) { |
|
287 /* |
|
288 * Now connect to the known SSID |
|
289 */ |
|
290 ESP_LOGD(TAG, "Connecting to `%s'", task_wifi_ConfigSTA->sta.ssid); |
|
291 ESP_ERROR_CHECK(esp_wifi_set_config(WIFI_IF_STA, task_wifi_ConfigSTA)); |
|
292 esp_err_t wifierror = esp_wifi_connect(); |
|
293 if (wifierror != ESP_OK) { |
|
294 ESP_LOGE(TAG, "esp_wifi_connect() `%s' rc=%04x", task_wifi_ConfigSTA->sta.ssid, (int)wifierror); |
|
295 xEventGroupSetBits(xEventGroupWifi, TASK_WIFI_STA_FAILED); |
|
296 } |
|
297 uxBits = xEventGroupWaitBits(xEventGroupWifi, TASK_WIFI_STA_CONNECTED | TASK_WIFI_STA_FAILED, pdFALSE, pdFALSE, 5000 / portTICK_PERIOD_MS); |
|
298 if (uxBits & TASK_WIFI_STA_CONNECTED) |
|
299 xEventGroupClearBits(xEventGroupWifi, TASK_WIFI_REQUEST_STA_CONNECT); // Only clear when connected. |
|
300 } else { |
|
301 ESP_LOGI(TAG, "No known AP found, scan again"); |
|
302 vTaskDelay(3000 / portTICK_PERIOD_MS); |
|
303 } |
|
304 } else if (uxBits & TASK_WIFI_REQUEST_STA_STATUS) { |
320 } else if (uxBits & TASK_WIFI_REQUEST_STA_STATUS) { |
305 /* |
321 /* |
306 * Request WiFi update status, refresh the rssi. |
322 * Request WiFi update status, refresh the rssi. |
307 */ |
323 */ |
|
324 ESP_LOGD(TAG, "Request STA status"); |
308 xEventGroupClearBits(xEventGroupWifi, TASK_WIFI_REQUEST_STA_STATUS); |
325 xEventGroupClearBits(xEventGroupWifi, TASK_WIFI_REQUEST_STA_STATUS); |
309 wifi_ap_record_t ap_info; |
326 wifi_ap_record_t ap_info; |
310 esp_wifi_sta_get_ap_info(&ap_info); |
327 esp_wifi_sta_get_ap_info(&ap_info); |
311 ESP_LOGD(TAG, "Event STA status, ssid:%s, bssid:" MACSTR ", rssi: %d", ap_info.ssid, MAC2STR(ap_info.bssid), ap_info.rssi); |
328 ESP_LOGI(TAG, "Event STA status, ssid:%s, bssid:" MACSTR ", rssi: %d", ap_info.ssid, MAC2STR(ap_info.bssid), ap_info.rssi); |
|
329 _wifi_RSSI = ap_info.rssi; |
|
330 _wifi_BetterAP = false; |
312 if (xSemaphoreTake(xSemaphoreWiFi, 35) == pdTRUE) { |
331 if (xSemaphoreTake(xSemaphoreWiFi, 35) == pdTRUE) { |
313 wifi_state->STA_rssi = ap_info.rssi; |
332 wifi_state->STA_rssi = ap_info.rssi; |
|
333 wifi_state->STA_channel = ap_info.primary; |
|
334 snprintf(wifi_state->STA_bssid, 18, "%02x:%02x:%02x:%02x:%02x:%02x", |
|
335 ap_info.bssid[0], ap_info.bssid[1], ap_info.bssid[2], ap_info.bssid[3], ap_info.bssid[4], ap_info.bssid[5]); |
314 xSemaphoreGive(xSemaphoreWiFi); |
336 xSemaphoreGive(xSemaphoreWiFi); |
315 } else { |
337 } else { |
316 ESP_LOGE(TAG, "lock error TASK_WIFI_REQUEST_STA_STATUS"); |
338 ESP_LOGE(TAG, "lock error TASK_WIFI_REQUEST_STA_STATUS"); |
317 } |
339 } |
318 user_refresh(); |
340 user_refresh(); |
|
341 |
|
342 } else if (uxBits & TASK_WIFI_REQUEST_STA_SCAN) { |
|
343 |
|
344 ESP_LOGI(TAG, "Request STA scan"); |
|
345 xEventGroupClearBits(xEventGroupWifi, TASK_WIFI_REQUEST_STA_SCAN); |
|
346 /* safe guard against overflow */ |
|
347 ap_num = MAX_AP_NUM; |
|
348 _wifi_ScanDone = false; |
|
349 _wifi_BetterAP = false; |
|
350 ESP_ERROR_CHECK(esp_wifi_scan_start(&scan_config, false)); |
319 } |
351 } |
320 |
352 |
321 } /* for(;;) */ |
353 } /* for(;;) */ |
322 vTaskDelay(10 / portTICK_PERIOD_MS); |
354 // vTaskDelay(10 / portTICK_PERIOD_MS); |
323 } |
355 } |
324 |
356 |
325 |
357 |