P2P: Optimize scan for GO during persistent group invocation
Scan for GO on the negotiated operating channel for few iterations before searching on all the supported channels during persistent group reinvocation. In addition, use the already known SSID of the group in the scans. These optimizations reduce group formation time. Signed-off-by: Jouni Malinen <jouni@qca.qualcomm.com>
This commit is contained in:
parent
406739c499
commit
41d5ce9e0b
7 changed files with 90 additions and 16 deletions
|
@ -3310,7 +3310,7 @@ static void p2p_timeout_invite_listen(struct p2p_data *p2p)
|
||||||
p2p->cfg->invitation_result(
|
p2p->cfg->invitation_result(
|
||||||
p2p->cfg->cb_ctx, -1, NULL, NULL,
|
p2p->cfg->cb_ctx, -1, NULL, NULL,
|
||||||
p2p->invite_peer->info.p2p_device_addr,
|
p2p->invite_peer->info.p2p_device_addr,
|
||||||
0);
|
0, 0);
|
||||||
}
|
}
|
||||||
p2p_set_state(p2p, P2P_IDLE);
|
p2p_set_state(p2p, P2P_IDLE);
|
||||||
}
|
}
|
||||||
|
|
|
@ -764,6 +764,8 @@ struct p2p_config {
|
||||||
* @channels: Available operating channels for the group
|
* @channels: Available operating channels for the group
|
||||||
* @addr: Peer address
|
* @addr: Peer address
|
||||||
* @freq: Frequency (in MHz) indicated during invitation or 0
|
* @freq: Frequency (in MHz) indicated during invitation or 0
|
||||||
|
* @peer_oper_freq: Operating frequency (in MHz) advertized by the peer
|
||||||
|
* during invitation or 0
|
||||||
*
|
*
|
||||||
* This callback is used to indicate result of an Invitation procedure
|
* This callback is used to indicate result of an Invitation procedure
|
||||||
* started with a call to p2p_invite(). The indicated status code is
|
* started with a call to p2p_invite(). The indicated status code is
|
||||||
|
@ -773,7 +775,7 @@ struct p2p_config {
|
||||||
*/
|
*/
|
||||||
void (*invitation_result)(void *ctx, int status, const u8 *bssid,
|
void (*invitation_result)(void *ctx, int status, const u8 *bssid,
|
||||||
const struct p2p_channels *channels,
|
const struct p2p_channels *channels,
|
||||||
const u8 *addr, int freq);
|
const u8 *addr, int freq, int peer_oper_freq);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* go_connected - Check whether we are connected to a GO
|
* go_connected - Check whether we are connected to a GO
|
||||||
|
|
|
@ -288,7 +288,9 @@ void p2p_process_invitation_req(struct p2p_data *p2p, const u8 *sa,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!p2p_channels_includes(&intersection, p2p->op_reg_class,
|
/* Reselect the channel only for the case of the GO */
|
||||||
|
if (go &&
|
||||||
|
!p2p_channels_includes(&intersection, p2p->op_reg_class,
|
||||||
p2p->op_channel)) {
|
p2p->op_channel)) {
|
||||||
p2p_dbg(p2p, "Initially selected channel (op_class %d channel %d) not in channel intersection - try to reselect",
|
p2p_dbg(p2p, "Initially selected channel (op_class %d channel %d) not in channel intersection - try to reselect",
|
||||||
p2p->op_reg_class, p2p->op_channel);
|
p2p->op_reg_class, p2p->op_channel);
|
||||||
|
@ -303,7 +305,7 @@ void p2p_process_invitation_req(struct p2p_data *p2p, const u8 *sa,
|
||||||
status = P2P_SC_FAIL_NO_COMMON_CHANNELS;
|
status = P2P_SC_FAIL_NO_COMMON_CHANNELS;
|
||||||
goto fail;
|
goto fail;
|
||||||
}
|
}
|
||||||
} else if (!(dev->flags & P2P_DEV_FORCE_FREQ) &&
|
} else if (go && !(dev->flags & P2P_DEV_FORCE_FREQ) &&
|
||||||
!p2p->cfg->cfg_op_channel) {
|
!p2p->cfg->cfg_op_channel) {
|
||||||
p2p_dbg(p2p, "Try to reselect channel selection with peer information received; previously selected op_class %u channel %u",
|
p2p_dbg(p2p, "Try to reselect channel selection with peer information received; previously selected op_class %u channel %u",
|
||||||
p2p->op_reg_class, p2p->op_channel);
|
p2p->op_reg_class, p2p->op_channel);
|
||||||
|
@ -444,13 +446,23 @@ void p2p_process_invitation_resp(struct p2p_data *p2p, const u8 *sa,
|
||||||
}
|
}
|
||||||
|
|
||||||
if (p2p->cfg->invitation_result) {
|
if (p2p->cfg->invitation_result) {
|
||||||
|
int peer_oper_freq = 0;
|
||||||
int freq = p2p_channel_to_freq(p2p->op_reg_class,
|
int freq = p2p_channel_to_freq(p2p->op_reg_class,
|
||||||
p2p->op_channel);
|
p2p->op_channel);
|
||||||
if (freq < 0)
|
if (freq < 0)
|
||||||
freq = 0;
|
freq = 0;
|
||||||
|
|
||||||
|
if (msg.operating_channel) {
|
||||||
|
peer_oper_freq = p2p_channel_to_freq(
|
||||||
|
msg.operating_channel[3],
|
||||||
|
msg.operating_channel[4]);
|
||||||
|
if (peer_oper_freq < 0)
|
||||||
|
peer_oper_freq = 0;
|
||||||
|
}
|
||||||
|
|
||||||
p2p->cfg->invitation_result(p2p->cfg->cb_ctx, *msg.status,
|
p2p->cfg->invitation_result(p2p->cfg->cb_ctx, *msg.status,
|
||||||
msg.group_bssid, channels, sa,
|
msg.group_bssid, channels, sa,
|
||||||
freq);
|
freq, peer_oper_freq);
|
||||||
}
|
}
|
||||||
|
|
||||||
p2p_parse_free(&msg);
|
p2p_parse_free(&msg);
|
||||||
|
|
|
@ -1430,7 +1430,8 @@ static int wpas_select_network_from_last_scan(struct wpa_supplicant *wpa_s,
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
if (wpa_s->p2p_in_provisioning ||
|
if (wpa_s->p2p_in_provisioning ||
|
||||||
wpa_s->show_group_started) {
|
wpa_s->show_group_started ||
|
||||||
|
wpa_s->p2p_in_invitation) {
|
||||||
/*
|
/*
|
||||||
* Use shorter wait during P2P Provisioning
|
* Use shorter wait during P2P Provisioning
|
||||||
* state and during P2P join-a-group operation
|
* state and during P2P join-a-group operation
|
||||||
|
|
|
@ -501,6 +501,8 @@ static int wpas_p2p_group_delete(struct wpa_supplicant *wpa_s,
|
||||||
wpa_s->p2p_in_provisioning = 0;
|
wpa_s->p2p_in_provisioning = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
wpa_s->p2p_in_invitation = 0;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Make sure wait for the first client does not remain active after the
|
* Make sure wait for the first client does not remain active after the
|
||||||
* group has been removed.
|
* group has been removed.
|
||||||
|
@ -3070,7 +3072,7 @@ static void wpas_invitation_received(void *ctx, const u8 *sa, const u8 *bssid,
|
||||||
if (s) {
|
if (s) {
|
||||||
int go = s->mode == WPAS_MODE_P2P_GO;
|
int go = s->mode == WPAS_MODE_P2P_GO;
|
||||||
wpas_p2p_group_add_persistent(
|
wpas_p2p_group_add_persistent(
|
||||||
wpa_s, s, go, 0, go ? op_freq : 0, 0, 0, NULL,
|
wpa_s, s, go, 0, op_freq, 0, 0, NULL,
|
||||||
go ? P2P_MAX_INITIAL_CONN_WAIT_GO_REINVOKE : 0);
|
go ? P2P_MAX_INITIAL_CONN_WAIT_GO_REINVOKE : 0);
|
||||||
} else if (bssid) {
|
} else if (bssid) {
|
||||||
wpa_s->user_initiated_pd = 0;
|
wpa_s->user_initiated_pd = 0;
|
||||||
|
@ -3177,10 +3179,12 @@ static void wpas_remove_persistent_client(struct wpa_supplicant *wpa_s,
|
||||||
|
|
||||||
static void wpas_invitation_result(void *ctx, int status, const u8 *bssid,
|
static void wpas_invitation_result(void *ctx, int status, const u8 *bssid,
|
||||||
const struct p2p_channels *channels,
|
const struct p2p_channels *channels,
|
||||||
const u8 *peer, int neg_freq)
|
const u8 *peer, int neg_freq,
|
||||||
|
int peer_oper_freq)
|
||||||
{
|
{
|
||||||
struct wpa_supplicant *wpa_s = ctx;
|
struct wpa_supplicant *wpa_s = ctx;
|
||||||
struct wpa_ssid *ssid;
|
struct wpa_ssid *ssid;
|
||||||
|
int freq;
|
||||||
|
|
||||||
if (bssid) {
|
if (bssid) {
|
||||||
wpa_msg_global(wpa_s, MSG_INFO, P2P_EVENT_INVITATION_RESULT
|
wpa_msg_global(wpa_s, MSG_INFO, P2P_EVENT_INVITATION_RESULT
|
||||||
|
@ -3236,10 +3240,21 @@ static void wpas_invitation_result(void *ctx, int status, const u8 *bssid,
|
||||||
"starting persistent group");
|
"starting persistent group");
|
||||||
os_sleep(0, 50000);
|
os_sleep(0, 50000);
|
||||||
|
|
||||||
|
if (neg_freq > 0 && ssid->mode == WPAS_MODE_P2P_GO &&
|
||||||
|
freq_included(channels, neg_freq))
|
||||||
|
freq = neg_freq;
|
||||||
|
else if (peer_oper_freq > 0 && ssid->mode != WPAS_MODE_P2P_GO &&
|
||||||
|
freq_included(channels, peer_oper_freq))
|
||||||
|
freq = peer_oper_freq;
|
||||||
|
else
|
||||||
|
freq = 0;
|
||||||
|
|
||||||
|
wpa_printf(MSG_DEBUG, "P2P: Persistent group invitation success - op_freq=%d MHz SSID=%s",
|
||||||
|
freq, wpa_ssid_txt(ssid->ssid, ssid->ssid_len));
|
||||||
wpas_p2p_group_add_persistent(wpa_s, ssid,
|
wpas_p2p_group_add_persistent(wpa_s, ssid,
|
||||||
ssid->mode == WPAS_MODE_P2P_GO,
|
ssid->mode == WPAS_MODE_P2P_GO,
|
||||||
wpa_s->p2p_persistent_go_freq,
|
wpa_s->p2p_persistent_go_freq,
|
||||||
neg_freq,
|
freq,
|
||||||
wpa_s->p2p_go_ht40, wpa_s->p2p_go_vht,
|
wpa_s->p2p_go_ht40, wpa_s->p2p_go_vht,
|
||||||
channels,
|
channels,
|
||||||
ssid->mode == WPAS_MODE_P2P_GO ?
|
ssid->mode == WPAS_MODE_P2P_GO ?
|
||||||
|
@ -5150,7 +5165,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)
|
||||||
{
|
{
|
||||||
struct wpa_ssid *ssid;
|
struct wpa_ssid *ssid;
|
||||||
|
|
||||||
|
@ -5187,6 +5203,8 @@ static int wpas_start_p2p_client(struct wpa_supplicant *wpa_s,
|
||||||
ssid->passphrase = os_strdup(params->passphrase);
|
ssid->passphrase = os_strdup(params->passphrase);
|
||||||
|
|
||||||
wpa_s->show_group_started = 1;
|
wpa_s->show_group_started = 1;
|
||||||
|
wpa_s->p2p_in_invitation = 1;
|
||||||
|
wpa_s->p2p_invite_go_freq = freq;
|
||||||
|
|
||||||
wpa_supplicant_select_network(wpa_s, ssid);
|
wpa_supplicant_select_network(wpa_s, ssid);
|
||||||
|
|
||||||
|
@ -5221,12 +5239,6 @@ int wpas_p2p_group_add_persistent(struct wpa_supplicant *wpa_s,
|
||||||
|
|
||||||
wpa_s->p2p_fallback_to_go_neg = 0;
|
wpa_s->p2p_fallback_to_go_neg = 0;
|
||||||
|
|
||||||
if (ssid->mode == WPAS_MODE_INFRA)
|
|
||||||
return wpas_start_p2p_client(wpa_s, ssid, addr_allocated);
|
|
||||||
|
|
||||||
if (ssid->mode != WPAS_MODE_P2P_GO)
|
|
||||||
return -1;
|
|
||||||
|
|
||||||
if (force_freq > 0) {
|
if (force_freq > 0) {
|
||||||
freq = wpas_p2p_select_go_freq(wpa_s, force_freq);
|
freq = wpas_p2p_select_go_freq(wpa_s, force_freq);
|
||||||
if (freq < 0)
|
if (freq < 0)
|
||||||
|
@ -5237,6 +5249,12 @@ int wpas_p2p_group_add_persistent(struct wpa_supplicant *wpa_s,
|
||||||
freq = 0;
|
freq = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (ssid->mode == WPAS_MODE_INFRA)
|
||||||
|
return wpas_start_p2p_client(wpa_s, ssid, addr_allocated, freq);
|
||||||
|
|
||||||
|
if (ssid->mode != WPAS_MODE_P2P_GO)
|
||||||
|
return -1;
|
||||||
|
|
||||||
if (wpas_p2p_init_go_params(wpa_s, ¶ms, freq, ht40, vht, channels))
|
if (wpas_p2p_init_go_params(wpa_s, ¶ms, freq, ht40, vht, channels))
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
|
|
|
@ -326,6 +326,32 @@ static void wpa_supplicant_optimize_freqs(
|
||||||
}
|
}
|
||||||
wpa_s->p2p_in_provisioning++;
|
wpa_s->p2p_in_provisioning++;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (params->freqs == NULL && wpa_s->p2p_in_invitation) {
|
||||||
|
/*
|
||||||
|
* Optimize scan based on GO information during persistent
|
||||||
|
* group reinvocation
|
||||||
|
*/
|
||||||
|
if (wpa_s->p2p_in_invitation < 5 ||
|
||||||
|
wpa_s->p2p_invite_go_freq > 0) {
|
||||||
|
wpa_dbg(wpa_s, MSG_DEBUG, "P2P: Scan only GO preferred frequency %d MHz during invitation",
|
||||||
|
wpa_s->p2p_invite_go_freq);
|
||||||
|
params->freqs = os_zalloc(2 * sizeof(int));
|
||||||
|
if (params->freqs)
|
||||||
|
params->freqs[0] = wpa_s->p2p_invite_go_freq;
|
||||||
|
}
|
||||||
|
wpa_s->p2p_in_invitation++;
|
||||||
|
if (wpa_s->p2p_in_invitation > 20) {
|
||||||
|
/*
|
||||||
|
* This should not really happen since the variable is
|
||||||
|
* cleared on group removal, but if it does happen, make
|
||||||
|
* sure we do not get stuck in special invitation scan
|
||||||
|
* mode.
|
||||||
|
*/
|
||||||
|
wpa_dbg(wpa_s, MSG_DEBUG, "P2P: Clear p2p_in_invitation");
|
||||||
|
wpa_s->p2p_in_invitation = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
#endif /* CONFIG_P2P */
|
#endif /* CONFIG_P2P */
|
||||||
|
|
||||||
#ifdef CONFIG_WPS
|
#ifdef CONFIG_WPS
|
||||||
|
@ -639,6 +665,19 @@ static void wpa_supplicant_scan(void *eloop_ctx, void *timeout_ctx)
|
||||||
params.num_ssids = 1;
|
params.num_ssids = 1;
|
||||||
goto ssid_list_set;
|
goto ssid_list_set;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (wpa_s->p2p_in_invitation) {
|
||||||
|
if (wpa_s->current_ssid) {
|
||||||
|
wpa_printf(MSG_DEBUG, "P2P: Use specific SSID for scan during invitation");
|
||||||
|
params.ssids[0].ssid = wpa_s->current_ssid->ssid;
|
||||||
|
params.ssids[0].ssid_len =
|
||||||
|
wpa_s->current_ssid->ssid_len;
|
||||||
|
params.num_ssids = 1;
|
||||||
|
} else {
|
||||||
|
wpa_printf(MSG_DEBUG, "P2P: No specific SSID known for scan during invitation");
|
||||||
|
}
|
||||||
|
goto ssid_list_set;
|
||||||
|
}
|
||||||
#endif /* CONFIG_P2P */
|
#endif /* CONFIG_P2P */
|
||||||
|
|
||||||
/* Find the starting point from which to continue scanning */
|
/* Find the starting point from which to continue scanning */
|
||||||
|
|
|
@ -687,6 +687,8 @@ struct wpa_supplicant {
|
||||||
u8 p2p_auth_invite[ETH_ALEN];
|
u8 p2p_auth_invite[ETH_ALEN];
|
||||||
int p2p_sd_over_ctrl_iface;
|
int p2p_sd_over_ctrl_iface;
|
||||||
int p2p_in_provisioning;
|
int p2p_in_provisioning;
|
||||||
|
int p2p_in_invitation;
|
||||||
|
int p2p_invite_go_freq;
|
||||||
int pending_invite_ssid_id;
|
int pending_invite_ssid_id;
|
||||||
int show_group_started;
|
int show_group_started;
|
||||||
u8 go_dev_addr[ETH_ALEN];
|
u8 go_dev_addr[ETH_ALEN];
|
||||||
|
|
Loading…
Reference in a new issue