[PATCH 12/23] P2P: Move a GO to a frequency that is also supported by the client
Ilan Peer
ilan.peer
Mon Jul 7 04:21:05 PDT 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.
Change-Id: I9004daaeef77c5c715b1769017431a7aac28d71b
Signed-off-by: Ilan Peer <ilan.peer at intel.com>
---
wpa_supplicant/p2p_supplicant.c | 114 ++++++++++++++++++++++-----------------
1 file changed, 66 insertions(+), 48 deletions(-)
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);
--
1.7.10.4
More information about the Hostap
mailing list