From 2e73394426db92643a30b2c9fb80d1ad800cc2a7 Mon Sep 17 00:00:00 2001 From: Matthew Wang Date: Fri, 4 Nov 2022 14:18:02 -0700 Subject: [PATCH] P2P: Discount current operating frequency when scanning new connection When scanning for a new connection, we currently optimize by scanning all frequencies only when our MCC capabilities will allow an additional operating frequency, and scan only the existing operating frequencies otherwise. This is problematic when there the current operating frequency singularly accounts for one of the shared radio frequencies because we should be able to switch operating frequencies without adding to the channel count. Fix this. Signed-off-by: Matthew Wang --- wpa_supplicant/p2p_supplicant.c | 12 +++++++----- wpa_supplicant/scan.c | 11 +++++++++-- wpa_supplicant/sme.c | 2 +- wpa_supplicant/wpa_supplicant.c | 13 +++++++++---- wpa_supplicant/wpa_supplicant_i.h | 5 +++-- 5 files changed, 29 insertions(+), 14 deletions(-) diff --git a/wpa_supplicant/p2p_supplicant.c b/wpa_supplicant/p2p_supplicant.c index 7ca0275be..aa0087ac4 100644 --- a/wpa_supplicant/p2p_supplicant.c +++ b/wpa_supplicant/p2p_supplicant.c @@ -189,7 +189,7 @@ static int wpas_p2p_num_unused_channels(struct wpa_supplicant *wpa_s) return -1; num = get_shared_radio_freqs(wpa_s, freqs, - wpa_s->num_multichan_concurrent); + wpa_s->num_multichan_concurrent, false); os_free(freqs); unused = wpa_s->num_multichan_concurrent - num; @@ -216,7 +216,8 @@ wpas_p2p_valid_oper_freqs(struct wpa_supplicant *wpa_s, return 0; num = get_shared_radio_freqs_data(wpa_s, freqs, - wpa_s->num_multichan_concurrent); + wpa_s->num_multichan_concurrent, + false); os_memset(p2p_freqs, 0, sizeof(struct wpa_used_freq_data) * len); @@ -6450,7 +6451,8 @@ static int wpas_p2p_init_go_params(struct wpa_supplicant *wpa_s, return -1; num = get_shared_radio_freqs_data(wpa_s, freqs, - wpa_s->num_multichan_concurrent); + wpa_s->num_multichan_concurrent, + false); if (wpa_s->current_ssid && wpa_s->current_ssid->mode == WPAS_MODE_P2P_GO && @@ -8321,7 +8323,7 @@ void wpas_p2p_update_channel_list(struct wpa_supplicant *wpa_s, if (!freqs) return; - num = get_shared_radio_freqs_data(wpa_s, freqs, num); + num = get_shared_radio_freqs_data(wpa_s, freqs, num, false); os_memset(&chan, 0, sizeof(chan)); os_memset(&cli_chan, 0, sizeof(cli_chan)); @@ -9871,7 +9873,7 @@ static void wpas_p2p_reconsider_moving_go(void *eloop_ctx, void *timeout_ctx) if (!freqs) return; - num = get_shared_radio_freqs_data(wpa_s, freqs, num); + num = get_shared_radio_freqs_data(wpa_s, freqs, num, false); /* Previous attempt to move a GO was not possible -- try again. */ wpas_p2p_consider_moving_gos(wpa_s, freqs, num, diff --git a/wpa_supplicant/scan.c b/wpa_supplicant/scan.c index 05913a181..abac3975a 100644 --- a/wpa_supplicant/scan.c +++ b/wpa_supplicant/scan.c @@ -1267,7 +1267,8 @@ ssid_list_set: params.freqs = os_calloc(num + 1, sizeof(int)); if (params.freqs) { - num = get_shared_radio_freqs(wpa_s, params.freqs, num); + num = get_shared_radio_freqs(wpa_s, params.freqs, num, + false); if (num > 0) { wpa_dbg(wpa_s, MSG_DEBUG, "Scan only the " "current operating channels since " @@ -1357,7 +1358,13 @@ scan: params.freqs = os_calloc(num + 1, sizeof(int)); if (params.freqs) { - num = get_shared_radio_freqs(wpa_s, params.freqs, num); + /* + * Exclude the operating frequency of the current + * interface since we're looking to transition off of + * it. + */ + num = get_shared_radio_freqs(wpa_s, params.freqs, num, + true); if (num > 0 && num == wpa_s->num_multichan_concurrent) { wpa_dbg(wpa_s, MSG_DEBUG, "Scan only the current operating channels since all channels are already used"); } else { diff --git a/wpa_supplicant/sme.c b/wpa_supplicant/sme.c index 896fa9df4..542be0b18 100644 --- a/wpa_supplicant/sme.c +++ b/wpa_supplicant/sme.c @@ -895,7 +895,7 @@ no_fils: */ if (wpa_s->num_multichan_concurrent < 2) { int freq, num; - num = get_shared_radio_freqs(wpa_s, &freq, 1); + num = get_shared_radio_freqs(wpa_s, &freq, 1, false); if (num > 0 && freq > 0 && freq != params.freq) { wpa_printf(MSG_DEBUG, "Conflicting frequency found (%d != %d)", diff --git a/wpa_supplicant/wpa_supplicant.c b/wpa_supplicant/wpa_supplicant.c index 6b3451fd4..875f7ae79 100644 --- a/wpa_supplicant/wpa_supplicant.c +++ b/wpa_supplicant/wpa_supplicant.c @@ -4129,7 +4129,7 @@ static void wpas_start_assoc_cb(struct wpa_radio_work *work, int deinit) */ if (wpa_s->num_multichan_concurrent < 2) { int freq, num; - num = get_shared_radio_freqs(wpa_s, &freq, 1); + num = get_shared_radio_freqs(wpa_s, &freq, 1, false); if (num > 0 && freq > 0 && freq != params.freq.freq) { wpa_printf(MSG_DEBUG, "Assoc conflicting freq found (%d != %d)", @@ -8419,7 +8419,7 @@ void dump_freq_data(struct wpa_supplicant *wpa_s, const char *title, */ int get_shared_radio_freqs_data(struct wpa_supplicant *wpa_s, struct wpa_used_freq_data *freqs_data, - unsigned int len) + unsigned int len, bool exclude_current) { struct wpa_supplicant *ifs; u8 bssid[ETH_ALEN]; @@ -8435,6 +8435,9 @@ int get_shared_radio_freqs_data(struct wpa_supplicant *wpa_s, if (idx == len) break; + if (exclude_current && ifs == wpa_s) + continue; + if (ifs->current_ssid == NULL || ifs->assoc_freq == 0) continue; @@ -8472,7 +8475,8 @@ int get_shared_radio_freqs_data(struct wpa_supplicant *wpa_s, * are using the same radio as the current interface. */ int get_shared_radio_freqs(struct wpa_supplicant *wpa_s, - int *freq_array, unsigned int len) + int *freq_array, unsigned int len, + bool exclude_current) { struct wpa_used_freq_data *freqs_data; int num, i; @@ -8483,7 +8487,8 @@ int get_shared_radio_freqs(struct wpa_supplicant *wpa_s, if (!freqs_data) return -1; - num = get_shared_radio_freqs_data(wpa_s, freqs_data, len); + num = get_shared_radio_freqs_data(wpa_s, freqs_data, len, + exclude_current); for (i = 0; i < num; i++) freq_array[i] = freqs_data[i].freq; diff --git a/wpa_supplicant/wpa_supplicant_i.h b/wpa_supplicant/wpa_supplicant_i.h index 891d091cd..e845b5382 100644 --- a/wpa_supplicant/wpa_supplicant_i.h +++ b/wpa_supplicant/wpa_supplicant_i.h @@ -1802,9 +1802,10 @@ void dump_freq_data(struct wpa_supplicant *wpa_s, const char *title, int get_shared_radio_freqs_data(struct wpa_supplicant *wpa_s, struct wpa_used_freq_data *freqs_data, - unsigned int len); + unsigned int len, bool exclude_current); int get_shared_radio_freqs(struct wpa_supplicant *wpa_s, - int *freq_array, unsigned int len); + int *freq_array, unsigned int len, + bool exclude_current); void wpas_network_reenabled(void *eloop_ctx, void *timeout_ctx); -- 2.47.2