Chromium Code Reviews| OLD | NEW |
|---|---|
| 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 932 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 943 selected = wpa_supplicant_pick_network(wpa_s, scan_res, &ssid); | 943 selected = wpa_supplicant_pick_network(wpa_s, scan_res, &ssid); |
| 944 | 944 |
| 945 if (selected) { | 945 if (selected) { |
| 946 int skip; | 946 int skip; |
| 947 skip = !wpa_supplicant_need_to_roam(wpa_s, selected, ssid, | 947 skip = !wpa_supplicant_need_to_roam(wpa_s, selected, ssid, |
| 948 scan_res); | 948 scan_res); |
| 949 wpa_scan_results_free(scan_res); | 949 wpa_scan_results_free(scan_res); |
| 950 if (skip) | 950 if (skip) |
| 951 return; | 951 return; |
| 952 wpa_supplicant_connect(wpa_s, selected, ssid); | 952 wpa_supplicant_connect(wpa_s, selected, ssid); |
| 953 } else if (wpa_s->fast_reconnect) { | |
|
Paul Stewart
2011/02/19 06:12:19
If the scan succeeds (selected != 0), we connect,
Sam Leffler
2011/02/22 21:35:26
Good catch; fixed.
| |
| 954 /* | |
| 955 * Processed deferred disassoc work on a failed | |
| 956 * fast reconnect. | |
| 957 */ | |
| 958 wpa_printf(MSG_INFO, "Fast reconnect failed"); | |
| 959 wpa_scan_results_free(scan_res); | |
| 960 wpa_s->fast_reconnect = 0; | |
| 961 wpa_supplicant_mark_disassoc(wpa_s); | |
| 962 bgscan_deinit(wpa_s); | |
|
Paul Stewart
2011/02/19 06:12:19
You should not do this here. bgscan should have b
Sam Leffler
2011/02/22 21:35:26
Done
| |
| 963 wpa_s->bgscan_ssid = NULL; | |
| 953 } else { | 964 } else { |
| 954 wpa_scan_results_free(scan_res); | 965 wpa_scan_results_free(scan_res); |
| 955 wpa_printf(MSG_DEBUG, "No suitable network found"); | 966 wpa_printf(MSG_DEBUG, "No suitable network found"); |
| 956 ssid = wpa_supplicant_pick_new_network(wpa_s); | 967 ssid = wpa_supplicant_pick_new_network(wpa_s); |
| 957 if (ssid) { | 968 if (ssid) { |
| 958 wpa_printf(MSG_DEBUG, "Setup a new network"); | 969 wpa_printf(MSG_DEBUG, "Setup a new network"); |
| 959 wpa_supplicant_associate(wpa_s, NULL, ssid); | 970 wpa_supplicant_associate(wpa_s, NULL, ssid); |
| 960 } else { | 971 } else { |
| 961 int timeout_sec = 5; | 972 int timeout_sec = 5; |
| 962 int timeout_usec = 0; | 973 int timeout_usec = 0; |
| (...skipping 275 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1238 if ((wpa_s->key_mgmt == WPA_KEY_MGMT_NONE || | 1249 if ((wpa_s->key_mgmt == WPA_KEY_MGMT_NONE || |
| 1239 wpa_s->key_mgmt == WPA_KEY_MGMT_IEEE8021X_NO_WPA) && | 1250 wpa_s->key_mgmt == WPA_KEY_MGMT_IEEE8021X_NO_WPA) && |
| 1240 wpa_s->current_ssid && wpa_drv_get_capa(wpa_s, &capa) == 0 && | 1251 wpa_s->current_ssid && wpa_drv_get_capa(wpa_s, &capa) == 0 && |
| 1241 capa.flags & WPA_DRIVER_FLAGS_SET_KEYS_AFTER_ASSOC_DONE) { | 1252 capa.flags & WPA_DRIVER_FLAGS_SET_KEYS_AFTER_ASSOC_DONE) { |
| 1242 /* Set static WEP keys again */ | 1253 /* Set static WEP keys again */ |
| 1243 wpa_set_wep_keys(wpa_s, wpa_s->current_ssid); | 1254 wpa_set_wep_keys(wpa_s, wpa_s->current_ssid); |
| 1244 } | 1255 } |
| 1245 } | 1256 } |
| 1246 | 1257 |
| 1247 | 1258 |
| 1259 /* | |
| 1260 * Try to return to the same AP immediately. Directly scan | |
| 1261 * on the current channel for the current BSSID and try to | |
| 1262 * reassociate. If the station is not present we will clock | |
| 1263 * the state machine to DISCONNECTED in wpa_supplicant_event_scan_results | |
| 1264 * which will notify external agents. | |
| 1265 */ | |
| 1266 static int wpa_supplicant_fast_reconnect(struct wpa_supplicant *wpa_s, | |
| 1267 const u8 *bssid) | |
| 1268 { | |
| 1269 struct wpa_driver_scan_params params; | |
| 1270 int freqs[2]; | |
| 1271 | |
| 1272 wpa_s->reassociate = 1; | |
| 1273 wpa_s->fast_reconnect = 1; | |
| 1274 | |
| 1275 os_memset(¶ms, 0, sizeof(params)); | |
| 1276 params.num_ssids = 1; | |
| 1277 params.ssids[0].ssid = wpa_s->current_ssid->ssid; | |
| 1278 params.ssids[0].ssid_len = wpa_s->current_ssid->ssid_len; | |
| 1279 freqs[0] = wpa_s->assoc_freq; | |
| 1280 freqs[1] = 0; | |
| 1281 params.freqs = freqs; | |
| 1282 | |
| 1283 wpa_msg(wpa_s, MSG_INFO, "Fast reconnect bssid=" MACSTR | |
| 1284 " ssid=%.*s freq=%d", MAC2STR(bssid), | |
| 1285 params.ssids[0].ssid_len, params.ssids[0].ssid, | |
| 1286 params.freqs[0]); | |
| 1287 | |
| 1288 return wpa_supplicant_trigger_scan(wpa_s, ¶ms); | |
| 1289 } | |
| 1290 | |
| 1291 | |
| 1248 static void wpa_supplicant_event_disassoc(struct wpa_supplicant *wpa_s, | 1292 static void wpa_supplicant_event_disassoc(struct wpa_supplicant *wpa_s, |
| 1249 u16 reason_code) | 1293 u16 reason_code) |
| 1250 { | 1294 { |
| 1251 const u8 *bssid; | 1295 const u8 *bssid; |
| 1296 int fast_reconnect; | |
| 1252 #ifdef CONFIG_SME | 1297 #ifdef CONFIG_SME |
| 1253 int authenticating; | 1298 int authenticating; |
| 1254 u8 prev_pending_bssid[ETH_ALEN]; | 1299 u8 prev_pending_bssid[ETH_ALEN]; |
| 1255 | 1300 |
| 1256 authenticating = wpa_s->wpa_state == WPA_AUTHENTICATING; | 1301 authenticating = wpa_s->wpa_state == WPA_AUTHENTICATING; |
| 1257 os_memcpy(prev_pending_bssid, wpa_s->pending_bssid, ETH_ALEN); | 1302 os_memcpy(prev_pending_bssid, wpa_s->pending_bssid, ETH_ALEN); |
| 1258 #endif /* CONFIG_SME */ | 1303 #endif /* CONFIG_SME */ |
| 1259 | 1304 |
| 1260 if (wpa_s->key_mgmt == WPA_KEY_MGMT_WPA_NONE) { | 1305 if (wpa_s->key_mgmt == WPA_KEY_MGMT_WPA_NONE) { |
| 1261 /* | 1306 /* |
| 1262 * At least Host AP driver and a Prism3 card seemed to be | 1307 * At least Host AP driver and a Prism3 card seemed to be |
| 1263 * generating streams of disconnected events when configuring | 1308 * generating streams of disconnected events when configuring |
| 1264 * IBSS for WPA-None. Ignore them for now. | 1309 * IBSS for WPA-None. Ignore them for now. |
| 1265 */ | 1310 */ |
| 1266 wpa_printf(MSG_DEBUG, "Disconnect event - ignore in " | 1311 wpa_printf(MSG_DEBUG, "Disconnect event - ignore in " |
| 1267 "IBSS/WPA-None mode"); | 1312 "IBSS/WPA-None mode"); |
| 1268 return; | 1313 return; |
| 1269 } | 1314 } |
| 1270 | 1315 |
| 1271 if (wpa_s->wpa_state == WPA_4WAY_HANDSHAKE && | 1316 if (wpa_s->wpa_state == WPA_4WAY_HANDSHAKE && |
| 1272 wpa_key_mgmt_wpa_psk(wpa_s->key_mgmt)) { | 1317 wpa_key_mgmt_wpa_psk(wpa_s->key_mgmt)) { |
| 1273 wpa_msg(wpa_s, MSG_INFO, "WPA: 4-Way Handshake failed - " | 1318 wpa_msg(wpa_s, MSG_INFO, "WPA: 4-Way Handshake failed - " |
| 1274 "pre-shared key may be incorrect"); | 1319 "pre-shared key may be incorrect"); |
| 1275 } | 1320 } |
| 1276 » if (wpa_s->wpa_state >= WPA_ASSOCIATING) | 1321 » /* |
| 1277 » » wpa_supplicant_req_scan(wpa_s, 0, 100000); | 1322 » * If in a COMPLETED state and we were dropped for a reason |
| 1323 » * we can directly recover from directly re-join the AP without | |
| 1324 » * clocking the state machine and/or notifying external agents. | |
| 1325 » * | |
| 1326 » * TODO(sleffler) guard against looping (should be only if AP is busted) | |
| 1327 » */ | |
| 1328 » fast_reconnect = | |
| 1329 » wpa_s->wpa_state == WPA_COMPLETED && | |
| 1330 » (reason_code == WLAN_REASON_DISASSOC_DUE_TO_INACTIVITY || | |
| 1331 » reason_code == WLAN_REASON_CLASS2_FRAME_FROM_NONAUTH_STA || | |
| 1332 » reason_code == WLAN_REASON_CLASS3_FRAME_FROM_NONASSOC_STA); | |
| 1278 bssid = wpa_s->bssid; | 1333 bssid = wpa_s->bssid; |
| 1279 » if (is_zero_ether_addr(bssid)) | 1334 » if (is_zero_ether_addr(bssid)) { |
| 1280 bssid = wpa_s->pending_bssid; | 1335 bssid = wpa_s->pending_bssid; |
| 1281 » /* | 1336 » » fast_reconnect = FALSE;»/* XXX can this happen? */ |
| 1282 » * Don't blacklist the AP on normal/expected disconnects. | 1337 » » wpa_printf(MSG_DEBUG, "Do not reconnect; pending bssid switch"); |
| 1283 » */ | 1338 » } |
| 1284 » if (reason_code != WLAN_REASON_DISASSOC_DUE_TO_INACTIVITY && | 1339 » if (!fast_reconnect) { |
| 1285 » reason_code != WLAN_REASON_CLASS2_FRAME_FROM_NONAUTH_STA && | 1340 » » if (wpa_s->wpa_state >= WPA_ASSOCIATING) |
| 1286 » reason_code != WLAN_REASON_CLASS3_FRAME_FROM_NONASSOC_STA) | 1341 » » » wpa_supplicant_req_scan(wpa_s, 0, 100000); |
| 1287 wpa_blacklist_add(wpa_s, bssid); | 1342 wpa_blacklist_add(wpa_s, bssid); |
| 1343 } | |
| 1288 wpa_sm_notify_disassoc(wpa_s->wpa); | 1344 wpa_sm_notify_disassoc(wpa_s->wpa); |
| 1289 wpa_msg(wpa_s, MSG_INFO, WPA_EVENT_DISCONNECTED "bssid=" MACSTR | 1345 wpa_msg(wpa_s, MSG_INFO, WPA_EVENT_DISCONNECTED "bssid=" MACSTR |
| 1290 " reason=%d", | 1346 " reason=%d", |
| 1291 MAC2STR(bssid), reason_code); | 1347 MAC2STR(bssid), reason_code); |
| 1292 if (wpa_supplicant_dynamic_keys(wpa_s)) { | 1348 if (wpa_supplicant_dynamic_keys(wpa_s)) { |
| 1293 wpa_printf(MSG_DEBUG, "Disconnect event - remove keys"); | 1349 wpa_printf(MSG_DEBUG, "Disconnect event - remove keys"); |
| 1294 wpa_s->keys_cleared = 0; | 1350 wpa_s->keys_cleared = 0; |
| 1295 wpa_clear_keys(wpa_s, wpa_s->bssid); | 1351 wpa_clear_keys(wpa_s, wpa_s->bssid); |
| 1296 } | 1352 } |
| 1353 if (fast_reconnect) { | |
|
Paul Stewart
2011/02/19 06:12:19
I think you should disable bgscan even in the fast
| |
| 1354 if (wpa_supplicant_fast_reconnect(wpa_s, bssid) == 0) | |
| 1355 return; | |
| 1356 /* NB: fall through to slow path */ | |
| 1357 wpa_printf(MSG_DEBUG, "Fast reconnect: Failed to trigger scan"); | |
| 1358 wpa_supplicant_req_scan(wpa_s, 0, 100000); | |
| 1359 } | |
| 1297 wpa_supplicant_mark_disassoc(wpa_s); | 1360 wpa_supplicant_mark_disassoc(wpa_s); |
| 1298 bgscan_deinit(wpa_s); | 1361 bgscan_deinit(wpa_s); |
| 1299 wpa_s->bgscan_ssid = NULL; | 1362 wpa_s->bgscan_ssid = NULL; |
| 1300 #ifdef CONFIG_SME | 1363 #ifdef CONFIG_SME |
| 1301 if (authenticating && | 1364 if (authenticating && |
| 1302 (wpa_s->drv_flags & WPA_DRIVER_FLAGS_SME)) { | 1365 (wpa_s->drv_flags & WPA_DRIVER_FLAGS_SME)) { |
| 1303 /* | 1366 /* |
| 1304 * mac80211-workaround to force deauth on failed auth cmd, | 1367 * mac80211-workaround to force deauth on failed auth cmd, |
| 1305 * requires us to remain in authenticating state to allow the | 1368 * requires us to remain in authenticating state to allow the |
| 1306 * second authentication attempt to be continued properly. | 1369 * second authentication attempt to be continued properly. |
| (...skipping 421 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1728 break; | 1791 break; |
| 1729 case EVENT_CONNECTION_CHANGE: | 1792 case EVENT_CONNECTION_CHANGE: |
| 1730 bgscan_notify_connection_change(wpa_s, | 1793 bgscan_notify_connection_change(wpa_s, |
| 1731 &data->connection_change); | 1794 &data->connection_change); |
| 1732 break; | 1795 break; |
| 1733 default: | 1796 default: |
| 1734 wpa_printf(MSG_INFO, "Unknown event %d", event); | 1797 wpa_printf(MSG_INFO, "Unknown event %d", event); |
| 1735 break; | 1798 break; |
| 1736 } | 1799 } |
| 1737 } | 1800 } |
| OLD | NEW |