aboutsummaryrefslogtreecommitdiffstats
path: root/wpa_supplicant/offchannel.c
diff options
context:
space:
mode:
authorJouni Malinen <jouni@qca.qualcomm.com>2017-06-15 18:18:07 (GMT)
committerJouni Malinen <j@w1.fi>2017-06-17 15:04:54 (GMT)
commitd4d76d9835d3e1daf9369eefe053294e98ebcb48 (patch)
tree557064b501b09bafc2658dc2c755c1c488498602 /wpa_supplicant/offchannel.c
parent00b02149ed887c61e278bc8b4f3b282aa3c3a736 (diff)
downloadhostap-d4d76d9835d3e1daf9369eefe053294e98ebcb48.zip
hostap-d4d76d9835d3e1daf9369eefe053294e98ebcb48.tar.gz
hostap-d4d76d9835d3e1daf9369eefe053294e98ebcb48.tar.bz2
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 <jouni@qca.qualcomm.com>
Diffstat (limited to 'wpa_supplicant/offchannel.c')
-rw-r--r--wpa_supplicant/offchannel.c5
1 files changed, 4 insertions, 1 deletions
diff --git a/wpa_supplicant/offchannel.c b/wpa_supplicant/offchannel.c
index 26d41a4..b74be7d 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;
}