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