Wed, 08 May 2019 15:46:50 +0200
Merged with default version 0.3.0
0 | 1 | /** |
2 | * @file task_wifi.c | |
3 | * @brief WiFi task. Connects to a known Access Point. If we know more then | |
4 | * one AP, try to connect all of them until it succeeds (Not yet written). | |
5 | */ | |
6 | ||
7 | ||
8 | #include "config.h" | |
9 | ||
10 | ||
11 | static const char *TAG = "task_wifi"; | |
12 | ||
13 | ||
14 | SemaphoreHandle_t xSemaphoreWiFi = NULL; ///< Semaphore WiFi task. | |
15 | EventGroupHandle_t xEventGroupWifi; ///< Events WiFi task. | |
16 | uint16_t ap_num = MAX_AP_NUM; ///< Scan counter. | |
17 | wifi_ap_record_t *accessp_records; ///< [MAX_AP_NUM] records array with scan results. | |
18 | wifi_config_t *task_wifi_ConfigSTA = NULL; ///< Current STA configuration. | |
19 | WIFI_State *wifi_state = NULL; ///< Public state for other tasks. | |
20 | ||
21 | ||
1
ad2c8b13eb88
Updated lots of doxygen comments
Michiel Broek <mbroek@mbse.eu>
parents:
0
diff
changeset
|
22 | uint8_t _wifi_ssid[33]; ///< Current SSID |
ad2c8b13eb88
Updated lots of doxygen comments
Michiel Broek <mbroek@mbse.eu>
parents:
0
diff
changeset
|
23 | bool _wifi_ScanAPs = false; ///< Scanning |
ad2c8b13eb88
Updated lots of doxygen comments
Michiel Broek <mbroek@mbse.eu>
parents:
0
diff
changeset
|
24 | bool _wifi_ScanDone = false; ///< Scan ready |
ad2c8b13eb88
Updated lots of doxygen comments
Michiel Broek <mbroek@mbse.eu>
parents:
0
diff
changeset
|
25 | uint16_t _wifi_Scanned = 0; ///< Total scanned APs. |
0 | 26 | |
27 | extern int Main_Screen; ///< Current Screen number. | |
28 | extern sButton Buttons[MAXBUTTONS]; ///< Buttons definitions. | |
29 | extern uint32_t TimeSpent; ///< Counter that is increased each second. | |
30 | ||
31 | const int TASK_WIFI_REQUEST_WIFI_SCAN = BIT0; ///< When set, means a client requested to scan wireless networks. | |
32 | const int TASK_WIFI_REQUEST_STA_DISCONNECT = BIT1; ///< When set, means a client requested to disconnect from currently connected AP. | |
33 | const int TASK_WIFI_REQUEST_STA_CONNECT = BIT2; ///< When set, means a client requested to connect to an access point. | |
34 | ||
35 | const int TASK_WIFI_HAS_IP = BIT3; ///< Indicate that we have an IP address | |
36 | const int TASK_WIFI_AP_STARTED = BIT4; ///< Indicate that the SoftAP is started | |
37 | const int TASK_WIFI_STA_FAILED = BIT5; ///< Indicate that we could not get a connection to AP as station. | |
1
ad2c8b13eb88
Updated lots of doxygen comments
Michiel Broek <mbroek@mbse.eu>
parents:
0
diff
changeset
|
38 | const int TASK_WIFI_STA_DISCONNECTED = BIT6; ///< Indicate that we are disconnected from an ap station. |
0 | 39 | const int TASK_WIFI_STA_CONNECTED = BIT7; ///< Indicate that we are connected to AP as station, flip of BIT6. |
40 | ||
41 | ||
42 | /** | |
43 | * @brief Local function, save station configuration. | |
44 | * @return Esp error code. | |
45 | */ | |
46 | esp_err_t SaveStaConfig(void); | |
47 | ||
48 | /** | |
49 | * @brief Local function, fetch last connected station configuration. | |
50 | * @return True if there was a last connection, false if there was not. | |
51 | */ | |
52 | bool FetchStaConfig(void); | |
53 | ||
54 | /** | |
55 | * @brief Local function, WiFi event handler. | |
1
ad2c8b13eb88
Updated lots of doxygen comments
Michiel Broek <mbroek@mbse.eu>
parents:
0
diff
changeset
|
56 | * @param ctx Context |
ad2c8b13eb88
Updated lots of doxygen comments
Michiel Broek <mbroek@mbse.eu>
parents:
0
diff
changeset
|
57 | * @param event The event |
0 | 58 | * @return Esp error code. |
59 | */ | |
60 | esp_err_t task_wifi_EventHandler(void *ctx, system_event_t *event); | |
61 | ||
62 | ||
63 | /****************************************************************************/ | |
64 | ||
65 | ||
66 | ||
67 | esp_err_t SaveStaConfig(void) | |
68 | { | |
69 | int record; | |
70 | ||
71 | if (task_wifi_ConfigSTA && strlen((char *)task_wifi_ConfigSTA->sta.ssid)) { | |
72 | /* | |
73 | * Store in /spiffs/stations.conf if it's a new station. | |
74 | */ | |
75 | record = read_station(task_wifi_ConfigSTA->sta.ssid); | |
76 | if (record == -1) { | |
77 | add_station(task_wifi_ConfigSTA->sta.ssid, task_wifi_ConfigSTA->sta.password); | |
78 | } | |
79 | ||
80 | /* | |
81 | * Update main configuration if needed. | |
82 | */ | |
83 | if (strcmp(config.lastSSID, (char *)task_wifi_ConfigSTA->sta.ssid)) { | |
84 | sprintf(config.lastSSID, "%s", task_wifi_ConfigSTA->sta.ssid); | |
85 | write_config(); | |
86 | } | |
87 | ESP_LOGI(TAG, "SaveStaConfig %s, record %d", wifiStation.SSID, record); | |
88 | } | |
89 | ||
90 | return ESP_OK; | |
91 | } | |
92 | ||
93 | ||
94 | ||
95 | bool FetchStaConfig(void) | |
96 | { | |
97 | if (task_wifi_ConfigSTA == NULL) { | |
98 | task_wifi_ConfigSTA = (wifi_config_t*)malloc(sizeof(wifi_config_t)); | |
99 | } | |
100 | memset(task_wifi_ConfigSTA, 0x00, sizeof(wifi_config_t)); | |
101 | ||
102 | /* | |
103 | * Search last connected AP as station. | |
104 | */ | |
105 | if (strlen(config.lastSSID)) { | |
106 | read_station((uint8_t *)config.lastSSID); | |
107 | ||
108 | /* ssid */ | |
109 | size_t sz = sizeof(task_wifi_ConfigSTA->sta.ssid); | |
110 | memcpy(task_wifi_ConfigSTA->sta.ssid, wifiStation.SSID, sz); | |
111 | ||
112 | /* password */ | |
113 | sz = sizeof(task_wifi_ConfigSTA->sta.password); | |
114 | memcpy(task_wifi_ConfigSTA->sta.password, wifiStation.Password, sz); | |
115 | ||
116 | ESP_LOGI(TAG, "FetchStaConfig: last connected to ssid: %s", task_wifi_ConfigSTA->sta.ssid); | |
117 | return task_wifi_ConfigSTA->sta.ssid[0] != '\0'; | |
118 | } | |
119 | ||
120 | ESP_LOGI(TAG, "FetchStaConfig: no last connection found"); | |
121 | return false; | |
122 | } | |
123 | ||
124 | ||
125 | ||
126 | esp_err_t task_wifi_EventHandler(void *ctx, system_event_t *event) | |
127 | { | |
128 | switch(event->event_id) { | |
129 | case SYSTEM_EVENT_SCAN_DONE: | |
130 | // Get the results so the memory used is freed. | |
131 | ESP_ERROR_CHECK(esp_wifi_scan_get_ap_records(&ap_num, accessp_records)); | |
132 | _wifi_Scanned = ap_num; | |
133 | _wifi_ScanDone = true; | |
134 | break; | |
135 | ||
136 | case SYSTEM_EVENT_STA_START: | |
137 | ESP_LOGD(TAG, "Event STA started"); | |
138 | // Set the configured hostname for the dhcp client. | |
139 | ESP_ERROR_CHECK(tcpip_adapter_set_hostname(TCPIP_ADAPTER_IF_STA, config.hostname)); | |
140 | esp_wifi_connect(); | |
141 | break; | |
142 | ||
143 | // SYSTEM_EVENT_STA_STOP 3 | |
144 | case SYSTEM_EVENT_STA_CONNECTED: | |
34
5c92103c5e72
Version 0.2.10. Fixed spelling error in websocket component. Updated esp-idf to v4.0-dev-459-gba1ff1692 and adjusted several sources for changed headers. Finalized keeping the AP running at all times. Increased websocket server stack depth from 6000 to 7000.
Michiel Broek <mbroek@mbse.eu>
parents:
22
diff
changeset
|
145 | ESP_LOGI(TAG, "Event STA connected"); |
0 | 146 | wifi_ap_record_t ap_info; |
147 | esp_wifi_sta_get_ap_info(&ap_info); | |
148 | if (xSemaphoreTake(xSemaphoreWiFi, 25) == pdTRUE) { | |
149 | wifi_state->STA_connected = true; | |
150 | wifi_state->STA_rssi = ap_info.rssi; | |
151 | sprintf(wifi_state->STA_ssid, "%s", ap_info.ssid); | |
152 | xSemaphoreGive(xSemaphoreWiFi); | |
153 | } | |
154 | xEventGroupSetBits(xEventGroupWifi, TASK_WIFI_STA_CONNECTED); | |
155 | xEventGroupClearBits(xEventGroupWifi, TASK_WIFI_STA_DISCONNECTED); | |
156 | break; | |
157 | ||
158 | case SYSTEM_EVENT_STA_DISCONNECTED: | |
34
5c92103c5e72
Version 0.2.10. Fixed spelling error in websocket component. Updated esp-idf to v4.0-dev-459-gba1ff1692 and adjusted several sources for changed headers. Finalized keeping the AP running at all times. Increased websocket server stack depth from 6000 to 7000.
Michiel Broek <mbroek@mbse.eu>
parents:
22
diff
changeset
|
159 | ESP_LOGI(TAG, "Event STA disconnected"); |
0 | 160 | if (xSemaphoreTake(xSemaphoreWiFi, 10) == pdTRUE) { |
161 | wifi_state->STA_connected = false; | |
22
90f22a101fc6
Boot now checks got IP status before installing the http and vnc servers.
Michiel Broek <mbroek@mbse.eu>
parents:
1
diff
changeset
|
162 | wifi_state->STA_online = false; |
0 | 163 | wifi_state->STA_rssi = 0; |
164 | xSemaphoreGive(xSemaphoreWiFi); | |
165 | } | |
166 | xEventGroupClearBits(xEventGroupWifi, TASK_WIFI_STA_CONNECTED); | |
167 | xEventGroupSetBits(xEventGroupWifi, TASK_WIFI_STA_DISCONNECTED); | |
168 | ||
169 | /* | |
170 | * Meanwhile, try to reconnect. | |
171 | */ | |
172 | if (FetchStaConfig()) { | |
173 | xEventGroupSetBits(xEventGroupWifi, TASK_WIFI_REQUEST_STA_CONNECT); | |
174 | } | |
175 | break; | |
176 | ||
177 | // SYSTEM_EVENT_STA_AUTHMODE_CHANGE 6 | |
178 | case SYSTEM_EVENT_STA_GOT_IP: | |
179 | xEventGroupSetBits(xEventGroupWifi, TASK_WIFI_HAS_IP); | |
180 | tcpip_adapter_ip_info_t ip; | |
181 | memset(&ip, 0, sizeof(tcpip_adapter_ip_info_t)); | |
182 | if (tcpip_adapter_get_ip_info(ESP_IF_WIFI_STA, &ip) == 0) { | |
183 | if (xSemaphoreTake(xSemaphoreWiFi, 10) == pdTRUE) { | |
22
90f22a101fc6
Boot now checks got IP status before installing the http and vnc servers.
Michiel Broek <mbroek@mbse.eu>
parents:
1
diff
changeset
|
184 | wifi_state->STA_online = true; |
0 | 185 | snprintf(wifi_state->STA_ip, 15, IPSTR, IP2STR(&ip.ip)); |
186 | snprintf(wifi_state->STA_nm, 15, IPSTR, IP2STR(&ip.netmask)); | |
187 | snprintf(wifi_state->STA_gw, 15, IPSTR, IP2STR(&ip.gw)); | |
188 | xSemaphoreGive(xSemaphoreWiFi); | |
189 | } | |
190 | } | |
191 | break; | |
192 | ||
193 | case SYSTEM_EVENT_STA_LOST_IP: | |
194 | ESP_LOGI(TAG, "Lost IP address"); | |
195 | xEventGroupClearBits(xEventGroupWifi, TASK_WIFI_HAS_IP); | |
196 | if (xSemaphoreTake(xSemaphoreWiFi, 10) == pdTRUE) { | |
197 | wifi_state->STA_ip[0] = '\0'; | |
198 | wifi_state->STA_nm[0] = '\0'; | |
199 | wifi_state->STA_gw[0] = '\0'; | |
22
90f22a101fc6
Boot now checks got IP status before installing the http and vnc servers.
Michiel Broek <mbroek@mbse.eu>
parents:
1
diff
changeset
|
200 | wifi_state->STA_online = false; |
0 | 201 | xSemaphoreGive(xSemaphoreWiFi); |
202 | } | |
203 | break; | |
204 | ||
205 | // SYSTEM_EVENT_STA_WPS_ER_SUCCESS 9 | |
206 | // SYSTEM_EVENT_STA_WPS_ER_FAILED 10 | |
207 | // SYSTEM_EVENT_STA_WPS_ER_TIMEOUT 11 | |
208 | // SYSTEM_EVENT_STA_WPS_ER_PIN 12 | |
209 | ||
210 | case SYSTEM_EVENT_AP_START: | |
211 | ESP_LOGD(TAG, "Event AP started"); | |
212 | xEventGroupSetBits(xEventGroupWifi, TASK_WIFI_AP_STARTED); | |
213 | if (xSemaphoreTake(xSemaphoreWiFi, 25) == pdTRUE) { | |
214 | wifi_state->AP_active = true; | |
215 | wifi_state->AP_clients = 0; | |
216 | xSemaphoreGive(xSemaphoreWiFi); | |
217 | } | |
218 | break; | |
219 | ||
220 | case SYSTEM_EVENT_AP_STOP: | |
221 | ESP_LOGD(TAG, "Event AP stopped"); | |
222 | xEventGroupClearBits(xEventGroupWifi, TASK_WIFI_AP_STARTED); | |
223 | if (xSemaphoreTake(xSemaphoreWiFi, 25) == pdTRUE) { | |
224 | wifi_state->AP_active = false; | |
225 | wifi_state->AP_clients = 0; | |
226 | xSemaphoreGive(xSemaphoreWiFi); | |
227 | } | |
228 | break; | |
229 | ||
230 | case SYSTEM_EVENT_AP_STACONNECTED: | |
231 | if (xSemaphoreTake(xSemaphoreWiFi, 25) == pdTRUE) { | |
232 | wifi_state->AP_clients++; | |
233 | xSemaphoreGive(xSemaphoreWiFi); | |
234 | } | |
235 | ESP_LOGI(TAG, "Event AP new client, %d connections", wifi_state->AP_clients); | |
236 | break; | |
237 | ||
238 | case SYSTEM_EVENT_AP_STADISCONNECTED: | |
239 | if (xSemaphoreTake(xSemaphoreWiFi, 25) == pdTRUE) { | |
240 | if (wifi_state->AP_clients > 0) | |
241 | wifi_state->AP_clients--; | |
242 | else | |
243 | wifi_state->AP_clients = 0; | |
244 | xSemaphoreGive(xSemaphoreWiFi); | |
245 | } | |
246 | ESP_LOGI(TAG, "Event AP client disconnect, %d connections", wifi_state->AP_clients); | |
247 | break; | |
248 | ||
249 | // SYSTEM_EVENT_AP_PROBEREQRECVED 17 | |
250 | // SYSTEM_EVENT_GOT_IP6 18 | |
251 | // SYSTEM_EVENT_ETH_START 19 | |
252 | // SYSTEM_EVENT_ETH_STOP 20 | |
253 | // SYSTEM_EVENT_ETH_CONNECTED 21 | |
254 | // SYSTEM_EVENT_ETH_DISCONNECTED 22 | |
255 | // SYSTEM_EVENT_ETH_GOT_IP 23 | |
256 | ||
257 | default: | |
258 | printf("Unknown event %d\n", event->event_id); | |
259 | break; | |
260 | } | |
261 | return ESP_OK; | |
262 | } | |
263 | ||
264 | ||
265 | ||
266 | void task_wifi( void * pvParameters ) | |
267 | { | |
268 | esp_err_t ret; | |
269 | ||
34
5c92103c5e72
Version 0.2.10. Fixed spelling error in websocket component. Updated esp-idf to v4.0-dev-459-gba1ff1692 and adjusted several sources for changed headers. Finalized keeping the AP running at all times. Increased websocket server stack depth from 6000 to 7000.
Michiel Broek <mbroek@mbse.eu>
parents:
22
diff
changeset
|
270 | ESP_LOGI(TAG, "Starting WiFi"); |
0 | 271 | |
272 | /* | |
273 | * Initialize NVS | |
274 | */ | |
275 | ret = nvs_flash_init(); | |
276 | if (ret == ESP_ERR_NVS_NO_FREE_PAGES) { | |
277 | ESP_ERROR_CHECK(nvs_flash_erase()); | |
278 | ret = nvs_flash_init(); | |
279 | } | |
280 | ESP_ERROR_CHECK(ret); | |
281 | ||
282 | /* event handler and event group for the wifi driver */ | |
283 | xEventGroupWifi = xEventGroupCreate(); | |
284 | /* initialize the tcp stack */ | |
285 | tcpip_adapter_init(); | |
286 | ESP_ERROR_CHECK(esp_event_loop_init(task_wifi_EventHandler, NULL)); | |
287 | ||
288 | /* | |
289 | * memory allocation of objects used by the task | |
290 | */ | |
291 | accessp_records = (wifi_ap_record_t*)malloc(sizeof(wifi_ap_record_t) * MAX_AP_NUM); | |
292 | task_wifi_ConfigSTA = (wifi_config_t*)malloc(sizeof(wifi_config_t)); | |
293 | memset(task_wifi_ConfigSTA, 0x00, sizeof(wifi_config_t)); | |
294 | ||
295 | xSemaphoreWiFi = xSemaphoreCreateMutex(); | |
296 | wifi_state = malloc(sizeof(WIFI_State)); | |
297 | wifi_state->AP_clients = 0; | |
298 | wifi_state->AP_active = false; | |
299 | wifi_state->STA_connected = false; | |
22
90f22a101fc6
Boot now checks got IP status before installing the http and vnc servers.
Michiel Broek <mbroek@mbse.eu>
parents:
1
diff
changeset
|
300 | wifi_state->STA_online = false; |
0 | 301 | wifi_state->STA_rssi = 0; |
302 | ||
303 | /* wifi scanner config */ | |
304 | wifi_scan_config_t scan_config = { | |
305 | .ssid = 0, | |
306 | .bssid = 0, | |
307 | .channel = 0, | |
308 | .show_hidden = false | |
309 | }; | |
310 | ||
311 | /* | |
312 | * start the softAP access point | |
313 | * stop DHCP server | |
314 | */ | |
315 | ESP_ERROR_CHECK(tcpip_adapter_dhcps_stop(TCPIP_ADAPTER_IF_AP)); | |
316 | ||
317 | /* | |
318 | * Assign a static IP to the AP network interface | |
319 | */ | |
320 | tcpip_adapter_ip_info_t info; | |
321 | memset(&info, 0x00, sizeof(info)); | |
322 | IP4_ADDR(&info.ip, 192, 168, 1, 1); | |
323 | IP4_ADDR(&info.gw, 192, 168, 1, 1); | |
324 | IP4_ADDR(&info.netmask, 255, 255, 255, 0); | |
325 | ESP_ERROR_CHECK(tcpip_adapter_set_ip_info(TCPIP_ADAPTER_IF_AP, &info)); | |
326 | ||
327 | /* start dhcp server */ | |
328 | ESP_ERROR_CHECK(tcpip_adapter_dhcps_start(TCPIP_ADAPTER_IF_AP)); | |
329 | ESP_LOGI(TAG, "AP start dhcps ip: 192.168.1.1 nm: 255.255.255.0 gw: 192.168.1.1"); | |
330 | ||
331 | /* start dhcp client */ | |
332 | ESP_ERROR_CHECK(tcpip_adapter_dhcpc_start(TCPIP_ADAPTER_IF_STA)); | |
333 | ESP_LOGI(TAG, "Start DHCP client for STA interface."); | |
334 | ||
335 | /* | |
336 | * init wifi as station + access point | |
337 | */ | |
338 | wifi_init_config_t wifi_init_config = WIFI_INIT_CONFIG_DEFAULT(); | |
339 | ESP_ERROR_CHECK(esp_wifi_init(&wifi_init_config)); | |
340 | ESP_ERROR_CHECK(esp_wifi_set_storage(WIFI_STORAGE_RAM)); | |
341 | ESP_ERROR_CHECK(esp_wifi_set_mode(WIFI_MODE_APSTA)); | |
342 | ESP_ERROR_CHECK(esp_wifi_set_bandwidth(WIFI_IF_AP, config.ap_bandwidth)); | |
343 | ||
344 | // configure the softAP and start it */ | |
345 | wifi_config_t ap_config = { | |
346 | .ap = { | |
347 | .ssid_len = 0, | |
348 | .channel = config.ap_channel, | |
349 | .authmode = WIFI_AUTH_WPA2_PSK, | |
350 | .ssid_hidden = config.ap_ssid_hidden, | |
351 | .max_connection = AP_MAX_CONNECTIONS, | |
352 | .beacon_interval = 100, | |
353 | }, | |
354 | }; | |
355 | memcpy(ap_config.ap.ssid, config.ap_ssid , sizeof(config.ap_ssid)); | |
356 | memcpy(ap_config.ap.password, config.ap_pwd, sizeof(config.ap_pwd)); | |
357 | ret = esp_wifi_set_config(WIFI_IF_AP, &ap_config); | |
358 | if (ret != ESP_OK) { | |
359 | ESP_LOGE(TAG, "esp_wifi_set_config(WIFI_IF_AP, nnn) rc=%d", ret); | |
360 | } | |
361 | ESP_ERROR_CHECK(esp_wifi_start()); | |
362 | ||
363 | ESP_LOGI(TAG, "SoftAP start ssid: `%s' pwd: `%s' channel: %d, hidden: %s", | |
364 | ap_config.ap.ssid, ap_config.ap.password, ap_config.ap.channel, ap_config.ap.ssid_hidden ? "yes":"no"); | |
365 | ||
366 | /* | |
367 | * try to get access to previously saved wifi | |
368 | */ | |
369 | if (FetchStaConfig()) { | |
370 | xEventGroupSetBits(xEventGroupWifi, TASK_WIFI_REQUEST_STA_CONNECT); | |
371 | } | |
372 | ||
373 | /* | |
374 | * Wait for access point to start | |
375 | */ | |
376 | xEventGroupSetBits(xEventGroupWifi, TASK_WIFI_STA_DISCONNECTED); | |
377 | xEventGroupWaitBits(xEventGroupWifi, TASK_WIFI_AP_STARTED, pdFALSE, pdTRUE, portMAX_DELAY ); | |
378 | EventBits_t uxBits; | |
379 | ||
380 | for(;;) { | |
381 | ||
382 | /* actions that can trigger: request a connection, a scan, or a disconnection */ | |
383 | uxBits = xEventGroupWaitBits(xEventGroupWifi, | |
384 | TASK_WIFI_REQUEST_STA_CONNECT | TASK_WIFI_REQUEST_WIFI_SCAN | TASK_WIFI_REQUEST_STA_DISCONNECT, | |
385 | pdFALSE, pdFALSE, portMAX_DELAY ); | |
386 | ||
387 | if (uxBits & TASK_WIFI_REQUEST_STA_DISCONNECT) { | |
388 | /* | |
389 | * user requested a disconnect, this will in effect disconnect the wifi but also erase NVS memory | |
390 | */ | |
391 | ESP_LOGI(TAG, "Request disconnect"); | |
392 | sntp_stop(); | |
393 | ESP_ERROR_CHECK(esp_wifi_disconnect()); | |
394 | xEventGroupWaitBits(xEventGroupWifi, TASK_WIFI_STA_DISCONNECTED, pdFALSE, pdTRUE, portMAX_DELAY ); | |
395 | ||
396 | /* | |
397 | * erase configuration | |
398 | */ | |
399 | if (task_wifi_ConfigSTA) { | |
400 | memset(task_wifi_ConfigSTA, 0x00, sizeof(wifi_config_t)); | |
401 | } | |
402 | config.lastSSID[0] = '\0'; | |
403 | write_config(); | |
404 | ||
405 | /* finally: release the scan request bit */ | |
406 | xEventGroupClearBits(xEventGroupWifi, TASK_WIFI_REQUEST_STA_DISCONNECT); | |
407 | ESP_LOGI(TAG, "Request disconnect is finished."); | |
408 | ||
409 | } else if (uxBits & TASK_WIFI_REQUEST_STA_CONNECT) { | |
410 | ||
411 | //someone requested a connection! | |
412 | ESP_LOGI(TAG, "Request STA connect `%s'", task_wifi_ConfigSTA->sta.ssid); | |
413 | /* set the new config and connect - reset the failed bit first as it is later tested */ | |
414 | xEventGroupClearBits(xEventGroupWifi, TASK_WIFI_STA_FAILED); | |
415 | ESP_ERROR_CHECK(esp_wifi_set_config(WIFI_IF_STA, task_wifi_ConfigSTA)); | |
416 | ||
417 | esp_err_t wifierror = esp_wifi_connect(); | |
418 | if (wifierror != ESP_OK) { | |
419 | ESP_LOGE(TAG, "esp_wifi_connect() rc=%04x", (int)wifierror); | |
420 | xEventGroupSetBits(xEventGroupWifi, TASK_WIFI_STA_FAILED); | |
421 | } | |
422 | ||
423 | /* | |
424 | * 2 scenarios here: connection is successful and TASK_WIFI_HAS_IP will be posted | |
425 | * or it's a failure and we get a TASK_WIFI_STA_FAILED with a reason code. | |
426 | * Note that the reason code is not exploited. For all intent and purposes a failure is a failure. | |
427 | */ | |
428 | uxBits = xEventGroupWaitBits(xEventGroupWifi, TASK_WIFI_HAS_IP | TASK_WIFI_STA_FAILED, pdFALSE, pdFALSE, portMAX_DELAY ); | |
429 | ||
430 | if (uxBits & (TASK_WIFI_HAS_IP | TASK_WIFI_STA_FAILED)) { | |
431 | /* | |
432 | * only save the config if the connection was successful! | |
433 | */ | |
434 | if(uxBits & TASK_WIFI_HAS_IP) { | |
435 | /* save wifi config */ | |
436 | SaveStaConfig(); | |
437 | sntp_setservername(0, "nl.pool.ntp.org"); | |
438 | sntp_init(); | |
439 | ESP_LOGI(TAG, "Initialized SNTP %s", sntp_getservername(0)); | |
440 | } else { | |
441 | ESP_LOGI(TAG, "Connection failed"); // TODO: Scan other SSID's for known networks. | |
442 | /* failed attempt to connect regardles of the reason */ | |
443 | ||
444 | /* otherwise: reset the config */ | |
445 | memset(task_wifi_ConfigSTA, 0x00, sizeof(wifi_config_t)); | |
446 | } | |
447 | } else { | |
448 | /* hit portMAX_DELAY limit ? */ | |
449 | abort(); | |
450 | } | |
451 | ||
452 | /* finally: release the connection request bit */ | |
453 | xEventGroupClearBits(xEventGroupWifi, TASK_WIFI_REQUEST_STA_CONNECT); | |
454 | ||
455 | } else if (uxBits & TASK_WIFI_REQUEST_WIFI_SCAN) { | |
456 | ||
457 | /* safe guard against overflow */ | |
458 | ap_num = MAX_AP_NUM; | |
459 | ESP_ERROR_CHECK(esp_wifi_scan_start(&scan_config, false)); | |
460 | ||
461 | /* finally: release the scan request bit */ | |
462 | xEventGroupClearBits(xEventGroupWifi, TASK_WIFI_REQUEST_WIFI_SCAN); | |
463 | } | |
464 | ||
465 | /* | |
466 | * Here we should check for reconnect actions. | |
467 | */ | |
468 | ||
469 | } /* for(;;) */ | |
470 | vTaskDelay( (TickType_t)10); | |
471 | } | |
472 | ||
473 | ||
1
ad2c8b13eb88
Updated lots of doxygen comments
Michiel Broek <mbroek@mbse.eu>
parents:
0
diff
changeset
|
474 | /** |
ad2c8b13eb88
Updated lots of doxygen comments
Michiel Broek <mbroek@mbse.eu>
parents:
0
diff
changeset
|
475 | * @brief Array with AP security names |
ad2c8b13eb88
Updated lots of doxygen comments
Michiel Broek <mbroek@mbse.eu>
parents:
0
diff
changeset
|
476 | */ |
0 | 477 | const char *apsec[] = { "Open", "WEP", "WPA", "WPA2", "WPA WPA2", "Enterprise" }; |
478 | ||
479 | ||
480 | /** | |
481 | * @brief Show an AP station as a button. The buttons are already defined. | |
482 | * @param idx The index position on the display, 1 to 7. | |
483 | * @param ap The AP information from the WiFi scan. | |
1
ad2c8b13eb88
Updated lots of doxygen comments
Michiel Broek <mbroek@mbse.eu>
parents:
0
diff
changeset
|
484 | * @param show How to display. 0 is blank, 1 is unknown, 2 is known, 3 is a connected AP. |
0 | 485 | */ |
486 | void Show_AP(uint8_t idx, wifi_ap_record_t ap, int show) | |
487 | { | |
488 | char tmp[33]; | |
489 | ||
490 | if ((idx > 7) || (idx < 1)) | |
491 | return; | |
492 | ||
493 | if (show == 0) { | |
494 | _bg = TFT_BLACK; | |
495 | } else { | |
496 | _bg = (color_t){ 63, 63, 64 }; | |
497 | } | |
498 | ||
499 | TFT_fillRect(Buttons[idx].x, Buttons[idx].y, Buttons[idx].w, Buttons[idx].h, _bg); | |
500 | if (show == 0) | |
501 | return; | |
502 | ||
503 | TFT_drawRect(Buttons[idx].x, Buttons[idx].y, Buttons[idx].w, Buttons[idx].h, TFT_NAVY); | |
504 | if (show == 3) { | |
505 | _fg = TFT_WHITE; | |
506 | } else if (show == 1) { | |
507 | _fg = TFT_YELLOW; | |
508 | } else { | |
509 | _fg = TFT_CYAN; | |
510 | } | |
511 | ||
512 | TFT_setFont(DEJAVU18_FONT, NULL); | |
513 | sprintf(tmp, "%s", ap.ssid); | |
514 | TFT_print(tmp, Buttons[idx].x + 5, Buttons[idx].y + 6); | |
515 | sprintf(tmp, "%d", ap.rssi); | |
516 | TFT_setFont(DEF_SMALL_FONT, NULL); | |
517 | TFT_print(tmp, Buttons[idx].x + Buttons[idx].w - (TFT_getStringWidth(tmp) + 5), Buttons[idx].y + 4); | |
518 | sprintf(tmp, "%s", apsec[ap.authmode]); | |
519 | TFT_print(tmp, Buttons[idx].x + Buttons[idx].w - (TFT_getStringWidth(tmp) + 5), Buttons[idx].y + 15); | |
520 | } | |
521 | ||
522 | ||
523 | ||
524 | bool WiFi_Init(void) | |
525 | { | |
526 | char pwd[65], pmpt[32]; | |
527 | ||
528 | switch (Main_Screen) { | |
529 | case MAIN_TOOLS_SETUP_WIFI: | |
530 | TopMessage("WiFi"); | |
531 | TFT_setFont(DEJAVU24_FONT, NULL); | |
532 | _fg = TFT_WHITE; | |
533 | TFT_print("Momentje ..", CENTER, CENTER); | |
534 | _wifi_ScanAPs = true; | |
535 | _wifi_ScanDone = false; | |
536 | Buttons_Add(260, 200, 60, 40, "Ok", 0); | |
537 | Buttons[0].dark = true; | |
538 | Buttons_Show(); | |
539 | // Now add the buttons we draw manually. | |
540 | Buttons_Add( 0, 30, 250, 30, "", 1); | |
541 | Buttons_Add( 0, 60, 250, 30, "", 2); | |
542 | Buttons_Add( 0, 90, 250, 30, "", 3); | |
543 | Buttons_Add( 0,120, 250, 30, "", 4); | |
544 | Buttons_Add( 0,150, 250, 30, "", 5); | |
545 | Buttons_Add( 0,180, 250, 30, "", 6); | |
546 | Buttons_Add( 0,210, 250, 30, "", 7); | |
547 | break; | |
548 | ||
549 | case MAIN_TOOLS_SETUP_WIFI_CUR: | |
550 | TopMessage("WiFi verbinding"); | |
551 | // Get extra information. | |
552 | wifi_ap_record_t ap_info; | |
553 | esp_wifi_sta_get_ap_info(&ap_info); | |
554 | ||
555 | wifi_config_t *wconfig = task_wifi_ConfigSTA /*task_wifi_GetWifiStaConfig( ) */; | |
556 | if (wconfig) { | |
557 | ||
558 | tcpip_adapter_ip_info_t ip_info; | |
559 | ESP_ERROR_CHECK(tcpip_adapter_get_ip_info(TCPIP_ADAPTER_IF_STA, &ip_info)); | |
560 | char ip[IP4ADDR_STRLEN_MAX]; | |
561 | char gw[IP4ADDR_STRLEN_MAX]; | |
562 | char netmask[IP4ADDR_STRLEN_MAX]; | |
563 | strcpy(ip, ip4addr_ntoa(&ip_info.ip)); | |
564 | strcpy(netmask, ip4addr_ntoa(&ip_info.netmask)); | |
565 | strcpy(gw, ip4addr_ntoa(&ip_info.gw)); | |
566 | TFT_setFont(DEFAULT_FONT, NULL); | |
567 | _fg = TFT_WHITE; | |
568 | TFT_print("SSID", 155 - TFT_getStringWidth("SSID"), 40); | |
569 | TFT_print("Kanaal", 155 - TFT_getStringWidth("Kanaal"), 60); | |
570 | TFT_print("Rssi", 155 - TFT_getStringWidth("Rssi"), 80); | |
571 | TFT_print("Mode", 155 - TFT_getStringWidth("Mode"), 100); | |
572 | TFT_print("IP adres", 155 - TFT_getStringWidth("IP adres"), 120); | |
573 | TFT_print("Netmask", 155 - TFT_getStringWidth("Netmask"), 140); | |
574 | TFT_print("Gateway", 155 - TFT_getStringWidth("Gateway"), 160); | |
575 | _fg = TFT_YELLOW; | |
576 | TFT_print((char*)wconfig->sta.ssid, 165, 40); | |
577 | sprintf(pmpt, "%d", ap_info.primary); | |
578 | TFT_print(pmpt, 165, 60); | |
579 | sprintf(pmpt, "%d", ap_info.rssi); | |
580 | TFT_print(pmpt, 165, 80); | |
581 | sprintf(pmpt, "%s%s%s", ap_info.phy_11b ? "b":"", ap_info.phy_11g ? "g":"", ap_info.phy_11n ? "n":""); | |
582 | TFT_print(pmpt, 165, 100); | |
583 | TFT_print((char*)ip, 165, 120); | |
584 | TFT_print((char*)netmask, 165, 140); | |
585 | TFT_print((char*)gw, 165, 160); | |
586 | } | |
587 | Buttons_Add(130, 200, 60, 40, "Ok", 0); | |
588 | Buttons[0].dark = true; | |
589 | Buttons_Show(); | |
590 | break; | |
591 | ||
592 | case MAIN_TOOLS_SETUP_WIFI_CON: | |
593 | TopMessage("WiFi verbinden"); | |
594 | TFT_setFont(DEJAVU18_FONT, NULL); | |
595 | _fg = TFT_WHITE; | |
596 | TFT_print("SSID", 155 - TFT_getStringWidth("SSID"), 70); | |
597 | _fg = TFT_YELLOW; | |
598 | TFT_print((char*)_wifi_ssid, 165, 70); | |
599 | Buttons_Add( 0, 200, 100, 40, "Annuleer", 0); | |
600 | Buttons_Add(110, 200, 100, 40, "Vergeet", 1); | |
601 | Buttons_Add(220, 200, 100, 40, "Verbind", 2); | |
602 | Buttons_Show(); | |
603 | Buttons[0].dark = true; | |
604 | break; | |
605 | ||
606 | case MAIN_TOOLS_SETUP_WIFI_NEW: | |
607 | TopMessage("WiFi nieuw"); | |
608 | snprintf(pmpt, 32, "Password for %s", _wifi_ssid); | |
609 | pwd[0] = '\0'; | |
610 | EditTextMin(pmpt, pwd, 64, 8); | |
611 | /* | |
612 | * Disconnect first | |
613 | */ | |
614 | _bg = TFT_BLACK; | |
615 | TFT_fillScreen(_bg); | |
616 | TFT_setFont(DEJAVU24_FONT, NULL); | |
617 | _fg = TFT_WHITE; | |
618 | TFT_print("Momentje ..", CENTER, CENTER); | |
619 | xEventGroupSetBits(xEventGroupWifi, TASK_WIFI_REQUEST_STA_DISCONNECT); | |
620 | vTaskDelay(100 / portTICK_PERIOD_MS); | |
621 | xEventGroupWaitBits(xEventGroupWifi, TASK_WIFI_STA_DISCONNECTED, pdFALSE, pdTRUE, portMAX_DELAY ); | |
622 | ||
623 | /* | |
624 | * Setup new connection | |
625 | */ | |
626 | if (strlen(pwd)) { | |
627 | wifi_config_t* config = task_wifi_ConfigSTA; | |
628 | memset(config, 0x00, sizeof(wifi_config_t)); | |
629 | memcpy(config->sta.ssid, _wifi_ssid, strlen((char*)_wifi_ssid)); | |
630 | memcpy(config->sta.password, pwd, strlen(pwd)); | |
631 | ESP_LOGI(TAG, "new AP %s %s", _wifi_ssid, pwd); | |
632 | xEventGroupSetBits(xEventGroupWifi, TASK_WIFI_REQUEST_STA_CONNECT); | |
633 | } else { | |
634 | // TODO: what about WPS, it works but how to insert it in this app. | |
635 | return true; | |
636 | } | |
637 | // We must wait here for the result. | |
638 | break; | |
639 | ||
640 | default: | |
641 | break; | |
642 | } | |
643 | ||
644 | return false; | |
645 | } | |
646 | ||
647 | ||
648 | bool WiFi_Loop(void) | |
649 | { | |
650 | uint8_t idx; | |
651 | int Choice; | |
652 | static int AP[8]; | |
653 | wifi_ap_record_t ap; | |
654 | ||
655 | switch (Main_Screen) { | |
656 | case MAIN_TOOLS_SETUP_WIFI: | |
657 | if (_wifi_ScanAPs) { | |
658 | xEventGroupSetBits(xEventGroupWifi, TASK_WIFI_REQUEST_WIFI_SCAN); | |
659 | _wifi_ScanAPs = false; | |
660 | TimeSpent = 0; | |
661 | } | |
662 | if (_wifi_ScanDone) { | |
663 | /* | |
664 | * Show scan results. There is room for 7 entries. If we have a connection, | |
665 | * the first one is that connection followed by available Access Points. | |
666 | * If there is no connection yet, there is only a iist of available Access | |
667 | * points. | |
668 | * The list is sorted by signal strength and is filled by the eventhandler. | |
669 | */ | |
670 | idx = 1; | |
671 | _wifi_ScanDone = false; | |
672 | ||
673 | if ((xEventGroupGetBits(xEventGroupWifi) & TASK_WIFI_STA_CONNECTED) == TASK_WIFI_STA_CONNECTED) { | |
674 | // We are connected. Search and display this one. | |
675 | if (xSemaphoreTake(xSemaphoreWiFi, 25) == pdTRUE) { | |
676 | for (int i = 0; i < _wifi_Scanned; i++) { | |
677 | ap = accessp_records[i]; | |
678 | if (strcmp(wifi_state->STA_ssid, (char *)ap.ssid) == 0) { | |
679 | AP[idx] = i; | |
680 | Show_AP(idx, ap, 3); | |
681 | idx++; | |
682 | break; | |
683 | } | |
684 | } | |
685 | xSemaphoreGive(xSemaphoreWiFi); | |
686 | } | |
687 | } | |
688 | ||
689 | // Display available Access Points. | |
690 | for (int i = 0; i < _wifi_Scanned; i++) { | |
691 | // The connected AP can be somewhere in this list, don't display it again. | |
692 | ap = accessp_records[i]; | |
693 | if (xSemaphoreTake(xSemaphoreWiFi, 25) == pdTRUE) { | |
694 | if (strcmp(wifi_state->STA_ssid, (char *)ap.ssid) == 0) { | |
695 | xSemaphoreGive(xSemaphoreWiFi); | |
696 | continue; // Skip connected AP, already on top of the list. | |
697 | } | |
698 | xSemaphoreGive(xSemaphoreWiFi); | |
699 | } | |
700 | // Check if we know this AP in the database. | |
701 | if ((read_station(ap.ssid) == -1)) { | |
702 | Show_AP(idx, ap, 2); // Unknown | |
703 | } else { | |
704 | if (wifiStation.hide) { | |
705 | continue; // Blacklisted. | |
706 | } | |
707 | Show_AP(idx, ap, 1); // We know this one. | |
708 | } | |
709 | AP[idx] = i; | |
710 | idx++; | |
711 | if (idx == 8) | |
712 | break; | |
713 | } | |
714 | if (idx < 7) { | |
715 | for (int i = idx; i < 8; i++) { | |
716 | Show_AP(i, ap, 0); | |
717 | AP[i] = 0; | |
718 | } | |
719 | } | |
720 | } | |
721 | ||
722 | Choice = Buttons_Scan(); | |
723 | if ((Choice >= 1) && (Choice <= 7)) { | |
724 | ap = accessp_records[AP[Choice]]; | |
725 | sprintf((char *)_wifi_ssid, "%s", ap.ssid); // Save selected SSID. | |
726 | } | |
727 | if ((Choice == 1) && ((xEventGroupGetBits(xEventGroupWifi) & TASK_WIFI_STA_CONNECTED) == TASK_WIFI_STA_CONNECTED)) { | |
728 | Main_Screen = MAIN_TOOLS_SETUP_WIFI_CUR; | |
729 | // Cancel a possible scan. | |
730 | ESP_ERROR_CHECK(esp_wifi_scan_stop()); | |
731 | } else if ((Choice >= 1) && (Choice <= 7)) { | |
732 | if ((read_station(_wifi_ssid) != -1)) { | |
733 | Main_Screen = MAIN_TOOLS_SETUP_WIFI_CON; | |
734 | } else { | |
735 | Main_Screen = MAIN_TOOLS_SETUP_WIFI_NEW; | |
736 | } | |
737 | ESP_ERROR_CHECK(esp_wifi_scan_stop()); | |
738 | } else if (Choice == 0) { | |
739 | Main_Screen = MAIN_TOOLS_SETUP; | |
740 | ESP_ERROR_CHECK(esp_wifi_scan_stop()); | |
741 | } | |
742 | if (TimeSpent > 10) { | |
743 | _wifi_ScanAPs = true; | |
744 | } | |
745 | break; | |
746 | ||
747 | case MAIN_TOOLS_SETUP_WIFI_CUR: | |
748 | ||
749 | if (Buttons_Scan() == 0) { | |
750 | Main_Screen = MAIN_TOOLS_SETUP_WIFI; | |
751 | } | |
752 | break; | |
753 | ||
754 | case MAIN_TOOLS_SETUP_WIFI_CON: | |
755 | switch (Buttons_Scan()) { | |
756 | case 0: // Cancel choice | |
757 | Main_Screen = MAIN_TOOLS_SETUP_WIFI; | |
758 | break; | |
759 | ||
760 | case 1: // Forget connection | |
761 | remove_station(_wifi_ssid); | |
762 | Main_Screen = MAIN_TOOLS_SETUP_WIFI; | |
763 | break; | |
764 | ||
765 | case 2: // Connect | |
766 | _bg = TFT_BLACK; | |
767 | TFT_fillScreen(_bg); | |
768 | TFT_setFont(DEJAVU24_FONT, NULL); | |
769 | _fg = TFT_WHITE; | |
770 | TFT_print("Momentje ..", CENTER, CENTER); | |
771 | /* | |
772 | * Disconnect old connections and wait until it's gone. | |
773 | */ | |
774 | xEventGroupSetBits(xEventGroupWifi, TASK_WIFI_REQUEST_STA_DISCONNECT); | |
775 | vTaskDelay(100 / portTICK_PERIOD_MS); | |
776 | xEventGroupWaitBits(xEventGroupWifi, TASK_WIFI_STA_DISCONNECTED, pdFALSE, pdTRUE, portMAX_DELAY ); | |
777 | /* | |
778 | * Setup new connection. | |
779 | */ | |
780 | if ((read_station(_wifi_ssid) != -1)) { | |
781 | wifi_config_t* config = task_wifi_ConfigSTA; | |
782 | memset(config, 0x00, sizeof(wifi_config_t)); | |
783 | memcpy(config->sta.ssid, wifiStation.SSID, strlen(wifiStation.SSID)); | |
784 | memcpy(config->sta.password, wifiStation.Password, strlen(wifiStation.Password)); | |
785 | xEventGroupSetBits(xEventGroupWifi, TASK_WIFI_REQUEST_STA_CONNECT); | |
786 | vTaskDelay(1000 / portTICK_PERIOD_MS); | |
787 | } | |
788 | Main_Screen = MAIN_TOOLS_SETUP_WIFI; | |
789 | break; | |
790 | ||
791 | default: break; | |
792 | } | |
793 | break; | |
794 | ||
795 | case MAIN_TOOLS_SETUP_WIFI_NEW: | |
796 | // All work is already done, jump to the base screen. | |
797 | Main_Screen = MAIN_TOOLS_SETUP_WIFI; | |
798 | break; | |
799 | ||
800 | default: | |
801 | break; | |
802 | } | |
803 | ||
804 | return false; | |
805 | } | |
806 | ||
807 |