]> git.ipfire.org Git - thirdparty/hostap.git/commitdiff
P2P: Require fresh scan results for persistent group re-invocation
authorJouni Malinen <jouni@qca.qualcomm.com>
Fri, 21 Aug 2015 15:28:28 +0000 (18:28 +0300)
committerJouni Malinen <j@w1.fi>
Fri, 21 Aug 2015 21:22:12 +0000 (00:22 +0300)
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>
wpa_supplicant/ctrl_iface.c
wpa_supplicant/dbus/dbus_new_handlers_p2p.c
wpa_supplicant/events.c
wpa_supplicant/p2p_supplicant.c
wpa_supplicant/p2p_supplicant.h
wpa_supplicant/wpa_supplicant_i.h

index e1f194f420fcb3c7fc86306c9fd8ca3ef426c85c..4d4d51ad366a2afb3309c9593c89086a27113c9b 100644 (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);
 
        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);
 }
 
 
index e9d60df2c1095c8f9542bceba3acfe630c0e3e81..ef07107d441f70bdbf4e64ad6849a08766eb7a75 100644 (file)
@@ -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");
index d95e06635548e38b672a2e4eb12d9bacdce77998..4f082d2a9832c7d95490a79dfca2d3d965258820 100644 (file)
@@ -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;
        }
index 3fa2c4349deecf36851848ca09b2f50003b3805f..2633ccaf2b0e2dcc3f15592f830cff57513c2848 100644 (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;
                        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;
        }
index f622c2849b6ed4f3652951b6ac63ab93642d2840..56e683498d66f60738d64adeff492ee2a139f237 100644 (file)
@@ -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 {
index 421f77fb2b157cd9c24b847f173a21b1360380e6..58df48c548ea592c0d1bb34ec38a2dcc11a8ea49 100644 (file)
@@ -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;