forked from espressif/esp-idf
Merge branch 'feature/bss_max_idle' into 'master'
feat(wifi): Improve and enable bss max idle support on all chips See merge request espressif/esp-idf!34656
This commit is contained in:
@ -92,7 +92,7 @@ ieee80211_deauth_construct = 0x40002040;
|
||||
ieee80211_disassoc_construct = 0x40002044;
|
||||
//ieee80211_add_xrates = 0x40002058;
|
||||
//ieee80211_assoc_req_construct = 0x40002060;
|
||||
ieee80211_assoc_resp_construct = 0x40002064;
|
||||
//ieee80211_assoc_resp_construct = 0x40002064;
|
||||
//ieee80211_timer_process = 0x4000208c;
|
||||
cnx_coexist_timeout = 0x40002090;
|
||||
//sta_recv_mgmt = 0x40002094;
|
||||
|
@ -209,7 +209,7 @@ ppDisableQueue = 0x40000ed4;
|
||||
ppCalVHTDeliNum = 0x40000ed8;
|
||||
ppCalTxVHTSMPDULength = 0x40000edc;
|
||||
ppCheckTxRTS = 0x40000ee0;
|
||||
ppProcessLifeTime = 0x40000ee4;
|
||||
/*ppProcessLifeTime = 0x40000ee4;*/
|
||||
ppProcTxCallback = 0x40000ee8;
|
||||
ppCalPreFecPaddingFactor = 0x40000eec;
|
||||
ppCalDeliNum = 0x40000ef0;
|
||||
|
@ -214,7 +214,7 @@ ppMapWaitTxq = 0x40000e44;
|
||||
ppProcessWaitingQueue = 0x40000e48;
|
||||
ppDisableQueue = 0x40000e4c;
|
||||
ppCheckTxRTS = 0x40000e50;
|
||||
ppProcessLifeTime = 0x40000e54;
|
||||
/*ppProcessLifeTime = 0x40000e54;*/
|
||||
ppProcTxCallback = 0x40000e58;
|
||||
ppCalPreFecPaddingFactor = 0x40000e5c;
|
||||
ppCalDeliNum = 0x40000e60;
|
||||
|
@ -363,14 +363,24 @@ menu "Wi-Fi"
|
||||
during this period, the time will be refreshed. If the time is up, but the station still has packets
|
||||
to receive or send, the time will also be refreshed. unit: milliseconds.
|
||||
|
||||
config ESP_WIFI_BSS_MAX_IDLE_SUPPORT
|
||||
bool "Enable bss max idle support"
|
||||
default y if (SOC_WIFI_HE_SUPPORT || ESP_WIFI_WNM_SUPPORT)
|
||||
help
|
||||
Enables bss max idle support for Station and SoftAP. BSS max idle period enables an SoftAP to indicate
|
||||
a time period during which the AP does not disassociate a STA due to nonreceipt of frames from the STA.
|
||||
For station, max idle period is default 10 (1000TUs) and can be set through
|
||||
ESP_WIFI_SLP_DEFAULT_MAX_ACTIVE_TIME. For softap, bss max idle parameters will be set through
|
||||
bss_max_idle_cfg in wifi_ap_config_t.
|
||||
|
||||
config ESP_WIFI_SLP_DEFAULT_MAX_ACTIVE_TIME
|
||||
int "Maximum keep alive time"
|
||||
range 10 60
|
||||
default 10
|
||||
help
|
||||
Only for station in WIFI_PS_MIN_MODEM or WIFI_PS_MAX_MODEM. If no packet has been
|
||||
sent within ESP_WIFI_SLP_DEFAULT_MAX_ACTIVE_TIME, a null data packet will be sent
|
||||
to maintain the connection with the AP. unit: seconds.
|
||||
Only for station. If no packet has been sent within ESP_WIFI_SLP_DEFAULT_MAX_ACTIVE_TIME, a null data
|
||||
packet will be sent to maintain the connection with the AP. If ESP_WIFI_BSS_MAX_IDLE_SUPPORT is set,
|
||||
it will be sent as bss max idle period in association request. unit: seconds.
|
||||
|
||||
config ESP_WIFI_SLP_DEFAULT_WAIT_BROADCAST_DATA_TIME
|
||||
int "Minimum wait broadcast data time"
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2022-2024 Espressif Systems (Shanghai) CO LTD
|
||||
* SPDX-FileCopyrightText: 2022-2025 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
@ -165,21 +165,6 @@ esp_err_t esp_wifi_get_tx_tb_statistics(esp_wifi_aci_t aci, esp_test_tx_tb_stati
|
||||
*/
|
||||
esp_err_t esp_wifi_softap_add_color_change_announcement(uint8_t color);
|
||||
|
||||
/**
|
||||
* @brief Add bss max idle ie
|
||||
*
|
||||
* @attention This API should be called after esp_wifi_start().
|
||||
*
|
||||
* @param[in] bss_max_idle_enable enable bss max idle
|
||||
* @param[in] bss_max_idle_period_secs bss max idle period, unit seconds
|
||||
* @param[in] protected_keep_alive using protected/unprotected frame to keep alive
|
||||
*
|
||||
* @return
|
||||
* - ESP_OK: succeed
|
||||
* - others: failed
|
||||
*/
|
||||
esp_err_t esp_wifi_softap_set_bss_max_idle(bool bss_max_idle_enable, uint16_t bss_max_idle_period_secs, bool protected_keep_alive);
|
||||
|
||||
/**
|
||||
* @brief Reset MU EDCA Timer
|
||||
*
|
||||
|
@ -278,6 +278,12 @@ extern wifi_osi_funcs_t g_wifi_osi_funcs;
|
||||
#define WIFI_TX_HETB_QUEUE_NUM 1
|
||||
#endif
|
||||
|
||||
#if CONFIG_ESP_WIFI_BSS_MAX_IDLE_SUPPORT
|
||||
#define WIFI_ENABLE_BSS_MAX_IDLE (1<<8)
|
||||
#else
|
||||
#define WIFI_ENABLE_BSS_MAX_IDLE 0
|
||||
#endif
|
||||
|
||||
#define CONFIG_FEATURE_WPA3_SAE_BIT (1<<0)
|
||||
#define CONFIG_FEATURE_CACHE_TX_BUF_BIT (1<<1)
|
||||
#define CONFIG_FEATURE_FTM_INITIATOR_BIT (1<<2)
|
||||
@ -286,6 +292,7 @@ extern wifi_osi_funcs_t g_wifi_osi_funcs;
|
||||
#define CONFIG_FEATURE_GMAC_BIT (1<<5)
|
||||
#define CONFIG_FEATURE_11R_BIT (1<<6)
|
||||
#define CONFIG_FEATURE_WIFI_ENT_BIT (1<<7)
|
||||
#define CONFIG_FEATURE_BSS_MAX_IDLE_BIT (1<<8)
|
||||
|
||||
/* Set additional WiFi features and capabilities */
|
||||
#define WIFI_FEATURE_CAPS (WIFI_ENABLE_WPA3_SAE | \
|
||||
@ -295,7 +302,8 @@ extern wifi_osi_funcs_t g_wifi_osi_funcs;
|
||||
WIFI_ENABLE_GCMP | \
|
||||
WIFI_ENABLE_GMAC | \
|
||||
WIFI_ENABLE_11R | \
|
||||
WIFI_ENABLE_ENTERPRISE)
|
||||
WIFI_ENABLE_ENTERPRISE | \
|
||||
WIFI_ENABLE_BSS_MAX_IDLE)
|
||||
|
||||
#define WIFI_INIT_CONFIG_DEFAULT() { \
|
||||
.osi_funcs = &g_wifi_osi_funcs, \
|
||||
|
@ -17,6 +17,8 @@
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#define WIFI_AP_DEFAULT_MAX_IDLE_PERIOD 292 /**< Default timeout for SoftAP BSS Max Idle. Unit: 1000TUs >**/
|
||||
|
||||
/**
|
||||
* @brief Wi-Fi mode type
|
||||
*/
|
||||
@ -507,6 +509,14 @@ typedef enum {
|
||||
WPA3_SAE_PK_MODE_DISABLED = 2,
|
||||
} wifi_sae_pk_mode_t;
|
||||
|
||||
/**
|
||||
* @brief Configuration structure for BSS max idle
|
||||
*/
|
||||
typedef struct {
|
||||
uint16_t period; /**< Sets BSS Max idle period (1 Unit = 1000TUs OR 1.024 Seconds). If there are no frames for this period from a STA, SoftAP will disassociate due to inactivity. Setting it to 0 disables the feature */
|
||||
bool protected_keep_alive; /**< Requires clients to use protected keep alive frames for BSS Max Idle period */
|
||||
} wifi_bss_max_idle_config_t;
|
||||
|
||||
/**
|
||||
* @brief Soft-AP configuration settings for the device
|
||||
*/
|
||||
@ -527,6 +537,7 @@ typedef struct {
|
||||
wifi_sae_pwe_method_t sae_pwe_h2e; /**< Configuration for SAE PWE derivation method */
|
||||
uint8_t transition_disable; /**< Whether to enable transition disable feature */
|
||||
uint8_t sae_ext; /**< Enable SAE EXT feature. SOC_GCMP_SUPPORT is required for this feature. */
|
||||
wifi_bss_max_idle_config_t bss_max_idle_cfg; /**< Configuration for bss max idle, effective if CONFIG_WIFI_BSS_MAX_IDLE_SUPPORT is enabled */
|
||||
} wifi_ap_config_t;
|
||||
|
||||
#define SAE_H2E_IDENTIFIER_LEN 32 /**< Length of the password identifier for H2E */
|
||||
|
Submodule components/esp_wifi/lib updated: 3e289f371e...d152ee7b81
@ -0,0 +1,242 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2025 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Unlicense OR CC0-1.0
|
||||
*/
|
||||
|
||||
#ifdef CONFIG_ESP_WIFI_BSS_MAX_IDLE_SUPPORT
|
||||
|
||||
#include <string.h>
|
||||
#include "unity.h"
|
||||
#include "freertos/FreeRTOS.h"
|
||||
#include "freertos/task.h"
|
||||
#include "esp_wifi.h"
|
||||
#include "esp_event.h"
|
||||
#include "esp_log.h"
|
||||
#include "test_utils.h"
|
||||
#include "freertos/event_groups.h"
|
||||
#include "unity_test_utils.h"
|
||||
#include "esp_private/wifi.h"
|
||||
|
||||
#ifdef __CHECKER__
|
||||
#define __force __attribute__((force))
|
||||
#define __bitwise __attribute__((bitwise))
|
||||
#else
|
||||
#define __force
|
||||
#define __bitwise
|
||||
#endif
|
||||
|
||||
#if defined(__linux__) || defined(__GLIBC__)
|
||||
#include <endian.h>
|
||||
#include <byteswap.h>
|
||||
#else
|
||||
#include <machine/endian.h>
|
||||
#define __BYTE_ORDER BYTE_ORDER
|
||||
#define __LITTLE_ENDIAN LITTLE_ENDIAN
|
||||
#endif /* __linux__ */
|
||||
#ifndef __BYTE_ORDER
|
||||
#ifndef __LITTLE_ENDIAN
|
||||
#define __LITTLE_ENDIAN 1234
|
||||
#endif
|
||||
#endif
|
||||
|
||||
typedef uint16_t u16;
|
||||
typedef uint8_t u8;
|
||||
typedef u16 __bitwise be16;
|
||||
|
||||
#define host_to_be16(n) ((__force be16) __builtin_bswap16((n)))
|
||||
|
||||
#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 MAXIMUM_RETRY (5)
|
||||
|
||||
#define WIFI_DISCONNECT_EVENT (1)
|
||||
#define WIFI_STA_CONNECTED (1<<1)
|
||||
#define WIFI_AP_STA_CONNECTED (1<<2)
|
||||
#define WIFI_FAIL (1<<3)
|
||||
#define EMPH_STR(s) "****** "s" ******"
|
||||
|
||||
#define MAX_IDLE_PERIOD (5)
|
||||
#define ETHTYPE_IP 0x0800
|
||||
|
||||
static const char* TAG = "test_bss_max_idle";
|
||||
|
||||
static bool s_sta_conn_first = false;
|
||||
static bool s_keep_alive_received = false;
|
||||
static int s_retry_num = 0;
|
||||
static EventGroupHandle_t wifi_events;
|
||||
|
||||
struct eth_header {
|
||||
u8 dest_mac[6];
|
||||
u8 src_mac[6];
|
||||
be16 ethertype;
|
||||
};
|
||||
|
||||
static esp_err_t wifi_ap_receive_test(void *buffer, uint16_t len, void *eb)
|
||||
{
|
||||
struct eth_header *pac = (struct eth_header *)buffer;
|
||||
if ((host_to_be16(pac->ethertype) == ETHTYPE_IP) && (len < 48)) {
|
||||
ESP_LOGI(TAG, "KEEP ALIVE RECEIVED");
|
||||
s_keep_alive_received = true;
|
||||
esp_wifi_deauth_sta(0);
|
||||
}
|
||||
esp_wifi_internal_free_rx_buffer(eb);
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
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_AP_START:
|
||||
ESP_LOGI(TAG, "WIFI_EVENT_AP_START");
|
||||
esp_wifi_internal_reg_rxcb(WIFI_IF_AP, wifi_ap_receive_test);
|
||||
break;
|
||||
case WIFI_EVENT_STA_START:
|
||||
ESP_LOGI(TAG, "WIFI_EVENT_STA_START");
|
||||
break;
|
||||
case WIFI_EVENT_AP_STACONNECTED:
|
||||
ESP_LOGI(TAG, "Wi-Fi AP got a station connected");
|
||||
break;
|
||||
case WIFI_EVENT_STA_CONNECTED:
|
||||
ESP_LOGI(TAG, "WIFI_EVENT_STA_CONNECTED");
|
||||
if (wifi_events) {
|
||||
xEventGroupSetBits(wifi_events, WIFI_STA_CONNECTED);
|
||||
s_sta_conn_first = true;
|
||||
}
|
||||
break;
|
||||
case WIFI_EVENT_STA_DISCONNECTED:
|
||||
if ((s_retry_num < MAXIMUM_RETRY) && !s_sta_conn_first) {
|
||||
esp_wifi_connect();
|
||||
s_retry_num++;
|
||||
ESP_LOGI(TAG, "retry to connect to AP");
|
||||
} else {
|
||||
xEventGroupSetBits(wifi_events, WIFI_DISCONNECT_EVENT);
|
||||
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);
|
||||
}
|
||||
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));
|
||||
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_loop_delete_default());
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
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_WPA3_PSK,
|
||||
.ap.ssid_hidden = false,
|
||||
.ap.max_connection = 4,
|
||||
.ap.beacon_interval = 100,
|
||||
.ap.bss_max_idle_cfg = {
|
||||
.period = MAX_IDLE_PERIOD,
|
||||
.protected_keep_alive = true,
|
||||
},
|
||||
};
|
||||
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 wifi_connect(void)
|
||||
{
|
||||
wifi_config_t w_config = {
|
||||
.sta.ssid = TEST_DEFAULT_SSID,
|
||||
.sta.password = TEST_DEFAULT_PWD,
|
||||
.sta.channel = TEST_DEFAULT_CHANNEL,
|
||||
};
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
static void test_bss_max_idle_sta(void)
|
||||
{
|
||||
start_wifi_as_sta();
|
||||
wifi_connect();
|
||||
// Waiting untill connection est or failed
|
||||
EventBits_t bits = xEventGroupWaitBits(wifi_events,
|
||||
WIFI_STA_CONNECTED | WIFI_FAIL,
|
||||
pdFALSE,
|
||||
pdFALSE,
|
||||
portMAX_DELAY);
|
||||
TEST_ASSERT(bits & WIFI_STA_CONNECTED);
|
||||
if (bits != WIFI_FAIL) {
|
||||
bits = xEventGroupWaitBits(wifi_events,
|
||||
WIFI_DISCONNECT_EVENT,
|
||||
pdFALSE,
|
||||
pdFALSE,
|
||||
portMAX_DELAY);
|
||||
}
|
||||
stop_wifi();
|
||||
}
|
||||
|
||||
static void test_bss_max_idle_softap(void)
|
||||
{
|
||||
start_wifi_as_softap();
|
||||
|
||||
vTaskDelay((CONNECT_TIMEOUT_MS + MAX_IDLE_PERIOD * 1000) / portTICK_PERIOD_MS);
|
||||
|
||||
TEST_ASSERT(s_keep_alive_received);
|
||||
stop_wifi();
|
||||
}
|
||||
|
||||
TEST_CASE_MULTIPLE_DEVICES("Connection with bss max idle enabled", "[wifi][bss max idle]", test_bss_max_idle_sta, test_bss_max_idle_softap);
|
||||
|
||||
#endif /* CONFIG_ESP_WIFI_BSS_MAX_IDLE_SUPPORT */
|
@ -1,3 +1,4 @@
|
||||
|
||||
# ignore task watchdog triggered by unity_run_menu
|
||||
CONFIG_ESP_TASK_WDT=n
|
||||
CONFIG_ESP_TASK_WDT_EN=n
|
||||
CONFIG_ESP_WIFI_BSS_MAX_IDLE_SUPPORT=y
|
||||
|
@ -75,6 +75,12 @@ void wifi_init_softap(void)
|
||||
.pmf_cfg = {
|
||||
.required = true,
|
||||
},
|
||||
#ifdef CONFIG_ESP_WIFI_BSS_MAX_IDLE_SUPPORT
|
||||
.bss_max_idle_cfg = {
|
||||
.period = WIFI_AP_DEFAULT_MAX_IDLE_PERIOD,
|
||||
.protected_keep_alive = 1,
|
||||
},
|
||||
#endif
|
||||
},
|
||||
};
|
||||
if (strlen(EXAMPLE_ESP_WIFI_PASS) == 0) {
|
||||
|
Reference in New Issue
Block a user