Patchwork [21/23] P2P: Disallow GO CS immediately after GoN or invitation

login
register
mail settings
Submitter Ilan Peer
Date July 7, 2014, 11:21 a.m.
Message ID <1404732076-32252-22-git-send-email-ilan.peer@intel.com>
Download mbox | patch
Permalink /patch/367524/
State New
Headers show

Comments

Ilan Peer - July 7, 2014, 11:21 a.m.
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 GON or invitation signaling, while the GO is on another
channel. This in turn might lead to a 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.

Change-Id: Iaac924e1b2573e7b66693b163d0ed9fcabe944b9
Signed-off-by: Ilan Peer <ilan.peer@intel.com>
---
 wpa_supplicant/p2p_supplicant.c |   42 +++++++++++++++++++++++++++++++++++++++
 1 file changed, 42 insertions(+)

Patch

diff --git a/wpa_supplicant/p2p_supplicant.c b/wpa_supplicant/p2p_supplicant.c
index ece5f34..c043950 100644
--- a/wpa_supplicant/p2p_supplicant.c
+++ b/wpa_supplicant/p2p_supplicant.c
@@ -90,6 +90,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,
@@ -134,6 +140,7 @@  static void wpas_p2p_optimize_listen_channel(struct wpa_supplicant *wpa_s,
 					     struct wpa_used_freq_data *freqs,
 					     unsigned int num);
 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);
 static void wpas_p2p_consider_moving_gos(struct wpa_supplicant *wpa_s,
 					 struct wpa_used_freq_data *freqs,
 					 unsigned int num);
@@ -518,6 +525,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
@@ -8213,6 +8221,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
@@ -8273,6 +8300,12 @@  static void wpas_p2p_consider_moving_one_go(struct wpa_supplicant *wpa_s,
 		wpa_dbg(wpa_s, MSG_DEBUG, "Cancel a GO move from freq=%dMHz",
 			freq);
 		eloop_cancel_timeout(wpas_p2p_move_go, wpa_s, NULL);
+
+		if (wpas_p2p_in_progress(wpa_s)) {
+			wpa_dbg(wpa_s, MSG_DEBUG,
+				"Go move: policy CS is not allowed");
+			goto reschedule;
+		}
 	}
 
 	if (invalid_freq == 0 && (policy_move == 0 || flags != 0)) {
@@ -8290,6 +8323,12 @@  static void wpas_p2p_consider_moving_one_go(struct wpa_supplicant *wpa_s,
 		freq, timeout);
 	eloop_register_timeout(timeout, 0, wpas_p2p_move_go, wpa_s, NULL);
 	return;
+
+reschedule:
+	wpa_dbg(wpa_s, MSG_DEBUG, "Setting timeout to re-consider GO move");
+	eloop_register_timeout(P2P_RECONSIDER_GO_MOVE_DELAY, 0,
+			       wpas_p2p_reconsider_moving_go,
+			       wpa_s, NULL);
 }
 
 
@@ -8299,6 +8338,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,