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

Side by Side 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 unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « no previous file | wpa_supplicant/wpa_supplicant_i.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 /* 1 /*
2 * WPA Supplicant - Driver event processing 2 * WPA Supplicant - Driver event processing
3 * Copyright (c) 2003-2010, Jouni Malinen <j@w1.fi> 3 * Copyright (c) 2003-2010, Jouni Malinen <j@w1.fi>
4 * 4 *
5 * This program is free software; you can redistribute it and/or modify 5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License version 2 as 6 * it under the terms of the GNU General Public License version 2 as
7 * published by the Free Software Foundation. 7 * published by the Free Software Foundation.
8 * 8 *
9 * Alternatively, this software may be distributed under the terms of BSD 9 * Alternatively, this software may be distributed under the terms of BSD
10 * license. 10 * license.
(...skipping 866 matching lines...) Expand 10 before | Expand all | Expand 10 after
877 return 1; 877 return 1;
878 } 878 }
879 879
880 880
881 static void wpa_supplicant_event_scan_results(struct wpa_supplicant *wpa_s, 881 static void wpa_supplicant_event_scan_results(struct wpa_supplicant *wpa_s,
882 union wpa_event_data *data) 882 union wpa_event_data *data)
883 { 883 {
884 struct wpa_bss *selected; 884 struct wpa_bss *selected;
885 struct wpa_ssid *ssid = NULL; 885 struct wpa_ssid *ssid = NULL;
886 struct wpa_scan_results *scan_res; 886 struct wpa_scan_results *scan_res;
887 int was_fast_reconnect;
887 888
888 wpa_supplicant_notify_scanning(wpa_s, 0); 889 wpa_supplicant_notify_scanning(wpa_s, 0);
889 890
891 was_fast_reconnect = wpa_s->fast_reconnect;
892 wpa_s->fast_reconnect = FALSE;
893
890 scan_res = wpa_supplicant_get_scan_results(wpa_s, 894 scan_res = wpa_supplicant_get_scan_results(wpa_s,
891 data ? &data->scan_info : 895 data ? &data->scan_info :
892 NULL, 1); 896 NULL, 1);
893 if (scan_res == NULL) { 897 if (scan_res == NULL) {
894 if (wpa_s->conf->ap_scan == 2) 898 if (wpa_s->conf->ap_scan == 2)
895 return; 899 return;
896 wpa_printf(MSG_DEBUG, "Failed to get scan results - try " 900 wpa_printf(MSG_DEBUG, "Failed to get scan results - try "
897 "scanning again"); 901 "scanning again");
898 wpa_supplicant_req_new_scan(wpa_s, 1, 0); 902 wpa_supplicant_req_new_scan(wpa_s, 1, 0);
899 return; 903 return;
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after
943 selected = wpa_supplicant_pick_network(wpa_s, scan_res, &ssid); 947 selected = wpa_supplicant_pick_network(wpa_s, scan_res, &ssid);
944 948
945 if (selected) { 949 if (selected) {
946 int skip; 950 int skip;
947 skip = !wpa_supplicant_need_to_roam(wpa_s, selected, ssid, 951 skip = !wpa_supplicant_need_to_roam(wpa_s, selected, ssid,
948 scan_res); 952 scan_res);
949 wpa_scan_results_free(scan_res); 953 wpa_scan_results_free(scan_res);
950 if (skip) 954 if (skip)
951 return; 955 return;
952 wpa_supplicant_connect(wpa_s, selected, ssid); 956 wpa_supplicant_connect(wpa_s, selected, ssid);
957 } else if (was_fast_reconnect) {
958 /*
959 * Processed deferred disassoc work on a failed
960 * fast reconnect.
961 */
962 wpa_printf(MSG_INFO, "Fast reconnect failed");
963 wpa_scan_results_free(scan_res);
964 wpa_supplicant_mark_disassoc(wpa_s);
953 } else { 965 } else {
954 wpa_scan_results_free(scan_res); 966 wpa_scan_results_free(scan_res);
955 wpa_printf(MSG_DEBUG, "No suitable network found"); 967 wpa_printf(MSG_DEBUG, "No suitable network found");
956 ssid = wpa_supplicant_pick_new_network(wpa_s); 968 ssid = wpa_supplicant_pick_new_network(wpa_s);
957 if (ssid) { 969 if (ssid) {
958 wpa_printf(MSG_DEBUG, "Setup a new network"); 970 wpa_printf(MSG_DEBUG, "Setup a new network");
959 wpa_supplicant_associate(wpa_s, NULL, ssid); 971 wpa_supplicant_associate(wpa_s, NULL, ssid);
960 } else { 972 } else {
961 int timeout_sec = 5; 973 int timeout_sec = 5;
962 int timeout_usec = 0; 974 int timeout_usec = 0;
(...skipping 275 matching lines...) Expand 10 before | Expand all | Expand 10 after
1238 if ((wpa_s->key_mgmt == WPA_KEY_MGMT_NONE || 1250 if ((wpa_s->key_mgmt == WPA_KEY_MGMT_NONE ||
1239 wpa_s->key_mgmt == WPA_KEY_MGMT_IEEE8021X_NO_WPA) && 1251 wpa_s->key_mgmt == WPA_KEY_MGMT_IEEE8021X_NO_WPA) &&
1240 wpa_s->current_ssid && wpa_drv_get_capa(wpa_s, &capa) == 0 && 1252 wpa_s->current_ssid && wpa_drv_get_capa(wpa_s, &capa) == 0 &&
1241 capa.flags & WPA_DRIVER_FLAGS_SET_KEYS_AFTER_ASSOC_DONE) { 1253 capa.flags & WPA_DRIVER_FLAGS_SET_KEYS_AFTER_ASSOC_DONE) {
1242 /* Set static WEP keys again */ 1254 /* Set static WEP keys again */
1243 wpa_set_wep_keys(wpa_s, wpa_s->current_ssid); 1255 wpa_set_wep_keys(wpa_s, wpa_s->current_ssid);
1244 } 1256 }
1245 } 1257 }
1246 1258
1247 1259
1260 /*
1261 * Try to return to the same AP immediately. Directly scan
1262 * on the current channel for the current BSSID and try to
1263 * reassociate. If the station is not present we will clock
1264 * the state machine to DISCONNECTED in wpa_supplicant_event_scan_results
1265 * which will notify external agents.
1266 */
1267 static int wpa_supplicant_fast_reconnect(struct wpa_supplicant *wpa_s,
1268 const u8 *bssid)
1269 {
1270 struct wpa_driver_scan_params params;
1271 int freqs[2];
1272
1273 wpa_s->reassociate = 1;
1274 wpa_s->fast_reconnect = 1;
1275
1276 os_memset(&params, 0, sizeof(params));
1277 params.num_ssids = 1;
1278 params.ssids[0].ssid = wpa_s->current_ssid->ssid;
1279 params.ssids[0].ssid_len = wpa_s->current_ssid->ssid_len;
1280 freqs[0] = wpa_s->assoc_freq;
1281 freqs[1] = 0;
1282 params.freqs = freqs;
1283
1284 wpa_msg(wpa_s, MSG_INFO, "Fast reconnect bssid=" MACSTR
1285 " ssid=%.*s freq=%d", MAC2STR(bssid),
1286 params.ssids[0].ssid_len, params.ssids[0].ssid,
1287 params.freqs[0]);
1288
1289 bgscan_deinit(wpa_s);
Paul Stewart 2011/02/22 21:56:25 Nit: Any reason why instead of adding these two li
1290 wpa_s->bgscan_ssid = NULL;
1291
1292 return wpa_supplicant_trigger_scan(wpa_s, &params);
1293 }
1294
1295
1248 static void wpa_supplicant_event_disassoc(struct wpa_supplicant *wpa_s, 1296 static void wpa_supplicant_event_disassoc(struct wpa_supplicant *wpa_s,
1249 u16 reason_code) 1297 u16 reason_code)
1250 { 1298 {
1251 const u8 *bssid; 1299 const u8 *bssid;
1300 int fast_reconnect;
1252 #ifdef CONFIG_SME 1301 #ifdef CONFIG_SME
1253 int authenticating; 1302 int authenticating;
1254 u8 prev_pending_bssid[ETH_ALEN]; 1303 u8 prev_pending_bssid[ETH_ALEN];
1255 1304
1256 authenticating = wpa_s->wpa_state == WPA_AUTHENTICATING; 1305 authenticating = wpa_s->wpa_state == WPA_AUTHENTICATING;
1257 os_memcpy(prev_pending_bssid, wpa_s->pending_bssid, ETH_ALEN); 1306 os_memcpy(prev_pending_bssid, wpa_s->pending_bssid, ETH_ALEN);
1258 #endif /* CONFIG_SME */ 1307 #endif /* CONFIG_SME */
1259 1308
1260 if (wpa_s->key_mgmt == WPA_KEY_MGMT_WPA_NONE) { 1309 if (wpa_s->key_mgmt == WPA_KEY_MGMT_WPA_NONE) {
1261 /* 1310 /*
1262 * At least Host AP driver and a Prism3 card seemed to be 1311 * At least Host AP driver and a Prism3 card seemed to be
1263 * generating streams of disconnected events when configuring 1312 * generating streams of disconnected events when configuring
1264 * IBSS for WPA-None. Ignore them for now. 1313 * IBSS for WPA-None. Ignore them for now.
1265 */ 1314 */
1266 wpa_printf(MSG_DEBUG, "Disconnect event - ignore in " 1315 wpa_printf(MSG_DEBUG, "Disconnect event - ignore in "
1267 "IBSS/WPA-None mode"); 1316 "IBSS/WPA-None mode");
1268 return; 1317 return;
1269 } 1318 }
1270 1319
1271 if (wpa_s->wpa_state == WPA_4WAY_HANDSHAKE && 1320 if (wpa_s->wpa_state == WPA_4WAY_HANDSHAKE &&
1272 wpa_key_mgmt_wpa_psk(wpa_s->key_mgmt)) { 1321 wpa_key_mgmt_wpa_psk(wpa_s->key_mgmt)) {
1273 wpa_msg(wpa_s, MSG_INFO, "WPA: 4-Way Handshake failed - " 1322 wpa_msg(wpa_s, MSG_INFO, "WPA: 4-Way Handshake failed - "
1274 "pre-shared key may be incorrect"); 1323 "pre-shared key may be incorrect");
1275 } 1324 }
1276 » if (wpa_s->wpa_state >= WPA_ASSOCIATING) 1325 » /*
1277 » » wpa_supplicant_req_scan(wpa_s, 0, 100000); 1326 » * If in a COMPLETED state and we were dropped for a reason
1327 » * we can directly recover from directly re-join the AP without
1328 » * clocking the state machine and/or notifying external agents.
1329 » *
1330 » * TODO(sleffler) guard against looping (should be only if AP is busted)
1331 » */
1332 » fast_reconnect =
1333 » wpa_s->wpa_state == WPA_COMPLETED &&
1334 » (reason_code == WLAN_REASON_DISASSOC_DUE_TO_INACTIVITY ||
1335 » reason_code == WLAN_REASON_CLASS2_FRAME_FROM_NONAUTH_STA ||
1336 » reason_code == WLAN_REASON_CLASS3_FRAME_FROM_NONASSOC_STA);
1278 bssid = wpa_s->bssid; 1337 bssid = wpa_s->bssid;
1279 » if (is_zero_ether_addr(bssid)) 1338 » if (is_zero_ether_addr(bssid)) {
1280 bssid = wpa_s->pending_bssid; 1339 bssid = wpa_s->pending_bssid;
1281 » /* 1340 » » fast_reconnect = FALSE;»/* XXX can this happen? */
1282 » * Don't blacklist the AP on normal/expected disconnects. 1341 » » wpa_printf(MSG_DEBUG, "Do not reconnect; pending bssid switch");
1283 » */ 1342 » }
1284 » if (reason_code != WLAN_REASON_DISASSOC_DUE_TO_INACTIVITY && 1343 » if (!fast_reconnect) {
1285 » reason_code != WLAN_REASON_CLASS2_FRAME_FROM_NONAUTH_STA && 1344 » » if (wpa_s->wpa_state >= WPA_ASSOCIATING)
1286 » reason_code != WLAN_REASON_CLASS3_FRAME_FROM_NONASSOC_STA) 1345 » » » wpa_supplicant_req_scan(wpa_s, 0, 100000);
1287 wpa_blacklist_add(wpa_s, bssid); 1346 wpa_blacklist_add(wpa_s, bssid);
1347 }
1288 wpa_sm_notify_disassoc(wpa_s->wpa); 1348 wpa_sm_notify_disassoc(wpa_s->wpa);
1289 wpa_msg(wpa_s, MSG_INFO, WPA_EVENT_DISCONNECTED "bssid=" MACSTR 1349 wpa_msg(wpa_s, MSG_INFO, WPA_EVENT_DISCONNECTED "bssid=" MACSTR
1290 " reason=%d", 1350 " reason=%d",
1291 MAC2STR(bssid), reason_code); 1351 MAC2STR(bssid), reason_code);
1292 if (wpa_supplicant_dynamic_keys(wpa_s)) { 1352 if (wpa_supplicant_dynamic_keys(wpa_s)) {
1293 wpa_printf(MSG_DEBUG, "Disconnect event - remove keys"); 1353 wpa_printf(MSG_DEBUG, "Disconnect event - remove keys");
1294 wpa_s->keys_cleared = 0; 1354 wpa_s->keys_cleared = 0;
1295 wpa_clear_keys(wpa_s, wpa_s->bssid); 1355 wpa_clear_keys(wpa_s, wpa_s->bssid);
1296 } 1356 }
1357 if (fast_reconnect) {
1358 if (wpa_supplicant_fast_reconnect(wpa_s, bssid) == 0)
1359 return;
1360 /* NB: fall through to slow path */
1361 wpa_printf(MSG_DEBUG, "Fast reconnect: Failed to trigger scan");
1362 wpa_supplicant_req_scan(wpa_s, 0, 100000);
1363 }
1297 wpa_supplicant_mark_disassoc(wpa_s); 1364 wpa_supplicant_mark_disassoc(wpa_s);
1298 bgscan_deinit(wpa_s); 1365 bgscan_deinit(wpa_s);
1299 wpa_s->bgscan_ssid = NULL; 1366 wpa_s->bgscan_ssid = NULL;
1300 #ifdef CONFIG_SME 1367 #ifdef CONFIG_SME
1301 if (authenticating && 1368 if (authenticating &&
1302 (wpa_s->drv_flags & WPA_DRIVER_FLAGS_SME)) { 1369 (wpa_s->drv_flags & WPA_DRIVER_FLAGS_SME)) {
1303 /* 1370 /*
1304 * mac80211-workaround to force deauth on failed auth cmd, 1371 * mac80211-workaround to force deauth on failed auth cmd,
1305 * requires us to remain in authenticating state to allow the 1372 * requires us to remain in authenticating state to allow the
1306 * second authentication attempt to be continued properly. 1373 * second authentication attempt to be continued properly.
(...skipping 421 matching lines...) Expand 10 before | Expand all | Expand 10 after
1728 break; 1795 break;
1729 case EVENT_CONNECTION_CHANGE: 1796 case EVENT_CONNECTION_CHANGE:
1730 bgscan_notify_connection_change(wpa_s, 1797 bgscan_notify_connection_change(wpa_s,
1731 &data->connection_change); 1798 &data->connection_change);
1732 break; 1799 break;
1733 default: 1800 default:
1734 wpa_printf(MSG_INFO, "Unknown event %d", event); 1801 wpa_printf(MSG_INFO, "Unknown event %d", event);
1735 break; 1802 break;
1736 } 1803 }
1737 } 1804 }
OLDNEW
« 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