Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(173)

Unified Diff: wpa_supplicant/events.c

Issue 6538036: CHROMIUMOS: wpa_supplicant: add fast reconnect support (Closed) Base URL: ssh://git@gitrw.chromium.org:9222/hostap.git@master
Patch Set: review comments Created 9 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « no previous file | wpa_supplicant/wpa_supplicant_i.h » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: wpa_supplicant/events.c
diff --git a/wpa_supplicant/events.c b/wpa_supplicant/events.c
index 85f7558d414529355c7ef4a9f2c8de312fb2afd8..1499378b4624d1cdc7e24ed9d73b38b4ce7f1616 100644
--- a/wpa_supplicant/events.c
+++ b/wpa_supplicant/events.c
@@ -884,9 +884,13 @@ static void wpa_supplicant_event_scan_results(struct wpa_supplicant *wpa_s,
struct wpa_bss *selected;
struct wpa_ssid *ssid = NULL;
struct wpa_scan_results *scan_res;
+ int was_fast_reconnect;
wpa_supplicant_notify_scanning(wpa_s, 0);
+ was_fast_reconnect = wpa_s->fast_reconnect;
+ wpa_s->fast_reconnect = FALSE;
+
scan_res = wpa_supplicant_get_scan_results(wpa_s,
data ? &data->scan_info :
NULL, 1);
@@ -950,6 +954,14 @@ static void wpa_supplicant_event_scan_results(struct wpa_supplicant *wpa_s,
if (skip)
return;
wpa_supplicant_connect(wpa_s, selected, ssid);
+ } else if (was_fast_reconnect) {
+ /*
+ * Processed deferred disassoc work on a failed
+ * fast reconnect.
+ */
+ wpa_printf(MSG_INFO, "Fast reconnect failed");
+ wpa_scan_results_free(scan_res);
+ wpa_supplicant_mark_disassoc(wpa_s);
} else {
wpa_scan_results_free(scan_res);
wpa_printf(MSG_DEBUG, "No suitable network found");
@@ -1245,10 +1257,47 @@ static void wpa_supplicant_event_assoc(struct wpa_supplicant *wpa_s,
}
+/*
+ * Try to return to the same AP immediately. Directly scan
+ * on the current channel for the current BSSID and try to
+ * reassociate. If the station is not present we will clock
+ * the state machine to DISCONNECTED in wpa_supplicant_event_scan_results
+ * which will notify external agents.
+ */
+static int wpa_supplicant_fast_reconnect(struct wpa_supplicant *wpa_s,
+ const u8 *bssid)
+{
+ struct wpa_driver_scan_params params;
+ int freqs[2];
+
+ wpa_s->reassociate = 1;
+ wpa_s->fast_reconnect = 1;
+
+ os_memset(&params, 0, sizeof(params));
+ params.num_ssids = 1;
+ params.ssids[0].ssid = wpa_s->current_ssid->ssid;
+ params.ssids[0].ssid_len = wpa_s->current_ssid->ssid_len;
+ freqs[0] = wpa_s->assoc_freq;
+ freqs[1] = 0;
+ params.freqs = freqs;
+
+ wpa_msg(wpa_s, MSG_INFO, "Fast reconnect bssid=" MACSTR
+ " ssid=%.*s freq=%d", MAC2STR(bssid),
+ params.ssids[0].ssid_len, params.ssids[0].ssid,
+ params.freqs[0]);
+
+ bgscan_deinit(wpa_s);
Paul Stewart 2011/02/22 21:56:25 Nit: Any reason why instead of adding these two li
+ wpa_s->bgscan_ssid = NULL;
+
+ return wpa_supplicant_trigger_scan(wpa_s, &params);
+}
+
+
static void wpa_supplicant_event_disassoc(struct wpa_supplicant *wpa_s,
u16 reason_code)
{
const u8 *bssid;
+ int fast_reconnect;
#ifdef CONFIG_SME
int authenticating;
u8 prev_pending_bssid[ETH_ALEN];
@@ -1273,18 +1322,29 @@ static void wpa_supplicant_event_disassoc(struct wpa_supplicant *wpa_s,
wpa_msg(wpa_s, MSG_INFO, "WPA: 4-Way Handshake failed - "
"pre-shared key may be incorrect");
}
- if (wpa_s->wpa_state >= WPA_ASSOCIATING)
- wpa_supplicant_req_scan(wpa_s, 0, 100000);
- bssid = wpa_s->bssid;
- if (is_zero_ether_addr(bssid))
- bssid = wpa_s->pending_bssid;
/*
- * Don't blacklist the AP on normal/expected disconnects.
+ * If in a COMPLETED state and we were dropped for a reason
+ * we can directly recover from directly re-join the AP without
+ * clocking the state machine and/or notifying external agents.
+ *
+ * TODO(sleffler) guard against looping (should be only if AP is busted)
*/
- if (reason_code != WLAN_REASON_DISASSOC_DUE_TO_INACTIVITY &&
- reason_code != WLAN_REASON_CLASS2_FRAME_FROM_NONAUTH_STA &&
- reason_code != WLAN_REASON_CLASS3_FRAME_FROM_NONASSOC_STA)
+ fast_reconnect =
+ wpa_s->wpa_state == WPA_COMPLETED &&
+ (reason_code == WLAN_REASON_DISASSOC_DUE_TO_INACTIVITY ||
+ reason_code == WLAN_REASON_CLASS2_FRAME_FROM_NONAUTH_STA ||
+ reason_code == WLAN_REASON_CLASS3_FRAME_FROM_NONASSOC_STA);
+ bssid = wpa_s->bssid;
+ if (is_zero_ether_addr(bssid)) {
+ bssid = wpa_s->pending_bssid;
+ fast_reconnect = FALSE; /* XXX can this happen? */
+ wpa_printf(MSG_DEBUG, "Do not reconnect; pending bssid switch");
+ }
+ if (!fast_reconnect) {
+ if (wpa_s->wpa_state >= WPA_ASSOCIATING)
+ wpa_supplicant_req_scan(wpa_s, 0, 100000);
wpa_blacklist_add(wpa_s, bssid);
+ }
wpa_sm_notify_disassoc(wpa_s->wpa);
wpa_msg(wpa_s, MSG_INFO, WPA_EVENT_DISCONNECTED "bssid=" MACSTR
" reason=%d",
@@ -1294,6 +1354,13 @@ static void wpa_supplicant_event_disassoc(struct wpa_supplicant *wpa_s,
wpa_s->keys_cleared = 0;
wpa_clear_keys(wpa_s, wpa_s->bssid);
}
+ if (fast_reconnect) {
+ if (wpa_supplicant_fast_reconnect(wpa_s, bssid) == 0)
+ return;
+ /* NB: fall through to slow path */
+ wpa_printf(MSG_DEBUG, "Fast reconnect: Failed to trigger scan");
+ wpa_supplicant_req_scan(wpa_s, 0, 100000);
+ }
wpa_supplicant_mark_disassoc(wpa_s);
bgscan_deinit(wpa_s);
wpa_s->bgscan_ssid = NULL;
« no previous file with comments | « no previous file | wpa_supplicant/wpa_supplicant_i.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698