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

Ilan Peer ilan.peer at intel.com
Mon Jul 27 15:24:21 EDT 2015


A P2P GO interface that was instantiated after a GO Negotiation or
Invitation holds the intersection of frequencies between the GO and the
client. In case that the GO is going to move to another 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 | 111 ++++++++++++++++++++++------------------
 1 file changed, 62 insertions(+), 49 deletions(-)

diff --git a/wpa_supplicant/p2p_supplicant.c b/wpa_supplicant/p2p_supplicant.c
index cfa9215..82cbb4b 100644
--- a/wpa_supplicant/p2p_supplicant.c
+++ b/wpa_supplicant/p2p_supplicant.c
@@ -2588,15 +2588,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;
@@ -2645,6 +2636,17 @@ 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.
  */
@@ -2817,7 +2819,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 "
@@ -3024,10 +3026,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;
@@ -5297,7 +5299,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) &&
 		    p2p_supported_freq(wpa_s->global->p2p, params->freq))
 			goto out;
 	}
@@ -5306,7 +5308,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) &&
 		    p2p_supported_freq(wpa_s->global->p2p, params->freq))
 			goto out;
 	}
@@ -5315,7 +5317,7 @@ static int wpas_p2p_select_freq_no_pref(struct wpa_supplicant *wpa_s,
 	for (i = 0; i < 4; i++) {
 		params->freq = 5180 + i * 20;
 		if (!wpas_p2p_disallowed_freq(wpa_s->global, params->freq) &&
-		    freq_included(channels, params->freq) &&
+		    wpas_freq_included(wpa_s, channels, params->freq) &&
 		    p2p_supported_freq(wpa_s->global->p2p, params->freq))
 			goto out;
 	}
@@ -5324,7 +5326,7 @@ static int wpas_p2p_select_freq_no_pref(struct wpa_supplicant *wpa_s,
 	for (i = 0; i < 4; i++) {
 		params->freq = 5745 + i * 20;
 		if (!wpas_p2p_disallowed_freq(wpa_s->global, params->freq) &&
-		    freq_included(channels, params->freq) &&
+		    wpas_freq_included(wpa_s, channels, params->freq) &&
 		    p2p_supported_freq(wpa_s->global->p2p, params->freq))
 			goto out;
 	}
@@ -5332,7 +5334,7 @@ static int wpas_p2p_select_freq_no_pref(struct wpa_supplicant *wpa_s,
 	/* try social channel class 180 channel 2 */
 	params->freq = 58320 + 1 * 2160;
 	if (!wpas_p2p_disallowed_freq(wpa_s->global, params->freq) &&
-	    freq_included(channels, params->freq) &&
+	    wpas_freq_included(wpa_s, channels, params->freq) &&
 	    p2p_supported_freq(wpa_s->global->p2p, params->freq))
 		goto out;
 
@@ -5340,7 +5342,7 @@ static int wpas_p2p_select_freq_no_pref(struct wpa_supplicant *wpa_s,
 	for (i = 0; i < 4; i++) {
 		params->freq = 58320 + i * 2160;
 		if (!wpas_p2p_disallowed_freq(wpa_s->global, params->freq) &&
-		    freq_included(channels, params->freq) &&
+		    wpas_freq_included(wpa_s, channels, params->freq) &&
 		    p2p_supported_freq(wpa_s->global->p2p, params->freq))
 			goto out;
 	}
@@ -5367,8 +5369,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;
@@ -5379,8 +5386,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);
@@ -5391,8 +5399,9 @@ static int wpas_p2p_init_go_params(struct wpa_supplicant *wpa_s,
 		    wpa_s->conf->p2p_oper_reg_class == 125 ||
 		    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);
@@ -5400,7 +5409,8 @@ 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);
@@ -5408,7 +5418,7 @@ 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);
@@ -5416,7 +5426,7 @@ 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);
@@ -5425,6 +5435,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)
@@ -5442,27 +5464,17 @@ static int wpas_p2p_init_go_params(struct wpa_supplicant *wpa_s,
 	cand_freq = wpas_p2p_pick_best_used_freq(wpa_s, 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++) {
@@ -5689,12 +5701,13 @@ int wpas_p2p_group_add_persistent(struct wpa_supplicant *wpa_s,
 		} else {
 			freq = wpas_p2p_select_go_freq(wpa_s, neg_freq);
 			if (freq < 0 ||
-			    (freq > 0 && !freq_included(channels, freq)))
+			    (freq > 0 &&
+			     !wpas_freq_included(wpa_s, channels, freq)))
 				freq = 0;
 		}
 	} else if (ssid->mode == WPAS_MODE_INFRA) {
 		freq = neg_freq;
-		if (freq <= 0 || !freq_included(channels, freq)) {
+		if (freq <= 0 || !wpas_freq_included(wpa_s, channels, freq)) {
 			struct os_reltime now;
 			struct wpa_bss *bss =
 				wpa_bss_get_p2p_dev_addr(wpa_s, ssid->bssid);
@@ -5702,7 +5715,7 @@ int wpas_p2p_group_add_persistent(struct wpa_supplicant *wpa_s,
 			os_get_reltime(&now);
 			if (bss &&
 			    !os_reltime_expired(&now, &bss->last_update, 5) &&
-			    freq_included(channels, bss->freq))
+			    wpas_freq_included(wpa_s, channels, bss->freq))
 				freq = bss->freq;
 			else
 				freq = 0;
@@ -6939,7 +6952,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.9.1



More information about the HostAP mailing list