From a6d157b6f606e75497e69ceb4c3aa9f2bd27ac4e Mon Sep 17 00:00:00 2001 From: Jouni Malinen Date: Thu, 3 Feb 2022 11:30:06 +0200 Subject: [PATCH] DPP: Start a listen operation for GAS server if needed Instead of depending on the TX-wait-response-time to be sufficient to cover the full GAS exchange, start an ongoing listen operation on the negotiation channel (if no such listen operation is already in place) to allow the configuration exchange to take longer amount of time. This is needed for cases where the conf=query is used to request Configurator parameters from upper layers and that upper layer processing (e.g., user interaction) takes significant amount of time. Signed-off-by: Jouni Malinen --- wpa_supplicant/dpp_supplicant.c | 36 ++++++++++++++++++++++++++++--- wpa_supplicant/dpp_supplicant.h | 1 + wpa_supplicant/events.c | 5 +++++ wpa_supplicant/wpa_supplicant_i.h | 1 + 4 files changed, 40 insertions(+), 3 deletions(-) diff --git a/wpa_supplicant/dpp_supplicant.c b/wpa_supplicant/dpp_supplicant.c index 863e45c70..ab3876c42 100644 --- a/wpa_supplicant/dpp_supplicant.c +++ b/wpa_supplicant/dpp_supplicant.c @@ -777,6 +777,7 @@ int wpas_dpp_auth_init(struct wpa_supplicant *wpa_s, const char *cmd) #endif /* CONFIG_DPP2 */ wpa_s->dpp_gas_client = 0; + wpa_s->dpp_gas_server = 0; pos = os_strstr(cmd, " peer="); if (!pos) @@ -1144,6 +1145,7 @@ static void wpas_dpp_rx_auth_req(struct wpa_supplicant *wpa_s, const u8 *src, } wpa_s->dpp_gas_client = 0; + wpa_s->dpp_gas_server = 0; wpa_s->dpp_auth_ok_on_ack = 0; wpa_s->dpp_auth = dpp_auth_req_rx(wpa_s->dpp, wpa_s, wpa_s->dpp_allowed_roles, @@ -1181,9 +1183,33 @@ static void wpas_dpp_rx_auth_req(struct wpa_supplicant *wpa_s, const u8 *src, } +void wpas_dpp_tx_wait_expire(struct wpa_supplicant *wpa_s) +{ + struct dpp_authentication *auth = wpa_s->dpp_auth; + int freq; + + if (!wpa_s->dpp_gas_server || !auth) + return; + + freq = auth->neg_freq > 0 ? auth->neg_freq : auth->curr_freq; + if (wpa_s->dpp_listen_work || (int) wpa_s->dpp_listen_freq == freq) + return; /* listen state is already in progress */ + + wpa_printf(MSG_DEBUG, "DPP: Start listen on %u MHz for GAS", freq); + wpa_s->dpp_in_response_listen = 1; + wpas_dpp_listen_start(wpa_s, freq); +} + + static void wpas_dpp_start_gas_server(struct wpa_supplicant *wpa_s) { - /* TODO: stop wait and start ROC */ + struct dpp_authentication *auth = wpa_s->dpp_auth; + + wpa_printf(MSG_DEBUG, + "DPP: Starting GAS server (curr_freq=%d neg_freq=%d dpp_listen_freq=%d dpp_listen_work=%d)", + auth->curr_freq, auth->neg_freq, wpa_s->dpp_listen_freq, + !!wpa_s->dpp_listen_work); + wpa_s->dpp_gas_server = 1; } @@ -1965,6 +1991,8 @@ static void wpas_dpp_rx_conf_result(struct wpa_supplicant *wpa_s, const u8 *src, status = dpp_conf_result_rx(auth, hdr, buf, len); if (status == DPP_STATUS_OK && auth->send_conn_status) { + int freq; + wpa_msg(wpa_s, MSG_INFO, DPP_EVENT_CONF_SENT "wait_conn_status=1"); wpa_printf(MSG_DEBUG, "DPP: Wait for Connection Status Result"); @@ -1977,8 +2005,10 @@ static void wpas_dpp_rx_conf_result(struct wpa_supplicant *wpa_s, const u8 *src, wpas_dpp_conn_status_result_wait_timeout, wpa_s, NULL); offchannel_send_action_done(wpa_s); - wpas_dpp_listen_start(wpa_s, auth->neg_freq ? auth->neg_freq : - auth->curr_freq); + freq = auth->neg_freq ? auth->neg_freq : auth->curr_freq; + if (!wpa_s->dpp_in_response_listen || + (int) wpa_s->dpp_listen_freq != freq) + wpas_dpp_listen_start(wpa_s, freq); return; } offchannel_send_action_done(wpa_s); diff --git a/wpa_supplicant/dpp_supplicant.h b/wpa_supplicant/dpp_supplicant.h index 105c81904..2b03a5462 100644 --- a/wpa_supplicant/dpp_supplicant.h +++ b/wpa_supplicant/dpp_supplicant.h @@ -24,6 +24,7 @@ void wpas_dpp_remain_on_channel_cb(struct wpa_supplicant *wpa_s, unsigned int freq, unsigned int duration); void wpas_dpp_cancel_remain_on_channel_cb(struct wpa_supplicant *wpa_s, unsigned int freq); +void wpas_dpp_tx_wait_expire(struct wpa_supplicant *wpa_s); void wpas_dpp_rx_action(struct wpa_supplicant *wpa_s, const u8 *src, const u8 *buf, size_t len, unsigned int freq); int wpas_dpp_configurator_sign(struct wpa_supplicant *wpa_s, const char *cmd); diff --git a/wpa_supplicant/events.c b/wpa_supplicant/events.c index f55e1846e..603ac33d1 100644 --- a/wpa_supplicant/events.c +++ b/wpa_supplicant/events.c @@ -5738,6 +5738,11 @@ void wpa_supplicant_event(void *ctx, enum wpa_event_type event, case EVENT_UNPROT_BEACON: wpas_event_unprot_beacon(wpa_s, &data->unprot_beacon); break; + case EVENT_TX_WAIT_EXPIRE: +#ifdef CONFIG_DPP + wpas_dpp_tx_wait_expire(wpa_s); +#endif /* CONFIG_DPP */ + break; default: wpa_msg(wpa_s, MSG_INFO, "Unknown event %d", event); break; diff --git a/wpa_supplicant/wpa_supplicant_i.h b/wpa_supplicant/wpa_supplicant_i.h index 8bb8672fb..ed1faca9f 100644 --- a/wpa_supplicant/wpa_supplicant_i.h +++ b/wpa_supplicant/wpa_supplicant_i.h @@ -1448,6 +1448,7 @@ struct wpa_supplicant { int dpp_auth_ok_on_ack; int dpp_in_response_listen; int dpp_gas_client; + int dpp_gas_server; int dpp_gas_dialog_token; u8 dpp_intro_bssid[ETH_ALEN]; void *dpp_intro_network;