Patchwork wpa_supplicant: Implement fast-associate on SelectNetwork

login
register
mail settings
Submitter Paul Stewart
Date Jan. 16, 2013, 2:28 a.m.
Message ID <20130116034602.F092220073F@clearcreek.mtv.corp.google.com>
Download mbox | patch
Permalink /patch/212383/
State Superseded
Headers show

Comments

Paul Stewart - Jan. 16, 2013, 2:28 a.m.
If scan results are available when we perform a SelectNetwork, use
them to make an associate decision.  This can save an entire scan
interval-worth of time in situations where something external to
wpa_supplicant (like a connection manager) has just previously
requested a scan before calling SelectNetwork.

Signed-hostap: Paul Stewart <pstew@chromium.org>
---
 wpa_supplicant/events.c           |   32 ++++++++++++++++++++++++++++++++
 wpa_supplicant/wpa_supplicant.c   |    4 +++-
 wpa_supplicant/wpa_supplicant_i.h |    2 ++
 3 files changed, 37 insertions(+), 1 deletions(-)
Jouni Malinen - Jan. 16, 2013, 9:47 a.m.
On Tue, Jan 15, 2013 at 06:28:09PM -0800, Paul Stewart wrote:
> If scan results are available when we perform a SelectNetwork, use
> them to make an associate decision.  This can save an entire scan
> interval-worth of time in situations where something external to
> wpa_supplicant (like a connection manager) has just previously
> requested a scan before calling SelectNetwork.

interworking_reconnect() does this conditionally on how old the previous
scan results are and by re-using the
wpas_select_network_from_last_scan() function. Is there reason to have
SelectNetwork behave differently? In other words, could this new
wpa_supplicant_fast_associate() be replaced with a call to the existing
wpas_select_network_from_last_scan()? I would also consider adding some
time limit based on wpa_s->last_scan. Five seconds may be a bit too
short for this, but using three minutes old results does not sound that
good either.
Paul Stewart - Jan. 16, 2013, 2:59 p.m.
I considered wpas_select_network_from_last_scan(), but I wondered whether
the calls to wpa_supplicant_rsn_preauth_scan_results on old scan results or
everything in the "else" clause for "if (selected)" was valid in this case.
 If you're okay with a hard-coded time limit like interworking_reconnect, I
can do that.  Also let me know if you're unconcerned by any side effects
the rest of wpas_select_network_from_last_scan().


On Wed, Jan 16, 2013 at 1:47 AM, Jouni Malinen <j@w1.fi> wrote:

> On Tue, Jan 15, 2013 at 06:28:09PM -0800, Paul Stewart wrote:
> > If scan results are available when we perform a SelectNetwork, use
> > them to make an associate decision.  This can save an entire scan
> > interval-worth of time in situations where something external to
> > wpa_supplicant (like a connection manager) has just previously
> > requested a scan before calling SelectNetwork.
>
> interworking_reconnect() does this conditionally on how old the previous
> scan results are and by re-using the
> wpas_select_network_from_last_scan() function. Is there reason to have
> SelectNetwork behave differently? In other words, could this new
> wpa_supplicant_fast_associate() be replaced with a call to the existing
> wpas_select_network_from_last_scan()? I would also consider adding some
> time limit based on wpa_s->last_scan. Five seconds may be a bit too
> short for this, but using three minutes old results does not sound that
> good either.
>
> --
> Jouni Malinen                                            PGP id EFC895FA
> _______________________________________________
> HostAP mailing list
> HostAP@lists.shmoo.com
> http://lists.shmoo.com/mailman/listinfo/hostap
>
Jouni Malinen - Jan. 16, 2013, 4:56 p.m.
On Wed, Jan 16, 2013 at 06:59:14AM -0800, Paul Stewart wrote:
> I considered wpas_select_network_from_last_scan(), but I wondered whether
> the calls to wpa_supplicant_rsn_preauth_scan_results on old scan results or
> everything in the "else" clause for "if (selected)" was valid in this case.
>  If you're okay with a hard-coded time limit like interworking_reconnect, I
> can do that.  Also let me know if you're unconcerned by any side effects
> the rest of wpas_select_network_from_last_scan().

If there are undesired side effects from
wpas_select_network_from_last_scan(), those need to be fixed for
Interworking case anyway, so yes, I'd like to see a single mechanism to
be used and any possible issues with it getting resolved. These two
cases are pretty much identical in the sense that both of them may have
run through a scan recently and could re-use information from it. The
Interworking one is guaranteed to have run through a scan, but these can
be handled with the same implementation with the use of that time limit.
The actual time limit value could end up becoming a configurable
parameter in the future, but a hard-coded limit would be fine as an
initial step.
Paul Stewart - Jan. 16, 2013, 5:28 p.m.
The big difference in wpa_supplicant_fast_associate() right now is that it
turns into a no-op if the selected network
(from wpa_supplicant_pick_network()) doesn't match the ssid chosen in
wpa_supplicant_select_network().  It didn't seem right to me for some other
network to be connected if select_network was unambiguous.  It's likely a
non-concern for me, so I'll drop it in a v3.

--
Paul


On Wed, Jan 16, 2013 at 8:56 AM, Jouni Malinen <j@w1.fi> wrote:

> On Wed, Jan 16, 2013 at 06:59:14AM -0800, Paul Stewart wrote:
> > I considered wpas_select_network_from_last_scan(), but I wondered whether
> > the calls to wpa_supplicant_rsn_preauth_scan_results on old scan results
> or
> > everything in the "else" clause for "if (selected)" was valid in this
> case.
> >  If you're okay with a hard-coded time limit like
> interworking_reconnect, I
> > can do that.  Also let me know if you're unconcerned by any side effects
> > the rest of wpas_select_network_from_last_scan().
>
> If there are undesired side effects from
> wpas_select_network_from_last_scan(), those need to be fixed for
> Interworking case anyway, so yes, I'd like to see a single mechanism to
> be used and any possible issues with it getting resolved. These two
> cases are pretty much identical in the sense that both of them may have
> run through a scan recently and could re-use information from it. The
> Interworking one is guaranteed to have run through a scan, but these can
> be handled with the same implementation with the use of that time limit.
> The actual time limit value could end up becoming a configurable
> parameter in the future, but a hard-coded limit would be fine as an
> initial step.
>
> --
> Jouni Malinen                                            PGP id EFC895FA
> _______________________________________________
> HostAP mailing list
> HostAP@lists.shmoo.com
> http://lists.shmoo.com/mailman/listinfo/hostap
>

Patch

diff --git a/wpa_supplicant/events.c b/wpa_supplicant/events.c
index 983f670..494e2f7 100644
--- a/wpa_supplicant/events.c
+++ b/wpa_supplicant/events.c
@@ -1308,6 +1308,38 @@  static void wpa_supplicant_event_scan_results(struct wpa_supplicant *wpa_s,
 #endif /* CONFIG_NO_SCAN_PROCESSING */
 
 
+int wpa_supplicant_fast_associate(struct wpa_supplicant *wpa_s,
+				  struct wpa_ssid *ssid)
+{
+#ifdef CONFIG_NO_SCAN_PROCESSING
+	return -1;
+#else /* CONFIG_NO_SCAN_PROCESSING */
+	struct wpa_bss *selected_bss;
+	struct wpa_ssid *selected_ssid = NULL;
+
+	selected_bss = wpa_supplicant_pick_network(wpa_s, &selected_ssid);
+
+	if (!selected_bss) {
+		wpa_dbg(wpa_s, MSG_DEBUG, "Fast associate: no suitable bss");
+		return -1;
+	}
+
+	if (selected_ssid != ssid) {
+		wpa_dbg(wpa_s, MSG_DEBUG, "Fast associate: ssid mismatch?!");
+		return -1;
+	}
+
+	if (wpa_supplicant_connect(wpa_s, selected_bss, ssid) < 0) {
+		wpa_dbg(wpa_s, MSG_DEBUG, "Fast associate: Connect failed");
+		return -1;
+	}
+
+	wpa_dbg(wpa_s, MSG_DEBUG, "Fast associate: Successful connect!");
+
+	return 0;
+#endif /* CONFIG_NO_SCAN_PROCESSING */
+}
+
 #ifdef CONFIG_WNM
 
 static void wnm_bss_keep_alive(void *eloop_ctx, void *sock_ctx)
diff --git a/wpa_supplicant/wpa_supplicant.c b/wpa_supplicant/wpa_supplicant.c
index 64f5c1b..cf086ab 100644
--- a/wpa_supplicant/wpa_supplicant.c
+++ b/wpa_supplicant/wpa_supplicant.c
@@ -1875,7 +1875,9 @@  void wpa_supplicant_select_network(struct wpa_supplicant *wpa_s,
 	wpa_s->connect_without_scan = NULL;
 	wpa_s->disconnected = 0;
 	wpa_s->reassociate = 1;
-	wpa_supplicant_req_scan(wpa_s, 0, disconnected ? 100000 : 0);
+
+	if (!ssid || wpa_supplicant_fast_associate(wpa_s, ssid) != 0)
+		wpa_supplicant_req_scan(wpa_s, 0, disconnected ? 100000 : 0);
 
 	if (ssid)
 		wpas_notify_network_selected(wpa_s, ssid);
diff --git a/wpa_supplicant/wpa_supplicant_i.h b/wpa_supplicant/wpa_supplicant_i.h
index ecbdedf..6b4e832 100644
--- a/wpa_supplicant/wpa_supplicant_i.h
+++ b/wpa_supplicant/wpa_supplicant_i.h
@@ -786,6 +786,8 @@  void wpa_supplicant_stop_countermeasures(void *eloop_ctx, void *sock_ctx);
 void wpa_supplicant_delayed_mic_error_report(void *eloop_ctx, void *sock_ctx);
 void wnm_bss_keep_alive_deinit(struct wpa_supplicant *wpa_s);
 int wpas_select_network_from_last_scan(struct wpa_supplicant *wpa_s);
+int wpa_supplicant_fast_associate(struct wpa_supplicant *wpa_s,
+				  struct wpa_ssid *ssid);
 
 /* eap_register.c */
 int eap_register_methods(void);