From dae4c82c9573268edd5dabc577b7bc7184b5ce22 Mon Sep 17 00:00:00 2001 From: Ilan Peer Date: Mon, 27 Jul 2015 22:24:26 +0300 Subject: [PATCH] P2P: Disallow GO CS immediately after GO Negotiation or invitation A newly created GO might move to another channel before the client was able to connect to it. This creates a situation where the client searches the GO on the channel agreed upon during GO Negotiation or invitation signaling, while the GO is on another channel. This in turn might lead to delayed connection or connection failure and group removal. Fix this by disallowing a GO CS as long as there is some activity that should delay the switch. If a GO move is not allowed, set a timeout to re-attempt the move. Signed-off-by: Ilan Peer --- wpa_supplicant/p2p_supplicant.c | 41 +++++++++++++++++++++++++++++++++ 1 file changed, 41 insertions(+) diff --git a/wpa_supplicant/p2p_supplicant.c b/wpa_supplicant/p2p_supplicant.c index 2d869e0b2..0ac7690e8 100644 --- a/wpa_supplicant/p2p_supplicant.c +++ b/wpa_supplicant/p2p_supplicant.c @@ -91,6 +91,12 @@ #define P2P_MGMT_DEVICE_PREFIX "p2p-dev-" +/* + * How many seconds to wait to re-attempt to move GOs, in case previous attempt + * was not possible. + */ +#define P2P_RECONSIDER_GO_MOVE_DELAY 30 + enum p2p_group_removal_reason { P2P_GROUP_REMOVAL_UNKNOWN, P2P_GROUP_REMOVAL_SILENT, @@ -143,6 +149,7 @@ static int wpas_p2p_go_is_peer_freq(struct wpa_supplicant *wpa_s, int freq); static void wpas_p2p_consider_moving_gos(struct wpa_supplicant *wpa_s, struct wpa_used_freq_data *freqs, unsigned int num); +static void wpas_p2p_reconsider_moving_go(void *eloop_ctx, void *timeout_ctx); /* @@ -892,6 +899,7 @@ static int wpas_p2p_group_delete(struct wpa_supplicant *wpa_s, wpa_s->p2p_in_invitation = 0; eloop_cancel_timeout(wpas_p2p_move_go, wpa_s, NULL); + eloop_cancel_timeout(wpas_p2p_reconsider_moving_go, wpa_s, NULL); /* * Make sure wait for the first client does not remain active after the @@ -8469,6 +8477,25 @@ static void wpas_p2p_move_go(void *eloop_ctx, void *timeout_ctx) } +static void wpas_p2p_reconsider_moving_go(void *eloop_ctx, void *timeout_ctx) +{ + struct wpa_supplicant *wpa_s = eloop_ctx; + struct wpa_used_freq_data *freqs = NULL; + unsigned int num = wpa_s->num_multichan_concurrent; + + freqs = os_calloc(num, sizeof(struct wpa_used_freq_data)); + if (!freqs) + return; + + num = get_shared_radio_freqs_data(wpa_s, freqs, num); + + /* Previous attempt to move a GO was not possible -- try again. */ + wpas_p2p_consider_moving_gos(wpa_s, freqs, num); + + os_free(freqs); +} + + /* * Consider moving a GO from its currently used frequency: * 1. It is possible that due to regulatory consideration the frequency @@ -8531,6 +8558,17 @@ static void wpas_p2p_consider_moving_one_go(struct wpa_supplicant *wpa_s, wpa_dbg(wpa_s, MSG_DEBUG, "P2P: Cancel a GO move from freq=%d MHz", freq); eloop_cancel_timeout(wpas_p2p_move_go, wpa_s, NULL); + + if (wpas_p2p_in_progress(wpa_s)) { + wpa_dbg(wpa_s, MSG_DEBUG, + "P2P: GO move: policy CS is not allowed - setting timeout to re-consider GO move"); + eloop_cancel_timeout(wpas_p2p_reconsider_moving_go, + wpa_s, NULL); + eloop_register_timeout(P2P_RECONSIDER_GO_MOVE_DELAY, 0, + wpas_p2p_reconsider_moving_go, + wpa_s, NULL); + return; + } } if (!invalid_freq && (!policy_move || flags != 0)) { @@ -8557,6 +8595,9 @@ static void wpas_p2p_consider_moving_gos(struct wpa_supplicant *wpa_s, { struct wpa_supplicant *ifs; + eloop_cancel_timeout(wpas_p2p_reconsider_moving_go, ELOOP_ALL_CTX, + NULL); + /* * Travers all the radio interfaces, and for each GO interface, check * if there is a need to move the GO from the frequency it is using,