|
64 | 64 | #define WIFI_JOIN_STATE_KEYED (0x0800) |
65 | 65 | #define WIFI_JOIN_STATE_ALL (0x0e01) |
66 | 66 |
|
| 67 | +// The cyw43 firmware not-uncommonly reports a transient authentication or WPA |
| 68 | +// handshake failure on the first association to an AP, even when the supplied |
| 69 | +// credentials are correct; a plain rejoin then succeeds. Automatically rejoin |
| 70 | +// this many times before reporting a bad-auth failure to the caller. A |
| 71 | +// genuinely wrong password still fails once the retries are exhausted. |
| 72 | +#ifndef CYW43_WIFI_JOIN_AUTH_RETRIES |
| 73 | +#define CYW43_WIFI_JOIN_AUTH_RETRIES (4) |
| 74 | +#endif |
| 75 | + |
67 | 76 | #define CYW43_STA_IS_ACTIVE(self) (((self)->itf_state >> CYW43_ITF_STA) & 1) |
68 | 77 | #define CYW43_AP_IS_ACTIVE(self) (((self)->itf_state >> CYW43_ITF_AP) & 1) |
69 | 78 |
|
@@ -390,8 +399,15 @@ void cyw43_cb_process_async_event(void *cb_data, const cyw43_async_event_t *ev) |
390 | 399 | } else if (ev->status == 6) { |
391 | 400 | // Unsolicited auth packet, ignore it |
392 | 401 | } else { |
393 | | - // Cannot authenticate |
394 | | - self->wifi_join_state = WIFI_JOIN_STATE_BADAUTH; |
| 402 | + // Cannot authenticate. This is often transient on a first |
| 403 | + // association, so rejoin a few times before reporting a bad-auth. |
| 404 | + if (self->wifi_join_retries > 0) { |
| 405 | + self->wifi_join_retries -= 1; |
| 406 | + self->pend_rejoin = true; |
| 407 | + cyw43_schedule_internal_poll_dispatch(cyw43_poll_func); |
| 408 | + } else { |
| 409 | + self->wifi_join_state = WIFI_JOIN_STATE_BADAUTH; |
| 410 | + } |
395 | 411 | } |
396 | 412 | } else if (ev->event_type == CYW43_EV_DEAUTH_IND) { |
397 | 413 | if (ev->status == 0 && ev->reason == 2) { |
@@ -422,8 +438,15 @@ void cyw43_cb_process_async_event(void *cb_data, const cyw43_async_event_t *ev) |
422 | 438 | self->pend_rejoin = true; |
423 | 439 | cyw43_schedule_internal_poll_dispatch(cyw43_poll_func); |
424 | 440 | } else { |
425 | | - // PSK_SUP failure |
426 | | - self->wifi_join_state = WIFI_JOIN_STATE_BADAUTH; |
| 441 | + // PSK_SUP failure. As with EV_AUTH this is often transient, so |
| 442 | + // rejoin a few times before reporting a bad-auth. |
| 443 | + if (self->wifi_join_retries > 0) { |
| 444 | + self->wifi_join_retries -= 1; |
| 445 | + self->pend_rejoin = true; |
| 446 | + cyw43_schedule_internal_poll_dispatch(cyw43_poll_func); |
| 447 | + } else { |
| 448 | + self->wifi_join_state = WIFI_JOIN_STATE_BADAUTH; |
| 449 | + } |
427 | 450 | } |
428 | 451 | } else if (ev->event_type == CYW43_EV_ICV_ERROR) { |
429 | 452 | self->pend_rejoin = true; |
@@ -651,6 +674,7 @@ int cyw43_wifi_join(cyw43_t *self, size_t ssid_len, const uint8_t *ssid, size_t |
651 | 674 | // Wait for responses: EV_AUTH, EV_LINK, EV_SET_SSID, EV_PSK_SUP |
652 | 675 | // Will get EV_DEAUTH_IND if password is invalid |
653 | 676 | self->wifi_join_state = WIFI_JOIN_STATE_ACTIVE; |
| 677 | + self->wifi_join_retries = CYW43_WIFI_JOIN_AUTH_RETRIES; |
654 | 678 |
|
655 | 679 | if (auth_type == CYW43_AUTH_OPEN) { |
656 | 680 | // For open security we don't need EV_PSK_SUP, so set that flag indicator now |
|
0 commit comments