P2P: Optimize join scan frequency
Allow clients to specify the BSSID of an auto GO. If the auto GO has been discovered on another interface, optimize scan frequency by performing a single channel scan first. Android and ChromeOS use this to streamline auto GO discovery. Signed-off-by: Matthew Wang <matthewmwang@chromium.org>
This commit is contained in:
parent
b3921db426
commit
0430756e65
8 changed files with 69 additions and 17 deletions
|
@ -240,7 +240,7 @@ void wpa_bss_remove(struct wpa_supplicant *wpa_s, struct wpa_bss *bss,
|
||||||
/**
|
/**
|
||||||
* wpa_bss_get - Fetch a BSS table entry based on BSSID and SSID
|
* wpa_bss_get - Fetch a BSS table entry based on BSSID and SSID
|
||||||
* @wpa_s: Pointer to wpa_supplicant data
|
* @wpa_s: Pointer to wpa_supplicant data
|
||||||
* @bssid: BSSID
|
* @bssid: BSSID, or %NULL to match any BSSID
|
||||||
* @ssid: SSID
|
* @ssid: SSID
|
||||||
* @ssid_len: Length of @ssid
|
* @ssid_len: Length of @ssid
|
||||||
* Returns: Pointer to the BSS entry or %NULL if not found
|
* Returns: Pointer to the BSS entry or %NULL if not found
|
||||||
|
@ -249,10 +249,11 @@ struct wpa_bss * wpa_bss_get(struct wpa_supplicant *wpa_s, const u8 *bssid,
|
||||||
const u8 *ssid, size_t ssid_len)
|
const u8 *ssid, size_t ssid_len)
|
||||||
{
|
{
|
||||||
struct wpa_bss *bss;
|
struct wpa_bss *bss;
|
||||||
if (!wpa_supplicant_filter_bssid_match(wpa_s, bssid))
|
|
||||||
|
if (bssid && !wpa_supplicant_filter_bssid_match(wpa_s, bssid))
|
||||||
return NULL;
|
return NULL;
|
||||||
dl_list_for_each(bss, &wpa_s->bss, struct wpa_bss, list) {
|
dl_list_for_each(bss, &wpa_s->bss, struct wpa_bss, list) {
|
||||||
if (os_memcmp(bss->bssid, bssid, ETH_ALEN) == 0 &&
|
if ((!bssid || os_memcmp(bss->bssid, bssid, ETH_ALEN) == 0) &&
|
||||||
bss->ssid_len == ssid_len &&
|
bss->ssid_len == ssid_len &&
|
||||||
os_memcmp(bss->ssid, ssid, ssid_len) == 0)
|
os_memcmp(bss->ssid, ssid, ssid_len) == 0)
|
||||||
return bss;
|
return bss;
|
||||||
|
|
|
@ -7128,7 +7128,7 @@ static int p2p_ctrl_group_add_persistent(struct wpa_supplicant *wpa_s,
|
||||||
return wpas_p2p_group_add_persistent(wpa_s, ssid, 0, freq,
|
return wpas_p2p_group_add_persistent(wpa_s, ssid, 0, freq,
|
||||||
vht_center_freq2, 0, ht40, vht,
|
vht_center_freq2, 0, ht40, vht,
|
||||||
vht_chwidth, he, edmg,
|
vht_chwidth, he, edmg,
|
||||||
NULL, 0, 0, allow_6ghz, 0);
|
NULL, 0, 0, allow_6ghz, 0, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -359,6 +359,7 @@ DBusMessage * wpas_dbus_handler_p2p_group_add(DBusMessage *message,
|
||||||
char *iface = NULL;
|
char *iface = NULL;
|
||||||
unsigned int group_id = 0;
|
unsigned int group_id = 0;
|
||||||
struct wpa_ssid *ssid;
|
struct wpa_ssid *ssid;
|
||||||
|
u8 go_bssid_buf[ETH_ALEN], *go_bssid = NULL;
|
||||||
|
|
||||||
dbus_message_iter_init(message, &iter);
|
dbus_message_iter_init(message, &iter);
|
||||||
|
|
||||||
|
@ -384,10 +385,16 @@ DBusMessage * wpas_dbus_handler_p2p_group_add(DBusMessage *message,
|
||||||
goto inv_args_clear;
|
goto inv_args_clear;
|
||||||
} else if (os_strcmp(entry.key, "persistent_group_object") ==
|
} else if (os_strcmp(entry.key, "persistent_group_object") ==
|
||||||
0 &&
|
0 &&
|
||||||
entry.type == DBUS_TYPE_OBJECT_PATH)
|
entry.type == DBUS_TYPE_OBJECT_PATH) {
|
||||||
pg_object_path = os_strdup(entry.str_value);
|
pg_object_path = os_strdup(entry.str_value);
|
||||||
else
|
} else if (os_strcmp(entry.key, "go_bssid") == 0 &&
|
||||||
|
entry.type == DBUS_TYPE_STRING) {
|
||||||
|
if (hwaddr_aton(entry.str_value, go_bssid_buf))
|
||||||
|
goto inv_args_clear;
|
||||||
|
go_bssid = go_bssid_buf;
|
||||||
|
} else {
|
||||||
goto inv_args_clear;
|
goto inv_args_clear;
|
||||||
|
}
|
||||||
|
|
||||||
wpa_dbus_dict_entry_clear(&entry);
|
wpa_dbus_dict_entry_clear(&entry);
|
||||||
}
|
}
|
||||||
|
@ -432,7 +439,8 @@ DBusMessage * wpas_dbus_handler_p2p_group_add(DBusMessage *message,
|
||||||
|
|
||||||
if (wpas_p2p_group_add_persistent(wpa_s, ssid, 0, freq, 0, 0, 0,
|
if (wpas_p2p_group_add_persistent(wpa_s, ssid, 0, freq, 0, 0, 0,
|
||||||
0, 0, 0, 0, NULL, 0, 0,
|
0, 0, 0, 0, NULL, 0, 0,
|
||||||
false, retry_limit)) {
|
false, retry_limit,
|
||||||
|
go_bssid)) {
|
||||||
reply = wpas_dbus_error_unknown_error(
|
reply = wpas_dbus_error_unknown_error(
|
||||||
message,
|
message,
|
||||||
"Failed to reinvoke a persistent group");
|
"Failed to reinvoke a persistent group");
|
||||||
|
|
|
@ -1163,7 +1163,7 @@ static void owe_trans_ssid(struct wpa_supplicant *wpa_s, struct wpa_bss *bss,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static int disabled_freq(struct wpa_supplicant *wpa_s, int freq)
|
int disabled_freq(struct wpa_supplicant *wpa_s, int freq)
|
||||||
{
|
{
|
||||||
int i, j;
|
int i, j;
|
||||||
|
|
||||||
|
|
|
@ -3373,7 +3373,8 @@ static void wpas_invitation_received(void *ctx, const u8 *sa, const u8 *bssid,
|
||||||
wpa_s->conf->p2p_go_he,
|
wpa_s->conf->p2p_go_he,
|
||||||
wpa_s->conf->p2p_go_edmg, NULL,
|
wpa_s->conf->p2p_go_edmg, NULL,
|
||||||
go ? P2P_MAX_INITIAL_CONN_WAIT_GO_REINVOKE : 0,
|
go ? P2P_MAX_INITIAL_CONN_WAIT_GO_REINVOKE : 0,
|
||||||
1, is_p2p_allow_6ghz(wpa_s->global->p2p), 0);
|
1, is_p2p_allow_6ghz(wpa_s->global->p2p), 0,
|
||||||
|
NULL);
|
||||||
} else if (bssid) {
|
} else if (bssid) {
|
||||||
wpa_s->user_initiated_pd = 0;
|
wpa_s->user_initiated_pd = 0;
|
||||||
wpa_msg_global(wpa_s, MSG_INFO,
|
wpa_msg_global(wpa_s, MSG_INFO,
|
||||||
|
@ -3603,7 +3604,8 @@ static void wpas_invitation_result(void *ctx, int status, const u8 *bssid,
|
||||||
ssid->mode == WPAS_MODE_P2P_GO ?
|
ssid->mode == WPAS_MODE_P2P_GO ?
|
||||||
P2P_MAX_INITIAL_CONN_WAIT_GO_REINVOKE :
|
P2P_MAX_INITIAL_CONN_WAIT_GO_REINVOKE :
|
||||||
0, 1,
|
0, 1,
|
||||||
is_p2p_allow_6ghz(wpa_s->global->p2p), 0);
|
is_p2p_allow_6ghz(wpa_s->global->p2p), 0,
|
||||||
|
NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -4689,7 +4691,7 @@ static void wpas_p2ps_prov_complete(void *ctx, u8 status, const u8 *dev,
|
||||||
persistent_go->mode ==
|
persistent_go->mode ==
|
||||||
WPAS_MODE_P2P_GO ?
|
WPAS_MODE_P2P_GO ?
|
||||||
P2P_MAX_INITIAL_CONN_WAIT_GO_REINVOKE :
|
P2P_MAX_INITIAL_CONN_WAIT_GO_REINVOKE :
|
||||||
0, 0, false, 0);
|
0, 0, false, 0, NULL);
|
||||||
} else if (response_done) {
|
} else if (response_done) {
|
||||||
wpas_p2p_group_add(wpa_s, 1, freq,
|
wpas_p2p_group_add(wpa_s, 1, freq,
|
||||||
0, 0, 0, 0, 0, 0, false);
|
0, 0, 0, 0, 0, 0, false);
|
||||||
|
@ -4812,7 +4814,7 @@ static int wpas_prov_disc_resp_cb(void *ctx)
|
||||||
NULL,
|
NULL,
|
||||||
persistent_go->mode == WPAS_MODE_P2P_GO ?
|
persistent_go->mode == WPAS_MODE_P2P_GO ?
|
||||||
P2P_MAX_INITIAL_CONN_WAIT_GO_REINVOKE : 0, 0,
|
P2P_MAX_INITIAL_CONN_WAIT_GO_REINVOKE : 0, 0,
|
||||||
is_p2p_allow_6ghz(wpa_s->global->p2p), 0);
|
is_p2p_allow_6ghz(wpa_s->global->p2p), 0, NULL);
|
||||||
} else {
|
} else {
|
||||||
wpas_p2p_group_add(wpa_s, 1, freq, 0, 0, 0, 0, 0, 0,
|
wpas_p2p_group_add(wpa_s, 1, freq, 0, 0, 0, 0, 0, 0,
|
||||||
is_p2p_allow_6ghz(wpa_s->global->p2p));
|
is_p2p_allow_6ghz(wpa_s->global->p2p));
|
||||||
|
@ -6946,7 +6948,8 @@ int wpas_p2p_group_add(struct wpa_supplicant *wpa_s, int persistent_group,
|
||||||
|
|
||||||
static int wpas_start_p2p_client(struct wpa_supplicant *wpa_s,
|
static int wpas_start_p2p_client(struct wpa_supplicant *wpa_s,
|
||||||
struct wpa_ssid *params, int addr_allocated,
|
struct wpa_ssid *params, int addr_allocated,
|
||||||
int freq, int force_scan, int retry_limit)
|
int freq, int force_scan, int retry_limit,
|
||||||
|
const u8 *go_bssid)
|
||||||
{
|
{
|
||||||
struct wpa_ssid *ssid;
|
struct wpa_ssid *ssid;
|
||||||
int other_iface_found = 0;
|
int other_iface_found = 0;
|
||||||
|
@ -6999,6 +7002,11 @@ static int wpas_start_p2p_client(struct wpa_supplicant *wpa_s,
|
||||||
if (params->passphrase)
|
if (params->passphrase)
|
||||||
ssid->passphrase = os_strdup(params->passphrase);
|
ssid->passphrase = os_strdup(params->passphrase);
|
||||||
|
|
||||||
|
if (go_bssid) {
|
||||||
|
ssid->bssid_set = 1;
|
||||||
|
os_memcpy(ssid->bssid, go_bssid, ETH_ALEN);
|
||||||
|
}
|
||||||
|
|
||||||
wpa_s->show_group_started = 1;
|
wpa_s->show_group_started = 1;
|
||||||
wpa_s->p2p_in_invitation = 1;
|
wpa_s->p2p_in_invitation = 1;
|
||||||
wpa_s->p2p_retry_limit = retry_limit;
|
wpa_s->p2p_retry_limit = retry_limit;
|
||||||
|
@ -7045,7 +7053,8 @@ int wpas_p2p_group_add_persistent(struct wpa_supplicant *wpa_s,
|
||||||
int edmg,
|
int edmg,
|
||||||
const struct p2p_channels *channels,
|
const struct p2p_channels *channels,
|
||||||
int connection_timeout, int force_scan,
|
int connection_timeout, int force_scan,
|
||||||
bool allow_6ghz, int retry_limit)
|
bool allow_6ghz, int retry_limit,
|
||||||
|
const u8 *go_bssid)
|
||||||
{
|
{
|
||||||
struct p2p_go_neg_results params;
|
struct p2p_go_neg_results params;
|
||||||
int go = 0, freq;
|
int go = 0, freq;
|
||||||
|
@ -7113,7 +7122,7 @@ int wpas_p2p_group_add_persistent(struct wpa_supplicant *wpa_s,
|
||||||
}
|
}
|
||||||
|
|
||||||
return wpas_start_p2p_client(wpa_s, ssid, addr_allocated, freq,
|
return wpas_start_p2p_client(wpa_s, ssid, addr_allocated, freq,
|
||||||
force_scan, retry_limit);
|
force_scan, retry_limit, go_bssid);
|
||||||
} else {
|
} else {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
|
@ -52,7 +52,8 @@ int wpas_p2p_group_add_persistent(struct wpa_supplicant *wpa_s,
|
||||||
int max_oper_chwidth, int he, int edmg,
|
int max_oper_chwidth, int he, int edmg,
|
||||||
const struct p2p_channels *channels,
|
const struct p2p_channels *channels,
|
||||||
int connection_timeout, int force_scan,
|
int connection_timeout, int force_scan,
|
||||||
bool allow_6ghz, int retry_limit);
|
bool allow_6ghz, int retry_limit,
|
||||||
|
const u8 *go_bssid);
|
||||||
struct p2p_group * wpas_p2p_group_init(struct wpa_supplicant *wpa_s,
|
struct p2p_group * wpas_p2p_group_init(struct wpa_supplicant *wpa_s,
|
||||||
struct wpa_ssid *ssid);
|
struct wpa_ssid *ssid);
|
||||||
enum wpas_p2p_prov_disc_use {
|
enum wpas_p2p_prov_disc_use {
|
||||||
|
|
|
@ -445,11 +445,43 @@ static void wpa_supplicant_optimize_freqs(
|
||||||
}
|
}
|
||||||
|
|
||||||
if (params->freqs == NULL && wpa_s->p2p_in_invitation) {
|
if (params->freqs == NULL && wpa_s->p2p_in_invitation) {
|
||||||
|
struct wpa_ssid *ssid = wpa_s->current_ssid;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Perform a single-channel scan if the GO has already been
|
||||||
|
* discovered on another non-P2P interface. Note that a scan
|
||||||
|
* initiated by a P2P interface (e.g., the device interface)
|
||||||
|
* should already have sufficient IEs and scan results will be
|
||||||
|
* fetched on interface creation in that case.
|
||||||
|
*/
|
||||||
|
if (wpa_s->p2p_in_invitation == 1 && ssid) {
|
||||||
|
struct wpa_supplicant *ifs;
|
||||||
|
struct wpa_bss *bss = NULL;
|
||||||
|
const u8 *bssid = ssid->bssid_set ? ssid->bssid : NULL;
|
||||||
|
|
||||||
|
dl_list_for_each(ifs, &wpa_s->radio->ifaces,
|
||||||
|
struct wpa_supplicant, radio_list) {
|
||||||
|
bss = wpa_bss_get(ifs, bssid, ssid->ssid,
|
||||||
|
ssid->ssid_len);
|
||||||
|
if (bss)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (bss && !disabled_freq(wpa_s, bss->freq)) {
|
||||||
|
params->freqs = os_calloc(2, sizeof(int));
|
||||||
|
if (params->freqs) {
|
||||||
|
wpa_dbg(wpa_s, MSG_DEBUG,
|
||||||
|
"P2P: Scan only the known GO frequency %d MHz during invitation",
|
||||||
|
bss->freq);
|
||||||
|
params->freqs[0] = bss->freq;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Optimize scan based on GO information during persistent
|
* Optimize scan based on GO information during persistent
|
||||||
* group reinvocation
|
* group reinvocation
|
||||||
*/
|
*/
|
||||||
if (wpa_s->p2p_in_invitation < 5 &&
|
if (!params->freqs && wpa_s->p2p_in_invitation < 5 &&
|
||||||
wpa_s->p2p_invite_go_freq > 0) {
|
wpa_s->p2p_invite_go_freq > 0) {
|
||||||
if (wpa_s->p2p_invite_go_freq == 2 ||
|
if (wpa_s->p2p_invite_go_freq == 2 ||
|
||||||
wpa_s->p2p_invite_go_freq == 5) {
|
wpa_s->p2p_invite_go_freq == 5) {
|
||||||
|
|
|
@ -1826,6 +1826,7 @@ int get_shared_radio_freqs_data(struct wpa_supplicant *wpa_s,
|
||||||
int get_shared_radio_freqs(struct wpa_supplicant *wpa_s,
|
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);
|
bool exclude_current);
|
||||||
|
int disabled_freq(struct wpa_supplicant *wpa_s, int freq);
|
||||||
|
|
||||||
void wpas_network_reenabled(void *eloop_ctx, void *timeout_ctx);
|
void wpas_network_reenabled(void *eloop_ctx, void *timeout_ctx);
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue