1 /*
2 Tests for the Wi-Fi
3 */
4 #include "string.h"
5 #include "esp_system.h"
6 #include "unity.h"
7 #include "esp_system.h"
8 #include "esp_event.h"
9 #include "esp_wifi.h"
10 #include "esp_wifi_types.h"
11 #include "esp_log.h"
12 #include "nvs_flash.h"
13 #include "test_utils.h"
14 #include "freertos/task.h"
15 #include "freertos/event_groups.h"
16
17
18 #define DEFAULT_SSID "TEST_SSID"
19 #define DEFAULT_PWD "TEST_PASS"
20
21 #define GOT_IP_EVENT 0x00000001
22 #define DISCONNECT_EVENT 0x00000002
23
24 #define EVENT_HANDLER_FLAG_DO_NOT_AUTO_RECONNECT 0x00000001
25
26 #if !TEMPORARY_DISABLED_FOR_TARGETS(ESP32S2, ESP32S3, ESP32C3)
27 /* TODO IDF-2618 */
28 static const char* TAG = "test_wifi";
29 static uint32_t wifi_event_handler_flag;
30
31 static EventGroupHandle_t wifi_events;
32
wifi_event_handler(void * arg,esp_event_base_t event_base,int32_t event_id,void * event_data)33 static void wifi_event_handler(void* arg, esp_event_base_t event_base,
34 int32_t event_id, void* event_data)
35 {
36 printf("wifi ev_handle_called.\n");
37 switch(event_id) {
38 case WIFI_EVENT_STA_START:
39 ESP_LOGI(TAG, "WIFI_EVENT_STA_START");
40 //do not actually connect in test case
41 //;
42 break;
43 case WIFI_EVENT_STA_DISCONNECTED:
44 ESP_LOGI(TAG, "WIFI_EVENT_STA_DISCONNECTED");
45 if (! (EVENT_HANDLER_FLAG_DO_NOT_AUTO_RECONNECT & wifi_event_handler_flag) ) {
46 TEST_ESP_OK(esp_wifi_connect());
47 }
48 if (wifi_events) {
49 xEventGroupSetBits(wifi_events, DISCONNECT_EVENT);
50 }
51 break;
52 default:
53 break;
54 }
55 return;
56 }
57
58
ip_event_handler(void * arg,esp_event_base_t event_base,int32_t event_id,void * event_data)59 static void ip_event_handler(void* arg, esp_event_base_t event_base,
60 int32_t event_id, void* event_data)
61 {
62 ip_event_got_ip_t *event;
63
64 printf("ip ev_handle_called.\n");
65 switch(event_id) {
66 case IP_EVENT_STA_GOT_IP:
67 event = (ip_event_got_ip_t*)event_data;
68 ESP_LOGI(TAG, "IP_EVENT_STA_GOT_IP");
69 ESP_LOGI(TAG, "got ip:" IPSTR "\n", IP2STR(&event->ip_info.ip));
70 if (wifi_events) {
71 xEventGroupSetBits(wifi_events, GOT_IP_EVENT);
72 }
73 break;
74 default:
75 break;
76 }
77 return;
78 }
79
event_init(void)80 static esp_err_t event_init(void)
81 {
82 ESP_ERROR_CHECK(esp_event_loop_create_default());
83 ESP_ERROR_CHECK(esp_event_handler_register(WIFI_EVENT, ESP_EVENT_ANY_ID, &wifi_event_handler, NULL));
84 ESP_ERROR_CHECK(esp_event_handler_register(IP_EVENT, ESP_EVENT_ANY_ID, &ip_event_handler, NULL));
85 esp_netif_create_default_wifi_sta();
86 esp_netif_create_default_wifi_ap();
87
88 return ESP_OK;
89 }
90
91 #define EMPH_STR(s) "****** "s" ******"
92
test_wifi_init_deinit(wifi_init_config_t * cfg,wifi_config_t * wifi_config)93 static void test_wifi_init_deinit(wifi_init_config_t *cfg, wifi_config_t* wifi_config)
94 {
95 ESP_LOGI(TAG, EMPH_STR("esp_wifi_deinit"));
96 TEST_ESP_ERR(ESP_ERR_WIFI_NOT_INIT, esp_wifi_deinit());
97 ESP_LOGI(TAG, EMPH_STR("esp_wifi_get_mode"));
98 wifi_mode_t mode_get;
99 TEST_ESP_ERR(ESP_ERR_WIFI_NOT_INIT, esp_wifi_get_mode(&mode_get));
100 ESP_LOGI(TAG, EMPH_STR("esp_wifi_init"));
101 TEST_ESP_OK(esp_wifi_init(cfg));
102 ESP_LOGI(TAG, EMPH_STR("esp_wifi_set_mode"));
103 TEST_ESP_OK(esp_wifi_set_mode(WIFI_MODE_STA));
104 ESP_LOGI(TAG, EMPH_STR("esp_wifi_set_config"));
105 TEST_ESP_OK(esp_wifi_set_config(WIFI_IF_STA, wifi_config));
106 ESP_LOGI(TAG, EMPH_STR("esp_wifi_deinit..."));
107 TEST_ESP_OK(esp_wifi_deinit());
108 }
109
test_wifi_start_stop(wifi_init_config_t * cfg,wifi_config_t * wifi_config)110 static void test_wifi_start_stop(wifi_init_config_t *cfg, wifi_config_t* wifi_config)
111 {
112 ESP_LOGI(TAG, EMPH_STR("esp_wifi_stop"));
113 TEST_ESP_ERR(ESP_ERR_WIFI_NOT_INIT, esp_wifi_stop());
114 ESP_LOGI(TAG, EMPH_STR("esp_wifi_init"));
115 TEST_ESP_OK(esp_wifi_init(cfg));
116 ESP_LOGI(TAG, EMPH_STR("esp_wifi_set_mode"));
117 TEST_ESP_OK(esp_wifi_set_mode(WIFI_MODE_STA));
118 ESP_LOGI(TAG, EMPH_STR("esp_wifi_set_config"));
119 TEST_ESP_OK(esp_wifi_set_config(WIFI_IF_STA, wifi_config));
120 //now start wifi
121 ESP_LOGI(TAG, EMPH_STR("esp_wifi_start..."));
122 TEST_ESP_OK(esp_wifi_start());
123 //wifi stop
124 ESP_LOGI(TAG, EMPH_STR("esp_wifi_stop..."));
125 TEST_ESP_OK( esp_wifi_stop() );
126 ESP_LOGI(TAG, EMPH_STR("esp_wifi_deinit..."));
127 TEST_ESP_OK(esp_wifi_deinit());
128 }
129
130 TEST_CASE("wifi stop and deinit","[wifi]")
131 {
132 test_case_uses_tcpip();
133
134 wifi_init_config_t cfg = WIFI_INIT_CONFIG_DEFAULT();
135 wifi_config_t wifi_config = {
136 .sta = {
137 .ssid = DEFAULT_SSID,
138 .password = DEFAULT_PWD
139 },
140 };
141
142 //init nvs
143 ESP_LOGI(TAG, EMPH_STR("nvs_flash_init"));
144 esp_err_t r = nvs_flash_init();
145 if (r == ESP_ERR_NVS_NO_FREE_PAGES || r == ESP_ERR_NVS_NEW_VERSION_FOUND) {
146 ESP_LOGI(TAG, EMPH_STR("no free pages or nvs version mismatch, erase.."));
147 TEST_ESP_OK(nvs_flash_erase());
148 r = nvs_flash_init();
149 }
150 TEST_ESP_OK(r);
151 //init tcpip
152 ESP_LOGI(TAG, EMPH_STR("esp_netif_init"));
153 esp_netif_init();
154 //init event loop
155
156 ESP_LOGI(TAG, EMPH_STR("event_init"));
157 event_init();
158
159 ESP_LOGI(TAG, "test wifi init & deinit...");
160 test_wifi_init_deinit(&cfg, &wifi_config);
161 ESP_LOGI(TAG, "wifi init & deinit seem to be OK.");
162
163 ESP_LOGI(TAG, "test wifi start & stop...");
164 test_wifi_start_stop(&cfg, &wifi_config);
165 ESP_LOGI(TAG, "wifi start & stop seem to be OK.");
166
167 ESP_LOGI(TAG, EMPH_STR("nvs_flash_deinit..."));
168 nvs_flash_deinit();
169 ESP_LOGI(TAG, "test passed...");
170
171 TEST_IGNORE_MESSAGE("this test case is ignored due to the critical memory leak of esp_netif and event_loop.");
172 }
173
start_wifi_as_softap(void)174 static void start_wifi_as_softap(void)
175 {
176 wifi_init_config_t cfg = WIFI_INIT_CONFIG_DEFAULT();
177 cfg.nvs_enable = false;
178
179 wifi_config_t w_config = {
180 .ap.ssid = DEFAULT_SSID,
181 .ap.password = DEFAULT_PWD,
182 .ap.ssid_len = 0,
183 .ap.channel = 1,
184 .ap.authmode = WIFI_AUTH_WPA2_PSK,
185 .ap.ssid_hidden = false,
186 .ap.max_connection = 4,
187 .ap.beacon_interval = 100,
188 };
189
190 event_init();
191
192 // can't deinit event loop, need to reset leak check
193 unity_reset_leak_checks();
194
195 if (wifi_events == NULL) {
196 wifi_events = xEventGroupCreate();
197 }
198
199 TEST_ESP_OK(esp_wifi_init(&cfg));
200 TEST_ESP_OK(esp_wifi_set_mode(WIFI_MODE_AP));
201 TEST_ESP_OK(esp_wifi_set_config(WIFI_IF_AP, &w_config));
202 TEST_ESP_OK(esp_wifi_start());
203 }
204
start_wifi_as_sta(void)205 static void start_wifi_as_sta(void)
206 {
207 wifi_init_config_t cfg = WIFI_INIT_CONFIG_DEFAULT();
208 cfg.nvs_enable = false;
209
210 // do not auto connect
211 wifi_event_handler_flag |= EVENT_HANDLER_FLAG_DO_NOT_AUTO_RECONNECT;
212 event_init();
213
214 // can't deinit event loop, need to reset leak check
215 unity_reset_leak_checks();
216
217 if (wifi_events == NULL) {
218 wifi_events = xEventGroupCreate();
219 } else {
220 xEventGroupClearBits(wifi_events, 0x00ffffff);
221 }
222
223 TEST_ESP_OK(esp_wifi_init(&cfg));
224 TEST_ESP_OK(esp_wifi_set_mode(WIFI_MODE_STA));
225 TEST_ESP_OK(esp_wifi_start());
226
227 }
228
stop_wifi(void)229 static void stop_wifi(void)
230 {
231 printf("stop wifi\n");
232 TEST_ESP_OK(esp_wifi_stop());
233 TEST_ESP_OK(esp_wifi_deinit());
234 if (wifi_events) {
235 vEventGroupDelete(wifi_events);
236 wifi_events = NULL;
237 }
238 vTaskDelay(1000/portTICK_PERIOD_MS);
239 }
240
receive_ds2ds_packet(void)241 static void receive_ds2ds_packet(void)
242 {
243 test_case_uses_tcpip();
244 start_wifi_as_softap();
245 unity_wait_for_signal("sender ready");
246 unity_send_signal("receiver ready");
247
248 // wait for sender to send packets
249 vTaskDelay(1000/portTICK_PERIOD_MS);
250 stop_wifi();
251 }
252
253 static const char ds2ds_pdu[] = {
254 0x48, 0x03, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
255 0xE8, 0x65, 0xD4, 0xCB, 0x74, 0x19, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
256 0x60, 0x94, 0xE8, 0x65, 0xD4, 0xCB, 0x74, 0x1C, 0x26, 0xB9,
257 0x0D, 0x02, 0x7D, 0x13, 0x00, 0x00, 0x01, 0xE8, 0x65, 0xD4, 0xCB, 0x74,
258 0x1C, 0x00, 0x00, 0x26, 0xB9, 0x00, 0x00, 0x00, 0x00
259 };
260
send_ds2ds_packet(void)261 static void send_ds2ds_packet(void)
262 {
263 test_case_uses_tcpip();
264 start_wifi_as_softap();
265 unity_send_signal("sender ready");
266 unity_wait_for_signal("receiver ready");
267
268 // send packet 20 times to make sure receiver will get this packet
269 for (uint16_t i = 0; i < 20; i++) {
270 esp_wifi_80211_tx(WIFI_IF_AP, ds2ds_pdu, sizeof(ds2ds_pdu), true);
271 vTaskDelay(50 / portTICK_PERIOD_MS);
272 }
273 stop_wifi();
274 }
275
276 TEST_CASE_MULTIPLE_DEVICES("receive ds2ds packet without exception", "[wifi][test_env=UT_T2_1]", receive_ds2ds_packet, send_ds2ds_packet);
277
wifi_connect_by_bssid(uint8_t * bssid)278 static void wifi_connect_by_bssid(uint8_t *bssid)
279 {
280 EventBits_t bits;
281
282 wifi_config_t w_config = {
283 .sta.ssid = DEFAULT_SSID,
284 .sta.password = DEFAULT_PWD,
285 .sta.bssid_set = true,
286 };
287
288 memcpy(w_config.sta.bssid, bssid, 6);
289
290 TEST_ESP_OK(esp_wifi_set_config(WIFI_IF_STA, &w_config));
291 TEST_ESP_OK(esp_wifi_connect());
292 ESP_LOGI(TAG, "called esp_wifi_connect()");
293 bits = xEventGroupWaitBits(wifi_events, GOT_IP_EVENT, 1, 0, 7000/portTICK_RATE_MS);
294 TEST_ASSERT(bits == GOT_IP_EVENT);
295 }
296
test_wifi_connection_sta(void)297 static void test_wifi_connection_sta(void)
298 {
299 char mac_str[19];
300 uint8_t mac[6];
301 EventBits_t bits;
302
303 test_case_uses_tcpip();
304
305 start_wifi_as_sta();
306
307 unity_wait_for_signal_param("SoftAP mac", mac_str, 19);
308
309 TEST_ASSERT_TRUE(unity_util_convert_mac_from_string(mac_str, mac));
310
311 wifi_connect_by_bssid(mac);
312
313 unity_send_signal("STA connected");
314
315 bits = xEventGroupWaitBits(wifi_events, DISCONNECT_EVENT, 1, 0, 60000 / portTICK_RATE_MS);
316 // disconnect event not triggered
317 printf("wait finish\n");
318 TEST_ASSERT(bits == 0);
319
320 stop_wifi();
321 }
322
test_wifi_connection_softap(void)323 static void test_wifi_connection_softap(void)
324 {
325 char mac_str[19] = {0};
326 uint8_t mac[6];
327
328 test_case_uses_tcpip();
329
330 start_wifi_as_softap();
331
332 TEST_ESP_OK(esp_wifi_get_mac(WIFI_IF_AP, mac));
333 sprintf(mac_str, MACSTR, MAC2STR(mac));
334
335 unity_send_signal_param("SoftAP mac", mac_str);
336
337 unity_wait_for_signal("STA connected");
338
339 vTaskDelay(60000 / portTICK_PERIOD_MS);
340
341 stop_wifi();
342 }
343
344 TEST_CASE_MULTIPLE_DEVICES("test wifi retain connection for 60s", "[wifi][test_env=UT_T2_1][timeout=90]", test_wifi_connection_sta, test_wifi_connection_softap);
345
346 #endif //!TEMPORARY_DISABLED_FOR_TARGETS(ESP32S2, ESP32S3, ESP32C3)
347