Merge branch 'bugfix/offchan_action_tx_failure' into 'master'

Fix issues with offchannel action tx and ROC operations

See merge request espressif/esp-idf!28204
This commit is contained in:
Jiang Jiang Jian
2025-03-19 19:14:36 +08:00
9 changed files with 202 additions and 86 deletions

View File

@ -513,7 +513,7 @@ lmacRecycleMPDU = 0x40001b44;
lmacRxDone = 0x40001b48; lmacRxDone = 0x40001b48;
/*lmacSetTxFrame = 0x40001b4c;*/ /*lmacSetTxFrame = 0x40001b4c;*/
lmacTxDone = 0x40001b50; lmacTxDone = 0x40001b50;
lmacTxFrame = 0x40001b54; /*lmacTxFrame = 0x40001b54;*/
mac_tx_set_duration = 0x40001b58; mac_tx_set_duration = 0x40001b58;
mac_tx_set_htsig = 0x40001b5c; mac_tx_set_htsig = 0x40001b5c;
mac_tx_set_plcp0 = 0x40001b60; mac_tx_set_plcp0 = 0x40001b60;
@ -555,7 +555,7 @@ ppEnqueueRxq = 0x40001bec;
ppEnqueueTxDone = 0x40001bf0; ppEnqueueTxDone = 0x40001bf0;
ppGetTxQFirstAvail_Locked = 0x40001bf4; ppGetTxQFirstAvail_Locked = 0x40001bf4;
ppGetTxframe = 0x40001bf8; ppGetTxframe = 0x40001bf8;
ppMapTxQueue = 0x40001bfc; /*ppMapTxQueue = 0x40001bfc;*/
ppProcTxSecFrame = 0x40001c00; ppProcTxSecFrame = 0x40001c00;
ppProcessRxPktHdr = 0x40001c04; ppProcessRxPktHdr = 0x40001c04;
/*ppProcessTxQ = 0x40001c08;*/ /*ppProcessTxQ = 0x40001c08;*/

View File

@ -1,5 +1,5 @@
/* /*
* SPDX-FileCopyrightText: 2015-2024 Espressif Systems (Shanghai) CO LTD * SPDX-FileCopyrightText: 2015-2025 Espressif Systems (Shanghai) CO LTD
* *
* SPDX-License-Identifier: Apache-2.0 * SPDX-License-Identifier: Apache-2.0
*/ */
@ -1788,6 +1788,29 @@ esp_err_t esp_wifi_set_bandwidths(wifi_interface_t ifx, wifi_bandwidths_t* bw);
*/ */
esp_err_t esp_wifi_get_bandwidths(wifi_interface_t ifx, wifi_bandwidths_t *bw); esp_err_t esp_wifi_get_bandwidths(wifi_interface_t ifx, wifi_bandwidths_t *bw);
/**
* @brief Send action frame on target channel
*
* @param req action tx request structure containing relevant fields
*
* @return
* - ESP_OK: succeed
* - ESP_ERR_NO_MEM: failed to allocate memory
* - ESP_FAIL: failed to send frame
*/
esp_err_t esp_wifi_action_tx_req(wifi_action_tx_req_t *req);
/**
* @brief Remain on the target channel for required duration
*
* @param req roc request structure containing relevant fields
*
* @return
* - ESP_OK: succeed
* - ESP_ERR_NO_MEM: failed to allocate memory
* - ESP_FAIL: failed to perform roc operation
*/
esp_err_t esp_wifi_remain_on_channel(wifi_roc_req_t * req);
#ifdef __cplusplus #ifdef __cplusplus
} }
#endif #endif

View File

@ -1,5 +1,5 @@
/* /*
* SPDX-FileCopyrightText: 2015-2024 Espressif Systems (Shanghai) CO LTD * SPDX-FileCopyrightText: 2015-2025 Espressif Systems (Shanghai) CO LTD
* *
* SPDX-License-Identifier: Apache-2.0 * SPDX-License-Identifier: Apache-2.0
*/ */
@ -41,12 +41,15 @@ typedef enum {
WIFI_IF_MAX /**< Maximum number of interfaces */ WIFI_IF_MAX /**< Maximum number of interfaces */
} wifi_interface_t; } wifi_interface_t;
#define WIFI_OFFCHAN_TX_REQ 1 /**< Request off-channel transmission */ typedef enum {
#define WIFI_OFFCHAN_TX_CANCEL 0 /**< Cancel off-channel transmission */ WIFI_OFFCHAN_TX_CANCEL, /**< Cancel off-channel transmission */
WIFI_OFFCHAN_TX_REQ, /**< Request off-channel transmission */
#define WIFI_ROC_REQ 1 /**< Request remain on channel */ } wifi_action_tx_t;
#define WIFI_ROC_CANCEL 0 /**< Cancel remain on channel */
typedef enum {
WIFI_ROC_CANCEL, /**< Cancel remain on channel */
WIFI_ROC_REQ, /**< Request remain on channel */
} wifi_roc_t;
/** /**
* @brief Wi-Fi country policy * @brief Wi-Fi country policy
*/ */
@ -771,12 +774,49 @@ typedef int (* wifi_action_rx_cb_t)(uint8_t *hdr, uint8_t *payload,
typedef struct { typedef struct {
wifi_interface_t ifx; /**< Wi-Fi interface to send request to */ wifi_interface_t ifx; /**< Wi-Fi interface to send request to */
uint8_t dest_mac[6]; /**< Destination MAC address */ uint8_t dest_mac[6]; /**< Destination MAC address */
wifi_action_tx_t type; /**< ACTION TX operation type */
uint8_t channel; /**< Channel on which to perform ACTION TX Operation */
uint32_t wait_time_ms; /**< Duration to wait for on target channel */
bool no_ack; /**< Indicates no ack required */ bool no_ack; /**< Indicates no ack required */
wifi_action_rx_cb_t rx_cb; /**< Rx Callback to receive any response */ wifi_action_rx_cb_t rx_cb; /**< Rx Callback to receive action frames */
uint8_t op_id; /**< Unique Identifier for operation provided by wifi driver */
uint32_t data_len; /**< Length of the appended Data */ uint32_t data_len; /**< Length of the appended Data */
uint8_t data[0]; /**< Appended Data payload */ uint8_t data[0]; /**< Appended Data payload */
} wifi_action_tx_req_t; } wifi_action_tx_req_t;
/** Status codes for WIFI_EVENT_ROC_DONE evt */
typedef enum {
WIFI_ROC_DONE = 0, /**< ROC operation was completed successfully */
WIFI_ROC_FAIL, /**< ROC operation was cancelled */
} wifi_roc_done_status_t;
/**
* @brief The callback function executed when ROC operation has ended
*
* @param context rxcb registered for the corresponding ROC operation
* @param op_id ID of the corresponding ROC operation
* @param status status code of the ROC operation denoted
*
*/
typedef void (* wifi_action_roc_done_cb_t)(uint32_t context, uint8_t op_id,
wifi_roc_done_status_t status);
/**
* @brief Remain on Channel request
*
*
*/
typedef struct {
wifi_interface_t ifx; /**< WiFi interface to send request to */
wifi_roc_t type; /**< ROC operation type */
uint8_t channel; /**< Channel on which to perform ROC Operation */
wifi_second_chan_t sec_channel; /**< Secondary channel */
uint32_t wait_time_ms; /**< Duration to wait for on target channel */
wifi_action_rx_cb_t rx_cb; /**< Rx Callback to receive any response */
uint8_t op_id; /**< ID of this specific ROC operation provided by wifi driver */
wifi_action_roc_done_cb_t done_cb; /**< Callback to function that will be called upon ROC done. If assigned, WIFI_EVENT_ROC_DONE event will not be posted */
} wifi_roc_req_t;
/** /**
* @brief FTM Initiator configuration * @brief FTM Initiator configuration
* *
@ -1198,21 +1238,32 @@ typedef struct {
#define WIFI_STATIS_PS (1<<4) /**< Power save status */ #define WIFI_STATIS_PS (1<<4) /**< Power save status */
#define WIFI_STATIS_ALL (-1) /**< All status */ #define WIFI_STATIS_ALL (-1) /**< All status */
/** /** Status codes for WIFI_EVENT_ACTION_TX_STATUS evt */
* @brief Argument structure for WIFI_EVENT_ACTION_TX_STATUS event /** There will be back to back events in success case TX_DONE and TX_DURATION_COMPLETED */
*/ typedef enum {
WIFI_ACTION_TX_DONE = 0, /**< ACTION_TX operation was completed successfully */
WIFI_ACTION_TX_FAILED, /**< ACTION_TX operation failed during tx */
WIFI_ACTION_TX_DURATION_COMPLETED, /**< ACTION_TX operation completed it's wait duration */
WIFI_ACTION_TX_OP_CANCELLED, /**< ACTION_TX operation was cancelled by application or higher priority operation */
} wifi_action_tx_status_type_t;
/** Argument structure for WIFI_EVENT_ACTION_TX_STATUS event */
typedef struct { typedef struct {
wifi_interface_t ifx; /**< Wi-Fi interface to send request to */ wifi_interface_t ifx; /**< WiFi interface to send request to */
uint32_t context; /**< Context to identify the request */ uint32_t context; /**< Context to identify the request */
uint8_t da[6]; /**< Destination MAC address */ wifi_action_tx_status_type_t status; /**< Status of the operation */
uint8_t status; /**< Status of the operation */ uint8_t op_id; /**< ID of the corresponding operation that was provided during action tx request */
uint8_t channel; /**< Channel provided in tx request */
} wifi_event_action_tx_status_t; } wifi_event_action_tx_status_t;
/** /**
* @brief Argument structure for WIFI_EVENT_ROC_DONE event * @brief Argument structure for WIFI_EVENT_ROC_DONE event
*/ */
typedef struct { typedef struct {
uint32_t context; /**< Context to identify the request */ uint32_t context; /**< Context to identify the initiator of the request */
wifi_roc_done_status_t status; /**< ROC status */
uint8_t op_id; /**< ID of the corresponding ROC operation */
uint8_t channel; /**< Channel provided in tx request */
} wifi_event_roc_done_t; } wifi_event_roc_done_t;
/** /**

View File

@ -1,5 +1,5 @@
/* /*
* SPDX-FileCopyrightText: 2020-2024 Espressif Systems (Shanghai) CO LTD * SPDX-FileCopyrightText: 2020-2025 Espressif Systems (Shanghai) CO LTD
* *
* SPDX-License-Identifier: Apache-2.0 * SPDX-License-Identifier: Apache-2.0
*/ */
@ -28,7 +28,7 @@ static void *s_dpp_api_lock = NULL;
static bool s_dpp_listen_in_progress; static bool s_dpp_listen_in_progress;
static struct esp_dpp_context_t s_dpp_ctx; static struct esp_dpp_context_t s_dpp_ctx;
static wifi_action_rx_cb_t s_action_rx_cb = esp_supp_rx_action; static wifi_action_rx_cb_t s_action_rx_cb = esp_supp_rx_action;
static uint8_t s_current_tx_op_id;
#define DPP_API_LOCK() os_mutex_lock(s_dpp_api_lock) #define DPP_API_LOCK() os_mutex_lock(s_dpp_api_lock)
#define DPP_API_UNLOCK() os_mutex_unlock(s_dpp_api_lock) #define DPP_API_UNLOCK() os_mutex_unlock(s_dpp_api_lock)
@ -101,7 +101,7 @@ static void esp_dpp_auth_conf_wait_timeout(void *eloop_ctx, void *timeout_ctx)
esp_err_t esp_dpp_send_action_frame(uint8_t *dest_mac, const uint8_t *buf, uint32_t len, esp_err_t esp_dpp_send_action_frame(uint8_t *dest_mac, const uint8_t *buf, uint32_t len,
uint8_t channel, uint32_t wait_time_ms) uint8_t channel, uint32_t wait_time_ms)
{ {
wifi_action_tx_req_t *req = os_zalloc(sizeof(*req) + len);; wifi_action_tx_req_t *req = os_zalloc(sizeof(*req) + len);
if (!req) { if (!req) {
return ESP_FAIL; return ESP_FAIL;
} }
@ -111,19 +111,23 @@ esp_err_t esp_dpp_send_action_frame(uint8_t *dest_mac, const uint8_t *buf, uint3
req->no_ack = false; req->no_ack = false;
req->data_len = len; req->data_len = len;
req->rx_cb = s_action_rx_cb; req->rx_cb = s_action_rx_cb;
req->channel = channel;
req->wait_time_ms = wait_time_ms;
req->type = WIFI_OFFCHAN_TX_REQ;
memcpy(req->data, buf, req->data_len); memcpy(req->data, buf, req->data_len);
wpa_printf(MSG_DEBUG, "DPP: Mgmt Tx - MAC:" MACSTR ", Channel-%d, WaitT-%d", wpa_printf(MSG_DEBUG, "DPP: Mgmt Tx - MAC:" MACSTR ", Channel-%d, WaitT-%d",
MAC2STR(dest_mac), channel, wait_time_ms); MAC2STR(dest_mac), channel, wait_time_ms);
if (ESP_OK != esp_wifi_action_tx_req(WIFI_OFFCHAN_TX_REQ, channel, if (ESP_OK != esp_wifi_action_tx_req(req)) {
wait_time_ms, req)) {
wpa_printf(MSG_ERROR, "DPP: Failed to perform offchannel operation"); wpa_printf(MSG_ERROR, "DPP: Failed to perform offchannel operation");
esp_dpp_call_cb(ESP_SUPP_DPP_FAIL, (void *)ESP_ERR_DPP_TX_FAILURE); esp_dpp_call_cb(ESP_SUPP_DPP_FAIL, (void *)ESP_ERR_DPP_TX_FAILURE);
os_free(req); os_free(req);
return ESP_FAIL; return ESP_FAIL;
} }
wpa_printf(MSG_DEBUG, "Sent DPP action frame %d", req->op_id);
s_current_tx_op_id = req->op_id;
os_free(req); os_free(req);
return ESP_OK; return ESP_OK;
} }
@ -560,21 +564,27 @@ static void esp_dpp_task(void *pvParameters)
case SIG_DPP_LISTEN_NEXT_CHANNEL: { case SIG_DPP_LISTEN_NEXT_CHANNEL: {
struct dpp_bootstrap_params_t *p = &s_dpp_ctx.bootstrap_params; struct dpp_bootstrap_params_t *p = &s_dpp_ctx.bootstrap_params;
static int counter; static int counter;
int channel;
esp_err_t ret = 0; esp_err_t ret = 0;
if (p->num_chan <= 0) { if (p->num_chan <= 0) {
wpa_printf(MSG_ERROR, "Listen channel not set"); wpa_printf(MSG_ERROR, "Listen channel not set");
break; break;
} }
channel = p->chan_list[counter++ % p->num_chan];
wpa_printf(MSG_DEBUG, "Listening on channel=%d", channel); wifi_roc_req_t req = {0};
ret = esp_wifi_remain_on_channel(WIFI_IF_STA, WIFI_ROC_REQ, channel, req.ifx = WIFI_IF_STA;
BOOTSTRAP_ROC_WAIT_TIME, s_action_rx_cb); req.type = WIFI_ROC_REQ;
req.channel = p->chan_list[counter++ % p->num_chan];
req.wait_time_ms = BOOTSTRAP_ROC_WAIT_TIME;
req.rx_cb = s_action_rx_cb;
req.done_cb = NULL;
wpa_printf(MSG_DEBUG, "Listening on channel=%d", req.channel);
ret = esp_wifi_remain_on_channel(&req);
if (ret != ESP_OK) { if (ret != ESP_OK) {
wpa_printf(MSG_ERROR, "Failed ROC. error : 0x%x", ret); wpa_printf(MSG_ERROR, "Failed ROC. error : 0x%x", ret);
break; break;
} }
wpa_printf(MSG_DEBUG, "Started DPP listen operation %d", req.op_id);
s_dpp_listen_in_progress = true; s_dpp_listen_in_progress = true;
} }
break; break;
@ -656,21 +666,22 @@ static void offchan_event_handler(void *arg, esp_event_base_t event_base,
if (event_id == WIFI_EVENT_ACTION_TX_STATUS) { if (event_id == WIFI_EVENT_ACTION_TX_STATUS) {
wifi_event_action_tx_status_t *evt = wifi_event_action_tx_status_t *evt =
(wifi_event_action_tx_status_t *)event_data; (wifi_event_action_tx_status_t *)event_data;
wpa_printf(MSG_DEBUG, "Mgmt Tx Status - %d, Cookie - 0x%x", if (evt->op_id == s_current_tx_op_id) {
evt->status, (uint32_t)evt->context); wpa_printf(MSG_DEBUG,
"Mgmt Tx Status - %d, Context - 0x%x Operation ID : %d", evt->status, (uint32_t)evt->context, evt->op_id);
if (evt->status) { if (evt->status == WIFI_ACTION_TX_FAILED) {
eloop_cancel_timeout(esp_dpp_auth_conf_wait_timeout, NULL, NULL); eloop_cancel_timeout(esp_dpp_auth_conf_wait_timeout, NULL, NULL);
if (s_dpp_listen_in_progress) { if (s_dpp_listen_in_progress) {
esp_supp_dpp_stop_listen(); esp_supp_dpp_stop_listen();
}
esp_dpp_call_cb(ESP_SUPP_DPP_FAIL, (void *)ESP_ERR_DPP_TX_FAILURE);
} }
esp_dpp_call_cb(ESP_SUPP_DPP_FAIL, (void *)ESP_ERR_DPP_TX_FAILURE);
} }
} else if (event_id == WIFI_EVENT_ROC_DONE) { } else if (event_id == WIFI_EVENT_ROC_DONE) {
wifi_event_roc_done_t *evt = (wifi_event_roc_done_t *)event_data; wifi_event_roc_done_t *evt = (wifi_event_roc_done_t *)event_data;
/*@TODO : Decide flow for when ROC fails*/
if (s_dpp_listen_in_progress && evt->context == (uint32_t)s_action_rx_cb) { if (s_dpp_listen_in_progress && evt->context == (uint32_t)s_action_rx_cb && evt->status == WIFI_ROC_DONE) {
esp_dpp_post_evt(SIG_DPP_LISTEN_NEXT_CHANNEL, 0); esp_dpp_post_evt(SIG_DPP_LISTEN_NEXT_CHANNEL, 0);
} }
} }
@ -856,7 +867,14 @@ esp_err_t esp_supp_dpp_start_listen(void)
esp_err_t esp_supp_dpp_stop_listen(void) esp_err_t esp_supp_dpp_stop_listen(void)
{ {
s_dpp_listen_in_progress = false; s_dpp_listen_in_progress = false;
return esp_wifi_remain_on_channel(WIFI_IF_STA, WIFI_ROC_CANCEL, 0, 0, NULL); wifi_roc_req_t req = {0};
req.ifx = WIFI_IF_STA;
req.type = WIFI_ROC_CANCEL;
esp_err_t ret = esp_wifi_remain_on_channel(&req);
if (ret != ESP_OK) {
wpa_printf(MSG_ERROR, "DPP: ROC cancel failed");
}
return ret;
} }
bool is_dpp_enabled(void) bool is_dpp_enabled(void)

View File

@ -1,5 +1,5 @@
/* /*
* SPDX-FileCopyrightText: 2019-2024 Espressif Systems (Shanghai) CO LTD * SPDX-FileCopyrightText: 2019-2025 Espressif Systems (Shanghai) CO LTD
* *
* SPDX-License-Identifier: Apache-2.0 * SPDX-License-Identifier: Apache-2.0
*/ */
@ -284,10 +284,6 @@ bool esp_wifi_is_btm_enabled_internal(uint8_t if_index);
esp_err_t esp_wifi_register_mgmt_frame_internal(uint32_t type, uint32_t subtype); esp_err_t esp_wifi_register_mgmt_frame_internal(uint32_t type, uint32_t subtype);
esp_err_t esp_wifi_send_mgmt_frm_internal(const wifi_mgmt_frm_req_t *req); esp_err_t esp_wifi_send_mgmt_frm_internal(const wifi_mgmt_frm_req_t *req);
uint8_t esp_wifi_ap_get_prof_pairwise_cipher_internal(void); uint8_t esp_wifi_ap_get_prof_pairwise_cipher_internal(void);
esp_err_t esp_wifi_action_tx_req(uint8_t type, uint8_t channel,
uint32_t wait_time_ms, const wifi_action_tx_req_t *req);
esp_err_t esp_wifi_remain_on_channel(uint8_t ifx, uint8_t type, uint8_t channel,
uint32_t wait_time_ms, wifi_action_rx_cb_t rx_cb);
bool esp_wifi_is_mbo_enabled_internal(uint8_t if_index); bool esp_wifi_is_mbo_enabled_internal(uint8_t if_index);
void esp_wifi_get_pmf_config_internal(wifi_pmf_config_t *pmf_cfg, uint8_t ifx); void esp_wifi_get_pmf_config_internal(wifi_pmf_config_t *pmf_cfg, uint8_t ifx);
bool esp_wifi_is_ft_enabled_internal(uint8_t if_index); bool esp_wifi_is_ft_enabled_internal(uint8_t if_index);

View File

@ -24,7 +24,9 @@
#include "esp_private/esp_wifi_private.h" #include "esp_private/esp_wifi_private.h"
#include "esp_wifi.h" #include "esp_wifi.h"
typedef time_t os_time_t; /* Modifying datatype for platform and compiler independence */
typedef uint64_t os_time_t;
/** /**
* os_sleep - Sleep (sec, usec) * os_sleep - Sleep (sec, usec)
@ -34,8 +36,8 @@ typedef time_t os_time_t;
void os_sleep(os_time_t sec, os_time_t usec); void os_sleep(os_time_t sec, os_time_t usec);
struct os_time { struct os_time {
os_time_t sec; os_time_t sec;
suseconds_t usec; suseconds_t usec;
}; };
#define os_reltime os_time #define os_reltime os_time
@ -60,17 +62,17 @@ int os_get_time(struct os_time *t);
/* Helper macros for handling struct os_time */ /* Helper macros for handling struct os_time */
#define os_time_before(a, b) \ #define os_time_before(a, b) \
((a)->sec < (b)->sec || \ ((a)->sec < (b)->sec || \
((a)->sec == (b)->sec && (a)->usec < (b)->usec)) ((a)->sec == (b)->sec && (a)->usec < (b)->usec))
#define os_reltime_before os_time_before #define os_reltime_before os_time_before
#define os_time_sub(a, b, res) do { \ #define os_time_sub(a, b, res) do { \
(res)->sec = (a)->sec - (b)->sec; \ (res)->sec = (a)->sec - (b)->sec; \
(res)->usec = (a)->usec - (b)->usec; \ (res)->usec = (a)->usec - (b)->usec; \
if ((res)->usec < 0) { \ if ((res)->usec < 0) { \
(res)->sec--; \ (res)->sec--; \
(res)->usec += 1000000; \ (res)->usec += 1000000; \
} \ } \
} while (0) } while (0)
#define os_reltime_sub os_time_sub #define os_reltime_sub os_time_sub
@ -90,7 +92,7 @@ int os_get_time(struct os_time *t);
* which is used by POSIX mktime(). * which is used by POSIX mktime().
*/ */
int os_mktime(int year, int month, int day, int hour, int min, int sec, int os_mktime(int year, int month, int day, int hour, int min, int sec,
os_time_t *t); os_time_t *t);
int os_gmtime(os_time_t t, struct os_tm *tm); int os_gmtime(os_time_t t, struct os_tm *tm);
@ -191,7 +193,7 @@ int os_unsetenv(const char *name);
/* We don't support file reading support */ /* We don't support file reading support */
static inline char *os_readfile(const char *name, size_t *len) static inline char *os_readfile(const char *name, size_t *len)
{ {
return NULL; return NULL;
} }
/* /*
@ -231,7 +233,6 @@ static inline char *os_readfile(const char *name, size_t *len)
#define os_bzero(s, n) bzero(s, n) #define os_bzero(s, n) bzero(s, n)
#endif #endif
#ifndef os_strdup #ifndef os_strdup
#ifdef _MSC_VER #ifdef _MSC_VER
#define os_strdup(s) _strdup(s) #define os_strdup(s) _strdup(s)
@ -309,14 +310,15 @@ char * ets_strdup(const char *s);
static inline int os_snprintf_error(size_t size, int res) static inline int os_snprintf_error(size_t size, int res)
{ {
return res < 0 || (unsigned int) res >= size; return res < 0 || (unsigned int) res >= size;
} }
static inline void * os_realloc_array(void *ptr, size_t nmemb, size_t size) static inline void * os_realloc_array(void *ptr, size_t nmemb, size_t size)
{ {
if (size && nmemb > (~(size_t) 0) / size) if (size && nmemb > (~(size_t) 0) / size) {
return NULL; return NULL;
return os_realloc(ptr, nmemb * size); }
return os_realloc(ptr, nmemb * size);
} }
#ifdef CONFIG_CRYPTO_MBEDTLS #ifdef CONFIG_CRYPTO_MBEDTLS
@ -335,10 +337,10 @@ static uint8_t forced_memzero_val;
static inline void forced_memzero(void *ptr, size_t len) static inline void forced_memzero(void *ptr, size_t len)
{ {
memset_func(ptr, 0, len); memset_func(ptr, 0, len);
if (len) { if (len) {
forced_memzero_val = ((uint8_t *) ptr)[0]; forced_memzero_val = ((uint8_t *) ptr)[0];
} }
} }
#endif #endif
@ -378,23 +380,23 @@ extern const wifi_osi_funcs_t *wifi_funcs;
static inline void os_timer_setfn(void *ptimer, void *pfunction, void *parg) static inline void os_timer_setfn(void *ptimer, void *pfunction, void *parg)
{ {
return wifi_funcs->_timer_setfn(ptimer, pfunction, parg); return wifi_funcs->_timer_setfn(ptimer, pfunction, parg);
} }
static inline void os_timer_disarm(void *ptimer) static inline void os_timer_disarm(void *ptimer)
{ {
return wifi_funcs->_timer_disarm(ptimer); return wifi_funcs->_timer_disarm(ptimer);
} }
static inline void os_timer_arm_us(void *ptimer,uint32_t u_seconds,bool repeat_flag) static inline void os_timer_arm_us(void *ptimer, uint32_t u_seconds, bool repeat_flag)
{ {
return wifi_funcs->_timer_arm_us(ptimer, u_seconds, repeat_flag); return wifi_funcs->_timer_arm_us(ptimer, u_seconds, repeat_flag);
} }
static inline void os_timer_arm(void *ptimer,uint32_t milliseconds,bool repeat_flag) static inline void os_timer_arm(void *ptimer, uint32_t milliseconds, bool repeat_flag)
{ {
return wifi_funcs->_timer_arm(ptimer, milliseconds, repeat_flag); return wifi_funcs->_timer_arm(ptimer, milliseconds, repeat_flag);
} }
static inline void os_timer_done(void *ptimer) static inline void os_timer_done(void *ptimer)
{ {
return wifi_funcs->_timer_done(ptimer); return wifi_funcs->_timer_done(ptimer);
} }
#endif /* OS_H */ #endif /* OS_H */

View File

@ -1209,7 +1209,9 @@ void wps_registrar_probe_req_rx(struct wps_registrar *reg, const u8 *addr,
struct os_reltime now, dur; struct os_reltime now, dur;
os_get_reltime(&now); os_get_reltime(&now);
os_reltime_sub(&now, &reg->pbc_ignore_start, &dur); os_reltime_sub(&now, &reg->pbc_ignore_start, &dur);
if (dur.sec >= 0 && dur.sec < 5) { #ifdef ESP_SUPPLICANT
if (dur.sec < 5) {
#endif /* ESP_SUPPLICANT */
wpa_printf(MSG_DEBUG, "WPS: Ignore PBC activation " wpa_printf(MSG_DEBUG, "WPS: Ignore PBC activation "
"based on Probe Request from the Enrollee " "based on Probe Request from the Enrollee "
"that just completed PBC provisioning"); "that just completed PBC provisioning");

View File

@ -1,5 +1,5 @@
/* /*
* SPDX-FileCopyrightText: 2020-2023 Espressif Systems (Shanghai) CO LTD * SPDX-FileCopyrightText: 2020-2025 Espressif Systems (Shanghai) CO LTD
* *
* SPDX-License-Identifier: Unlicense OR CC0-1.0 * SPDX-License-Identifier: Unlicense OR CC0-1.0
* *
@ -54,7 +54,7 @@ static void wifi_event_handler(void *arg, esp_event_base_t event_base,
wifi_event_action_tx_status_t *evt = wifi_event_action_tx_status_t *evt =
(wifi_event_action_tx_status_t *)event_data; (wifi_event_action_tx_status_t *)event_data;
if (evt->status == 0) { if (evt->status == WIFI_ACTION_TX_DONE) {
ESP_LOGI(TAG, "Action Tx Successful"); ESP_LOGI(TAG, "Action Tx Successful");
} }
} }
@ -137,17 +137,21 @@ void esp_send_action_frame(uint8_t *dest_mac, const uint8_t *buf, uint32_t len,
req->no_ack = false; req->no_ack = false;
req->data_len = len; req->data_len = len;
req->rx_cb = dummy_rx_action; req->rx_cb = dummy_rx_action;
req->channel = channel;
req->wait_time_ms = wait_time_ms;
req->type = WIFI_OFFCHAN_TX_REQ;
memcpy(req->data, buf, req->data_len); memcpy(req->data, buf, req->data_len);
ESP_LOGI(TAG, "Action Tx - MAC:" MACSTR ", Channel-%d, WaitT-%" PRId32 "", ESP_LOGI(TAG, "Action Tx - MAC:" MACSTR ", Channel-%d, WaitT-%" PRId32 "",
MAC2STR(dest_mac), channel, wait_time_ms); MAC2STR(dest_mac), channel, wait_time_ms);
TEST_ESP_OK(esp_wifi_action_tx_req(WIFI_OFFCHAN_TX_REQ, channel, wait_time_ms, req)); TEST_ESP_OK(esp_wifi_action_tx_req(req));
os_free(req); os_free(req);
} }
/* Test that foreground Scan doesn't pre-empt ROC & vice versa */ /* Test that foreground Scan doesn't preempt ROC & vice versa */
TEST_CASE("Test scan and ROC simultaneously", "[Offchan]") TEST_CASE("Test scan and ROC simultaneously", "[Offchan]")
{ {
wifi_action_rx_cb_t rx_cb = dummy_rx_action; wifi_action_rx_cb_t rx_cb = dummy_rx_action;
@ -158,8 +162,16 @@ TEST_CASE("Test scan and ROC simultaneously", "[Offchan]")
xEventGroupWaitBits(wifi_event, WIFI_START_EVENT, 1, 0, 5000 / portTICK_PERIOD_MS); xEventGroupWaitBits(wifi_event, WIFI_START_EVENT, 1, 0, 5000 / portTICK_PERIOD_MS);
TEST_ESP_OK(esp_wifi_remain_on_channel(WIFI_IF_STA, WIFI_ROC_REQ, TEST_LISTEN_CHANNEL, wifi_roc_req_t req = {0};
100, rx_cb)); req.ifx = WIFI_IF_STA;
req.type = WIFI_ROC_REQ;
req.channel = TEST_LISTEN_CHANNEL;
req.wait_time_ms = 100;
req.rx_cb = rx_cb;
req.done_cb = NULL;
TEST_ESP_OK(esp_wifi_remain_on_channel(&req));
ESP_ERROR_CHECK(esp_wifi_scan_start(NULL, false)); ESP_ERROR_CHECK(esp_wifi_scan_start(NULL, false));
bits = xEventGroupWaitBits(wifi_event, WIFI_ROC_DONE_EVENT | WIFI_SCAN_DONE_EVENT, bits = xEventGroupWaitBits(wifi_event, WIFI_ROC_DONE_EVENT | WIFI_SCAN_DONE_EVENT,
pdTRUE, pdFALSE, 5000 / portTICK_PERIOD_MS); pdTRUE, pdFALSE, 5000 / portTICK_PERIOD_MS);
@ -167,8 +179,9 @@ TEST_CASE("Test scan and ROC simultaneously", "[Offchan]")
vTaskDelay(1000 / portTICK_PERIOD_MS); vTaskDelay(1000 / portTICK_PERIOD_MS);
ESP_ERROR_CHECK(esp_wifi_scan_start(NULL, false)); ESP_ERROR_CHECK(esp_wifi_scan_start(NULL, false));
TEST_ESP_OK(esp_wifi_remain_on_channel(WIFI_IF_STA, WIFI_ROC_REQ, TEST_LISTEN_CHANNEL,
100, rx_cb)); TEST_ESP_OK(esp_wifi_remain_on_channel(&req));
bits = xEventGroupWaitBits(wifi_event, WIFI_ROC_DONE_EVENT | WIFI_SCAN_DONE_EVENT, bits = xEventGroupWaitBits(wifi_event, WIFI_ROC_DONE_EVENT | WIFI_SCAN_DONE_EVENT,
pdTRUE, pdFALSE, 5000 / portTICK_PERIOD_MS); pdTRUE, pdFALSE, 5000 / portTICK_PERIOD_MS);
TEST_ASSERT_TRUE(bits == WIFI_SCAN_DONE_EVENT); TEST_ASSERT_TRUE(bits == WIFI_SCAN_DONE_EVENT);
@ -228,13 +241,24 @@ static void test_wifi_roc(void)
sprintf(mac_str, MACSTR, MAC2STR(mac)); sprintf(mac_str, MACSTR, MAC2STR(mac));
unity_send_signal_param("Listener mac", mac_str); unity_send_signal_param("Listener mac", mac_str);
TEST_ESP_OK(esp_wifi_remain_on_channel(WIFI_IF_STA, WIFI_ROC_REQ, TEST_LISTEN_CHANNEL, wifi_roc_req_t req = {0};
10000, rx_cb)); req.ifx = WIFI_IF_STA;
req.type = WIFI_ROC_REQ;
req.channel = TEST_LISTEN_CHANNEL;
req.wait_time_ms = 10000;
req.rx_cb = rx_cb;
req.done_cb = NULL;
TEST_ESP_OK(esp_wifi_remain_on_channel(&req));
bits = xEventGroupWaitBits(wifi_event, WIFI_ROC_DONE_EVENT | WIFI_ACTION_RX_EVENT, bits = xEventGroupWaitBits(wifi_event, WIFI_ROC_DONE_EVENT | WIFI_ACTION_RX_EVENT,
pdTRUE, pdFALSE, portMAX_DELAY); pdTRUE, pdFALSE, portMAX_DELAY);
/* Confirm that Frame has been received successfully */ /* Confirm that Frame has been received successfully */
if (bits == WIFI_ACTION_RX_EVENT) { if (bits == WIFI_ACTION_RX_EVENT) {
TEST_ESP_OK(esp_wifi_remain_on_channel(WIFI_IF_STA, WIFI_ROC_CANCEL, 0, 0, NULL)); wifi_roc_req_t req = {0};
req.ifx = WIFI_IF_STA;
req.type = WIFI_ROC_CANCEL;
TEST_ESP_OK(esp_wifi_remain_on_channel(&req));
vTaskDelay(1000 / portTICK_PERIOD_MS); vTaskDelay(1000 / portTICK_PERIOD_MS);
stop_wifi(); stop_wifi();
} else { } else {