esp-idf/components/esp_wifi/test_apps/wifi_connect/main/test_wifi_conn.c

350 wiersze
11 KiB
C

/*
* SPDX-FileCopyrightText: 2021-2024 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Unlicense OR CC0-1.0
*
* This test code is in the Public Domain (or CC0 licensed, at your option.)
*
* Unless required by applicable law or agreed to in writing, this
* software is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
* CONDITIONS OF ANY KIND, either express or implied.
*/
#include <stdio.h>
#include <string.h>
#include "unity.h"
#include "esp_mac.h"
#include "esp_event.h"
#include "esp_wifi.h"
#include "esp_wifi_types.h"
#include "esp_log.h"
#include "nvs_flash.h"
#include "test_utils.h"
#include "memory_checks.h"
#include "freertos/task.h"
#include "freertos/event_groups.h"
#ifndef TEST_SUFFIX_STR
#define TEST_SUFFIX_STR "_0000"
#endif
#define TEST_DEFAULT_SSID "SSID_" CONFIG_IDF_TARGET TEST_SUFFIX_STR
#define TEST_DEFAULT_PWD "PASS_" CONFIG_IDF_TARGET TEST_SUFFIX_STR
#define TEST_DEFAULT_CHANNEL (6)
#define CONNECT_TIMEOUT_MS (8000)
#define GOT_IP_EVENT (1)
#define WIFI_DISCONNECT_EVENT (1<<1)
#define WIFI_STA_CONNECTED (1<<2)
#define WIFI_AP_STA_CONNECTED (1<<3)
#define EVENT_HANDLER_FLAG_DO_NOT_AUTO_RECONNECT 0x00000001
static const char* TAG = "test_wifi";
static uint32_t wifi_event_handler_flag;
static esp_netif_t* s_ap_netif = NULL;
static esp_netif_t* s_sta_netif = NULL;
static EventGroupHandle_t wifi_events;
static void wifi_event_handler(void* arg, esp_event_base_t event_base,
int32_t event_id, void* event_data)
{
ESP_LOGI(TAG, "wifi event handler: %"PRIi32, event_id);
switch (event_id) {
case WIFI_EVENT_STA_START:
ESP_LOGI(TAG, "WIFI_EVENT_STA_START");
break;
case WIFI_EVENT_AP_STACONNECTED:
ESP_LOGI(TAG, "WIFI_EVENT_AP_STACONNECTED");
if (wifi_events) {
xEventGroupSetBits(wifi_events, WIFI_AP_STA_CONNECTED);
}
break;
case WIFI_EVENT_STA_CONNECTED:
ESP_LOGI(TAG, "WIFI_EVENT_STA_CONNECTED");
if (wifi_events) {
xEventGroupSetBits(wifi_events, WIFI_STA_CONNECTED);
}
break;
case WIFI_EVENT_STA_DISCONNECTED:
ESP_LOGI(TAG, "WIFI_EVENT_STA_DISCONNECTED");
wifi_event_sta_disconnected_t *event = (wifi_event_sta_disconnected_t *)event_data;
ESP_LOGI(TAG, "disconnect reason: %u", event->reason);
if (!(EVENT_HANDLER_FLAG_DO_NOT_AUTO_RECONNECT & wifi_event_handler_flag)) {
TEST_ESP_OK(esp_wifi_connect());
}
if (wifi_events) {
xEventGroupSetBits(wifi_events, WIFI_DISCONNECT_EVENT);
}
break;
default:
break;
}
return;
}
static void ip_event_handler(void* arg, esp_event_base_t event_base,
int32_t event_id, void* event_data)
{
ip_event_got_ip_t *event;
ESP_LOGI(TAG, "ip event handler");
switch (event_id) {
case IP_EVENT_STA_GOT_IP:
event = (ip_event_got_ip_t*)event_data;
ESP_LOGI(TAG, "IP_EVENT_STA_GOT_IP");
ESP_LOGI(TAG, "got ip:" IPSTR, IP2STR(&event->ip_info.ip));
if (wifi_events) {
xEventGroupSetBits(wifi_events, GOT_IP_EVENT);
}
break;
default:
break;
}
return;
}
static esp_err_t event_init(void)
{
ESP_ERROR_CHECK(esp_event_loop_create_default());
ESP_ERROR_CHECK(esp_event_handler_register(WIFI_EVENT, ESP_EVENT_ANY_ID, &wifi_event_handler, NULL));
ESP_ERROR_CHECK(esp_event_handler_register(IP_EVENT, ESP_EVENT_ANY_ID, &ip_event_handler, NULL));
s_sta_netif = esp_netif_create_default_wifi_sta();
s_ap_netif = esp_netif_create_default_wifi_ap();
return ESP_OK;
}
static esp_err_t event_deinit(void)
{
ESP_ERROR_CHECK(esp_event_handler_unregister(WIFI_EVENT, ESP_EVENT_ANY_ID, &wifi_event_handler));
ESP_ERROR_CHECK(esp_event_handler_unregister(IP_EVENT, ESP_EVENT_ANY_ID, &ip_event_handler));
esp_netif_destroy_default_wifi(s_sta_netif);
esp_netif_destroy_default_wifi(s_ap_netif);
ESP_ERROR_CHECK(esp_event_loop_delete_default());
return ESP_OK;
}
#define EMPH_STR(s) "****** "s" ******"
static void start_wifi_as_softap(void)
{
wifi_config_t w_config = {
.ap.ssid = TEST_DEFAULT_SSID,
.ap.password = TEST_DEFAULT_PWD,
.ap.ssid_len = strlen(TEST_DEFAULT_SSID),
.ap.channel = TEST_DEFAULT_CHANNEL,
.ap.authmode = WIFI_AUTH_WPA2_PSK,
.ap.ssid_hidden = false,
.ap.max_connection = 4,
.ap.beacon_interval = 100,
};
event_init();
if (wifi_events == NULL) {
wifi_events = xEventGroupCreate();
}
xEventGroupClearBits(wifi_events, 0x00ffffff);
TEST_ESP_OK(esp_wifi_set_mode(WIFI_MODE_AP));
TEST_ESP_OK(esp_wifi_set_config(WIFI_IF_AP, &w_config));
TEST_ESP_OK(esp_wifi_start());
ESP_LOGI(TAG, "start wifi softap: %s", TEST_DEFAULT_SSID);
}
static void start_wifi_as_sta(void)
{
event_init();
if (wifi_events == NULL) {
wifi_events = xEventGroupCreate();
}
xEventGroupClearBits(wifi_events, 0x00ffffff);
TEST_ESP_OK(esp_wifi_set_mode(WIFI_MODE_STA));
TEST_ESP_OK(esp_wifi_start());
}
static void stop_wifi(void)
{
TEST_ESP_OK(esp_wifi_stop());
event_deinit();
if (wifi_events) {
vEventGroupDelete(wifi_events);
wifi_events = NULL;
}
vTaskDelay(500 / portTICK_PERIOD_MS);
}
static void receive_ds2ds_packet(void)
{
start_wifi_as_softap();
// wait for sender to send packets
vTaskDelay(1000 / portTICK_PERIOD_MS);
stop_wifi();
}
static const char ds2ds_pdu[] = {
0x48, 0x03, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
0xE8, 0x65, 0xD4, 0xCB, 0x74, 0x19, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
0x60, 0x94, 0xE8, 0x65, 0xD4, 0xCB, 0x74, 0x1C, 0x26, 0xB9,
0x0D, 0x02, 0x7D, 0x13, 0x00, 0x00, 0x01, 0xE8, 0x65, 0xD4, 0xCB, 0x74,
0x1C, 0x00, 0x00, 0x26, 0xB9, 0x00, 0x00, 0x00, 0x00
};
static void send_ds2ds_packet(void)
{
start_wifi_as_softap();
// send packet 20 times to make sure receiver will get this packet
for (uint16_t i = 0; i < 20; i++) {
esp_wifi_80211_tx(WIFI_IF_AP, ds2ds_pdu, sizeof(ds2ds_pdu), true);
vTaskDelay(50 / portTICK_PERIOD_MS);
}
vTaskDelay(500 / portTICK_PERIOD_MS);
stop_wifi();
}
TEST_CASE_MULTIPLE_DEVICES("send receive ds2ds packet without exception", "[wifi]", receive_ds2ds_packet, send_ds2ds_packet);
static void wifi_connect(void)
{
EventBits_t bits;
wifi_config_t w_config = {
.sta.ssid = TEST_DEFAULT_SSID,
.sta.password = TEST_DEFAULT_PWD,
};
TEST_ESP_OK(esp_wifi_set_config(WIFI_IF_STA, &w_config));
TEST_ESP_OK(esp_wifi_connect());
ESP_LOGI(TAG, "start esp_wifi_connect: %s", TEST_DEFAULT_SSID);
bits = xEventGroupWaitBits(wifi_events, GOT_IP_EVENT, 1, 0, CONNECT_TIMEOUT_MS / portTICK_PERIOD_MS);
TEST_ASSERT(bits & GOT_IP_EVENT);
}
static void test_wifi_connection_sta(void)
{
EventBits_t bits;
start_wifi_as_sta();
// make sure softap has started
vTaskDelay(1000 / portTICK_PERIOD_MS);
wifi_connect();
// do not auto reconnect after connected
xEventGroupClearBits(wifi_events, WIFI_DISCONNECT_EVENT);
wifi_event_handler_flag |= EVENT_HANDLER_FLAG_DO_NOT_AUTO_RECONNECT;
// disconnect event not triggered after 60s
bits = xEventGroupWaitBits(wifi_events, WIFI_DISCONNECT_EVENT, 1, 0, 60000 / portTICK_PERIOD_MS);
TEST_ASSERT((bits & WIFI_DISCONNECT_EVENT) == 0);
stop_wifi();
}
static void test_wifi_connection_softap(void)
{
EventBits_t bits;
start_wifi_as_softap();
// wait station connected
bits = xEventGroupWaitBits(wifi_events, WIFI_AP_STA_CONNECTED, 1, 0, CONNECT_TIMEOUT_MS / portTICK_PERIOD_MS);
TEST_ASSERT(bits & WIFI_AP_STA_CONNECTED);
// wait 70s (longer than station side)
vTaskDelay((60000 + CONNECT_TIMEOUT_MS) / portTICK_PERIOD_MS);
stop_wifi();
}
TEST_CASE_MULTIPLE_DEVICES("test wifi retain connection for 60s", "[wifi][timeout=90]", test_wifi_connection_sta, test_wifi_connection_softap);
// single core have issue as WIFIBUG-92
#if !CONFIG_FREERTOS_UNICORE
static void esp_wifi_connect_first_time(void)
{
start_wifi_as_sta();
// make sure softap has started
vTaskDelay(1000 / portTICK_PERIOD_MS);
wifi_config_t w_config;
memset(&w_config, 0, sizeof(w_config));
memcpy(w_config.sta.ssid, TEST_DEFAULT_SSID, strlen(TEST_DEFAULT_SSID));
memcpy(w_config.sta.password, TEST_DEFAULT_PWD, strlen(TEST_DEFAULT_PWD));
w_config.sta.channel = 1;
wifi_event_handler_flag |= EVENT_HANDLER_FLAG_DO_NOT_AUTO_RECONNECT;
TEST_ESP_OK(esp_wifi_set_config(WIFI_IF_STA, &w_config));
ESP_LOGI(TAG, "start esp_wifi_connect first time: %s", TEST_DEFAULT_SSID);
TEST_ESP_OK(esp_wifi_connect());
}
static void test_wifi_connect_at_scan_phase(void)
{
esp_wifi_connect_first_time();
// connect when first connect in scan
vTaskDelay(300 / portTICK_PERIOD_MS);
ESP_LOGI(TAG, "connect when first connect in scan");
TEST_ESP_ERR(ESP_ERR_WIFI_CONN, esp_wifi_connect());
wifi_event_handler_flag |= EVENT_HANDLER_FLAG_DO_NOT_AUTO_RECONNECT;
stop_wifi();
}
static void test_wifi_connect_before_connected_phase(void)
{
esp_wifi_connect_first_time();
// connect before connected
vTaskDelay(730 / portTICK_PERIOD_MS);
ESP_LOGI(TAG, "connect when first connect after scan before connected");
TEST_ESP_ERR(ESP_ERR_WIFI_CONN, esp_wifi_connect());
wifi_event_handler_flag |= EVENT_HANDLER_FLAG_DO_NOT_AUTO_RECONNECT;
stop_wifi();
}
static void test_wifi_connect_after_connected_phase(void)
{
EventBits_t bits;
start_wifi_as_sta();
wifi_event_handler_flag = 0;
wifi_connect();
xEventGroupClearBits(wifi_events, WIFI_STA_CONNECTED | WIFI_DISCONNECT_EVENT);
ESP_LOGI(TAG, "connect after connected");
TEST_ESP_OK(esp_wifi_connect());
bits = xEventGroupWaitBits(wifi_events, WIFI_STA_CONNECTED | WIFI_DISCONNECT_EVENT, pdTRUE, pdFALSE, CONNECT_TIMEOUT_MS / portTICK_PERIOD_MS);
// shouldn't reconnect
TEST_ASSERT((bits & WIFI_AP_STA_CONNECTED) == 0);
// shouldn't disconnect
TEST_ASSERT((bits & WIFI_DISCONNECT_EVENT) == 0);
wifi_event_handler_flag |= EVENT_HANDLER_FLAG_DO_NOT_AUTO_RECONNECT;
stop_wifi();
}
static void set_wifi_softap(void)
{
start_wifi_as_softap();
// wait for sta connect
vTaskDelay(20000 / portTICK_PERIOD_MS);
stop_wifi();
}
TEST_CASE_MULTIPLE_DEVICES("test wifi connect at scan", "[wifi]", test_wifi_connect_at_scan_phase, set_wifi_softap);
TEST_CASE_MULTIPLE_DEVICES("test wifi connect before connected", "[wifi]", test_wifi_connect_before_connected_phase, set_wifi_softap);
TEST_CASE_MULTIPLE_DEVICES("test wifi connect after connected", "[wifi]", test_wifi_connect_after_connected_phase, set_wifi_softap);
#endif