aboutsummaryrefslogtreecommitdiffstats
path: root/wpa_supplicant/offchannel.c
diff options
context:
space:
mode:
authorJouni Malinen <jouni@qca.qualcomm.com>2014-06-03 12:35:01 (GMT)
committerJouni Malinen <j@w1.fi>2014-06-04 13:07:59 (GMT)
commitd4b951f31b7eb72df19e570f636d51fa3e6c95ac (patch)
tree9290441cbc75bbd041a56a11acd0e448d9a6a1d1 /wpa_supplicant/offchannel.c
parent95b6bca66de9dc0a2ddd9164ec052a7d5f58804b (diff)
downloadhostap-d4b951f31b7eb72df19e570f636d51fa3e6c95ac.zip
hostap-d4b951f31b7eb72df19e570f636d51fa3e6c95ac.tar.gz
hostap-d4b951f31b7eb72df19e570f636d51fa3e6c95ac.tar.bz2
Fix offchannel TX not to retransmit pending frame on callback
If the offchannel TX frame command was offloaded to the driver in offchannel_send_action(), we must not send another copy of the frame if a remain-on-channel event happens to be delivered between this TX command and the matching TX status event. It was possible for the duplicated frame to cause problems, e.g., with P2P invitation exchange if the same Invitation Request frame got sent twice and only the first one getting accepted by the peer. Signed-off-by: Jouni Malinen <jouni@qca.qualcomm.com>
Diffstat (limited to 'wpa_supplicant/offchannel.c')
-rw-r--r--wpa_supplicant/offchannel.c16
1 files changed, 11 insertions, 5 deletions
diff --git a/wpa_supplicant/offchannel.c b/wpa_supplicant/offchannel.c
index 40cbea1..77683b6 100644
--- a/wpa_supplicant/offchannel.c
+++ b/wpa_supplicant/offchannel.c
@@ -55,11 +55,12 @@ static void wpas_send_action_cb(void *eloop_ctx, void *timeout_ctx)
without_roc = wpa_s->pending_action_without_roc;
wpa_s->pending_action_without_roc = 0;
- wpa_printf(MSG_DEBUG, "Off-channel: Send Action callback "
- "(without_roc=%d pending_action_tx=%p)",
- without_roc, wpa_s->pending_action_tx);
+ wpa_printf(MSG_DEBUG,
+ "Off-channel: Send Action callback (without_roc=%d pending_action_tx=%p pending_action_tx_done=%d)",
+ without_roc, wpa_s->pending_action_tx,
+ !!wpa_s->pending_action_tx_done);
- if (wpa_s->pending_action_tx == NULL)
+ if (wpa_s->pending_action_tx == NULL || wpa_s->pending_action_tx_done)
return;
/*
@@ -235,6 +236,7 @@ int offchannel_send_action(struct wpa_supplicant *wpa_s, unsigned int freq,
MAC2STR(wpa_s->pending_action_dst));
wpabuf_free(wpa_s->pending_action_tx);
}
+ wpa_s->pending_action_tx_done = 0;
wpa_s->pending_action_tx = wpabuf_alloc(len);
if (wpa_s->pending_action_tx == NULL) {
wpa_printf(MSG_DEBUG, "Off-channel: Failed to allocate Action "
@@ -251,18 +253,22 @@ int offchannel_send_action(struct wpa_supplicant *wpa_s, unsigned int freq,
if (freq != 0 && wpa_s->drv_flags & WPA_DRIVER_FLAGS_OFFCHANNEL_TX) {
struct wpa_supplicant *iface;
+ int ret;
iface = wpas_get_tx_interface(wpa_s,
wpa_s->pending_action_src);
wpa_s->action_tx_wait_time = wait_time;
- return wpa_drv_send_action(
+ ret = wpa_drv_send_action(
iface, wpa_s->pending_action_freq,
wait_time, wpa_s->pending_action_dst,
wpa_s->pending_action_src, wpa_s->pending_action_bssid,
wpabuf_head(wpa_s->pending_action_tx),
wpabuf_len(wpa_s->pending_action_tx),
wpa_s->pending_action_no_cck);
+ if (ret == 0)
+ wpa_s->pending_action_tx_done = 1;
+ return ret;
}
if (freq) {