Skip to content

Commit df2c123

Browse files
author
Jiang Jiang Jian
committed
Merge branch 'bugfix/offchan_action_tx_failure_v5.4' into 'release/v5.4'
Fix issues with offchannel action tx and ROC operations (Backport v5.4) See merge request espressif/esp-idf!38497
2 parents 101cab3 + bd98882 commit df2c123

File tree

11 files changed

+173
-60
lines changed

11 files changed

+173
-60
lines changed

components/esp_rom/esp32c2/ld/esp32c2.rom.ld

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -513,7 +513,7 @@ lmacRecycleMPDU = 0x40001b44;
513513
lmacRxDone = 0x40001b48;
514514
/*lmacSetTxFrame = 0x40001b4c;*/
515515
lmacTxDone = 0x40001b50;
516-
lmacTxFrame = 0x40001b54;
516+
/*lmacTxFrame = 0x40001b54;*/
517517
mac_tx_set_duration = 0x40001b58;
518518
mac_tx_set_htsig = 0x40001b5c;
519519
mac_tx_set_plcp0 = 0x40001b60;
@@ -555,7 +555,7 @@ ppEnqueueRxq = 0x40001bec;
555555
ppEnqueueTxDone = 0x40001bf0;
556556
ppGetTxQFirstAvail_Locked = 0x40001bf4;
557557
ppGetTxframe = 0x40001bf8;
558-
ppMapTxQueue = 0x40001bfc;
558+
/*ppMapTxQueue = 0x40001bfc;*/
559559
ppProcTxSecFrame = 0x40001c00;
560560
ppProcessRxPktHdr = 0x40001c04;
561561
/*ppProcessTxQ = 0x40001c08;*/

components/esp_rom/esp32c3/ld/esp32c3.rom.eco7.ld

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ ic_mac_deinit = 0x400015dc;
1111
lmacDiscardMSDU = 0x400015f4;
1212
/*lmacSetTxFrame = 0x40001628;*/
1313
lmacTxDone = 0x4000162c;
14-
lmacTxFrame = 0x40001630;
14+
/*lmacTxFrame = 0x40001630;*/
1515
mac_tx_set_htsig = 0x40001638;
1616
mac_tx_set_plcp1 = 0x40001640;
1717
pm_check_state = 0x40001648;
@@ -22,7 +22,7 @@ pm_rx_beacon_process = 0x40001690;
2222
pm_rx_data_process = 0x40001694;
2323
/* pm_sleep = 0x40001698;*/
2424
/* pm_tbtt_process = 0x400016a0;*/
25-
ppMapTxQueue = 0x400016d8;
25+
/*ppMapTxQueue = 0x400016d8;*/
2626
ppProcTxSecFrame = 0x400016dc;
2727
/*ppRxFragmentProc = 0x40001704;*/
2828
/* rcGetSched = 0x40001764;*/

components/esp_rom/esp32c5/ld/esp32c5.rom.pp.ld

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -76,7 +76,7 @@ lmacRecycleMPDU = 0x40000cc0;
7676
lmacRxDone = 0x40000cc4;
7777
lmacSetTxFrame = 0x40000cc8;
7878
lmacTxDone = 0x40000ccc;
79-
lmacTxFrame = 0x40000cd0;
79+
/*lmacTxFrame = 0x40000cd0;*/
8080
lmacDisableTransmit = 0x40000cd4;
8181
lmacDiscardFrameExchangeSequence = 0x40000cd8;
8282
lmacProcessCollision = 0x40000cdc;
@@ -177,7 +177,7 @@ ppEmptyDelimiterLength = 0x40000e54;
177177
ppEnqueueRxq = 0x40000e58;
178178
ppEnqueueTxDone = 0x40000e5c;
179179
ppGetTxframe = 0x40000e60;
180-
ppMapTxQueue = 0x40000e64;
180+
/*ppMapTxQueue = 0x40000e64;*/
181181
ppProcTxSecFrame = 0x40000e68;
182182
ppProcessRxPktHdr = 0x40000e6c;
183183
/*ppProcessTxQ = 0x40000e70;*/

components/esp_rom/esp32c61/ld/esp32c61.rom.pp.ld

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -81,7 +81,7 @@ lmacRecycleMPDU = 0x40000c30;
8181
lmacRxDone = 0x40000c34;
8282
lmacSetTxFrame = 0x40000c38;
8383
lmacTxDone = 0x40000c3c;
84-
lmacTxFrame = 0x40000c40;
84+
/*lmacTxFrame = 0x40000c40;*/
8585
lmacDisableTransmit = 0x40000c44;
8686
lmacDiscardFrameExchangeSequence = 0x40000c48;
8787
lmacProcessCollision = 0x40000c4c;
@@ -184,7 +184,7 @@ ppEmptyDelimiterLength = 0x40000dcc;
184184
ppEnqueueRxq = 0x40000dd0;
185185
ppEnqueueTxDone = 0x40000dd4;
186186
ppGetTxframe = 0x40000dd8;
187-
ppMapTxQueue = 0x40000ddc;
187+
/*ppMapTxQueue = 0x40000ddc;*/
188188
ppProcTxSecFrame = 0x40000de0;
189189
ppProcessRxPktHdr = 0x40000de4;
190190
/*ppProcessTxQ = 0x40000de8;*/

components/esp_wifi/include/esp_wifi.h

Lines changed: 24 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* SPDX-FileCopyrightText: 2015-2024 Espressif Systems (Shanghai) CO LTD
2+
* SPDX-FileCopyrightText: 2015-2025 Espressif Systems (Shanghai) CO LTD
33
*
44
* SPDX-License-Identifier: Apache-2.0
55
*/
@@ -1789,6 +1789,29 @@ esp_err_t esp_wifi_set_bandwidths(wifi_interface_t ifx, wifi_bandwidths_t* bw);
17891789
*/
17901790
esp_err_t esp_wifi_get_bandwidths(wifi_interface_t ifx, wifi_bandwidths_t *bw);
17911791

1792+
/**
1793+
* @brief Send action frame on target channel
1794+
*
1795+
* @param req action tx request structure containing relevant fields
1796+
*
1797+
* @return
1798+
* - ESP_OK: succeed
1799+
* - ESP_ERR_NO_MEM: failed to allocate memory
1800+
* - ESP_FAIL: failed to send frame
1801+
*/
1802+
esp_err_t esp_wifi_action_tx_req(wifi_action_tx_req_t *req);
1803+
1804+
/**
1805+
* @brief Remain on the target channel for required duration
1806+
*
1807+
* @param req roc request structure containing relevant fields
1808+
*
1809+
* @return
1810+
* - ESP_OK: succeed
1811+
* - ESP_ERR_NO_MEM: failed to allocate memory
1812+
* - ESP_FAIL: failed to perform roc operation
1813+
*/
1814+
esp_err_t esp_wifi_remain_on_channel(wifi_roc_req_t * req);
17921815
#ifdef __cplusplus
17931816
}
17941817
#endif

components/esp_wifi/include/esp_wifi_types_generic.h

Lines changed: 65 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -41,12 +41,15 @@ typedef enum {
4141
WIFI_IF_MAX /**< Maximum number of interfaces */
4242
} wifi_interface_t;
4343

44-
#define WIFI_OFFCHAN_TX_REQ 1 /**< Request off-channel transmission */
45-
#define WIFI_OFFCHAN_TX_CANCEL 0 /**< Cancel off-channel transmission */
46-
47-
#define WIFI_ROC_REQ 1 /**< Request remain on channel */
48-
#define WIFI_ROC_CANCEL 0 /**< Cancel remain on channel */
44+
typedef enum {
45+
WIFI_OFFCHAN_TX_CANCEL, /**< Cancel off-channel transmission */
46+
WIFI_OFFCHAN_TX_REQ, /**< Request off-channel transmission */
47+
} wifi_action_tx_t;
4948

49+
typedef enum {
50+
WIFI_ROC_CANCEL, /**< Cancel remain on channel */
51+
WIFI_ROC_REQ, /**< Request remain on channel */
52+
} wifi_roc_t;
5053
/**
5154
* @brief Wi-Fi country policy
5255
*/
@@ -773,12 +776,49 @@ typedef int (* wifi_action_rx_cb_t)(uint8_t *hdr, uint8_t *payload,
773776
typedef struct {
774777
wifi_interface_t ifx; /**< Wi-Fi interface to send request to */
775778
uint8_t dest_mac[6]; /**< Destination MAC address */
779+
wifi_action_tx_t type; /**< ACTION TX operation type */
780+
uint8_t channel; /**< Channel on which to perform ACTION TX Operation */
781+
uint32_t wait_time_ms; /**< Duration to wait for on target channel */
776782
bool no_ack; /**< Indicates no ack required */
777-
wifi_action_rx_cb_t rx_cb; /**< Rx Callback to receive any response */
783+
wifi_action_rx_cb_t rx_cb; /**< Rx Callback to receive action frames */
784+
uint8_t op_id; /**< Unique Identifier for operation provided by wifi driver */
778785
uint32_t data_len; /**< Length of the appended Data */
779786
uint8_t data[0]; /**< Appended Data payload */
780787
} wifi_action_tx_req_t;
781788

789+
/** Status codes for WIFI_EVENT_ROC_DONE evt */
790+
typedef enum {
791+
WIFI_ROC_DONE = 0, /**< ROC operation was completed successfully */
792+
WIFI_ROC_FAIL, /**< ROC operation was cancelled */
793+
} wifi_roc_done_status_t;
794+
795+
/**
796+
* @brief The callback function executed when ROC operation has ended
797+
*
798+
* @param context rxcb registered for the corresponding ROC operation
799+
* @param op_id ID of the corresponding ROC operation
800+
* @param status status code of the ROC operation denoted
801+
*
802+
*/
803+
typedef void (* wifi_action_roc_done_cb_t)(uint32_t context, uint8_t op_id,
804+
wifi_roc_done_status_t status);
805+
806+
/**
807+
* @brief Remain on Channel request
808+
*
809+
*
810+
*/
811+
typedef struct {
812+
wifi_interface_t ifx; /**< WiFi interface to send request to */
813+
wifi_roc_t type; /**< ROC operation type */
814+
uint8_t channel; /**< Channel on which to perform ROC Operation */
815+
wifi_second_chan_t sec_channel; /**< Secondary channel */
816+
uint32_t wait_time_ms; /**< Duration to wait for on target channel */
817+
wifi_action_rx_cb_t rx_cb; /**< Rx Callback to receive any response */
818+
uint8_t op_id; /**< ID of this specific ROC operation provided by wifi driver */
819+
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 */
820+
} wifi_roc_req_t;
821+
782822
/**
783823
* @brief FTM Initiator configuration
784824
*
@@ -1236,21 +1276,32 @@ typedef struct {
12361276
#define WIFI_STATIS_PS (1<<4) /**< Power save status */
12371277
#define WIFI_STATIS_ALL (-1) /**< All status */
12381278

1239-
/**
1240-
* @brief Argument structure for WIFI_EVENT_ACTION_TX_STATUS event
1241-
*/
1279+
/** Status codes for WIFI_EVENT_ACTION_TX_STATUS evt */
1280+
/** There will be back to back events in success case TX_DONE and TX_DURATION_COMPLETED */
1281+
typedef enum {
1282+
WIFI_ACTION_TX_DONE = 0, /**< ACTION_TX operation was completed successfully */
1283+
WIFI_ACTION_TX_FAILED, /**< ACTION_TX operation failed during tx */
1284+
WIFI_ACTION_TX_DURATION_COMPLETED, /**< ACTION_TX operation completed it's wait duration */
1285+
WIFI_ACTION_TX_OP_CANCELLED, /**< ACTION_TX operation was cancelled by application or higher priority operation */
1286+
} wifi_action_tx_status_type_t;
1287+
1288+
/** Argument structure for WIFI_EVENT_ACTION_TX_STATUS event */
12421289
typedef struct {
1243-
wifi_interface_t ifx; /**< Wi-Fi interface to send request to */
1244-
uint32_t context; /**< Context to identify the request */
1245-
uint8_t da[6]; /**< Destination MAC address */
1246-
uint8_t status; /**< Status of the operation */
1290+
wifi_interface_t ifx; /**< WiFi interface to send request to */
1291+
uint32_t context; /**< Context to identify the request */
1292+
wifi_action_tx_status_type_t status; /**< Status of the operation */
1293+
uint8_t op_id; /**< ID of the corresponding operation that was provided during action tx request */
1294+
uint8_t channel; /**< Channel provided in tx request */
12471295
} wifi_event_action_tx_status_t;
12481296

12491297
/**
12501298
* @brief Argument structure for WIFI_EVENT_ROC_DONE event
12511299
*/
12521300
typedef struct {
1253-
uint32_t context; /**< Context to identify the request */
1301+
uint32_t context; /**< Context to identify the initiator of the request */
1302+
wifi_roc_done_status_t status; /**< ROC status */
1303+
uint8_t op_id; /**< ID of the corresponding ROC operation */
1304+
uint8_t channel; /**< Channel provided in tx request */
12541305
} wifi_event_roc_done_t;
12551306

12561307
/**

components/wpa_supplicant/esp_supplicant/src/esp_dpp.c

Lines changed: 39 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* SPDX-FileCopyrightText: 2020-2024 Espressif Systems (Shanghai) CO LTD
2+
* SPDX-FileCopyrightText: 2020-2025 Espressif Systems (Shanghai) CO LTD
33
*
44
* SPDX-License-Identifier: Apache-2.0
55
*/
@@ -28,7 +28,7 @@ static void *s_dpp_api_lock = NULL;
2828
static bool s_dpp_listen_in_progress;
2929
static struct esp_dpp_context_t s_dpp_ctx;
3030
static wifi_action_rx_cb_t s_action_rx_cb = esp_supp_rx_action;
31-
31+
static uint8_t s_current_tx_op_id;
3232
#define DPP_API_LOCK() os_mutex_lock(s_dpp_api_lock)
3333
#define DPP_API_UNLOCK() os_mutex_unlock(s_dpp_api_lock)
3434

@@ -101,7 +101,7 @@ static void esp_dpp_auth_conf_wait_timeout(void *eloop_ctx, void *timeout_ctx)
101101
esp_err_t esp_dpp_send_action_frame(uint8_t *dest_mac, const uint8_t *buf, uint32_t len,
102102
uint8_t channel, uint32_t wait_time_ms)
103103
{
104-
wifi_action_tx_req_t *req = os_zalloc(sizeof(*req) + len);;
104+
wifi_action_tx_req_t *req = os_zalloc(sizeof(*req) + len);
105105
if (!req) {
106106
return ESP_FAIL;
107107
}
@@ -111,19 +111,23 @@ esp_err_t esp_dpp_send_action_frame(uint8_t *dest_mac, const uint8_t *buf, uint3
111111
req->no_ack = false;
112112
req->data_len = len;
113113
req->rx_cb = s_action_rx_cb;
114+
req->channel = channel;
115+
req->wait_time_ms = wait_time_ms;
116+
req->type = WIFI_OFFCHAN_TX_REQ;
114117
memcpy(req->data, buf, req->data_len);
115118

116119
wpa_printf(MSG_DEBUG, "DPP: Mgmt Tx - MAC:" MACSTR ", Channel-%d, WaitT-%d",
117120
MAC2STR(dest_mac), channel, wait_time_ms);
118121

119-
if (ESP_OK != esp_wifi_action_tx_req(WIFI_OFFCHAN_TX_REQ, channel,
120-
wait_time_ms, req)) {
122+
if (ESP_OK != esp_wifi_action_tx_req(req)) {
121123
wpa_printf(MSG_ERROR, "DPP: Failed to perform offchannel operation");
122124
esp_dpp_call_cb(ESP_SUPP_DPP_FAIL, (void *)ESP_ERR_DPP_TX_FAILURE);
123125
os_free(req);
124126
return ESP_FAIL;
125127
}
126128

129+
wpa_printf(MSG_DEBUG, "Sent DPP action frame %d", req->op_id);
130+
s_current_tx_op_id = req->op_id;
127131
os_free(req);
128132
return ESP_OK;
129133
}
@@ -560,21 +564,27 @@ static void esp_dpp_task(void *pvParameters)
560564
case SIG_DPP_LISTEN_NEXT_CHANNEL: {
561565
struct dpp_bootstrap_params_t *p = &s_dpp_ctx.bootstrap_params;
562566
static int counter;
563-
int channel;
564567
esp_err_t ret = 0;
565568

566569
if (p->num_chan <= 0) {
567570
wpa_printf(MSG_ERROR, "Listen channel not set");
568571
break;
569572
}
570-
channel = p->chan_list[counter++ % p->num_chan];
571-
wpa_printf(MSG_DEBUG, "Listening on channel=%d", channel);
572-
ret = esp_wifi_remain_on_channel(WIFI_IF_STA, WIFI_ROC_REQ, channel,
573-
BOOTSTRAP_ROC_WAIT_TIME, s_action_rx_cb);
573+
574+
wifi_roc_req_t req = {0};
575+
req.ifx = WIFI_IF_STA;
576+
req.type = WIFI_ROC_REQ;
577+
req.channel = p->chan_list[counter++ % p->num_chan];
578+
req.wait_time_ms = BOOTSTRAP_ROC_WAIT_TIME;
579+
req.rx_cb = s_action_rx_cb;
580+
req.done_cb = NULL;
581+
wpa_printf(MSG_DEBUG, "Listening on channel=%d", req.channel);
582+
ret = esp_wifi_remain_on_channel(&req);
574583
if (ret != ESP_OK) {
575584
wpa_printf(MSG_ERROR, "Failed ROC. error : 0x%x", ret);
576585
break;
577586
}
587+
wpa_printf(MSG_DEBUG, "Started DPP listen operation %d", req.op_id);
578588
s_dpp_listen_in_progress = true;
579589
}
580590
break;
@@ -656,21 +666,22 @@ static void offchan_event_handler(void *arg, esp_event_base_t event_base,
656666
if (event_id == WIFI_EVENT_ACTION_TX_STATUS) {
657667
wifi_event_action_tx_status_t *evt =
658668
(wifi_event_action_tx_status_t *)event_data;
659-
wpa_printf(MSG_DEBUG, "Mgmt Tx Status - %d, Cookie - 0x%x",
660-
evt->status, (uint32_t)evt->context);
669+
if (evt->op_id == s_current_tx_op_id) {
670+
wpa_printf(MSG_DEBUG,
671+
"Mgmt Tx Status - %d, Context - 0x%x Operation ID : %d", evt->status, (uint32_t)evt->context, evt->op_id);
661672

662-
if (evt->status) {
663-
eloop_cancel_timeout(esp_dpp_auth_conf_wait_timeout, NULL, NULL);
664-
if (s_dpp_listen_in_progress) {
665-
esp_supp_dpp_stop_listen();
673+
if (evt->status == WIFI_ACTION_TX_FAILED) {
674+
eloop_cancel_timeout(esp_dpp_auth_conf_wait_timeout, NULL, NULL);
675+
if (s_dpp_listen_in_progress) {
676+
esp_supp_dpp_stop_listen();
677+
}
678+
esp_dpp_call_cb(ESP_SUPP_DPP_FAIL, (void *)ESP_ERR_DPP_TX_FAILURE);
666679
}
667-
esp_dpp_call_cb(ESP_SUPP_DPP_FAIL, (void *)ESP_ERR_DPP_TX_FAILURE);
668680
}
669-
670681
} else if (event_id == WIFI_EVENT_ROC_DONE) {
671682
wifi_event_roc_done_t *evt = (wifi_event_roc_done_t *)event_data;
672-
673-
if (s_dpp_listen_in_progress && evt->context == (uint32_t)s_action_rx_cb) {
683+
/*@TODO : Decide flow for when ROC fails*/
684+
if (s_dpp_listen_in_progress && evt->context == (uint32_t)s_action_rx_cb && evt->status == WIFI_ROC_DONE) {
674685
esp_dpp_post_evt(SIG_DPP_LISTEN_NEXT_CHANNEL, 0);
675686
}
676687
}
@@ -856,7 +867,14 @@ esp_err_t esp_supp_dpp_start_listen(void)
856867
esp_err_t esp_supp_dpp_stop_listen(void)
857868
{
858869
s_dpp_listen_in_progress = false;
859-
return esp_wifi_remain_on_channel(WIFI_IF_STA, WIFI_ROC_CANCEL, 0, 0, NULL);
870+
wifi_roc_req_t req = {0};
871+
req.ifx = WIFI_IF_STA;
872+
req.type = WIFI_ROC_CANCEL;
873+
esp_err_t ret = esp_wifi_remain_on_channel(&req);
874+
if (ret != ESP_OK) {
875+
wpa_printf(MSG_ERROR, "DPP: ROC cancel failed");
876+
}
877+
return ret;
860878
}
861879

862880
bool is_dpp_enabled(void)

components/wpa_supplicant/esp_supplicant/src/esp_wifi_driver.h

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -284,10 +284,6 @@ bool esp_wifi_is_btm_enabled_internal(uint8_t if_index);
284284
esp_err_t esp_wifi_register_mgmt_frame_internal(uint32_t type, uint32_t subtype);
285285
esp_err_t esp_wifi_send_mgmt_frm_internal(const wifi_mgmt_frm_req_t *req);
286286
uint8_t esp_wifi_ap_get_prof_pairwise_cipher_internal(void);
287-
esp_err_t esp_wifi_action_tx_req(uint8_t type, uint8_t channel,
288-
uint32_t wait_time_ms, const wifi_action_tx_req_t *req);
289-
esp_err_t esp_wifi_remain_on_channel(uint8_t ifx, uint8_t type, uint8_t channel,
290-
uint32_t wait_time_ms, wifi_action_rx_cb_t rx_cb);
291287
uint8_t esp_wifi_ap_get_sae_ext_config_internal(void);
292288
bool esp_wifi_is_mbo_enabled_internal(uint8_t if_index);
293289
void esp_wifi_get_pmf_config_internal(wifi_pmf_config_t *pmf_cfg, uint8_t ifx);

components/wpa_supplicant/port/include/os.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@
2525
#include "esp_wifi.h"
2626

2727
/* Modifying datatype for platform and compiler independence */
28+
2829
typedef uint64_t os_time_t;
2930

3031
/**

0 commit comments

Comments
 (0)