Skip to content

Commit

Permalink
Merge branch 'feature/itwt_add_setup_timeout_timer' into 'master'
Browse files Browse the repository at this point in the history
esp_wifi: itwt add setup timeout timer to track response frame

Closes WIFI-5916, WIFI-5905, and WIFI-5983

See merge request espressif/esp-idf!23942
  • Loading branch information
jack0c committed Jun 2, 2023
2 parents 6a6fc7e + 722c60c commit 175e887
Show file tree
Hide file tree
Showing 12 changed files with 157 additions and 70 deletions.
5 changes: 5 additions & 0 deletions components/esp_common/src/esp_err_to_name.c
Original file line number Diff line number Diff line change
Expand Up @@ -399,6 +399,11 @@ static const esp_err_msg_t esp_err_msg_table[] = {
# endif
# ifdef ESP_ERR_WIFI_TWT_FULL
ERR_TBL_IT(ESP_ERR_WIFI_TWT_FULL), /* 12311 0x3017 no available flow id */
# endif
# ifdef ESP_ERR_WIFI_TWT_SETUP_TIMEOUT
ERR_TBL_IT(ESP_ERR_WIFI_TWT_SETUP_TIMEOUT), /* 12312 0x3018 Timeout of receiving twt setup response
frame, timeout times can be set during
twt setup */
# endif
// components/wpa_supplicant/esp_supplicant/include/esp_wps.h
# ifdef ESP_ERR_WIFI_REGISTRAR
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,11 @@ void modem_clock_select_lp_clock_source(periph_module_t module, modem_clock_lpcl
*/
void modem_clock_deselect_lp_clock_source(periph_module_t module);

/**
* @brief Reset wifi mac
*/
void modem_clock_wifi_mac_reset(void);

#ifdef __cplusplus
}
#endif
11 changes: 11 additions & 0 deletions components/esp_hw_support/modem_clock.c
Original file line number Diff line number Diff line change
Expand Up @@ -214,6 +214,17 @@ static void IRAM_ATTR modem_clock_device_disable(modem_clock_context_t *ctx, uin
assert(refs >= 0);
}

void IRAM_ATTR modem_clock_wifi_mac_reset(void)
{
#if SOC_WIFI_SUPPORTED
modem_clock_context_t *ctx = MODEM_CLOCK_instance();
portENTER_CRITICAL_SAFE(&ctx->lock);
//TODO: IDF-5713
modem_syscon_ll_reset_wifimac(ctx->hal->syscon_dev);
portEXIT_CRITICAL_SAFE(&ctx->lock);
#endif
}

#define WIFI_CLOCK_DEPS (BIT(MODEM_CLOCK_WIFI_MAC) | BIT(MODEM_CLOCK_FE) | BIT(MODEM_CLOCK_WIFI_BB) | BIT(MODEM_CLOCK_COEXIST))
#define BLE_CLOCK_DEPS (BIT(MODEM_CLOCK_BLE_MAC) | BIT(MODEM_CLOCK_FE) | BIT(MODEM_CLOCK_BLE_BB) | BIT(MODEM_CLOCK_ETM) | BIT(MODEM_CLOCK_COEXIST))
#define IEEE802154_CLOCK_DEPS (BIT(MODEM_CLOCK_802154_MAC) | BIT(MODEM_CLOCK_FE) | BIT(MODEM_CLOCK_BLE_BB) | BIT(MODEM_CLOCK_ETM) | BIT(MODEM_CLOCK_COEXIST))
Expand Down
2 changes: 2 additions & 0 deletions components/esp_wifi/esp32c6/esp_adapter.c
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@
#include "esp_coexist_internal.h"
#include "esp32c6/rom/ets_sys.h"
#include "esp_modem_wrapper.h"
#include "esp_private/esp_modem_clock.h"

#if SOC_PM_MODEM_RETENTION_BY_REGDMA
#include "esp_private/esp_regdma.h"
Expand Down Expand Up @@ -297,6 +298,7 @@ static void IRAM_ATTR timer_arm_wrapper(void *timer, uint32_t tmout, bool repeat
static void wifi_reset_mac_wrapper(void)
{
// TODO: IDF-5713
modem_clock_wifi_mac_reset();
ESP_LOGW(TAG, "wifi_reset_mac_wrapper() has not been implemented yet");
}

Expand Down
47 changes: 24 additions & 23 deletions components/esp_wifi/include/esp_wifi.h
Original file line number Diff line number Diff line change
Expand Up @@ -61,29 +61,30 @@
extern "C" {
#endif

#define ESP_ERR_WIFI_NOT_INIT (ESP_ERR_WIFI_BASE + 1) /*!< WiFi driver was not installed by esp_wifi_init */
#define ESP_ERR_WIFI_NOT_STARTED (ESP_ERR_WIFI_BASE + 2) /*!< WiFi driver was not started by esp_wifi_start */
#define ESP_ERR_WIFI_NOT_STOPPED (ESP_ERR_WIFI_BASE + 3) /*!< WiFi driver was not stopped by esp_wifi_stop */
#define ESP_ERR_WIFI_IF (ESP_ERR_WIFI_BASE + 4) /*!< WiFi interface error */
#define ESP_ERR_WIFI_MODE (ESP_ERR_WIFI_BASE + 5) /*!< WiFi mode error */
#define ESP_ERR_WIFI_STATE (ESP_ERR_WIFI_BASE + 6) /*!< WiFi internal state error */
#define ESP_ERR_WIFI_CONN (ESP_ERR_WIFI_BASE + 7) /*!< WiFi internal control block of station or soft-AP error */
#define ESP_ERR_WIFI_NVS (ESP_ERR_WIFI_BASE + 8) /*!< WiFi internal NVS module error */
#define ESP_ERR_WIFI_MAC (ESP_ERR_WIFI_BASE + 9) /*!< MAC address is invalid */
#define ESP_ERR_WIFI_SSID (ESP_ERR_WIFI_BASE + 10) /*!< SSID is invalid */
#define ESP_ERR_WIFI_PASSWORD (ESP_ERR_WIFI_BASE + 11) /*!< Password is invalid */
#define ESP_ERR_WIFI_TIMEOUT (ESP_ERR_WIFI_BASE + 12) /*!< Timeout error */
#define ESP_ERR_WIFI_WAKE_FAIL (ESP_ERR_WIFI_BASE + 13) /*!< WiFi is in sleep state(RF closed) and wakeup fail */
#define ESP_ERR_WIFI_WOULD_BLOCK (ESP_ERR_WIFI_BASE + 14) /*!< The caller would block */
#define ESP_ERR_WIFI_NOT_CONNECT (ESP_ERR_WIFI_BASE + 15) /*!< Station still in disconnect status */

#define ESP_ERR_WIFI_POST (ESP_ERR_WIFI_BASE + 18) /*!< Failed to post the event to WiFi task */
#define ESP_ERR_WIFI_INIT_STATE (ESP_ERR_WIFI_BASE + 19) /*!< Invalid WiFi state when init/deinit is called */
#define ESP_ERR_WIFI_STOP_STATE (ESP_ERR_WIFI_BASE + 20) /*!< Returned when WiFi is stopping */
#define ESP_ERR_WIFI_NOT_ASSOC (ESP_ERR_WIFI_BASE + 21) /*!< The WiFi connection is not associated */
#define ESP_ERR_WIFI_TX_DISALLOW (ESP_ERR_WIFI_BASE + 22) /*!< The WiFi TX is disallowed */

#define ESP_ERR_WIFI_TWT_FULL (ESP_ERR_WIFI_BASE + 23) /*!< no available flow id */
#define ESP_ERR_WIFI_NOT_INIT (ESP_ERR_WIFI_BASE + 1) /*!< WiFi driver was not installed by esp_wifi_init */
#define ESP_ERR_WIFI_NOT_STARTED (ESP_ERR_WIFI_BASE + 2) /*!< WiFi driver was not started by esp_wifi_start */
#define ESP_ERR_WIFI_NOT_STOPPED (ESP_ERR_WIFI_BASE + 3) /*!< WiFi driver was not stopped by esp_wifi_stop */
#define ESP_ERR_WIFI_IF (ESP_ERR_WIFI_BASE + 4) /*!< WiFi interface error */
#define ESP_ERR_WIFI_MODE (ESP_ERR_WIFI_BASE + 5) /*!< WiFi mode error */
#define ESP_ERR_WIFI_STATE (ESP_ERR_WIFI_BASE + 6) /*!< WiFi internal state error */
#define ESP_ERR_WIFI_CONN (ESP_ERR_WIFI_BASE + 7) /*!< WiFi internal control block of station or soft-AP error */
#define ESP_ERR_WIFI_NVS (ESP_ERR_WIFI_BASE + 8) /*!< WiFi internal NVS module error */
#define ESP_ERR_WIFI_MAC (ESP_ERR_WIFI_BASE + 9) /*!< MAC address is invalid */
#define ESP_ERR_WIFI_SSID (ESP_ERR_WIFI_BASE + 10) /*!< SSID is invalid */
#define ESP_ERR_WIFI_PASSWORD (ESP_ERR_WIFI_BASE + 11) /*!< Password is invalid */
#define ESP_ERR_WIFI_TIMEOUT (ESP_ERR_WIFI_BASE + 12) /*!< Timeout error */
#define ESP_ERR_WIFI_WAKE_FAIL (ESP_ERR_WIFI_BASE + 13) /*!< WiFi is in sleep state(RF closed) and wakeup fail */
#define ESP_ERR_WIFI_WOULD_BLOCK (ESP_ERR_WIFI_BASE + 14) /*!< The caller would block */
#define ESP_ERR_WIFI_NOT_CONNECT (ESP_ERR_WIFI_BASE + 15) /*!< Station still in disconnect status */

#define ESP_ERR_WIFI_POST (ESP_ERR_WIFI_BASE + 18) /*!< Failed to post the event to WiFi task */
#define ESP_ERR_WIFI_INIT_STATE (ESP_ERR_WIFI_BASE + 19) /*!< Invalid WiFi state when init/deinit is called */
#define ESP_ERR_WIFI_STOP_STATE (ESP_ERR_WIFI_BASE + 20) /*!< Returned when WiFi is stopping */
#define ESP_ERR_WIFI_NOT_ASSOC (ESP_ERR_WIFI_BASE + 21) /*!< The WiFi connection is not associated */
#define ESP_ERR_WIFI_TX_DISALLOW (ESP_ERR_WIFI_BASE + 22) /*!< The WiFi TX is disallowed */

#define ESP_ERR_WIFI_TWT_FULL (ESP_ERR_WIFI_BASE + 23) /*!< no available flow id */
#define ESP_ERR_WIFI_TWT_SETUP_TIMEOUT (ESP_ERR_WIFI_BASE + 24) /*!< Timeout of receiving twt setup response frame, timeout times can be set during twt setup */

/**
* @brief WiFi stack configuration parameters passed to esp_wifi_init call.
Expand Down
14 changes: 3 additions & 11 deletions components/esp_wifi/include/esp_wifi_he.h
Original file line number Diff line number Diff line change
Expand Up @@ -22,18 +22,10 @@ extern "C" {
* - e.g. TWT Wake Interval Mantissa = 512, TWT Wake Interval Exponent = 12, then TWT Wake Interval is 2097.152 ms
* Nominal Minimum Wake Duration = 255, then TWT Wake Duration is 65.28 ms
*
* @attention Support at most 4 TWT agreements, otherwise ESP_ERR_WIFI_TWT_FULL will be returned.
* @attention Support at most 8 TWT agreements, otherwise ESP_ERR_WIFI_TWT_FULL will be returned.
* Support sleep time up to (1 << 35) us.
*
* @param[in] setup_cmd Indicates the type of TWT command
* @param[in] trigger true: a trigger-enabled TWT, false: a non-trigger-enabled TWT
* @param[in] flow_type 0: an announced TWT, 1: an unannounced TWT
* @param[in] min_wake_dura Nominal Minimum Wake Duration, indicates the minimum amount of time, in unit of 256 us, that the TWT requesting STA expects that it needs to be awake. The value range is [1, 255].
* @param[in] wake_invl_expn TWT Wake Interval Exponent. The value range is [0, 31].
* @param[in] wake_invl_mant TWT Wake Interval Mantissa. The value range is [1, 65535].
* @param[in/out] flow_id When set up an individual TWT agreement, the flow id will be assigned by AP after a successful agreement setup.
* flow_id is allowed to be NULL. flow_id could be specified to a value in the range of [0, 7], but it might be changed by AP in the response.
* When change TWT parameters of the existing TWT agreement, flow_id should be an existing one. The value range is [0, 7].
* @param[in/out] setup_config pointer to itwt setup config structure.
*
* @return
* - ESP_OK: succeed
Expand All @@ -44,7 +36,7 @@ extern "C" {
* - ESP_ERR_WIFI_TWT_FULL: no available flow id
* - ESP_ERR_INVALID_ARG: invalid argument
*/
esp_err_t esp_wifi_sta_itwt_setup(wifi_twt_setup_cmds_t setup_cmd, bool trigger, int flow_type, int min_wake_dura, int wake_invl_expn, int wake_invl_mant, int *flow_id);
esp_err_t esp_wifi_sta_itwt_setup(wifi_twt_setup_config_t *setup_config);

/**
* @brief Tear down individual TWT agreements
Expand Down
29 changes: 21 additions & 8 deletions components/esp_wifi/include/esp_wifi_he_types.h
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,25 @@ typedef enum {
TWT_REJECT, /**< indicate that the negotiation has ended in failure to crate a new TWT agreement */
} wifi_twt_setup_cmds_t;

/**
* @brief TWT setup config
*/
typedef struct
{
wifi_twt_setup_cmds_t setup_cmd; /**< Indicates the type of TWT command */
uint16_t trigger :1; /**< 1: a trigger-enabled TWT, 0: a non-trigger-enabled TWT */
uint16_t flow_type :1; /**< 0: an announced TWT, 1: an unannounced TWT */
uint16_t flow_id :3; /**< When set up an individual TWT agreement, the flow id will be assigned by AP after a successful agreement setup.
flow_id could be specified to a value in the range of [0, 7], but it might be changed by AP in the response.
When change TWT parameters of the existing TWT agreement, flow_id should be an existing one. The value range is [0, 7]. */
uint16_t wake_invl_expn :5; /**< TWT Wake Interval Exponent. The value range is [0, 31]. */
uint16_t reserved :6; /**< bit: 10.15 reserved */
uint8_t min_wake_dura; /**< Nominal Minimum Wake Duration, indicates the minimum amount of time, in unit of 256 us, that the TWT requesting STA expects that it needs to be awake. The value range is [1, 255]. */
uint16_t wake_invl_mant; /**< TWT Wake Interval Mantissa. The value range is [1, 65535]. */
uint16_t twt_id; /**< TWT connection id, the value range is [0, 32767]. */
uint16_t timeout_time_ms; /**< Timeout times of receiving setup action frame response, default 5s*/
} wifi_twt_setup_config_t;

/**
* @brief HE SU GI and LTF types
*/
Expand Down Expand Up @@ -185,14 +204,8 @@ typedef struct {

/** Argument structure for WIFI_EVENT_TWT_SET_UP event */
typedef struct {
wifi_twt_setup_cmds_t setup_cmd; /**< TWT setup command */
uint8_t flow_id; /**< flow id */
uint8_t min_wake_dura; /**< the min. wake duration, unit: 256 us by default */
uint8_t wake_invl_expn; /**< the exponent of the TWT wake interval in microseconds, base 2 */
uint16_t wake_invl_mant; /**< the value of the mantissa of the TWT wake interval value in microseconds, base 2 */
bool trigger; /**< true: indicates a trigger-enabled TWT, false: indicates a non-trigger-enabled TWT */
uint8_t flow_type; /**< 0: indicate an announced TWT, 1: indicates an unannounced TWT */
esp_err_t status; /**< 1: indicate tx success, others : indicate tx fail */
wifi_twt_setup_config_t config; /**< itwt setup config*/
esp_err_t status; /**< 1: indicate tx success, others : indicate tx fail */
} wifi_event_sta_itwt_setup_t;

/** Argument structure for WIFI_EVENT_TWT_TEARDOWN event */
Expand Down
6 changes: 3 additions & 3 deletions examples/common_components/iperf/iperf.c
Original file line number Diff line number Diff line change
Expand Up @@ -372,12 +372,12 @@ static esp_err_t iperf_run_tcp_client(void)
wifi_cmd_clr_tx_statistics(0, NULL);
#endif
socket_send(client_socket, dest_addr, IPERF_TRANS_TYPE_TCP, s_iperf_ctrl.cfg.bw_lim);
#if CONFIG_ESP_WIFI_ENABLE_WIFI_TX_STATS
wifi_cmd_get_tx_statistics(0, NULL);
#endif
#if CONFIG_ESP_WIFI_ENABLE_WIFI_RX_STATS
wifi_cmd_get_rx_statistics(0, NULL);
#endif
#if CONFIG_ESP_WIFI_ENABLE_WIFI_TX_STATS
wifi_cmd_get_tx_statistics(0, NULL);
#endif

exit:
if (client_socket != -1) {
Expand Down
58 changes: 48 additions & 10 deletions examples/common_components/iperf/wifi_twt.c
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,8 @@ typedef struct {
struct arg_int *wakeinvlman; //setup
struct arg_int *minwakedur; //setup
struct arg_int *flowid;
struct arg_int *twtid;
struct arg_int *setup_timeout_time_ms;
struct arg_int *suspend_time_ms;
struct arg_int *all_twt;
struct arg_end *end;
Expand Down Expand Up @@ -71,16 +73,50 @@ static int wifi_cmd_itwt(int argc, char **argv)

esp_err_t err = ESP_OK;
if (itwt_args.setup->count) {
// setup command, trigger, flow type, min wake duration, wake interval exponent, wake interval mantissa
wifi_twt_setup_cmds_t setup = (itwt_args.setup->ival[0] <= TWT_DEMAND) ? itwt_args.setup->ival[0] : TWT_REQUEST;
bool trigger = itwt_args.trigger->count ? (itwt_args.trigger->ival[0] ? true : false) : true;
uint8_t flowtype = itwt_args.flowtype->count ? ((itwt_args.flowtype->ival[0] == 0) ? 0 : 1) : 0;
int minwakedur = itwt_args.minwakedur->count ? itwt_args.minwakedur->ival[0] : 255;
int wakeinvlexp = itwt_args.wakeinvlexp->count ? itwt_args.wakeinvlexp->ival[0] : 10;
int wakeinvlman = itwt_args.wakeinvlman->count ? itwt_args.wakeinvlman->ival[0] : 512;
int flow_id = 0;
err = esp_wifi_sta_itwt_setup(setup, trigger, flowtype, minwakedur, wakeinvlexp, wakeinvlman, &flow_id);
ESP_LOGI(TAG, "(itwt)setup, trigger:%d, %s, flow_id:%d, err:0x%x", trigger, flowtype ? "unannounce" : "announced", flow_id, err);
if (itwt_args.wakeinvlman->count) {
if (itwt_args.wakeinvlman->ival[0] < 0 || itwt_args.wakeinvlman->ival[0] > 65535) {
ESP_LOGE(TAG, "(itwt)expect [0, 65535], wake_invl_mant: %d", itwt_args.wakeinvlman->ival[0]);
return 1;
}
}
if (itwt_args.wakeinvlexp->count) {
if (itwt_args.wakeinvlexp->ival[0] < 0 || itwt_args.wakeinvlexp->ival[0] > 31) {
ESP_LOGE(TAG, "(itwt)expect [0, 31], wake_invl_expn: %d", itwt_args.wakeinvlexp->ival[0]);
return 1;
}
}
if (itwt_args.minwakedur->count) {
if (itwt_args.minwakedur->ival[0] < 0 || itwt_args.minwakedur->ival[0] > 255) {
ESP_LOGE(TAG, "(itwt)expect [0, 255], min_wake_dura: %d", itwt_args.minwakedur->ival[0]);
return 1;
}
}
if (itwt_args.twtid->count) {
if (itwt_args.twtid->ival[0] < 0 || itwt_args.twtid->ival[0] > 32767) {
ESP_LOGE(TAG, "(itwt)expect [0, 32767], twt id: %d", itwt_args.twtid->ival[0]);
return 1;
}
}
if (itwt_args.setup_timeout_time_ms->count) {
if (itwt_args.setup_timeout_time_ms->ival[0] < 0 || itwt_args.setup_timeout_time_ms->ival[0] > 65535) {
ESP_LOGE(TAG, "(itwt)expect [0, 65535], setup timeout time: %d", itwt_args.setup_timeout_time_ms->ival[0]);
return 1;
}
}
wifi_twt_setup_config_t setup_config = {
.setup_cmd = (itwt_args.setup->ival[0] <= TWT_DEMAND) ? itwt_args.setup->ival[0] : TWT_REQUEST,
.flow_id = 0,
.twt_id = itwt_args.twtid->count ? itwt_args.twtid->ival[0] : 0,
.flow_type = itwt_args.flowtype->count ? ((itwt_args.flowtype->ival[0] == 0) ? 0 : 1) : 0,
.min_wake_dura = itwt_args.minwakedur->count ? itwt_args.minwakedur->ival[0] : 255,
.wake_invl_expn = itwt_args.wakeinvlexp->count ? itwt_args.wakeinvlexp->ival[0] : 10,
.wake_invl_mant = itwt_args.wakeinvlman->count ? itwt_args.wakeinvlman->ival[0] : 512,
.trigger = itwt_args.trigger->count ? (itwt_args.trigger->ival[0] ? 1 : 0) : 1,
.timeout_time_ms = itwt_args.setup_timeout_time_ms->count ? itwt_args.setup_timeout_time_ms->ival[0] : 5000,
};
err = esp_wifi_sta_itwt_setup(&setup_config);
ESP_LOGI(TAG, "(itwt)setup, trigger:%d, %s, flow_id:%d, err:0x%x",
setup_config.trigger, setup_config.flow_type ? "unannounce" : "announced", setup_config.flow_id, err);
}
if (itwt_args.teardown->count) {
// teardown a given flow id, all_twt has a high priority
Expand Down Expand Up @@ -146,6 +182,8 @@ void register_wifi_itwt(void)
itwt_args.wakeinvlman = arg_int0("m", NULL, "<wakeinvlman>", "Wake Interval Mantissa");
itwt_args.flowid = arg_int0("i", NULL, "<flow_id>", "Flow ID");
itwt_args.suspend_time_ms = arg_int0("s", NULL, "<suspend_time_ms>", "time of suspending iTWT agreements, unit ms");
itwt_args.twtid = arg_int0("w", NULL, "<twt_id>", "TWT ID");
itwt_args.setup_timeout_time_ms = arg_int0("u", NULL, "<setup_timeout_time_ms>", "iTWT setup timeout time, unit ms");
itwt_args.all_twt = arg_int0("a", NULL, "<all_twt>", "All TWT");
itwt_args.end = arg_end(1);
const esp_console_cmd_t itwt_cmd = {
Expand Down
12 changes: 12 additions & 0 deletions examples/wifi/itwt/main/Kconfig.projbuild
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,18 @@ menu "Example Configuration"
default 512
help
TWT Wake Interval Mantissa, in microseconds. The value range is [1, 65535].
config EXAMPLE_ITWT_ID
int "itwt connection id"
range 0 32767
default 0
help
TWT Connection id. The value range is [0, 32767].
config EXAMPLE_ITWT_SETUP_TIMEOUT_TIME_MS
int "itwt wake interval mantissa"
range 100 65535
default 5000
help
TWT setup timeout time, in microseconds. The value range is [100, 65535].
endmenu

choice EXAMPLE_MAX_CPU_FREQ
Expand Down
Loading

0 comments on commit 175e887

Please sign in to comment.