main/task_wifi.c

changeset 4
d0155c16e992
child 5
b1f38105ca7e
equal deleted inserted replaced
3:e5d91caa6ab4 4:d0155c16e992
1 /**
2 * @file task_wifi.c
3 * @brief WiFi task. Connects to a known Access Point.
4 */
5
6
7 #include "config.h"
8
9
10 static const char *TAG = "task_wifi";
11
12 #define ESP_WIFI_SSID CONFIG_ESP_WIFI_SSID
13 #define ESP_WIFI_PASS CONFIG_ESP_WIFI_PASSWORD
14
15 SemaphoreHandle_t xSemaphoreWiFi = NULL; ///< Semaphore WiFi task.
16 EventGroupHandle_t xEventGroupWifi; ///< Events WiFi task.
17 wifi_config_t wifi_Config = { ///< Current STA configuration.
18 .sta = {
19 .ssid = ESP_WIFI_SSID,
20 .password = ESP_WIFI_PASS,
21 .scan_method = WIFI_FAST_SCAN,
22 .sort_method = WIFI_CONNECT_AP_BY_SECURITY,
23 .threshold.rssi = -127,
24 .threshold.authmode = WIFI_AUTH_WPA2_PSK,
25 },
26 };
27 WIFI_State *wifi_state = NULL; ///< Public state for other tasks.
28 esp_netif_t *sta_netif = NULL; ///< Station interface
29
30
31 const int TASK_WIFI_REQUEST_STA_DISCONNECT = BIT1; ///< When set, means a client requested to disconnect from currently connected AP.
32 const int TASK_WIFI_REQUEST_STA_CONNECT = BIT2; ///< When set, means a client requested to connect to an access point.
33
34 const int TASK_WIFI_HAS_IP = BIT3; ///< Indicate that we have an IP address
35 const int TASK_WIFI_STA_FAILED = BIT5; ///< Indicate that we could not get a connection to AP as station.
36 const int TASK_WIFI_STA_DISCONNECTED = BIT6; ///< Indicate that we are disconnected from an ap station.
37 const int TASK_WIFI_STA_CONNECTED = BIT7; ///< Indicate that we are connected to AP as station, flip of BIT6.
38
39
40 /****************************************************************************/
41
42
43 bool ready_WiFi(void)
44 {
45 if (wifi_state->STA_connected && wifi_state->STA_online)
46 return true;
47 return false;
48 }
49
50
51
52 void request_WiFi(bool connect)
53 {
54 if (connect)
55 xEventGroupSetBits(xEventGroupWifi, TASK_WIFI_REQUEST_STA_CONNECT);
56 else
57 xEventGroupSetBits(xEventGroupWifi, TASK_WIFI_REQUEST_STA_DISCONNECT);
58 }
59
60
61
62 static void wifi_event_handler(void* arg, esp_event_base_t event_base, int32_t event_id, void* event_data)
63 {
64 switch (event_id) {
65
66 case WIFI_EVENT_STA_START:
67 ESP_LOGI(TAG, "Event wifi START");
68 // Set the hostname for the dhcp client.
69 #ifdef CONFIG_CODE_PRODUCTION
70 ESP_ERROR_CHECK(esp_netif_set_hostname(sta_netif, "balkon"));
71 #endif
72 #ifdef CONFIG_CODE_TESTING
73 ESP_ERROR_CHECK(esp_netif_set_hostname(sta_netif, "wemos"));
74 #endif
75 // ESP_ERROR_CHECK(esp_wifi_connect());
76 break;
77
78 case WIFI_EVENT_STA_CONNECTED: {
79 // system_event_sta_connected_t* event = (wifi_event_sta_connected_t*) event_data;
80 wifi_ap_record_t ap_info;
81 esp_wifi_sta_get_ap_info(&ap_info);
82 ESP_LOGI(TAG, "Event STA connected rssi=%d", ap_info.rssi);
83 if (xSemaphoreTake(xSemaphoreWiFi, 35) == pdTRUE) {
84 wifi_state->STA_connected = true;
85 wifi_state->STA_rssi = ap_info.rssi;
86 xSemaphoreGive(xSemaphoreWiFi);
87 } else {
88 ESP_LOGE(TAG, "wifi_event_handler() lock error WIFI_EVENT_STA_CONNECTED");
89 }
90 xEventGroupSetBits(xEventGroupWifi, TASK_WIFI_STA_CONNECTED);
91 xEventGroupClearBits(xEventGroupWifi, TASK_WIFI_STA_DISCONNECTED);
92 break;
93 }
94
95 case WIFI_EVENT_STA_DISCONNECTED: {
96 ESP_LOGI(TAG, "Event STA disconnected");
97 // wifi_event_sta_disconnected_t* disconnected = (wifi_event_sta_disconnected_t*) event_data;
98 // ESP_LOGI(TAG, "Event STA disconnected, reason:%d", disconnected->reason);
99 if (xSemaphoreTake(xSemaphoreWiFi, 35) == pdTRUE) {
100 wifi_state->STA_connected = false;
101 wifi_state->STA_online = false;
102 //wifi_state->STA_rssi = 0;
103 xSemaphoreGive(xSemaphoreWiFi);
104 } else {
105 ESP_LOGE(TAG, "wifi_event_handler() lock error WIFI_EVENT_STA_DISCONNECTED");
106 }
107 // connect_mqtt(false);
108 xEventGroupClearBits(xEventGroupWifi, TASK_WIFI_STA_CONNECTED);
109 xEventGroupSetBits(xEventGroupWifi, TASK_WIFI_STA_DISCONNECTED);
110 break;
111 }
112
113 default:
114 ESP_LOGW(TAG, "Unknown WiFi event %d", (int)event_id);
115 break;
116 }
117 }
118
119
120
121 static void got_ip_event_handler(void* arg, esp_event_base_t event_base, int32_t event_id, void* event_data)
122 {
123 switch (event_id) {
124
125 case IP_EVENT_STA_GOT_IP:
126 ESP_LOGE(TAG, "got_ip_event_handler()");
127 xEventGroupSetBits(xEventGroupWifi, TASK_WIFI_HAS_IP);
128 ip_event_got_ip_t* event = (ip_event_got_ip_t*) event_data;
129 if (xSemaphoreTake(xSemaphoreWiFi, 25) == pdTRUE) {
130 wifi_state->STA_online = true;
131 snprintf(wifi_state->STA_ip, 16, IPSTR, IP2STR(&event->ip_info.ip));
132 snprintf(wifi_state->STA_nm, 16, IPSTR, IP2STR(&event->ip_info.netmask));
133 snprintf(wifi_state->STA_gw, 16, IPSTR, IP2STR(&event->ip_info.gw));
134 xSemaphoreGive(xSemaphoreWiFi);
135 } else {
136 ESP_LOGE(TAG, "got_ip_event_handler() lock error IP_EVENT_STA_GOT_IP");
137 }
138 // connect_mqtt(true);
139 break;
140
141 case IP_EVENT_STA_LOST_IP:
142 ESP_LOGW(TAG, "Lost IP address");
143 xEventGroupClearBits(xEventGroupWifi, TASK_WIFI_HAS_IP);
144 if (xSemaphoreTake(xSemaphoreWiFi, 25) == pdTRUE) {
145 wifi_state->STA_ip[0] = '\0';
146 wifi_state->STA_nm[0] = '\0';
147 wifi_state->STA_gw[0] = '\0';
148 wifi_state->STA_online = false;
149 xSemaphoreGive(xSemaphoreWiFi);
150 } else {
151 ESP_LOGE(TAG, "got_ip_event_handler() lock error IP_EVENT_STA_LOST_IP");
152 }
153 // connect_mqtt(false);
154 break;
155
156 case IP_EVENT_AP_STAIPASSIGNED:
157 ESP_LOGI(TAG, "IP_EVENT_AP_STAIPASSIGNED");
158 break;
159
160 default:
161 ESP_LOGW(TAG, "Unknown IP event %d", (int)event_id);
162 break;
163 }
164 }
165
166
167
168 void task_wifi( void * pvParameters )
169 {
170 ESP_LOGI(TAG, "Start WiFi");
171
172 /*
173 * Initialize NVS
174 */
175 esp_err_t ret = nvs_flash_init();
176 if (ret == ESP_ERR_NVS_NO_FREE_PAGES || ret == ESP_ERR_NVS_NEW_VERSION_FOUND) {
177 ESP_ERROR_CHECK(nvs_flash_erase());
178 ret = nvs_flash_init();
179 }
180 ESP_ERROR_CHECK(ret);
181
182 /* event handler and event group for the wifi driver */
183 xEventGroupWifi = xEventGroupCreate();
184 /* initialize the tcp stack */
185 ESP_ERROR_CHECK(esp_netif_init());
186 ESP_ERROR_CHECK(esp_event_loop_create_default());
187 sta_netif = esp_netif_create_default_wifi_sta();
188 assert(sta_netif);
189
190 /*
191 * memory allocation of objects used by the task
192 */
193 xSemaphoreWiFi = xSemaphoreCreateMutex();
194 wifi_state = malloc(sizeof(WIFI_State));
195 memset(wifi_state, 0x00, sizeof(WIFI_State));
196 sprintf(wifi_state->STA_ssid, "%s", ESP_WIFI_SSID);
197
198 /*
199 * init wifi as station
200 */
201 wifi_init_config_t wifi_init_config = WIFI_INIT_CONFIG_DEFAULT();
202 ESP_ERROR_CHECK(esp_wifi_init(&wifi_init_config));
203
204 esp_event_handler_instance_t instance_any_id;
205 esp_event_handler_instance_t instance_got_ip;
206 ESP_ERROR_CHECK(esp_event_handler_instance_register(WIFI_EVENT, ESP_EVENT_ANY_ID, &wifi_event_handler, NULL, &instance_any_id) );
207 ESP_ERROR_CHECK(esp_event_handler_instance_register(IP_EVENT, /*IP_EVENT_STA_GOT_IP*/ ESP_EVENT_ANY_ID, &got_ip_event_handler, NULL, &instance_got_ip) );
208
209 ESP_ERROR_CHECK(esp_wifi_set_mode(WIFI_MODE_STA));
210 ESP_ERROR_CHECK(esp_wifi_set_config(WIFI_IF_STA, &wifi_Config) );
211 ESP_ERROR_CHECK(esp_wifi_start());
212
213 //xEventGroupSetBits(xEventGroupWifi, TASK_WIFI_REQUEST_STA_CONNECT);
214 xEventGroupClearBits(xEventGroupWifi, TASK_WIFI_STA_CONNECTED);
215 xEventGroupSetBits(xEventGroupWifi, TASK_WIFI_STA_DISCONNECTED);
216 EventBits_t uxBits;
217
218 ESP_LOGI(TAG, "Startup completed, enter task loop");
219
220 for(;;) {
221
222 /* actions that can trigger: request a connection or a disconnection */
223 uxBits = xEventGroupWaitBits(xEventGroupWifi, TASK_WIFI_REQUEST_STA_CONNECT | TASK_WIFI_REQUEST_STA_DISCONNECT,
224 pdFALSE, pdFALSE, portMAX_DELAY );
225
226 if (uxBits & TASK_WIFI_REQUEST_STA_DISCONNECT) {
227 /*
228 * user requested a disconnect, this will in effect disconnect the wifi
229 */
230 // connect_mqtt(false);
231 ESP_LOGI(TAG, "Request STA disconnect");
232 ESP_ERROR_CHECK(esp_wifi_disconnect());
233 xEventGroupWaitBits(xEventGroupWifi, TASK_WIFI_STA_DISCONNECTED, pdFALSE, pdTRUE, portMAX_DELAY );
234
235 /* finally: release the request bit */
236 xEventGroupClearBits(xEventGroupWifi, TASK_WIFI_REQUEST_STA_DISCONNECT);
237
238 } else if (uxBits & TASK_WIFI_REQUEST_STA_CONNECT) {
239
240 ESP_LOGI(TAG, "Request STA connect `%s' `%s'", wifi_Config.sta.ssid, wifi_Config.sta.password);
241 xEventGroupClearBits(xEventGroupWifi, TASK_WIFI_STA_FAILED);
242 ESP_ERROR_CHECK(esp_wifi_set_config(WIFI_IF_STA, &wifi_Config));
243
244 esp_err_t wifierror = esp_wifi_connect();
245 if (wifierror != ESP_OK) {
246 ESP_LOGE(TAG, "esp_wifi_connect() rc=%04x", (int)wifierror);
247 xEventGroupSetBits(xEventGroupWifi, TASK_WIFI_STA_FAILED);
248 } else {
249 ESP_LOGI(TAG, "Connected Ok");
250 }
251
252 /*
253 * 3 scenarios here: connection is successful and TASK_WIFI_STA_CONNECTED will be posted
254 * or it's a failure and we get a TASK_WIFI_STA_FAILED with a reason code.
255 * Or, option 3, the 5 seconds timeout is reached. This happens when the AP is not in range.
256 * Note that the reason code is not exploited. For all intent and purposes a failure is a failure.
257 */
258 uxBits = xEventGroupWaitBits(xEventGroupWifi, TASK_WIFI_STA_CONNECTED | TASK_WIFI_STA_FAILED, pdFALSE, pdFALSE, 5000 / portTICK_PERIOD_MS);
259
260 if (uxBits & (TASK_WIFI_STA_CONNECTED | TASK_WIFI_STA_FAILED)) {
261 /*
262 * only save the config if the connection was successful!
263 */
264 if (uxBits & TASK_WIFI_STA_CONNECTED) {
265 /* save wifi config */
266 //SaveStaConfig();
267 } else {
268 ESP_LOGI(TAG, "No AP found");
269 vTaskDelay(3000 / portTICK_PERIOD_MS);
270 ESP_LOGW(TAG, "Connection failed");
271 /* failed attempt to connect regardles of the reason */
272
273 /* otherwise: reset the config */
274 //memset(task_wifi_ConfigSTA, 0x00, sizeof(wifi_config_t));
275 }
276 }
277
278 /* finally: release the request bit */
279 xEventGroupClearBits(xEventGroupWifi, TASK_WIFI_REQUEST_STA_CONNECT);
280 }
281
282 } /* for(;;) */
283 vTaskDelay(10 / portTICK_PERIOD_MS);
284 }
285
286

mercurial