P2P: Require fresh scan results for persistent group re-invocation

The P2P group is not yet operating when going through invitation
exchange for re-invocation. Previously, an old cached scan result could
be used to skip the scan immediately after the invitation exchange.
While this may result in the fastest possible connection, it does have
some issues with cases where the GO takes some time to start up. It
would also be at least theoretically possible for some of the BSS
parameters to be different, so having a fresh scan result from the new
GO instance may be desired in any case.

Add a mechanism to skip scan results that have been last updated before
a specific point in time and as the first user for this mechanism,
require chan results to be more recent than the invitation message
exchange for the P2P Client role in persistent group re-invocation case.

Signed-off-by: Jouni Malinen <jouni@qca.qualcomm.com>
This commit is contained in:
Jouni Malinen 2015-08-21 18:28:28 +03:00 committed by Jouni Malinen
parent 8493fe3457
commit dfaf11d648
6 changed files with 33 additions and 10 deletions

View file

@ -2744,6 +2744,8 @@ static int wpa_supplicant_ctrl_iface_select_network(
} }
} }
wpa_s->scan_min_time.sec = 0;
wpa_s->scan_min_time.usec = 0;
wpa_supplicant_select_network(wpa_s, ssid); wpa_supplicant_select_network(wpa_s, ssid);
return 0; return 0;
@ -2781,6 +2783,8 @@ static int wpa_supplicant_ctrl_iface_enable_network(
return 0; return 0;
} }
} }
wpa_s->scan_min_time.sec = 0;
wpa_s->scan_min_time.usec = 0;
wpa_supplicant_enable_network(wpa_s, ssid); wpa_supplicant_enable_network(wpa_s, ssid);
return 0; return 0;
@ -5599,7 +5603,7 @@ static int p2p_ctrl_group_add_persistent(struct wpa_supplicant *wpa_s,
} }
return wpas_p2p_group_add_persistent(wpa_s, ssid, 0, freq, 0, ht40, vht, return wpas_p2p_group_add_persistent(wpa_s, ssid, 0, freq, 0, ht40, vht,
NULL, 0); NULL, 0, 0);
} }

View file

@ -364,7 +364,7 @@ DBusMessage * wpas_dbus_handler_p2p_group_add(DBusMessage *message,
goto inv_args; goto inv_args;
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,
NULL, 0)) { NULL, 0, 0)) {
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");

View file

@ -1036,6 +1036,19 @@ static struct wpa_ssid * wpa_scan_res_match(struct wpa_supplicant *wpa_s,
*/ */
#endif /* CONFIG_P2P */ #endif /* CONFIG_P2P */
if (os_reltime_before(&bss->last_update, &wpa_s->scan_min_time))
{
struct os_reltime diff;
os_reltime_sub(&wpa_s->scan_min_time,
&bss->last_update, &diff);
wpa_dbg(wpa_s, MSG_DEBUG,
" skip - scan result not recent enough (%u.%06u seconds too old)",
(unsigned int) diff.sec,
(unsigned int) diff.usec);
continue;
}
/* Matching configuration found */ /* Matching configuration found */
return ssid; return ssid;
} }

View file

@ -2890,7 +2890,8 @@ static void wpas_invitation_received(void *ctx, const u8 *sa, const u8 *bssid,
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, op_freq, 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,
1);
} else if (bssid) { } else if (bssid) {
wpa_s->user_initiated_pd = 0; wpa_s->user_initiated_pd = 0;
wpas_p2p_join(wpa_s, bssid, go_dev_addr, wpas_p2p_join(wpa_s, bssid, go_dev_addr,
@ -3077,7 +3078,7 @@ static void wpas_invitation_result(void *ctx, int status, const u8 *bssid,
channels, channels,
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); 0, 1);
} }
@ -3924,7 +3925,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, 0);
} else if (response_done) { } else if (response_done) {
wpas_p2p_group_add(wpa_s, 1, 0, 0, 0); wpas_p2p_group_add(wpa_s, 1, 0, 0, 0);
} }
@ -4029,7 +4030,7 @@ static int wpas_prov_disc_resp_cb(void *ctx)
wpas_p2p_group_add_persistent( wpas_p2p_group_add_persistent(
wpa_s, persistent_go, 0, 0, 0, 0, 0, NULL, wpa_s, persistent_go, 0, 0, 0, 0, 0, NULL,
persistent_go->mode == WPAS_MODE_P2P_GO ? persistent_go->mode == WPAS_MODE_P2P_GO ?
P2P_MAX_INITIAL_CONN_WAIT_GO_REINVOKE : 0); P2P_MAX_INITIAL_CONN_WAIT_GO_REINVOKE : 0, 0);
} else { } else {
wpas_p2p_group_add(wpa_s, 1, 0, 0, 0); wpas_p2p_group_add(wpa_s, 1, 0, 0, 0);
} }
@ -5793,13 +5794,15 @@ 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 freq, int force_scan)
{ {
struct wpa_ssid *ssid; struct wpa_ssid *ssid;
wpa_s = wpas_p2p_get_group_iface(wpa_s, addr_allocated, 0); wpa_s = wpas_p2p_get_group_iface(wpa_s, addr_allocated, 0);
if (wpa_s == NULL) if (wpa_s == NULL)
return -1; return -1;
if (force_scan)
os_get_reltime(&wpa_s->scan_min_time);
wpa_s->p2p_last_4way_hs_fail = NULL; wpa_s->p2p_last_4way_hs_fail = NULL;
wpa_supplicant_ap_deinit(wpa_s); wpa_supplicant_ap_deinit(wpa_s);
@ -5849,7 +5852,7 @@ int wpas_p2p_group_add_persistent(struct wpa_supplicant *wpa_s,
struct wpa_ssid *ssid, int addr_allocated, struct wpa_ssid *ssid, int addr_allocated,
int force_freq, int neg_freq, int ht40, int force_freq, int neg_freq, int ht40,
int vht, const struct p2p_channels *channels, int vht, const struct p2p_channels *channels,
int connection_timeout) int connection_timeout, int force_scan)
{ {
struct p2p_go_neg_results params; struct p2p_go_neg_results params;
int go = 0, freq; int go = 0, freq;
@ -5916,7 +5919,8 @@ int wpas_p2p_group_add_persistent(struct wpa_supplicant *wpa_s,
freq = 0; freq = 0;
} }
return wpas_start_p2p_client(wpa_s, ssid, addr_allocated, freq); return wpas_start_p2p_client(wpa_s, ssid, addr_allocated, freq,
force_scan);
} else { } else {
return -1; return -1;
} }

View file

@ -45,7 +45,7 @@ int wpas_p2p_group_add_persistent(struct wpa_supplicant *wpa_s,
struct wpa_ssid *ssid, int addr_allocated, struct wpa_ssid *ssid, int addr_allocated,
int force_freq, int neg_freq, int ht40, int force_freq, int neg_freq, int ht40,
int vht, const struct p2p_channels *channels, int vht, const struct p2p_channels *channels,
int connection_timeout); int connection_timeout, int force_scan);
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 {

View file

@ -593,6 +593,8 @@ struct wpa_supplicant {
} scan_req, last_scan_req; } scan_req, last_scan_req;
enum wpa_states scan_prev_wpa_state; enum wpa_states scan_prev_wpa_state;
struct os_reltime scan_trigger_time, scan_start_time; struct os_reltime scan_trigger_time, scan_start_time;
/* Minimum freshness requirement for connection purposes */
struct os_reltime scan_min_time;
int scan_runs; /* number of scan runs since WPS was started */ int scan_runs; /* number of scan runs since WPS was started */
int *next_scan_freqs; int *next_scan_freqs;
int *manual_scan_freqs; int *manual_scan_freqs;