12 #define ESP_WIFI_SSID CONFIG_ESP_WIFI_SSID |
12 #define ESP_WIFI_SSID CONFIG_ESP_WIFI_SSID |
13 #define ESP_WIFI_PASS CONFIG_ESP_WIFI_PASSWORD |
13 #define ESP_WIFI_PASS CONFIG_ESP_WIFI_PASSWORD |
14 |
14 |
15 SemaphoreHandle_t xSemaphoreWiFi = NULL; ///< Semaphore WiFi task. |
15 SemaphoreHandle_t xSemaphoreWiFi = NULL; ///< Semaphore WiFi task. |
16 EventGroupHandle_t xEventGroupWifi; ///< Events WiFi task. |
16 EventGroupHandle_t xEventGroupWifi; ///< Events WiFi task. |
17 wifi_config_t wifi_Config = { ///< Current STA configuration. |
17 esp_event_handler_instance_t instance_any_id; ///< WiFi event handler. |
18 .sta = { |
18 esp_event_handler_instance_t instance_got_ip; ///< IP event handler. |
19 .ssid = ESP_WIFI_SSID, |
19 |
20 .password = ESP_WIFI_PASS, |
|
21 .scan_method = WIFI_FAST_SCAN, |
|
22 }, |
|
23 }; |
|
24 WIFI_State *wifi_state = NULL; ///< Public state for other tasks. |
20 WIFI_State *wifi_state = NULL; ///< Public state for other tasks. |
25 esp_netif_t *sta_netif = NULL; ///< Station interface |
21 esp_netif_t *sta_netif = NULL; ///< Station interface. |
26 |
22 |
27 |
23 |
28 const int TASK_WIFI_REQUEST_STA_DISCONNECT = BIT1; ///< When set, means a client requested to disconnect from currently connected AP. |
24 const int TASK_WIFI_REQUEST_STA_DISCONNECT = BIT1; ///< When set, means a client requested to disconnect from currently connected AP. |
29 const int TASK_WIFI_REQUEST_STA_CONNECT = BIT2; ///< When set, means a client requested to connect to an access point. |
25 const int TASK_WIFI_REQUEST_STA_CONNECT = BIT2; ///< When set, means a client requested to connect to an access point. |
30 |
26 |
31 const int TASK_WIFI_HAS_IP = BIT3; ///< Indicate that we have an IP address |
27 const int TASK_WIFI_HAS_IP = BIT3; ///< Indicate that we have an IP address |
32 const int TASK_WIFI_STA_FAILED = BIT5; ///< Indicate that we could not get a connection to AP as station. |
28 const int TASK_WIFI_STA_FAILED = BIT5; ///< Indicate that we could not get a connection to AP as station. |
33 const int TASK_WIFI_STA_DISCONNECTED = BIT6; ///< Indicate that we are disconnected from an ap station. |
29 const int TASK_WIFI_STA_DISCONNECTED = BIT6; ///< Indicate that we are disconnected from an ap station. |
34 const int TASK_WIFI_STA_CONNECTED = BIT7; ///< Indicate that we are connected to AP as station, flip of BIT6. |
30 const int TASK_WIFI_STA_CONNECTED = BIT7; ///< Indicate that we are connected to AP as station, flip of BIT6. |
|
31 |
|
32 |
|
33 static void init_wifi(void); |
|
34 void wifi_connect(void); |
35 |
35 |
36 |
36 |
37 /****************************************************************************/ |
37 /****************************************************************************/ |
38 |
38 |
39 |
39 |
88 break; |
87 break; |
89 } |
88 } |
90 |
89 |
91 case WIFI_EVENT_STA_DISCONNECTED: { |
90 case WIFI_EVENT_STA_DISCONNECTED: { |
92 wifi_event_sta_disconnected_t* disconnected = (wifi_event_sta_disconnected_t*) event_data; |
91 wifi_event_sta_disconnected_t* disconnected = (wifi_event_sta_disconnected_t*) event_data; |
93 |
|
94 ESP_LOGI(TAG, "Event STA disconnected, reason: %d", disconnected->reason); |
92 ESP_LOGI(TAG, "Event STA disconnected, reason: %d", disconnected->reason); |
|
93 |
|
94 /* |
|
95 * If it's not a normal request to disconnect, make sure the mqtt |
|
96 * connection will be removed. |
|
97 */ |
95 if (disconnected->reason != 8) |
98 if (disconnected->reason != 8) |
96 request_mqtt(false); |
99 request_mqtt(false); |
97 if (xSemaphoreTake(xSemaphoreWiFi, 35) == pdTRUE) { |
100 |
|
101 /* |
|
102 * Error conditions. |
|
103 */ |
|
104 if (disconnected->reason == 2) { |
|
105 ESP_LOGW(TAG, "Auth Expire: try to recover"); |
|
106 wifi_connect(); |
|
107 } else if (disconnected->reason == 39) { |
|
108 ESP_LOGW(TAG, "Timeout: try to recover"); |
|
109 ESP_ERROR_CHECK(esp_wifi_connect()); |
|
110 } |
|
111 if (xSemaphoreTake(xSemaphoreWiFi, 25) == pdTRUE) { |
98 wifi_state->STA_connected = false; |
112 wifi_state->STA_connected = false; |
99 wifi_state->STA_online = false; |
113 wifi_state->STA_online = false; |
100 xSemaphoreGive(xSemaphoreWiFi); |
114 xSemaphoreGive(xSemaphoreWiFi); |
101 } else { |
115 } else { |
102 ESP_LOGE(TAG, "wifi_event_handler() lock error WIFI_EVENT_STA_DISCONNECTED"); |
116 ESP_LOGE(TAG, "wifi_event_handler() lock error WIFI_EVENT_STA_DISCONNECTED"); |
152 break; |
166 break; |
153 } |
167 } |
154 } |
168 } |
155 |
169 |
156 |
170 |
157 |
171 static void init_wifi(void) |
158 void task_wifi( void * pvParameters ) |
172 { |
159 { |
173 ESP_LOGI(TAG, "initialise_wifi() start"); |
160 ESP_LOGI(TAG, "Start WiFi"); |
174 ESP_ERROR_CHECK(esp_event_loop_create_default()); |
161 |
175 xSemaphoreWiFi = xSemaphoreCreateMutex(); |
162 /* event handler and event group for the wifi driver */ |
176 |
163 xEventGroupWifi = xEventGroupCreate(); |
|
164 /* initialize the tcp stack */ |
177 /* initialize the tcp stack */ |
165 ESP_ERROR_CHECK(esp_netif_init()); |
178 ESP_ERROR_CHECK(esp_netif_init()); |
166 ESP_ERROR_CHECK(esp_event_loop_create_default()); |
|
167 sta_netif = esp_netif_create_default_wifi_sta(); |
179 sta_netif = esp_netif_create_default_wifi_sta(); |
168 assert(sta_netif); |
180 assert(sta_netif); |
|
181 |
|
182 wifi_init_config_t wifi_init_config = WIFI_INIT_CONFIG_DEFAULT(); |
|
183 ESP_ERROR_CHECK(esp_wifi_init(&wifi_init_config)); |
|
184 |
|
185 ESP_ERROR_CHECK(esp_event_handler_instance_register(WIFI_EVENT, ESP_EVENT_ANY_ID, &wifi_event_handler, NULL, &instance_any_id) ); |
|
186 ESP_ERROR_CHECK(esp_event_handler_instance_register(IP_EVENT, ESP_EVENT_ANY_ID, &got_ip_event_handler, NULL, &instance_got_ip) ); |
|
187 |
|
188 ESP_ERROR_CHECK(esp_wifi_set_mode(WIFI_MODE_STA)); |
|
189 ESP_ERROR_CHECK( esp_wifi_start() ); |
|
190 |
|
191 xEventGroupClearBits(xEventGroupWifi, TASK_WIFI_STA_CONNECTED); |
|
192 xEventGroupSetBits(xEventGroupWifi, TASK_WIFI_STA_DISCONNECTED); |
|
193 |
|
194 ESP_LOGI(TAG, "initialise_wifi() done"); |
|
195 } |
|
196 |
|
197 |
|
198 void wifi_connect(void) |
|
199 { |
|
200 ESP_LOGI(TAG, "wifi_connect() start"); |
|
201 wifi_config_t wifi_Config = { ///< Current STA configuration. |
|
202 .sta = { |
|
203 .ssid = ESP_WIFI_SSID, |
|
204 .password = ESP_WIFI_PASS, |
|
205 }, |
|
206 }; |
|
207 // .threshold.authmode = WIFI_AUTH_WPA2_PSK, |
|
208 // .pmf_cfg = { |
|
209 // .capable = true, |
|
210 // .required = false |
|
211 // }, |
|
212 |
|
213 ESP_ERROR_CHECK(esp_wifi_disconnect()); |
|
214 ESP_ERROR_CHECK(esp_wifi_set_config(ESP_IF_WIFI_STA, &wifi_Config) ); |
|
215 |
|
216 xEventGroupClearBits(xEventGroupWifi, TASK_WIFI_STA_FAILED); |
|
217 esp_err_t wifierror = esp_wifi_connect(); |
|
218 |
|
219 if (wifierror != ESP_OK) { |
|
220 ESP_LOGE(TAG, "esp_wifi_connect() rc=%04x %s", (int)wifierror, esp_err_to_name(wifierror)); |
|
221 xEventGroupSetBits(xEventGroupWifi, TASK_WIFI_STA_FAILED); |
|
222 } else { |
|
223 ESP_LOGI(TAG, "Connected Ok"); |
|
224 } |
|
225 ESP_LOGI(TAG, "wifi_connect() done"); |
|
226 } |
|
227 |
|
228 |
|
229 void task_wifi( void * pvParameters ) |
|
230 { |
|
231 uint64_t starttime = 0; |
|
232 |
|
233 ESP_LOGI(TAG, "Start WiFi"); |
|
234 esp_log_level_set("wifi", ESP_LOG_WARNING); |
169 |
235 |
170 /* |
236 /* |
171 * memory allocation of objects used by the task |
237 * memory allocation of objects used by the task |
172 */ |
238 */ |
173 xSemaphoreWiFi = xSemaphoreCreateMutex(); |
|
174 wifi_state = malloc(sizeof(WIFI_State)); |
239 wifi_state = malloc(sizeof(WIFI_State)); |
175 memset(wifi_state, 0x00, sizeof(WIFI_State)); |
240 memset(wifi_state, 0x00, sizeof(WIFI_State)); |
176 sprintf(wifi_state->STA_ssid, "%s", ESP_WIFI_SSID); |
241 sprintf(wifi_state->STA_ssid, "%s", ESP_WIFI_SSID); |
177 |
242 |
178 /* |
243 /* |
|
244 * event group for the wifi driver |
|
245 */ |
|
246 xEventGroupWifi = xEventGroupCreate(); |
|
247 |
|
248 /* |
179 * init wifi as station |
249 * init wifi as station |
180 */ |
250 */ |
181 wifi_init_config_t wifi_init_config = WIFI_INIT_CONFIG_DEFAULT(); |
251 init_wifi(); |
182 ESP_ERROR_CHECK(esp_wifi_init(&wifi_init_config)); |
|
183 |
|
184 esp_event_handler_instance_t instance_any_id; |
|
185 esp_event_handler_instance_t instance_got_ip; |
|
186 ESP_ERROR_CHECK(esp_event_handler_instance_register(WIFI_EVENT, ESP_EVENT_ANY_ID, &wifi_event_handler, NULL, &instance_any_id) ); |
|
187 ESP_ERROR_CHECK(esp_event_handler_instance_register(IP_EVENT, ESP_EVENT_ANY_ID, &got_ip_event_handler, NULL, &instance_got_ip) ); |
|
188 |
|
189 ESP_ERROR_CHECK(esp_wifi_set_mode(WIFI_MODE_STA)); |
|
190 ESP_ERROR_CHECK(esp_wifi_set_config(WIFI_IF_STA, &wifi_Config) ); |
|
191 ESP_ERROR_CHECK(esp_wifi_start()); |
|
192 |
|
193 //xEventGroupSetBits(xEventGroupWifi, TASK_WIFI_REQUEST_STA_CONNECT); |
|
194 xEventGroupClearBits(xEventGroupWifi, TASK_WIFI_STA_CONNECTED); |
|
195 xEventGroupSetBits(xEventGroupWifi, TASK_WIFI_STA_DISCONNECTED); |
|
196 EventBits_t uxBits; |
252 EventBits_t uxBits; |
197 |
253 |
198 ESP_LOGI(TAG, "Startup completed, enter task loop"); |
254 ESP_LOGI(TAG, "Startup completed, enter task loop"); |
199 |
255 |
200 for(;;) { |
256 for(;;) { |
201 |
257 |
202 /* actions that can trigger: request a connection or a disconnection */ |
258 /* |
|
259 * Actions that can trigger: request a connection or a disconnection |
|
260 */ |
203 uxBits = xEventGroupWaitBits(xEventGroupWifi, TASK_WIFI_REQUEST_STA_CONNECT | TASK_WIFI_REQUEST_STA_DISCONNECT, |
261 uxBits = xEventGroupWaitBits(xEventGroupWifi, TASK_WIFI_REQUEST_STA_CONNECT | TASK_WIFI_REQUEST_STA_DISCONNECT, |
204 pdFALSE, pdFALSE, portMAX_DELAY ); |
262 pdFALSE, pdFALSE, portMAX_DELAY ); |
205 |
263 |
206 if (uxBits & TASK_WIFI_REQUEST_STA_DISCONNECT) { |
264 if (uxBits & TASK_WIFI_REQUEST_STA_DISCONNECT) { |
207 /* |
265 /* |
209 */ |
267 */ |
210 ESP_LOGI(TAG, "Request STA disconnect"); |
268 ESP_LOGI(TAG, "Request STA disconnect"); |
211 ESP_ERROR_CHECK(esp_wifi_disconnect()); |
269 ESP_ERROR_CHECK(esp_wifi_disconnect()); |
212 xEventGroupWaitBits(xEventGroupWifi, TASK_WIFI_STA_DISCONNECTED, pdFALSE, pdTRUE, portMAX_DELAY ); |
270 xEventGroupWaitBits(xEventGroupWifi, TASK_WIFI_STA_DISCONNECTED, pdFALSE, pdTRUE, portMAX_DELAY ); |
213 |
271 |
214 /* finally: release the request bit */ |
272 /* |
|
273 * Finally: release the request bit |
|
274 */ |
215 xEventGroupClearBits(xEventGroupWifi, TASK_WIFI_REQUEST_STA_DISCONNECT); |
275 xEventGroupClearBits(xEventGroupWifi, TASK_WIFI_REQUEST_STA_DISCONNECT); |
|
276 ESP_LOGI(TAG, "Connection time %llu", (esp_timer_get_time() / 1000) - starttime); |
216 |
277 |
217 } else if (uxBits & TASK_WIFI_REQUEST_STA_CONNECT) { |
278 } else if (uxBits & TASK_WIFI_REQUEST_STA_CONNECT) { |
218 |
279 |
219 ESP_LOGI(TAG, "Request STA connect `%s' `%s'", wifi_Config.sta.ssid, wifi_Config.sta.password); |
280 ESP_LOGI(TAG, "Request STA connect `%s' `%s'", ESP_WIFI_SSID, ESP_WIFI_PASS); |
220 xEventGroupClearBits(xEventGroupWifi, TASK_WIFI_STA_FAILED); |
281 starttime = esp_timer_get_time() / 1000; |
221 ESP_ERROR_CHECK(esp_wifi_set_config(WIFI_IF_STA, &wifi_Config)); |
282 wifi_connect(); |
222 |
|
223 esp_err_t wifierror = esp_wifi_connect(); |
|
224 if (wifierror != ESP_OK) { |
|
225 ESP_LOGE(TAG, "esp_wifi_connect() rc=%04x", (int)wifierror); |
|
226 xEventGroupSetBits(xEventGroupWifi, TASK_WIFI_STA_FAILED); |
|
227 } else { |
|
228 ESP_LOGI(TAG, "Connected Ok"); |
|
229 } |
|
230 |
283 |
231 /* |
284 /* |
232 * 3 scenarios here: connection is successful and TASK_WIFI_STA_CONNECTED will be posted |
285 * 3 scenarios here: connection is successful and TASK_WIFI_STA_CONNECTED will be posted |
233 * or it's a failure and we get a TASK_WIFI_STA_FAILED with a reason code. |
286 * or it's a failure and we get a TASK_WIFI_STA_FAILED with a reason code. |
234 * Or, option 3, the 5 seconds timeout is reached. This happens when the AP is not in range. |
287 * Or, option 3, the 5 seconds timeout is reached. This happens when the AP is not in range. |
238 |
291 |
239 if (uxBits & (TASK_WIFI_STA_CONNECTED | TASK_WIFI_STA_FAILED)) { |
292 if (uxBits & (TASK_WIFI_STA_CONNECTED | TASK_WIFI_STA_FAILED)) { |
240 /* |
293 /* |
241 * only save the config if the connection was successful! |
294 * only save the config if the connection was successful! |
242 */ |
295 */ |
243 if (uxBits & TASK_WIFI_STA_CONNECTED) { |
296 if (uxBits & TASK_WIFI_STA_FAILED) { |
244 /* save wifi config */ |
|
245 //SaveStaConfig(); |
|
246 } else { |
|
247 ESP_LOGI(TAG, "No AP found"); |
297 ESP_LOGI(TAG, "No AP found"); |
248 vTaskDelay(3000 / portTICK_PERIOD_MS); |
298 vTaskDelay(3000 / portTICK_PERIOD_MS); |
249 ESP_LOGW(TAG, "Connection failed"); |
299 ESP_LOGW(TAG, "Connection failed"); |
250 /* failed attempt to connect regardles of the reason */ |
300 /* failed attempt to connect regardles of the reason */ |
251 |
|
252 /* otherwise: reset the config */ |
|
253 //memset(task_wifi_ConfigSTA, 0x00, sizeof(wifi_config_t)); |
|
254 } |
301 } |
255 } |
302 } |
256 |
303 |
257 /* finally: release the request bit */ |
304 /* |
|
305 * Finally: release the request bit |
|
306 */ |
258 xEventGroupClearBits(xEventGroupWifi, TASK_WIFI_REQUEST_STA_CONNECT); |
307 xEventGroupClearBits(xEventGroupWifi, TASK_WIFI_REQUEST_STA_CONNECT); |
259 } |
308 } |
260 |
309 |
261 } /* for(;;) */ |
310 } /* for(;;) */ |
262 vTaskDelay(10 / portTICK_PERIOD_MS); |
311 } |
263 } |
312 |
264 |
313 |
265 |
|