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 866 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
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 Loading... | |
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 Loading... | |
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(¶ms, 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, ¶ms); | |
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 Loading... | |
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 } |
OLD | NEW |