P2P: Avoid multi-channel scans when they are not needed
If the driver does not support multi-channel concurrency and a virtual interface that shares the same radio with the current interface is operating there may not be need to scan other channels apart from the current operating channel on the other virtual interface. Filter out other channels in case we are trying to find a connection for a station interface when we are not configured to prefer station connection and a concurrent operation is already in process. Signed-hostap: Jouni Malinen <j@w1.fi>
This commit is contained in:
parent
13e1d2e292
commit
5cc7032239
3 changed files with 101 additions and 0 deletions
|
@ -877,6 +877,8 @@ static void wpa_supplicant_req_new_scan(struct wpa_supplicant *wpa_s,
|
||||||
#endif /* CONFIG_P2P */
|
#endif /* CONFIG_P2P */
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
wpa_s->scan_for_connection = 1;
|
||||||
wpa_supplicant_req_scan(wpa_s, timeout_sec, timeout_usec);
|
wpa_supplicant_req_scan(wpa_s, timeout_sec, timeout_usec);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -435,6 +435,72 @@ static struct wpabuf * wpa_supplicant_extra_ies(struct wpa_supplicant *wpa_s)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef CONFIG_P2P
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Check whether there are any enabled networks or credentials that could be
|
||||||
|
* used for a non-P2P connection.
|
||||||
|
*/
|
||||||
|
static int non_p2p_network_enabled(struct wpa_supplicant *wpa_s)
|
||||||
|
{
|
||||||
|
struct wpa_ssid *ssid;
|
||||||
|
|
||||||
|
for (ssid = wpa_s->conf->ssid; ssid; ssid = ssid->next) {
|
||||||
|
if (wpas_network_disabled(wpa_s, ssid))
|
||||||
|
continue;
|
||||||
|
if (!ssid->p2p_group)
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (wpa_s->conf->cred && wpa_s->conf->interworking &&
|
||||||
|
wpa_s->conf->auto_interworking)
|
||||||
|
return 1;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Find the operating frequency of any other virtual interface that is using
|
||||||
|
* the same radio concurrently.
|
||||||
|
*/
|
||||||
|
static int shared_vif_oper_freq(struct wpa_supplicant *wpa_s)
|
||||||
|
{
|
||||||
|
const char *rn, *rn2;
|
||||||
|
struct wpa_supplicant *ifs;
|
||||||
|
u8 bssid[ETH_ALEN];
|
||||||
|
|
||||||
|
if (!wpa_s->driver->get_radio_name)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
rn = wpa_s->driver->get_radio_name(wpa_s->drv_priv);
|
||||||
|
if (rn == NULL || rn[0] == '\0')
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
for (ifs = wpa_s->global->ifaces; ifs; ifs = ifs->next) {
|
||||||
|
if (ifs == wpa_s || !ifs->driver->get_radio_name)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
rn2 = ifs->driver->get_radio_name(ifs->drv_priv);
|
||||||
|
if (!rn2 || os_strcmp(rn, rn2) != 0)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (ifs->current_ssid == NULL || ifs->assoc_freq == 0)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (ifs->current_ssid->mode == WPAS_MODE_AP ||
|
||||||
|
ifs->current_ssid->mode == WPAS_MODE_P2P_GO)
|
||||||
|
return ifs->current_ssid->frequency;
|
||||||
|
if (wpa_drv_get_bssid(ifs, bssid) == 0)
|
||||||
|
return ifs->assoc_freq;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif /* CONFIG_P2P */
|
||||||
|
|
||||||
|
|
||||||
static void wpa_supplicant_scan(void *eloop_ctx, void *timeout_ctx)
|
static void wpa_supplicant_scan(void *eloop_ctx, void *timeout_ctx)
|
||||||
{
|
{
|
||||||
struct wpa_supplicant *wpa_s = eloop_ctx;
|
struct wpa_supplicant *wpa_s = eloop_ctx;
|
||||||
|
@ -686,6 +752,35 @@ ssid_list_set:
|
||||||
scan_params = ¶ms;
|
scan_params = ¶ms;
|
||||||
|
|
||||||
scan:
|
scan:
|
||||||
|
#ifdef CONFIG_P2P
|
||||||
|
/*
|
||||||
|
* If the driver does not support multi-channel concurrency and a
|
||||||
|
* virtual interface that shares the same radio with the wpa_s interface
|
||||||
|
* is operating there may not be need to scan other channels apart from
|
||||||
|
* the current operating channel on the other virtual interface. Filter
|
||||||
|
* out other channels in case we are trying to find a connection for a
|
||||||
|
* station interface when we are not configured to prefer station
|
||||||
|
* connection and a concurrent operation is already in process.
|
||||||
|
*/
|
||||||
|
if (wpa_s->scan_for_connection && !scan_req &&
|
||||||
|
!scan_params->freqs && !params.freqs &&
|
||||||
|
wpas_is_p2p_prioritized(wpa_s) &&
|
||||||
|
!(wpa_s->drv_flags & WPA_DRIVER_FLAGS_MULTI_CHANNEL_CONCURRENT) &&
|
||||||
|
wpa_s->p2p_group_interface == NOT_P2P_GROUP_INTERFACE &&
|
||||||
|
non_p2p_network_enabled(wpa_s)) {
|
||||||
|
int freq = shared_vif_oper_freq(wpa_s);
|
||||||
|
if (freq > 0) {
|
||||||
|
wpa_dbg(wpa_s, MSG_DEBUG, "P2P: Scan only the current "
|
||||||
|
"operating channel (%d MHz) since driver does "
|
||||||
|
"not support multi-channel concurrency", freq);
|
||||||
|
params.freqs = os_zalloc(sizeof(int) * 2);
|
||||||
|
if (params.freqs)
|
||||||
|
params.freqs[0] = freq;
|
||||||
|
scan_params->freqs = params.freqs;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif /* CONFIG_P2P */
|
||||||
|
|
||||||
ret = wpa_supplicant_trigger_scan(wpa_s, scan_params);
|
ret = wpa_supplicant_trigger_scan(wpa_s, scan_params);
|
||||||
|
|
||||||
wpabuf_free(extra_ie);
|
wpabuf_free(extra_ie);
|
||||||
|
@ -699,6 +794,8 @@ scan:
|
||||||
/* Restore scan_req since we will try to scan again */
|
/* Restore scan_req since we will try to scan again */
|
||||||
wpa_s->scan_req = scan_req;
|
wpa_s->scan_req = scan_req;
|
||||||
wpa_supplicant_req_scan(wpa_s, 1, 0);
|
wpa_supplicant_req_scan(wpa_s, 1, 0);
|
||||||
|
} else {
|
||||||
|
wpa_s->scan_for_connection = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -403,6 +403,8 @@ struct wpa_supplicant {
|
||||||
int *next_scan_freqs;
|
int *next_scan_freqs;
|
||||||
int scan_interval; /* time in sec between scans to find suitable AP */
|
int scan_interval; /* time in sec between scans to find suitable AP */
|
||||||
int normal_scans; /* normal scans run before sched_scan */
|
int normal_scans; /* normal scans run before sched_scan */
|
||||||
|
int scan_for_connection; /* whether the scan request was triggered for
|
||||||
|
* finding a connection */
|
||||||
|
|
||||||
unsigned int drv_flags;
|
unsigned int drv_flags;
|
||||||
unsigned int drv_enc;
|
unsigned int drv_enc;
|
||||||
|
|
Loading…
Reference in a new issue