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 |