From d4d76d9835d3e1daf9369eefe053294e98ebcb48 Mon Sep 17 00:00:00 2001 From: Jouni Malinen Date: Thu, 15 Jun 2017 21:18:07 +0300 Subject: [PATCH] Fix offchannel TX done handling for sequence of TX frames There could be multiple pending TX operations and if the earlier ones have used wait_time, but the last one did not, the driver call for canceling pending wait was not done. This could result in the driver getting stuck waiting for the previously scheduled wait time and not being able to do new operations until that. Fix this by canceling the wait if any of the past offchannel_send_action() calls since the last offchannel_send_action_done() used non-zero wait_time. This was showing up as issues in certain DPP Public Action frame sequences when the same offchannel operation is used with multiple frames and the last frame in the sequence does not need wait_time. Signed-off-by: Jouni Malinen --- wpa_supplicant/offchannel.c | 5 ++++- wpa_supplicant/wpa_supplicant_i.h | 1 + 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/wpa_supplicant/offchannel.c b/wpa_supplicant/offchannel.c index 26d41a4ad..b74be7dad 100644 --- a/wpa_supplicant/offchannel.c +++ b/wpa_supplicant/offchannel.c @@ -310,6 +310,8 @@ int offchannel_send_action(struct wpa_supplicant *wpa_s, unsigned int freq, iface = wpas_get_tx_interface(wpa_s, src); wpa_s->action_tx_wait_time = wait_time; + if (wait_time) + wpa_s->action_tx_wait_time_used = 1; ret = wpa_drv_send_action( iface, wpa_s->pending_action_freq, @@ -398,13 +400,14 @@ void offchannel_send_action_done(struct wpa_supplicant *wpa_s) wpabuf_free(wpa_s->pending_action_tx); wpa_s->pending_action_tx = NULL; if (wpa_s->drv_flags & WPA_DRIVER_FLAGS_OFFCHANNEL_TX && - wpa_s->action_tx_wait_time) + (wpa_s->action_tx_wait_time || wpa_s->action_tx_wait_time_used)) wpa_drv_send_action_cancel_wait(wpa_s); else if (wpa_s->off_channel_freq || wpa_s->roc_waiting_drv_freq) { wpa_drv_cancel_remain_on_channel(wpa_s); wpa_s->off_channel_freq = 0; wpa_s->roc_waiting_drv_freq = 0; } + wpa_s->action_tx_wait_time_used = 0; } diff --git a/wpa_supplicant/wpa_supplicant_i.h b/wpa_supplicant/wpa_supplicant_i.h index 45dc05c7f..9c0500191 100644 --- a/wpa_supplicant/wpa_supplicant_i.h +++ b/wpa_supplicant/wpa_supplicant_i.h @@ -827,6 +827,7 @@ struct wpa_supplicant { result); unsigned int roc_waiting_drv_freq; int action_tx_wait_time; + int action_tx_wait_time_used; int p2p_mgmt;