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

Ilan Peer ilan.peer at intel.com
Mon May 19 03:06:09 EDT 2014


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.

Signed-off-by: Ilan Peer <ilan.peer at intel.com>
---
 wpa_supplicant/p2p_supplicant.c |  130 ++++++++++++++++++++++++---------------
 1 file changed, 80 insertions(+), 50 deletions(-)

diff --git a/wpa_supplicant/p2p_supplicant.c b/wpa_supplicant/p2p_supplicant.c
index bcdb1c1..2726aba 100644
--- a/wpa_supplicant/p2p_supplicant.c
+++ b/wpa_supplicant/p2p_supplicant.c
@@ -2956,15 +2956,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;
@@ -3015,22 +3006,46 @@ static int wpas_p2p_go_is_peer_freq(struct wpa_supplicant *wpa_s, int freq)
 	return 0;
 }
 
+
+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.
  * The function assumes that all the freqs in freqs_data are valid P2P
  * 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_data,
 					unsigned int num)
 {
-	unsigned int i, c = 0;
+	unsigned int i, c;
 
 	if (num == 0)
 		return 0;
 
-	for (i = 1; i < num; i++) {
-		/* 1. BSS interfaces have higher preference.
+	/* find the first valid freq */
+	for (c = 0; c < num; c++)
+		if (wpas_freq_included(wpa_s, channels, freqs_data[c].freq))
+			break;
+
+	if (c == num)
+		return 0;
+
+	for (i = c + 1; i < num; i++) {
+		if (!wpas_freq_included(wpa_s, channels, freqs_data[i].freq))
+			continue;
+
+		/*
+		 * 1. BSS interfaces have higher preference.
 		 * 2. P2P Clients have higher preference.
 		 * 3. All others.
 		 */
@@ -3153,8 +3168,8 @@ accept_inv:
 		int num_channels = wpa_s->num_multichan_concurrent;
 		int num = wpas_p2p_valid_oper_freqs(wpa_s, freqs_data,
 						    num_channels);
-		best_freq = wpas_p2p_pick_best_used_freq(wpa_s, freqs_data,
-							 num);
+		best_freq = wpas_p2p_pick_best_used_freq(wpa_s, channels,
+							 freqs_data, num);
 		os_free(freqs_data);
 	}
 
@@ -3172,7 +3187,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 "
@@ -3380,10 +3395,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;
@@ -4855,7 +4870,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_data, num);
+	best_freq = wpas_p2p_pick_best_used_freq(wpa_s, NULL, freqs_data, num);
 
 	/* We have a candidate frequency to use */
 	if (best_freq > 0) {
@@ -5223,7 +5238,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;
 	}
 
@@ -5231,7 +5246,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;
 	}
 
@@ -5257,8 +5272,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;
@@ -5269,8 +5289,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);
@@ -5280,8 +5301,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);
@@ -5289,7 +5311,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);
@@ -5297,7 +5321,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);
@@ -5305,7 +5330,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);
@@ -5314,6 +5340,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)
@@ -5328,30 +5366,21 @@ static int wpas_p2p_init_go_params(struct wpa_supplicant *wpa_s,
 	num = wpas_p2p_valid_oper_freqs(wpa_s, freqs_data,
 					wpa_s->num_multichan_concurrent);
 
-	cand_freq = wpas_p2p_pick_best_used_freq(wpa_s, freqs_data, num);
+	cand_freq = wpas_p2p_pick_best_used_freq(wpa_s, channels, freqs_data,
+						 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_data[i].freq)) {
-				wpa_printf(MSG_DEBUG, "P2P: Force GO on a channel we are already using (%u MHz)",
-					   freqs_data[i].freq);
-				params->freq = freqs_data[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_data);
-				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_data);
+			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++) {
@@ -5547,7 +5576,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;
 	}
 
@@ -6728,7 +6758,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);
-- 
1.7.10.4



More information about the HostAP mailing list