|
@@ -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,
|
|
|
- struct p2p_go_neg_results *params,
|
|
|
- const struct p2p_channels *channels)
|
|
|
+static int wpas_p2p_supported_freq_go(struct wpa_supplicant *wpa_s,
|
|
|
+ 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;
|
|
|
|
|
|
/* first try some random selection of the social channels */
|
|
|
if (os_get_random((u8 *) &r, sizeof(r)) < 0)
|
|
|
- return -1;
|
|
|
+ return;
|
|
|
|
|
|
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(wpa_s, channels, params->freq) &&
|
|
|
- p2p_supported_freq(wpa_s->global->p2p, params->freq))
|
|
|
+ if (wpas_p2p_supported_freq_go(wpa_s, channels, params->freq))
|
|
|
goto out;
|
|
|
}
|
|
|
|
|
|
- /* try all channels in reg. class 81 */
|
|
|
+ /* try all other channels in operating class 81 */
|
|
|
for (i = 0; i < 11; i++) {
|
|
|
params->freq = 2412 + i * 5;
|
|
|
- if (!wpas_p2p_disallowed_freq(wpa_s->global, params->freq) &&
|
|
|
- freq_included(wpa_s, channels, params->freq) &&
|
|
|
- p2p_supported_freq(wpa_s->global->p2p, params->freq))
|
|
|
+
|
|
|
+ /* skip social channels; covered in the previous loop */
|
|
|
+ if (params->freq == 2412 ||
|
|
|
+ params->freq == 2437 ||
|
|
|
+ params->freq == 2462)
|
|
|
+ continue;
|
|
|
+
|
|
|
+ if (wpas_p2p_supported_freq_go(wpa_s, channels, params->freq))
|
|
|
goto out;
|
|
|
}
|
|
|
|
|
@@ -5416,12 +5431,12 @@ static int wpas_p2p_select_freq_no_pref(struct wpa_supplicant *wpa_s,
|
|
|
goto out;
|
|
|
}
|
|
|
|
|
|
+ params->freq = 0;
|
|
|
wpa_printf(MSG_DEBUG, "P2P: No 2.4, 5, or 60 GHz channel allowed");
|
|
|
- return -1;
|
|
|
+ return;
|
|
|
out:
|
|
|
wpa_printf(MSG_DEBUG, "P2P: Set GO freq %d MHz (no preference known)",
|
|
|
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)
|
|
|
{
|
|
|
struct wpa_used_freq_data *freqs;
|
|
|
- unsigned int pref_freq, cand_freq;
|
|
|
+ unsigned int cand;
|
|
|
unsigned int num, i;
|
|
|
|
|
|
os_memset(params, 0, sizeof(*params));
|
|
@@ -5443,124 +5458,174 @@ static int wpas_p2p_init_go_params(struct wpa_supplicant *wpa_s,
|
|
|
wpa_printf(MSG_DEBUG, "P2P: %s called for an active GO",
|
|
|
__func__);
|
|
|
|
|
|
+ freqs = os_calloc(wpa_s->num_multichan_concurrent,
|
|
|
+ sizeof(struct wpa_used_freq_data));
|
|
|
+ if (!freqs)
|
|
|
+ return -1;
|
|
|
+
|
|
|
+ num = wpas_p2p_valid_oper_freqs(wpa_s, freqs,
|
|
|
+ wpa_s->num_multichan_concurrent);
|
|
|
+
|
|
|
+ /* try using the forced freq */
|
|
|
if (freq) {
|
|
|
- if (!freq_included(wpa_s, channels, freq)) {
|
|
|
- wpa_printf(MSG_DEBUG, "P2P: Forced GO freq %d MHz not "
|
|
|
- "accepted", freq);
|
|
|
- return -1;
|
|
|
+ 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;
|
|
|
+ }
|
|
|
}
|
|
|
- wpa_printf(MSG_DEBUG, "P2P: Set GO freq based on forced "
|
|
|
- "frequency %d MHz", freq);
|
|
|
+
|
|
|
+ if (wpas_p2p_num_unused_channels(wpa_s) <= 0) {
|
|
|
+ wpa_printf(MSG_DEBUG,
|
|
|
+ "P2P: Cannot force GO on freq (%d MHz) as all the channels are in use",
|
|
|
+ freq);
|
|
|
+ goto fail;
|
|
|
+ }
|
|
|
+
|
|
|
+ wpa_printf(MSG_DEBUG,
|
|
|
+ "P2P: force GO freq (%d MHz) on a free channel",
|
|
|
+ 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)) {
|
|
|
+ goto success;
|
|
|
+ }
|
|
|
+
|
|
|
+ /* 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);
|
|
|
- } 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)) {
|
|
|
+ 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);
|
|
|
- } 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)) {
|
|
|
+ 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);
|
|
|
- } 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)) {
|
|
|
+ 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);
|
|
|
- } 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)) {
|
|
|
+ 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);
|
|
|
- } else if ((pref_freq = p2p_get_pref_freq(wpa_s->global->p2p,
|
|
|
- channels))) {
|
|
|
- params->freq = pref_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);
|
|
|
- } else if (wpa_s->p2p_group_common_freqs) {
|
|
|
+ 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++) {
|
|
|
- if (freq_included(wpa_s, channels,
|
|
|
- wpa_s->p2p_group_common_freqs[i])) {
|
|
|
- params->freq = wpa_s->p2p_group_common_freqs[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);
|
|
|
- break;
|
|
|
+ goto success;
|
|
|
}
|
|
|
}
|
|
|
- } 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,
|
|
|
- sizeof(struct wpa_used_freq_data));
|
|
|
- if (!freqs)
|
|
|
- return -1;
|
|
|
-
|
|
|
- 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);
|
|
|
-
|
|
|
- /* 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) {
|
|
|
- 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++) {
|
|
|
- if (freqs[i].freq == freq)
|
|
|
- break;
|
|
|
- }
|
|
|
+ /* no preference, select some channel */
|
|
|
+ wpas_p2p_select_go_freq_no_pref(wpa_s, params, channels);
|
|
|
|
|
|
- if (i == num) {
|
|
|
- if (wpas_p2p_num_unused_channels(wpa_s) <= 0) {
|
|
|
- if (freq)
|
|
|
- wpa_printf(MSG_DEBUG, "P2P: Cannot force GO on freq (%u MHz) as all the channels are in use", freq);
|
|
|
- os_free(freqs);
|
|
|
- return -1;
|
|
|
- } else {
|
|
|
- wpa_printf(MSG_DEBUG, "P2P: Use one of the free channels");
|
|
|
- }
|
|
|
- }
|
|
|
+ if (params->freq == 0) {
|
|
|
+ wpa_printf(MSG_DEBUG, "P2P: did not find a freq for GO use");
|
|
|
+ goto fail;
|
|
|
}
|
|
|
|
|
|
+success:
|
|
|
os_free(freqs);
|
|
|
return 0;
|
|
|
+fail:
|
|
|
+ os_free(freqs);
|
|
|
+ return -1;
|
|
|
}
|
|
|
|
|
|
|