P2P: Do not schedule new remain-on-channel if waiting for drv event

The driver event for remain-on-channel may be delayed in a way that
allows management-frame-received event to be received before
wpa_supplicant knows that the driver is actually already on the
previously requested channel. We should not request a new
remain-on-channel to send a response to just a frame if we are waiting
for the driver to get to the same channel. Instead, just continue
waiting for the driver event.
This commit is contained in:
Jouni Malinen 2010-06-23 21:51:38 -07:00 committed by Jouni Malinen
parent d6ae995057
commit 07a30a66c3
2 changed files with 17 additions and 1 deletions

View file

@ -487,7 +487,9 @@ static void wpas_send_action_cb(void *eloop_ctx, void *timeout_ctx)
"driver to remain on channel (%u "
"MHz) for Action Frame TX",
wpa_s->pending_action_freq);
}
} else
wpa_s->roc_waiting_drv_freq =
wpa_s->pending_action_freq;
}
return;
}
@ -622,6 +624,13 @@ static int wpas_send_action(void *ctx, unsigned int freq, const u8 *dst,
}
wpa_s->pending_action_without_roc = 0;
if (wpa_s->roc_waiting_drv_freq == freq) {
wpa_printf(MSG_DEBUG, "P2P: Already waiting for driver to get "
"to frequency %u MHz; continue waiting to send the "
"Action frame", freq);
return 0;
}
wpa_printf(MSG_DEBUG, "P2P: Schedule Action frame to be transmitted "
"once the driver gets to the requested channel");
if (wait_time > wpa_s->max_remain_on_chan)
@ -632,6 +641,7 @@ static int wpas_send_action(void *ctx, unsigned int freq, const u8 *dst,
"Frame TX", freq);
return -1;
}
wpa_s->roc_waiting_drv_freq = freq;
return 0;
}
@ -646,6 +656,7 @@ static void wpas_send_action_done(void *ctx)
if (wpa_s->off_channel_freq) {
wpa_drv_cancel_remain_on_channel(wpa_s);
wpa_s->off_channel_freq = 0;
wpa_s->roc_waiting_drv_freq = 0;
}
}
@ -897,6 +908,7 @@ void wpas_go_neg_completed(void *ctx, struct p2p_go_neg_results *res)
if (wpa_s->off_channel_freq) {
wpa_drv_cancel_remain_on_channel(wpa_s);
wpa_s->off_channel_freq = 0;
wpa_s->roc_waiting_drv_freq = 0;
}
if (res->status) {
@ -994,6 +1006,7 @@ static int wpas_start_listen(void *ctx, unsigned int freq,
wpa_s->pending_listen_freq = 0;
return -1;
}
wpa_s->roc_waiting_drv_freq = freq;
return 0;
}
@ -1005,6 +1018,7 @@ static void wpas_stop_listen(void *ctx)
if (wpa_s->off_channel_freq) {
wpa_drv_cancel_remain_on_channel(wpa_s);
wpa_s->off_channel_freq = 0;
wpa_s->roc_waiting_drv_freq = 0;
}
wpa_drv_probe_req_report(wpa_s, 0);
}
@ -2436,6 +2450,7 @@ int wpas_p2p_connect(struct wpa_supplicant *wpa_s, const u8 *peer_addr,
void wpas_p2p_remain_on_channel_cb(struct wpa_supplicant *wpa_s,
unsigned int freq, unsigned int duration)
{
wpa_s->roc_waiting_drv_freq = 0;
wpa_s->off_channel_freq = freq;
wpas_send_action_cb(wpa_s, NULL);
if (wpa_s->off_channel_freq == wpa_s->pending_listen_freq) {

View file

@ -482,6 +482,7 @@ struct wpa_supplicant {
u8 pending_join_iface_addr[ETH_ALEN];
u8 pending_join_dev_addr[ETH_ALEN];
int pending_join_wps_method;
unsigned int roc_waiting_drv_freq;
#endif /* CONFIG_P2P */
struct wpa_ssid *bgscan_ssid;