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>
This commit is contained in:
Jouni Malinen 2017-06-15 21:18:07 +03:00 committed by Jouni Malinen
parent 00b02149ed
commit d4d76d9835
2 changed files with 5 additions and 1 deletions

View File

@ -310,6 +310,8 @@ int offchannel_send_action(struct wpa_supplicant *wpa_s, unsigned int freq,
iface = wpas_get_tx_interface(wpa_s, src); iface = wpas_get_tx_interface(wpa_s, src);
wpa_s->action_tx_wait_time = wait_time; wpa_s->action_tx_wait_time = wait_time;
if (wait_time)
wpa_s->action_tx_wait_time_used = 1;
ret = wpa_drv_send_action( ret = wpa_drv_send_action(
iface, wpa_s->pending_action_freq, 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); wpabuf_free(wpa_s->pending_action_tx);
wpa_s->pending_action_tx = NULL; wpa_s->pending_action_tx = NULL;
if (wpa_s->drv_flags & WPA_DRIVER_FLAGS_OFFCHANNEL_TX && 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); wpa_drv_send_action_cancel_wait(wpa_s);
else if (wpa_s->off_channel_freq || wpa_s->roc_waiting_drv_freq) { else if (wpa_s->off_channel_freq || wpa_s->roc_waiting_drv_freq) {
wpa_drv_cancel_remain_on_channel(wpa_s); wpa_drv_cancel_remain_on_channel(wpa_s);
wpa_s->off_channel_freq = 0; wpa_s->off_channel_freq = 0;
wpa_s->roc_waiting_drv_freq = 0; wpa_s->roc_waiting_drv_freq = 0;
} }
wpa_s->action_tx_wait_time_used = 0;
} }

View File

@ -827,6 +827,7 @@ struct wpa_supplicant {
result); result);
unsigned int roc_waiting_drv_freq; unsigned int roc_waiting_drv_freq;
int action_tx_wait_time; int action_tx_wait_time;
int action_tx_wait_time_used;
int p2p_mgmt; int p2p_mgmt;