P2P: Modify wpas_p2p_init_go_params()
Not all paths in wpas_p2p_init_go_params() verified that the candidate frequency can be used for GO purposes. Fix this, and in addition re-factor the code to put better emphasis on the frequency selection priorities. Signed-off-by: Ilan Peer <ilan.peer@intel.com>
This commit is contained in:
parent
a7160f7ede
commit
b130812100
1 changed files with 178 additions and 113 deletions
|
@ -5355,30 +5355,45 @@ static int wpas_p2p_select_go_freq(struct wpa_supplicant *wpa_s, int freq)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static int wpas_p2p_select_freq_no_pref(struct wpa_supplicant *wpa_s,
|
static int wpas_p2p_supported_freq_go(struct wpa_supplicant *wpa_s,
|
||||||
struct p2p_go_neg_results *params,
|
const struct p2p_channels *channels,
|
||||||
const struct p2p_channels *channels)
|
int freq)
|
||||||
|
{
|
||||||
|
if (!wpas_p2p_disallowed_freq(wpa_s->global, freq) &&
|
||||||
|
p2p_supported_freq_go(wpa_s->global->p2p, freq) &&
|
||||||
|
freq_included(wpa_s, channels, freq))
|
||||||
|
return 1;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static void wpas_p2p_select_go_freq_no_pref(struct wpa_supplicant *wpa_s,
|
||||||
|
struct p2p_go_neg_results *params,
|
||||||
|
const struct p2p_channels *channels)
|
||||||
{
|
{
|
||||||
unsigned int i, r;
|
unsigned int i, r;
|
||||||
|
|
||||||
/* first try some random selection of the social channels */
|
/* first try some random selection of the social channels */
|
||||||
if (os_get_random((u8 *) &r, sizeof(r)) < 0)
|
if (os_get_random((u8 *) &r, sizeof(r)) < 0)
|
||||||
return -1;
|
return;
|
||||||
|
|
||||||
for (i = 0; i < 3; i++) {
|
for (i = 0; i < 3; i++) {
|
||||||
params->freq = 2412 + ((r + i) % 3) * 25;
|
params->freq = 2412 + ((r + i) % 3) * 25;
|
||||||
if (!wpas_p2p_disallowed_freq(wpa_s->global, params->freq) &&
|
if (wpas_p2p_supported_freq_go(wpa_s, channels, params->freq))
|
||||||
freq_included(wpa_s, channels, params->freq) &&
|
|
||||||
p2p_supported_freq(wpa_s->global->p2p, params->freq))
|
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* try all channels in reg. class 81 */
|
/* try all other channels in operating class 81 */
|
||||||
for (i = 0; i < 11; i++) {
|
for (i = 0; i < 11; i++) {
|
||||||
params->freq = 2412 + i * 5;
|
params->freq = 2412 + i * 5;
|
||||||
if (!wpas_p2p_disallowed_freq(wpa_s->global, params->freq) &&
|
|
||||||
freq_included(wpa_s, channels, params->freq) &&
|
/* skip social channels; covered in the previous loop */
|
||||||
p2p_supported_freq(wpa_s->global->p2p, params->freq))
|
if (params->freq == 2412 ||
|
||||||
|
params->freq == 2437 ||
|
||||||
|
params->freq == 2462)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (wpas_p2p_supported_freq_go(wpa_s, channels, params->freq))
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -5416,12 +5431,12 @@ static int wpas_p2p_select_freq_no_pref(struct wpa_supplicant *wpa_s,
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
params->freq = 0;
|
||||||
wpa_printf(MSG_DEBUG, "P2P: No 2.4, 5, or 60 GHz channel allowed");
|
wpa_printf(MSG_DEBUG, "P2P: No 2.4, 5, or 60 GHz channel allowed");
|
||||||
return -1;
|
return;
|
||||||
out:
|
out:
|
||||||
wpa_printf(MSG_DEBUG, "P2P: Set GO freq %d MHz (no preference known)",
|
wpa_printf(MSG_DEBUG, "P2P: Set GO freq %d MHz (no preference known)",
|
||||||
params->freq);
|
params->freq);
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -5431,7 +5446,7 @@ static int wpas_p2p_init_go_params(struct wpa_supplicant *wpa_s,
|
||||||
const struct p2p_channels *channels)
|
const struct p2p_channels *channels)
|
||||||
{
|
{
|
||||||
struct wpa_used_freq_data *freqs;
|
struct wpa_used_freq_data *freqs;
|
||||||
unsigned int pref_freq, cand_freq;
|
unsigned int cand;
|
||||||
unsigned int num, i;
|
unsigned int num, i;
|
||||||
|
|
||||||
os_memset(params, 0, sizeof(*params));
|
os_memset(params, 0, sizeof(*params));
|
||||||
|
@ -5443,81 +5458,6 @@ static int wpas_p2p_init_go_params(struct wpa_supplicant *wpa_s,
|
||||||
wpa_printf(MSG_DEBUG, "P2P: %s called for an active GO",
|
wpa_printf(MSG_DEBUG, "P2P: %s called for an active GO",
|
||||||
__func__);
|
__func__);
|
||||||
|
|
||||||
if (freq) {
|
|
||||||
if (!freq_included(wpa_s, channels, freq)) {
|
|
||||||
wpa_printf(MSG_DEBUG, "P2P: Forced GO freq %d MHz not "
|
|
||||||
"accepted", freq);
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
wpa_printf(MSG_DEBUG, "P2P: Set GO freq based on forced "
|
|
||||||
"frequency %d MHz", freq);
|
|
||||||
params->freq = freq;
|
|
||||||
} 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(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);
|
|
||||||
} else if ((wpa_s->conf->p2p_oper_reg_class == 115 ||
|
|
||||||
wpa_s->conf->p2p_oper_reg_class == 116 ||
|
|
||||||
wpa_s->conf->p2p_oper_reg_class == 117 ||
|
|
||||||
wpa_s->conf->p2p_oper_reg_class == 124 ||
|
|
||||||
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(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);
|
|
||||||
} else if (wpa_s->conf->p2p_oper_channel == 0 &&
|
|
||||||
wpa_s->best_overall_freq > 0 &&
|
|
||||||
p2p_supported_freq_go(wpa_s->global->p2p,
|
|
||||||
wpa_s->best_overall_freq) &&
|
|
||||||
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);
|
|
||||||
} else if (wpa_s->conf->p2p_oper_channel == 0 &&
|
|
||||||
wpa_s->best_24_freq > 0 &&
|
|
||||||
p2p_supported_freq_go(wpa_s->global->p2p,
|
|
||||||
wpa_s->best_24_freq) &&
|
|
||||||
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);
|
|
||||||
} else if (wpa_s->conf->p2p_oper_channel == 0 &&
|
|
||||||
wpa_s->best_5_freq > 0 &&
|
|
||||||
p2p_supported_freq_go(wpa_s->global->p2p,
|
|
||||||
wpa_s->best_5_freq) &&
|
|
||||||
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);
|
|
||||||
} else if ((pref_freq = p2p_get_pref_freq(wpa_s->global->p2p,
|
|
||||||
channels))) {
|
|
||||||
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 (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 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)
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
freqs = os_calloc(wpa_s->num_multichan_concurrent,
|
freqs = os_calloc(wpa_s->num_multichan_concurrent,
|
||||||
sizeof(struct wpa_used_freq_data));
|
sizeof(struct wpa_used_freq_data));
|
||||||
if (!freqs)
|
if (!freqs)
|
||||||
|
@ -5526,41 +5466,166 @@ static int wpas_p2p_init_go_params(struct wpa_supplicant *wpa_s,
|
||||||
num = wpas_p2p_valid_oper_freqs(wpa_s, freqs,
|
num = wpas_p2p_valid_oper_freqs(wpa_s, freqs,
|
||||||
wpa_s->num_multichan_concurrent);
|
wpa_s->num_multichan_concurrent);
|
||||||
|
|
||||||
cand_freq = wpas_p2p_pick_best_used_freq(wpa_s, freqs, num);
|
/* try using the forced freq */
|
||||||
|
if (freq) {
|
||||||
|
if (!wpas_p2p_supported_freq_go(wpa_s, channels, freq)) {
|
||||||
|
wpa_printf(MSG_DEBUG,
|
||||||
|
"P2P: Forced GO freq %d MHz not accepted",
|
||||||
|
freq);
|
||||||
|
goto fail;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (i = 0; i < num; i++) {
|
||||||
|
if (freqs[i].freq == freq) {
|
||||||
|
wpa_printf(MSG_DEBUG,
|
||||||
|
"P2P: forced freq (%d MHz) is also shared",
|
||||||
|
freq);
|
||||||
|
params->freq = freq;
|
||||||
|
goto success;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* First try the best used frequency if possible */
|
|
||||||
if (!freq && cand_freq > 0) {
|
|
||||||
params->freq = cand_freq;
|
|
||||||
} else if (!freq) {
|
|
||||||
if (wpas_p2p_num_unused_channels(wpa_s) <= 0) {
|
if (wpas_p2p_num_unused_channels(wpa_s) <= 0) {
|
||||||
wpa_printf(MSG_DEBUG,
|
wpa_printf(MSG_DEBUG,
|
||||||
"P2P: Cannot force GO on any of the channels we are already using");
|
"P2P: Cannot force GO on freq (%d MHz) as all the channels are in use",
|
||||||
os_free(freqs);
|
freq);
|
||||||
return -1;
|
goto fail;
|
||||||
} 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++) {
|
|
||||||
if (freqs[i].freq == freq)
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (i == num) {
|
wpa_printf(MSG_DEBUG,
|
||||||
if (wpas_p2p_num_unused_channels(wpa_s) <= 0) {
|
"P2P: force GO freq (%d MHz) on a free channel",
|
||||||
if (freq)
|
freq);
|
||||||
wpa_printf(MSG_DEBUG, "P2P: Cannot force GO on freq (%u MHz) as all the channels are in use", freq);
|
params->freq = freq;
|
||||||
os_free(freqs);
|
goto success;
|
||||||
return -1;
|
}
|
||||||
} else {
|
|
||||||
wpa_printf(MSG_DEBUG, "P2P: Use one of the free channels");
|
/* consider using one of the shared frequencies */
|
||||||
|
if (num) {
|
||||||
|
cand = wpas_p2p_pick_best_used_freq(wpa_s, freqs, num);
|
||||||
|
if (wpas_p2p_supported_freq_go(wpa_s, channels, cand)) {
|
||||||
|
wpa_printf(MSG_DEBUG,
|
||||||
|
"P2P: Use shared freq (%d MHz) for GO",
|
||||||
|
freq);
|
||||||
|
params->freq = cand;
|
||||||
|
goto success;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* try using one of the shared freqs */
|
||||||
|
for (i = 0; i < num; i++) {
|
||||||
|
if (wpas_p2p_supported_freq_go(wpa_s, channels,
|
||||||
|
freqs[i].freq)) {
|
||||||
|
wpa_printf(MSG_DEBUG,
|
||||||
|
"P2P: Use shared freq (%d MHz) for GO",
|
||||||
|
freq);
|
||||||
|
params->freq = freqs[i].freq;
|
||||||
|
goto success;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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");
|
||||||
|
goto fail;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* try using the setting from the configuration file */
|
||||||
|
if (wpa_s->conf->p2p_oper_reg_class == 81 &&
|
||||||
|
wpa_s->conf->p2p_oper_channel >= 1 &&
|
||||||
|
wpa_s->conf->p2p_oper_channel <= 11 &&
|
||||||
|
wpas_p2p_supported_freq_go(
|
||||||
|
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);
|
||||||
|
goto success;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((wpa_s->conf->p2p_oper_reg_class == 115 ||
|
||||||
|
wpa_s->conf->p2p_oper_reg_class == 116 ||
|
||||||
|
wpa_s->conf->p2p_oper_reg_class == 117 ||
|
||||||
|
wpa_s->conf->p2p_oper_reg_class == 124 ||
|
||||||
|
wpa_s->conf->p2p_oper_reg_class == 125 ||
|
||||||
|
wpa_s->conf->p2p_oper_reg_class == 126 ||
|
||||||
|
wpa_s->conf->p2p_oper_reg_class == 127) &&
|
||||||
|
wpas_p2p_supported_freq_go(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);
|
||||||
|
goto success;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Try using best channels */
|
||||||
|
if (wpa_s->conf->p2p_oper_channel == 0 &&
|
||||||
|
wpa_s->best_overall_freq > 0 &&
|
||||||
|
wpas_p2p_supported_freq_go(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);
|
||||||
|
goto success;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (wpa_s->conf->p2p_oper_channel == 0 &&
|
||||||
|
wpa_s->best_24_freq > 0 &&
|
||||||
|
wpas_p2p_supported_freq_go(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);
|
||||||
|
goto success;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (wpa_s->conf->p2p_oper_channel == 0 &&
|
||||||
|
wpa_s->best_5_freq > 0 &&
|
||||||
|
wpas_p2p_supported_freq_go(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);
|
||||||
|
goto success;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* try using preferred channels */
|
||||||
|
cand = p2p_get_pref_freq(wpa_s->global->p2p, channels);
|
||||||
|
if (cand && wpas_p2p_supported_freq_go(wpa_s, channels, cand)) {
|
||||||
|
params->freq = cand;
|
||||||
|
wpa_printf(MSG_DEBUG, "P2P: Set GO freq %d MHz from preferred "
|
||||||
|
"channels", params->freq);
|
||||||
|
goto success;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Try using one of the group common freqs */
|
||||||
|
if (wpa_s->p2p_group_common_freqs) {
|
||||||
|
for (i = 0; i < wpa_s->p2p_group_common_freqs_num; i++) {
|
||||||
|
cand = wpa_s->p2p_group_common_freqs[i];
|
||||||
|
if (wpas_p2p_supported_freq_go(wpa_s, channels, cand)) {
|
||||||
|
params->freq = cand;
|
||||||
|
wpa_printf(MSG_DEBUG,
|
||||||
|
"P2P: Use freq %d MHz common with the peer",
|
||||||
|
params->freq);
|
||||||
|
goto success;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* no preference, select some channel */
|
||||||
|
wpas_p2p_select_go_freq_no_pref(wpa_s, params, channels);
|
||||||
|
|
||||||
|
if (params->freq == 0) {
|
||||||
|
wpa_printf(MSG_DEBUG, "P2P: did not find a freq for GO use");
|
||||||
|
goto fail;
|
||||||
|
}
|
||||||
|
|
||||||
|
success:
|
||||||
os_free(freqs);
|
os_free(freqs);
|
||||||
return 0;
|
return 0;
|
||||||
|
fail:
|
||||||
|
os_free(freqs);
|
||||||
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue