36
#define SME_AUTH_TIMEOUT 5
37
#define SME_ASSOC_TIMEOUT 5
39
static void sme_auth_timer(void *eloop_ctx, void *timeout_ctx);
40
static void sme_assoc_timer(void *eloop_ctx, void *timeout_ctx);
35
43
void sme_authenticate(struct wpa_supplicant *wpa_s,
36
44
struct wpa_bss *bss, struct wpa_ssid *ssid)
271
280
wpa_hexdump(MSG_MSGDUMP, "SME: Authentication response IEs",
272
281
data->auth.ies, data->auth.ies_len);
283
eloop_cancel_timeout(sme_auth_timer, wpa_s, NULL);
274
285
if (data->auth.status_code != WLAN_STATUS_SUCCESS) {
275
286
wpa_printf(MSG_DEBUG, "SME: Authentication failed (status "
276
287
"code %d)", data->auth.status_code);
278
289
if (data->auth.status_code !=
279
290
WLAN_STATUS_NOT_SUPPORTED_AUTH_ALG ||
280
291
wpa_s->sme.auth_alg == data->auth.auth_type ||
281
wpa_s->current_ssid->auth_alg == WPA_AUTH_ALG_LEAP)
292
wpa_s->current_ssid->auth_alg == WPA_AUTH_ALG_LEAP) {
293
wpas_connection_failed(wpa_s, wpa_s->pending_bssid);
284
297
switch (data->auth.auth_type) {
285
298
case WLAN_AUTH_OPEN:
333
346
params.wpa_ie = wpa_s->sme.assoc_req_ie_len ?
334
347
wpa_s->sme.assoc_req_ie : NULL;
335
348
params.wpa_ie_len = wpa_s->sme.assoc_req_ie_len;
349
params.pairwise_suite = cipher_suite2driver(wpa_s->pairwise_cipher);
350
params.group_suite = cipher_suite2driver(wpa_s->group_cipher);
336
351
#ifdef CONFIG_IEEE80211R
337
352
if (auth_type == WLAN_AUTH_FT && wpa_s->sme.ft_ies) {
338
353
params.wpa_ie = wpa_s->sme.ft_ies;
369
384
if (wpa_drv_associate(wpa_s, ¶ms) < 0) {
370
385
wpa_msg(wpa_s, MSG_INFO, "Association request to the driver "
372
wpa_supplicant_req_scan(wpa_s, 5, 0);
387
wpas_connection_failed(wpa_s, wpa_s->pending_bssid);
388
os_memset(wpa_s->pending_bssid, 0, ETH_ALEN);
376
/* TODO: add timeout on association */
392
eloop_register_timeout(SME_ASSOC_TIMEOUT, 0, sme_assoc_timer, wpa_s,
421
static void sme_deauth(struct wpa_supplicant *wpa_s)
425
bssid_changed = !is_zero_ether_addr(wpa_s->bssid);
427
if (wpa_drv_deauthenticate(wpa_s, wpa_s->pending_bssid,
428
WLAN_REASON_DEAUTH_LEAVING) < 0) {
429
wpa_msg(wpa_s, MSG_INFO,
430
"Deauth request to the driver failed");
432
wpa_s->sme.prev_bssid_set = 0;
434
wpas_connection_failed(wpa_s, wpa_s->pending_bssid);
435
wpa_supplicant_set_state(wpa_s, WPA_DISCONNECTED);
436
os_memset(wpa_s->bssid, 0, ETH_ALEN);
437
os_memset(wpa_s->pending_bssid, 0, ETH_ALEN);
439
wpas_notify_bssid_changed(wpa_s);
404
443
void sme_event_assoc_reject(struct wpa_supplicant *wpa_s,
405
444
union wpa_event_data *data)
410
446
wpa_printf(MSG_DEBUG, "SME: Association with " MACSTR " failed: "
411
447
"status code %d", MAC2STR(wpa_s->pending_bssid),
412
448
data->assoc_reject.status_code);
414
bssid_changed = !is_zero_ether_addr(wpa_s->bssid);
450
eloop_cancel_timeout(sme_assoc_timer, wpa_s, NULL);
417
453
* For now, unconditionally terminate the previous authentication. In
420
456
* benefit from using the previous authentication, so this could be
421
457
* optimized in the future.
423
if (wpa_drv_deauthenticate(wpa_s, wpa_s->pending_bssid,
424
WLAN_REASON_DEAUTH_LEAVING) < 0) {
425
wpa_msg(wpa_s, MSG_INFO,
426
"Deauth request to the driver failed");
428
wpa_s->sme.prev_bssid_set = 0;
430
if (wpa_blacklist_add(wpa_s, wpa_s->pending_bssid) == 0) {
431
struct wpa_blacklist *b;
432
b = wpa_blacklist_get(wpa_s, wpa_s->pending_bssid);
433
if (b && b->count < 3) {
435
* Speed up next attempt if there could be other APs
436
* that could accept association.
441
wpa_supplicant_set_state(wpa_s, WPA_DISCONNECTED);
442
os_memset(wpa_s->bssid, 0, ETH_ALEN);
443
os_memset(wpa_s->pending_bssid, 0, ETH_ALEN);
445
wpas_notify_bssid_changed(wpa_s);
448
* TODO: if more than one possible AP is available in scan results,
449
* could try the other ones before requesting a new scan.
451
wpa_supplicant_req_scan(wpa_s, timeout / 1000,
452
1000 * (timeout % 1000));
457
464
union wpa_event_data *data)
459
466
wpa_printf(MSG_DEBUG, "SME: Authentication timed out");
460
wpa_supplicant_req_scan(wpa_s, 5, 0);
467
wpas_connection_failed(wpa_s, wpa_s->pending_bssid);
465
472
union wpa_event_data *data)
467
474
wpa_printf(MSG_DEBUG, "SME: Association timed out");
475
wpas_connection_failed(wpa_s, wpa_s->pending_bssid);
468
476
wpa_supplicant_mark_disassoc(wpa_s);
469
wpa_supplicant_req_scan(wpa_s, 5, 0);
488
495
WLAN_REASON_DEAUTH_LEAVING);
500
static void sme_auth_timer(void *eloop_ctx, void *timeout_ctx)
502
struct wpa_supplicant *wpa_s = eloop_ctx;
503
if (wpa_s->wpa_state == WPA_AUTHENTICATING) {
504
wpa_msg(wpa_s, MSG_DEBUG, "SME: Authentication timeout");
510
static void sme_assoc_timer(void *eloop_ctx, void *timeout_ctx)
512
struct wpa_supplicant *wpa_s = eloop_ctx;
513
if (wpa_s->wpa_state == WPA_ASSOCIATING) {
514
wpa_msg(wpa_s, MSG_DEBUG, "SME: Association timeout");
520
void sme_state_changed(struct wpa_supplicant *wpa_s)
522
/* Make sure timers are cleaned up appropriately. */
523
if (wpa_s->wpa_state != WPA_ASSOCIATING)
524
eloop_cancel_timeout(sme_assoc_timer, wpa_s, NULL);
525
if (wpa_s->wpa_state != WPA_AUTHENTICATING)
526
eloop_cancel_timeout(sme_auth_timer, wpa_s, NULL);
530
void sme_disassoc_while_authenticating(struct wpa_supplicant *wpa_s,
531
const u8 *prev_pending_bssid)
534
* mac80211-workaround to force deauth on failed auth cmd,
535
* requires us to remain in authenticating state to allow the
536
* second authentication attempt to be continued properly.
538
wpa_printf(MSG_DEBUG, "SME: Allow pending authentication "
539
"to proceed after disconnection event");
540
wpa_supplicant_set_state(wpa_s, WPA_AUTHENTICATING);
541
os_memcpy(wpa_s->pending_bssid, prev_pending_bssid, ETH_ALEN);
544
* Re-arm authentication timer in case auth fails for whatever reason.
546
eloop_cancel_timeout(sme_auth_timer, wpa_s, NULL);
547
eloop_register_timeout(SME_AUTH_TIMEOUT, 0, sme_auth_timer, wpa_s,
552
void sme_deinit(struct wpa_supplicant *wpa_s)
554
os_free(wpa_s->sme.ft_ies);
555
wpa_s->sme.ft_ies = NULL;
556
wpa_s->sme.ft_ies_len = 0;
558
eloop_cancel_timeout(sme_assoc_timer, wpa_s, NULL);
559
eloop_cancel_timeout(sme_auth_timer, wpa_s, NULL);