Skip to content

Commit a96d680

Browse files
committed
fix(esp_wifi): Add various DPP fixes observed during testing
1 parent 4dac548 commit a96d680

File tree

5 files changed

+150
-39
lines changed

5 files changed

+150
-39
lines changed

components/wpa_supplicant/esp_supplicant/include/esp_dpp.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,14 +16,15 @@
1616
extern "C" {
1717
#endif
1818

19-
#define ESP_DPP_AUTH_TIMEOUT_SECS 1
19+
#define ESP_DPP_AUTH_TIMEOUT_SECS 2
2020
#define ESP_DPP_MAX_CHAN_COUNT 5
2121

2222
#define ESP_ERR_DPP_FAILURE (ESP_ERR_WIFI_BASE + 151) /*!< Generic failure during DPP Operation */
2323
#define ESP_ERR_DPP_TX_FAILURE (ESP_ERR_WIFI_BASE + 152) /*!< DPP Frame Tx failed OR not Acked */
2424
#define ESP_ERR_DPP_INVALID_ATTR (ESP_ERR_WIFI_BASE + 153) /*!< Encountered invalid DPP Attribute */
2525
#define ESP_ERR_DPP_AUTH_TIMEOUT (ESP_ERR_WIFI_BASE + 154) /*!< DPP Auth response was not received in time */
2626
#define ESP_ERR_DPP_INVALID_LIST (ESP_ERR_WIFI_BASE + 155) /*!< Channel list given in esp_supp_dpp_bootstrap_gen() is not valid or too big */
27+
#define ESP_ERR_DPP_CONF_TIMEOUT (ESP_ERR_WIFI_BASE + 155) /*!< DPP Configuration was not recieved in time */
2728

2829
/** @brief Types of Bootstrap Methods for DPP. */
2930
typedef enum dpp_bootstrap_type {

components/wpa_supplicant/esp_supplicant/src/crypto/crypto_mbedtls-ec.c

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -848,17 +848,17 @@ void crypto_ec_key_debug_print(struct crypto_ec_key *key, const char *title)
848848
mbedtls_pk_context *pkey = (mbedtls_pk_context *)key;
849849
mbedtls_ecp_keypair *ecp = mbedtls_pk_ec(*pkey);
850850
u8 x[32], y[32], d[32];
851-
wpa_printf(MSG_INFO, "curve: %s",
851+
wpa_printf(MSG_DEBUG, "curve: %s",
852852
mbedtls_ecp_curve_info_from_grp_id(ecp->MBEDTLS_PRIVATE(grp).id)->name);
853853
int len = mbedtls_mpi_size((mbedtls_mpi *)crypto_ec_get_prime((struct crypto_ec *)crypto_ec_get_group_from_key(key)));
854854

855-
wpa_printf(MSG_INFO, "prime len is %d", len);
855+
wpa_printf(MSG_DEBUG, "prime len is %d", len);
856856
crypto_ec_point_to_bin((struct crypto_ec *)crypto_ec_get_group_from_key(key), crypto_ec_key_get_public_key(key), x, y);
857857
crypto_bignum_to_bin(crypto_ec_key_get_private_key(key),
858858
d, len, len);
859-
wpa_hexdump(MSG_INFO, "Q_x:", x, 32);
860-
wpa_hexdump(MSG_INFO, "Q_y:", y, 32);
861-
wpa_hexdump(MSG_INFO, "d: ", d, 32);
859+
wpa_hexdump(MSG_DEBUG, "Q_x:", x, 32);
860+
wpa_hexdump(MSG_DEBUG, "Q_y:", y, 32);
861+
wpa_hexdump(MSG_DEBUG, "d: ", d, 32);
862862
#endif
863863
}
864864

components/wpa_supplicant/esp_supplicant/src/esp_dpp.c

Lines changed: 141 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -177,36 +177,59 @@ static void esp_dpp_rx_auth_req(struct action_rx_param *rx_param, uint8_t *dpp_d
177177
(const u8 *)&rx_param->action_frm->u.public_action.v, dpp_data, len);
178178
os_memcpy(s_dpp_ctx.dpp_auth->peer_mac_addr, rx_param->sa, ETH_ALEN);
179179

180-
wpa_printf(MSG_DEBUG, "DPP: Sending authentication response.");
180+
wpa_printf(MSG_INFO, "DPP: Sending authentication response.");
181181
esp_dpp_send_action_frame(rx_param->sa, wpabuf_head(s_dpp_ctx.dpp_auth->resp_msg),
182182
wpabuf_len(s_dpp_ctx.dpp_auth->resp_msg),
183183
rx_param->channel, OFFCHAN_TX_WAIT_TIME);
184-
eloop_cancel_timeout(esp_dpp_auth_conf_wait_timeout, NULL, NULL);
185-
eloop_register_timeout(ESP_DPP_AUTH_TIMEOUT_SECS, 0, esp_dpp_auth_conf_wait_timeout, NULL, NULL);
186184

187185
return;
188186
fail:
189187
esp_dpp_call_cb(ESP_SUPP_DPP_FAIL, (void *)rc);
190188
}
191189

192-
static void gas_query_req_tx(struct dpp_authentication *auth)
190+
static void gas_query_timeout(void *eloop_data, void *user_ctx)
191+
{
192+
struct dpp_authentication *auth = user_ctx;
193+
194+
if (!auth || !auth->auth_success) {
195+
return;
196+
}
197+
198+
wpa_printf(MSG_DEBUG, "GAS: No response received for GAS query");
199+
if (auth->conf_req) {
200+
wpabuf_free(auth->conf_req);
201+
auth->conf_req = NULL;
202+
}
203+
esp_dpp_call_cb(ESP_SUPP_DPP_FAIL, (void *)ESP_ERR_DPP_CONF_TIMEOUT);
204+
}
205+
206+
static int gas_query_req_tx(struct dpp_authentication *auth)
193207
{
194208
struct wpabuf *buf;
195209
int supp_op_classes[] = {81, 0};
210+
int ret;
196211

197212
buf = dpp_build_conf_req_helper(auth, NULL, 0, NULL,
198213
supp_op_classes);
199214
if (!buf) {
200215
wpa_printf(MSG_DEBUG, "DPP: No configuration request data available");
201216
esp_dpp_call_cb(ESP_SUPP_DPP_FAIL, (void *)ESP_ERR_DPP_FAILURE);
202-
return;
217+
return ESP_FAIL;
203218
}
204219

205-
wpa_printf(MSG_DEBUG, "DPP: GAS request to " MACSTR " (chan %u)",
220+
wpa_printf(MSG_INFO, "DPP: GAS request to " MACSTR " (chan %u)",
206221
MAC2STR(auth->peer_mac_addr), auth->curr_chan);
207222

208-
esp_dpp_send_action_frame(auth->peer_mac_addr, wpabuf_head(buf), wpabuf_len(buf),
209-
auth->curr_chan, OFFCHAN_TX_WAIT_TIME);
223+
ret = esp_dpp_send_action_frame(auth->peer_mac_addr, wpabuf_head(buf), wpabuf_len(buf),
224+
auth->curr_chan, OFFCHAN_TX_WAIT_TIME);
225+
if (ret != ESP_OK) {
226+
wpabuf_free(buf);
227+
}
228+
229+
auth->conf_req = buf;
230+
eloop_register_timeout(2, 0, gas_query_timeout, NULL, auth);
231+
232+
return ret;
210233
}
211234

212235
static int esp_dpp_handle_config_obj(struct dpp_authentication *auth,
@@ -253,7 +276,7 @@ static void esp_dpp_rx_auth_conf(struct action_rx_param *rx_param, uint8_t *dpp_
253276
size_t len = rx_param->vendor_data_len - 2;
254277
int rc;
255278

256-
wpa_printf(MSG_DEBUG, "DPP: Authentication Confirmation from " MACSTR,
279+
wpa_printf(MSG_INFO, "DPP: Authentication Confirmation from " MACSTR,
257280
MAC2STR(rx_param->sa));
258281

259282
if (!auth) {
@@ -279,7 +302,9 @@ static void esp_dpp_rx_auth_conf(struct action_rx_param *rx_param, uint8_t *dpp_
279302
}
280303

281304
/* Send GAS Query Req */
282-
gas_query_req_tx(auth);
305+
if (gas_query_req_tx(auth) != ESP_OK) {
306+
goto fail;
307+
}
283308

284309
return;
285310

@@ -447,6 +472,7 @@ static void gas_query_resp_rx(struct action_rx_param *rx_param)
447472

448473
if (pos[1] == WLAN_EID_VENDOR_SPECIFIC && pos[2] == 5 &&
449474
WPA_GET_BE24(&pos[3]) == OUI_WFA && pos[6] == 0x1a && pos[7] == 1 && auth) {
475+
eloop_cancel_timeout(gas_query_timeout, NULL, auth);
450476
if (dpp_conf_resp_rx(auth, resp, rx_param->vendor_data_len - 2) < 0) {
451477
wpa_printf(MSG_DEBUG, "DPP: Configuration attempt failed");
452478
goto fail;
@@ -504,6 +530,7 @@ static esp_err_t esp_dpp_rx_action(struct action_rx_param *rx_param)
504530
public_action->v.pa_gas_resp.length -
505531
(u8 *)rx_param->action_frm);
506532

533+
wpa_printf(MSG_DEBUG, "DPP: Gas response received");
507534
gas_query_resp_rx(rx_param);
508535
}
509536
}
@@ -513,6 +540,32 @@ static esp_err_t esp_dpp_rx_action(struct action_rx_param *rx_param)
513540
return ret;
514541
}
515542

543+
void esp_dpp_rx_action_eloop(void *data, void *user_ctx)
544+
{
545+
esp_dpp_rx_action(data);
546+
}
547+
548+
void esp_dpp_listen_next_channel(void *data, void *user_ctx)
549+
{
550+
struct dpp_bootstrap_params_t *p = &s_dpp_ctx.bootstrap_params;
551+
static int counter;
552+
int channel;
553+
esp_err_t ret = 0;
554+
555+
if (p->num_chan <= 0) {
556+
wpa_printf(MSG_ERROR, "Listen channel not set");
557+
return;
558+
}
559+
channel = p->chan_list[counter++ % p->num_chan];
560+
ret = esp_wifi_remain_on_channel(WIFI_IF_STA, WIFI_ROC_REQ, channel,
561+
BOOTSTRAP_ROC_WAIT_TIME, s_action_rx_cb);
562+
if (ret != ESP_OK) {
563+
wpa_printf(MSG_ERROR, "Failed ROC. error : 0x%x", ret);
564+
return;
565+
}
566+
s_dpp_listen_in_progress = true;
567+
}
568+
516569
static void esp_dpp_task(void *pvParameters)
517570
{
518571
dpp_event_t evt;
@@ -648,41 +701,94 @@ int esp_supp_rx_action(uint8_t *hdr, uint8_t *payload, size_t len, uint8_t chann
648701
rx_param->frm_len = len;
649702
os_memcpy(rx_param->action_frm, payload, len);
650703

651-
ret = esp_dpp_post_evt(SIG_DPP_RX_ACTION, (u32)rx_param);
652-
if (ESP_OK != ret) {
653-
wpa_printf(MSG_ERROR, "Failed to post event to DPP Task(status=%d)", ret);
654-
os_free(rx_param->action_frm);
655-
os_free(rx_param);
656-
return ret;
657-
}
704+
eloop_register_timeout(0, 0, esp_dpp_rx_action_eloop, rx_param, NULL);
658705
}
659706

660707
return ret;
661708
}
662709

710+
static void esp_dpp_auth_resp_retry_timeout(void *eloop_ctx, void *timeout_ctx)
711+
{
712+
struct dpp_authentication *auth = s_dpp_ctx.dpp_auth;
713+
714+
if (!auth || !auth->resp_msg) {
715+
return;
716+
}
717+
718+
wpa_printf(MSG_DEBUG,
719+
"DPP: Retry Authentication Response after timeout");
720+
wpa_msg(wpa_s, MSG_INFO, DPP_EVENT_TX "dst=" MACSTR
721+
" chan=%u type=%d",
722+
MAC2STR(auth->peer_mac_addr), auth->curr_chan,
723+
DPP_PA_AUTHENTICATION_RESP);
724+
725+
esp_dpp_send_action_frame(s_dpp_ctx.dpp_auth->peer_mac_addr,
726+
wpabuf_head(s_dpp_ctx.dpp_auth->resp_msg),
727+
wpabuf_len(s_dpp_ctx.dpp_auth->resp_msg),
728+
auth->curr_chan, OFFCHAN_TX_WAIT_TIME);
729+
}
730+
731+
static void esp_dpp_auth_resp_retry(void)
732+
{
733+
struct dpp_authentication *auth = s_dpp_ctx.dpp_auth;
734+
unsigned int wait_time, max_tries = 5;
735+
736+
if (!auth || !auth->resp_msg) {
737+
return;
738+
}
739+
740+
auth->auth_resp_tries++;
741+
if (auth->auth_resp_tries >= max_tries) {
742+
wpa_printf(MSG_INFO, "DPP: No confirm received from initiator - stopping exchange");
743+
esp_dpp_call_cb(ESP_SUPP_DPP_FAIL, (void *)ESP_ERR_DPP_TX_FAILURE);
744+
return;
745+
}
746+
747+
wait_time = 1;
748+
wpa_printf(MSG_INFO,
749+
"DPP: Schedule retransmission %d of Authentication Response frame in %u s", auth->auth_resp_tries,
750+
wait_time);
751+
eloop_cancel_timeout(esp_dpp_auth_resp_retry_timeout, NULL, NULL);
752+
eloop_register_timeout(wait_time, 0, esp_dpp_auth_resp_retry_timeout, NULL, NULL);
753+
}
754+
663755
static void offchan_event_handler(void *arg, esp_event_base_t event_base,
664756
int32_t event_id, void *event_data)
665757
{
758+
struct dpp_authentication *auth = s_dpp_ctx.dpp_auth;
759+
666760
if (event_id == WIFI_EVENT_ACTION_TX_STATUS) {
667-
wifi_event_action_tx_status_t *evt =
668-
(wifi_event_action_tx_status_t *)event_data;
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);
761+
wifi_event_action_tx_status_t *evt = event_data;
672762

673-
if (evt->status == WIFI_ACTION_TX_FAILED) {
763+
wpa_printf(MSG_DEBUG, "Mgmt Tx Status - %d, Cookie - 0x%x",
764+
evt->status, (uint32_t)evt->context);
765+
if (!auth) {
766+
esp_dpp_call_cb(ESP_SUPP_DPP_FAIL, (void *)ESP_ERR_DPP_TX_FAILURE);
767+
return;
768+
}
769+
if (auth->waiting_auth_conf) {
770+
if (evt->status) {
771+
/* failed to send auth response frame */
674772
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-
}
773+
esp_dpp_auth_resp_retry();
774+
} else {
775+
eloop_cancel_timeout(esp_dpp_auth_conf_wait_timeout, NULL, NULL);
776+
eloop_register_timeout(ESP_DPP_AUTH_TIMEOUT_SECS, 0, esp_dpp_auth_conf_wait_timeout, NULL, NULL);
777+
}
778+
} else if (auth->auth_success) {
779+
if (evt->status) {
780+
/* failed to send gas query frame, retry logic needed? */
678781
esp_dpp_call_cb(ESP_SUPP_DPP_FAIL, (void *)ESP_ERR_DPP_TX_FAILURE);
782+
} else {
783+
eloop_cancel_timeout(gas_query_timeout, NULL, auth);
784+
eloop_register_timeout(2, 0, gas_query_timeout, NULL, auth);
679785
}
680786
}
681787
} else if (event_id == WIFI_EVENT_ROC_DONE) {
682788
wifi_event_roc_done_t *evt = (wifi_event_roc_done_t *)event_data;
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) {
685-
esp_dpp_post_evt(SIG_DPP_LISTEN_NEXT_CHANNEL, 0);
789+
790+
if (s_dpp_listen_in_progress && evt->context == (uint32_t)s_action_rx_cb) {
791+
eloop_register_timeout(0, 0, esp_dpp_listen_next_channel, NULL, NULL);
686792
}
687793
}
688794
}
@@ -861,7 +967,11 @@ esp_err_t esp_supp_dpp_start_listen(void)
861967
return ESP_ERR_INVALID_STATE;
862968
}
863969

864-
return esp_dpp_post_evt(SIG_DPP_LISTEN_NEXT_CHANNEL, 0);
970+
/* cancel previous ROC if ongoing */
971+
esp_supp_dpp_stop_listen();
972+
973+
eloop_register_timeout(0, 0, esp_dpp_listen_next_channel, NULL, NULL);
974+
return 0;
865975
}
866976

867977
esp_err_t esp_supp_dpp_stop_listen(void)
@@ -925,7 +1035,7 @@ esp_err_t esp_supp_dpp_init(esp_supp_dpp_event_cb_t cb)
9251035
goto init_fail;
9261036
}
9271037

928-
ret = os_task_create(esp_dpp_task, "dppT", DPP_TASK_STACK_SIZE, NULL, 2, &s_dpp_task_hdl);
1038+
ret = os_task_create(esp_dpp_task, "dppT", DPP_TASK_STACK_SIZE, NULL, 15, &s_dpp_task_hdl);
9291039
if (ret != TRUE) {
9301040
wpa_printf(MSG_ERROR, "DPP: failed to create task");
9311041
ret = ESP_ERR_NO_MEM;

components/wpa_supplicant/esp_supplicant/src/esp_dpp_i.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ typedef struct {
3434
} dpp_event_t;
3535

3636
#define BOOTSTRAP_ROC_WAIT_TIME 500
37-
#define OFFCHAN_TX_WAIT_TIME 500
37+
#define OFFCHAN_TX_WAIT_TIME 600
3838

3939
struct dpp_bootstrap_params_t {
4040
enum dpp_bootstrap_type type;

components/wpa_supplicant/src/common/dpp.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -261,7 +261,7 @@ struct dpp_authentication {
261261
* Authentication exchange */
262262
unsigned int freq[DPP_BOOTSTRAP_MAX_FREQ];
263263
unsigned int num_freq, freq_idx;
264-
unsigned int curr_chan;
264+
unsigned int curr_chan;
265265
unsigned int curr_freq;
266266
unsigned int neg_freq;
267267
unsigned int num_freq_iters;

0 commit comments

Comments
 (0)