From dfaf11d648fb131237dfe1df80d8537d5cce92fb Mon Sep 17 00:00:00 2001 From: Jouni Malinen Date: Fri, 21 Aug 2015 18:28:28 +0300 Subject: [PATCH] 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 --- wpa_supplicant/ctrl_iface.c | 6 +++++- wpa_supplicant/dbus/dbus_new_handlers_p2p.c | 2 +- wpa_supplicant/events.c | 13 +++++++++++++ wpa_supplicant/p2p_supplicant.c | 18 +++++++++++------- wpa_supplicant/p2p_supplicant.h | 2 +- wpa_supplicant/wpa_supplicant_i.h | 2 ++ 6 files changed, 33 insertions(+), 10 deletions(-) diff --git a/wpa_supplicant/ctrl_iface.c b/wpa_supplicant/ctrl_iface.c index e1f194f42..4d4d51ad3 100644 --- a/wpa_supplicant/ctrl_iface.c +++ b/wpa_supplicant/ctrl_iface.c @@ -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); return 0; @@ -2781,6 +2783,8 @@ static int wpa_supplicant_ctrl_iface_enable_network( return 0; } } + wpa_s->scan_min_time.sec = 0; + wpa_s->scan_min_time.usec = 0; wpa_supplicant_enable_network(wpa_s, ssid); 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, - NULL, 0); + NULL, 0, 0); } diff --git a/wpa_supplicant/dbus/dbus_new_handlers_p2p.c b/wpa_supplicant/dbus/dbus_new_handlers_p2p.c index e9d60df2c..ef07107d4 100644 --- a/wpa_supplicant/dbus/dbus_new_handlers_p2p.c +++ b/wpa_supplicant/dbus/dbus_new_handlers_p2p.c @@ -364,7 +364,7 @@ DBusMessage * wpas_dbus_handler_p2p_group_add(DBusMessage *message, goto inv_args; 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( message, "Failed to reinvoke a persistent group"); diff --git a/wpa_supplicant/events.c b/wpa_supplicant/events.c index d95e06635..4f082d2a9 100644 --- a/wpa_supplicant/events.c +++ b/wpa_supplicant/events.c @@ -1036,6 +1036,19 @@ static struct wpa_ssid * wpa_scan_res_match(struct wpa_supplicant *wpa_s, */ #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 */ return ssid; } diff --git a/wpa_supplicant/p2p_supplicant.c b/wpa_supplicant/p2p_supplicant.c index 3fa2c4349..2633ccaf2 100644 --- a/wpa_supplicant/p2p_supplicant.c +++ b/wpa_supplicant/p2p_supplicant.c @@ -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; wpas_p2p_group_add_persistent( 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) { wpa_s->user_initiated_pd = 0; 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, ssid->mode == WPAS_MODE_P2P_GO ? 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 == WPAS_MODE_P2P_GO ? P2P_MAX_INITIAL_CONN_WAIT_GO_REINVOKE : - 0); + 0, 0); } else if (response_done) { 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( wpa_s, persistent_go, 0, 0, 0, 0, 0, NULL, 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 { 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, struct wpa_ssid *params, int addr_allocated, - int freq) + int freq, int force_scan) { struct wpa_ssid *ssid; wpa_s = wpas_p2p_get_group_iface(wpa_s, addr_allocated, 0); if (wpa_s == NULL) return -1; + if (force_scan) + os_get_reltime(&wpa_s->scan_min_time); wpa_s->p2p_last_4way_hs_fail = NULL; 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, int force_freq, int neg_freq, int ht40, int vht, const struct p2p_channels *channels, - int connection_timeout) + int connection_timeout, int force_scan) { struct p2p_go_neg_results params; int go = 0, freq; @@ -5916,7 +5919,8 @@ int wpas_p2p_group_add_persistent(struct wpa_supplicant *wpa_s, 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 { return -1; } diff --git a/wpa_supplicant/p2p_supplicant.h b/wpa_supplicant/p2p_supplicant.h index f622c2849..56e683498 100644 --- a/wpa_supplicant/p2p_supplicant.h +++ b/wpa_supplicant/p2p_supplicant.h @@ -45,7 +45,7 @@ int wpas_p2p_group_add_persistent(struct wpa_supplicant *wpa_s, struct wpa_ssid *ssid, int addr_allocated, int force_freq, int neg_freq, int ht40, 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 wpa_ssid *ssid); enum wpas_p2p_prov_disc_use { diff --git a/wpa_supplicant/wpa_supplicant_i.h b/wpa_supplicant/wpa_supplicant_i.h index 421f77fb2..58df48c54 100644 --- a/wpa_supplicant/wpa_supplicant_i.h +++ b/wpa_supplicant/wpa_supplicant_i.h @@ -593,6 +593,8 @@ struct wpa_supplicant { } scan_req, last_scan_req; enum wpa_states scan_prev_wpa_state; 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 *next_scan_freqs; int *manual_scan_freqs;