Patchwork [12/23] P2P: Move a GO to a frequency that is also supported by the client

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

Comments

Ilan Peer - July 7, 2014, 11:21 a.m.
A P2P GO interface that was instantiated after a GoN/Invitation holds the
intersection of frequencies between the GO and the client. In case
that the GO is going to move to anther frequency, allow it to
move only to a frequency that is also supported by the client.

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

Patch

diff --git a/wpa_supplicant/p2p_supplicant.c b/wpa_supplicant/p2p_supplicant.c
index 0f9cdf7..30665c9 100644
--- a/wpa_supplicant/p2p_supplicant.c
+++ b/wpa_supplicant/p2p_supplicant.c
@@ -2959,15 +2959,6 @@  static void wpas_prov_disc_fail(void *ctx, const u8 *peer,
 }
 
 
-static int freq_included(const struct p2p_channels *channels, unsigned int freq)
-{
-	if (channels == NULL)
-		return 1; /* Assume no restrictions */
-	return p2p_channels_includes_freq(channels, freq);
-
-}
-
-
 static void wpas_p2p_go_update_common_freqs(struct wpa_supplicant *wpa_s)
 {
 	unsigned int num = P2P_MAX_CHANNELS;
@@ -3019,10 +3010,22 @@  static int wpas_p2p_go_is_peer_freq(struct wpa_supplicant *wpa_s, int freq)
 }
 
 
+static int wpas_freq_included(struct wpa_supplicant *wpa_s,
+			      const struct p2p_channels *channels,
+			      unsigned int freq)
+{
+	if ((channels == NULL || p2p_channels_includes_freq(channels, freq)) &&
+	    wpas_p2p_go_is_peer_freq(wpa_s, freq))
+		return 1;
+	return 0;
+}
+
+
 /**
  * Pick the best frequency to use from all the currently used frequencies.
  */
 static int wpas_p2p_pick_best_used_freq(struct wpa_supplicant *wpa_s,
+					const struct p2p_channels *channels,
 					struct wpa_used_freq_data *freqs,
 					unsigned int num)
 {
@@ -3030,7 +3033,7 @@  static int wpas_p2p_pick_best_used_freq(struct wpa_supplicant *wpa_s,
 
 	/* find a candidate freq that is supported by P2P */
 	for (c = 0; c < num; c++)
-		if (p2p_supported_freq(wpa_s->global->p2p, freqs[c].freq))
+		if (wpas_freq_included(wpa_s, channels, freqs[c].freq))
 			break;
 
 	if (c == num)
@@ -3038,7 +3041,7 @@  static int wpas_p2p_pick_best_used_freq(struct wpa_supplicant *wpa_s,
 
 	/* once we have a candidate, try to find a 'better' one */
 	for (i = c + 1; i < num; i++) {
-		if (!p2p_supported_freq(wpa_s->global->p2p, freqs[i].freq))
+		if (!wpas_freq_included(wpa_s, channels, freqs[i].freq))
 			continue;
 
 		/*
@@ -3167,7 +3170,8 @@  accept_inv:
 	if (freqs) {
 		int num_channels = wpa_s->num_multichan_concurrent;
 		int num = wpas_p2p_valid_oper_freqs(wpa_s, freqs, num_channels);
-		best_freq = wpas_p2p_pick_best_used_freq(wpa_s, freqs, num);
+		best_freq = wpas_p2p_pick_best_used_freq(wpa_s, channels,
+							 freqs, num);
 		os_free(freqs);
 	}
 
@@ -3191,7 +3195,7 @@  accept_inv:
 				   "running a GO but we are capable of MCC, "
 				   "figure out the best channel to use");
 			*force_freq = 0;
-		} else if (!freq_included(channels, *force_freq)) {
+		} else if (!wpas_freq_included(wpa_s, channels, *force_freq)) {
 			/* We are the GO, and *force_freq is not in the
 			 * intersection */
 			wpa_printf(MSG_DEBUG, "P2P: Forced GO freq %d MHz not "
@@ -3397,10 +3401,10 @@  static void wpas_invitation_result(void *ctx, int status, const u8 *bssid,
 	os_sleep(0, 50000);
 
 	if (neg_freq > 0 && ssid->mode == WPAS_MODE_P2P_GO &&
-	    freq_included(channels, neg_freq))
+	    wpas_freq_included(wpa_s, channels, neg_freq))
 		freq = neg_freq;
 	else if (peer_oper_freq > 0 && ssid->mode != WPAS_MODE_P2P_GO &&
-		 freq_included(channels, peer_oper_freq))
+		 wpas_freq_included(wpa_s, channels, peer_oper_freq))
 		freq = peer_oper_freq;
 	else
 		freq = 0;
@@ -4908,7 +4912,7 @@  static int wpas_p2p_setup_freqs(struct wpa_supplicant *wpa_s, int freq,
 		goto exit_ok;
 	}
 
-	best_freq = wpas_p2p_pick_best_used_freq(wpa_s, freqs, num);
+	best_freq = wpas_p2p_pick_best_used_freq(wpa_s, NULL, freqs, num);
 
 	/* We have a candidate frequency to use */
 	if (best_freq > 0) {
@@ -5272,7 +5276,7 @@  static int wpas_p2p_select_freq_no_pref(struct wpa_supplicant *wpa_s,
 	for (i = 0; i < 3; i++) {
 		params->freq = 2412 + ((r + i) % 3) * 25;
 		if (!wpas_p2p_disallowed_freq(wpa_s->global, params->freq) &&
-		    freq_included(channels, params->freq))
+		    wpas_freq_included(wpa_s, channels, params->freq))
 			goto out;
 	}
 
@@ -5280,7 +5284,7 @@  static int wpas_p2p_select_freq_no_pref(struct wpa_supplicant *wpa_s,
 	for (i = 0; i < 11; i++) {
 		params->freq = 2412 + i * 5;
 		if (!wpas_p2p_disallowed_freq(wpa_s->global, params->freq) &&
-		    freq_included(channels, params->freq))
+		    wpas_freq_included(wpa_s, channels, params->freq))
 			goto out;
 	}
 
@@ -5306,8 +5310,13 @@  static int wpas_p2p_init_go_params(struct wpa_supplicant *wpa_s,
 	params->role_go = 1;
 	params->ht40 = ht40;
 	params->vht = vht;
+
+	if (wpa_s->p2p_group_common_freqs_num)
+		wpa_printf(MSG_DEBUG, "P2P: %s called for an active GO",
+			   __func__);
+
 	if (freq) {
-		if (!freq_included(channels, freq)) {
+		if (!wpas_freq_included(wpa_s, channels, freq)) {
 			wpa_printf(MSG_DEBUG, "P2P: Forced GO freq %d MHz not "
 				   "accepted", freq);
 			return -1;
@@ -5318,8 +5327,9 @@  static int wpas_p2p_init_go_params(struct wpa_supplicant *wpa_s,
 	} else if (wpa_s->conf->p2p_oper_reg_class == 81 &&
 		   wpa_s->conf->p2p_oper_channel >= 1 &&
 		   wpa_s->conf->p2p_oper_channel <= 11 &&
-		   freq_included(channels,
-				 2407 + 5 * wpa_s->conf->p2p_oper_channel)) {
+		   wpas_freq_included(wpa_s,
+				      channels,
+				      2407 + 5 * wpa_s->conf->p2p_oper_channel)) {
 		params->freq = 2407 + 5 * wpa_s->conf->p2p_oper_channel;
 		wpa_printf(MSG_DEBUG, "P2P: Set GO freq based on configured "
 			   "frequency %d MHz", params->freq);
@@ -5329,8 +5339,9 @@  static int wpas_p2p_init_go_params(struct wpa_supplicant *wpa_s,
 		    wpa_s->conf->p2p_oper_reg_class == 124 ||
 		    wpa_s->conf->p2p_oper_reg_class == 126 ||
 		    wpa_s->conf->p2p_oper_reg_class == 127) &&
-		   freq_included(channels,
-				 5000 + 5 * wpa_s->conf->p2p_oper_channel)) {
+		   wpas_freq_included(wpa_s,
+				      channels,
+				      5000 + 5 * wpa_s->conf->p2p_oper_channel)) {
 		params->freq = 5000 + 5 * wpa_s->conf->p2p_oper_channel;
 		wpa_printf(MSG_DEBUG, "P2P: Set GO freq based on configured "
 			   "frequency %d MHz", params->freq);
@@ -5338,7 +5349,9 @@  static int wpas_p2p_init_go_params(struct wpa_supplicant *wpa_s,
 		   wpa_s->best_overall_freq > 0 &&
 		   p2p_supported_freq_go(wpa_s->global->p2p,
 					 wpa_s->best_overall_freq) &&
-		   freq_included(channels, wpa_s->best_overall_freq)) {
+		   wpas_freq_included(wpa_s,
+				      channels,
+				      wpa_s->best_overall_freq)) {
 		params->freq = wpa_s->best_overall_freq;
 		wpa_printf(MSG_DEBUG, "P2P: Set GO freq based on best overall "
 			   "channel %d MHz", params->freq);
@@ -5346,7 +5359,8 @@  static int wpas_p2p_init_go_params(struct wpa_supplicant *wpa_s,
 		   wpa_s->best_24_freq > 0 &&
 		   p2p_supported_freq_go(wpa_s->global->p2p,
 					 wpa_s->best_24_freq) &&
-		   freq_included(channels, wpa_s->best_24_freq)) {
+		   wpas_freq_included(wpa_s,
+				      channels, wpa_s->best_24_freq)) {
 		params->freq = wpa_s->best_24_freq;
 		wpa_printf(MSG_DEBUG, "P2P: Set GO freq based on best 2.4 GHz "
 			   "channel %d MHz", params->freq);
@@ -5354,7 +5368,8 @@  static int wpas_p2p_init_go_params(struct wpa_supplicant *wpa_s,
 		   wpa_s->best_5_freq > 0 &&
 		   p2p_supported_freq_go(wpa_s->global->p2p,
 					 wpa_s->best_5_freq) &&
-		   freq_included(channels, wpa_s->best_5_freq)) {
+		   wpas_freq_included(wpa_s,
+				      channels, wpa_s->best_5_freq)) {
 		params->freq = wpa_s->best_5_freq;
 		wpa_printf(MSG_DEBUG, "P2P: Set GO freq based on best 5 GHz "
 			   "channel %d MHz", params->freq);
@@ -5363,6 +5378,18 @@  static int wpas_p2p_init_go_params(struct wpa_supplicant *wpa_s,
 		params->freq = pref_freq;
 		wpa_printf(MSG_DEBUG, "P2P: Set GO freq %d MHz from preferred "
 			   "channels", params->freq);
+	} else if (wpa_s->p2p_group_common_freqs) {
+		for (i = 0; i < wpa_s->p2p_group_common_freqs_num; i++) {
+			if (wpas_freq_included(wpa_s,
+					       channels,
+					       wpa_s->p2p_group_common_freqs[i])) {
+				params->freq = wpa_s->p2p_group_common_freqs[i];
+				wpa_printf(MSG_DEBUG,
+					   "P2P: use a freq %d MHz common with the peer",
+					   params->freq);
+				break;
+			}
+		}
 	} else {
 		/* no preference, select some channel */
 		if (wpas_p2p_select_freq_no_pref(wpa_s, params, channels) < 0)
@@ -5377,30 +5404,20 @@  static int wpas_p2p_init_go_params(struct wpa_supplicant *wpa_s,
 	num = wpas_p2p_valid_oper_freqs(wpa_s, freqs,
 					wpa_s->num_multichan_concurrent);
 
-	cand_freq = wpas_p2p_pick_best_used_freq(wpa_s, freqs, num);
+	cand_freq = wpas_p2p_pick_best_used_freq(wpa_s, NULL, freqs, num);
 
 	/* First try the best used frequency if possible */
-	if (!freq && cand_freq > 0 && freq_included(channels, cand_freq)) {
+	if (!freq && cand_freq > 0) {
 		params->freq = cand_freq;
 	} else if (!freq) {
-		/* Try any of the used frequencies */
-		for (i = 0; i < num; i++) {
-			if (freq_included(channels, freqs[i].freq)) {
-				wpa_printf(MSG_DEBUG, "P2P: Force GO on a channel we are already using (%u MHz)",
-					   freqs[i].freq);
-				params->freq = freqs[i].freq;
-				break;
-			}
-		}
-
-		if (i == num) {
-			if (wpas_p2p_num_unused_channels(wpa_s) <= 0) {
-				wpa_printf(MSG_DEBUG, "P2P: Cannot force GO on any of the channels we are already using");
-				os_free(freqs);
-				return -1;
-			} else {
-				wpa_printf(MSG_DEBUG, "P2P: Cannot force GO on any of the channels we are already using. Use one of the free channels");
-			}
+		if (wpas_p2p_num_unused_channels(wpa_s) <= 0) {
+			wpa_printf(MSG_DEBUG,
+				   "P2P: Cannot force GO on any of the channels we are already using");
+			os_free(freqs);
+			return -1;
+		} else {
+			wpa_printf(MSG_DEBUG,
+				   "P2P: Cannot force GO on any of the channels we are already using. Use one of the free channels");
 		}
 	} else {
 		for (i = 0; i < num; i++) {
@@ -5597,7 +5614,8 @@  int wpas_p2p_group_add_persistent(struct wpa_supplicant *wpa_s,
 			return -1;
 	} else {
 		freq = wpas_p2p_select_go_freq(wpa_s, neg_freq);
-		if (freq < 0 || (freq > 0 && !freq_included(channels, freq)))
+		if (freq < 0 || (freq > 0 &&
+				 !wpas_freq_included(wpa_s, channels, freq)))
 			freq = 0;
 	}
 
@@ -6781,7 +6799,7 @@  void wpas_p2p_update_channel_list(struct wpa_supplicant *wpa_s)
 		     ifs->current_ssid->mode != WPAS_MODE_P2P_GROUP_FORMATION))
 				continue;
 		freq = ifs->current_ssid->frequency;
-		if (freq_included(&chan, freq)) {
+		if (wpas_freq_included(ifs, &chan, freq)) {
 			wpa_dbg(ifs, MSG_DEBUG,
 				"P2P GO operating frequency %d MHz in valid range",
 				freq);