drivers/ninaw10: Connect to WiFi asynchronously.

Before this patch, WiFi connection was blocking, and could raise exceptions
if the connection failed for any reason (including timeouts).  This doesn't
match the behavior of other WiFi modules, which connect asynchronously, and
requires handling of exceptions on connect.  This change makes `connect()`
work asynchronously by scheduling code to poll connection status, and
handle reconnects (if needed), and return immediately without blocking.
This commit is contained in:
iabdalkader
2022-10-21 20:51:42 +02:00
committed by Damien George
parent 8a91c71966
commit b9c1e4c205
3 changed files with 79 additions and 29 deletions

View File

@@ -108,6 +108,7 @@ typedef enum {
// Disonnect/status commands.
NINA_CMD_DISCONNECT = 0x30,
NINA_CMD_CONN_STATUS = 0x20,
NINA_CMD_CONN_REASON = 0x1F,
// Interface config commands.
NINA_CMD_SET_IF_CONFIG = 0x14,
@@ -173,19 +174,6 @@ typedef enum {
NINA_CMD_CMD_DOWNLOAD_OTA = 0x67,
} nina_cmd_t;
typedef enum {
NINA_STATUS_IDLE = 0,
NINA_STATUS_NO_SSID_AVAIL,
NINA_STATUS_SCAN_COMPLETED,
NINA_STATUS_CONNECTED,
NINA_STATUS_CONNECT_FAILED,
NINA_STATUS_CONNECTION_LOST,
NINA_STATUS_DISCONNECTED,
NINA_STATUS_AP_LISTENING,
NINA_STATUS_AP_CONNECTED,
NINA_STATUS_AP_FAILED
} nina_status_t;
typedef enum {
SOCKET_STATE_CLOSED = 0,
SOCKET_STATE_LISTEN,
@@ -364,13 +352,15 @@ int nina_deinit(void) {
return nina_bsp_deinit();
}
static int nina_connection_status() {
int nina_connection_status(void) {
return nina_send_command_read_ack(NINA_CMD_CONN_STATUS, 0, ARG_8BITS, NULL);
}
int nina_connect(const char *ssid, uint8_t security, const char *key, uint16_t channel) {
uint8_t status = NINA_STATUS_CONNECT_FAILED;
int nina_connection_reason(void) {
return nina_send_command_read_ack(NINA_CMD_CONN_REASON, 0, ARG_8BITS, NULL);
}
int nina_connect(const char *ssid, uint8_t security, const char *key, uint16_t channel) {
if (key == NULL && security != NINA_SEC_OPEN) {
return -1;
}
@@ -398,18 +388,7 @@ int nina_connect(const char *ssid, uint8_t security, const char *key, uint16_t c
return -1;
}
for (mp_uint_t start = mp_hal_ticks_ms(); ; mp_hal_delay_ms(10)) {
status = nina_connection_status();
if ((status != NINA_STATUS_IDLE) && (status != NINA_STATUS_NO_SSID_AVAIL) && (status != NINA_STATUS_SCAN_COMPLETED)) {
break;
}
if ((mp_hal_ticks_ms() - start) >= NINA_CONNECT_TIMEOUT) {
break;
}
}
return (status == NINA_STATUS_CONNECTED) ? 0 : -1;
return 0;
}
int nina_start_ap(const char *ssid, uint8_t security, const char *key, uint16_t channel) {
@@ -439,7 +418,7 @@ int nina_start_ap(const char *ssid, uint8_t security, const char *key, uint16_t
for (mp_uint_t start = mp_hal_ticks_ms(); ; mp_hal_delay_ms(10)) {
status = nina_connection_status();
if ((status != NINA_STATUS_IDLE) && (status != NINA_STATUS_NO_SSID_AVAIL) && (status != NINA_STATUS_SCAN_COMPLETED)) {
if ((status != NINA_STATUS_IDLE) && (status != NINA_STATUS_NO_SSID_AVAIL)) {
break;
}

View File

@@ -46,6 +46,17 @@
#define NINA_FW_VER_MINOR_OFFS (2)
#define NINA_FW_VER_PATCH_OFFS (4)
#define NINA_ESP_REASON_AUTH_EXPIRE (2)
#define NINA_ESP_REASON_ASSOC_EXPIRE (4)
#define NINA_ESP_REASON_NOT_AUTHED (6)
#define NINA_ESP_REASON_4WAY_HANDSHAKE_TIMEOUT (15)
#define NINA_ESP_REASON_BEACON_TIMEOUT (200)
#define NINA_ESP_REASON_NO_AP_FOUND (201)
#define NINA_ESP_REASON_AUTH_FAIL (202)
#define NINA_ESP_REASON_ASSOC_FAIL (203)
#define NINA_ESP_REASON_HANDSHAKE_TIMEOUT (204)
#define NINA_ESP_REASON_CONNECTION_FAIL (205)
typedef enum {
NINA_SEC_INVALID = 0,
NINA_SEC_OPEN,
@@ -59,6 +70,19 @@ typedef enum {
NINA_SOCKET_TYPE_RAW = 3,
} nina_socket_type_t;
typedef enum {
NINA_STATUS_IDLE = 0,
NINA_STATUS_NO_SSID_AVAIL = 1,
NINA_STATUS_SCAN_COMPLETED = 2,
NINA_STATUS_CONNECTED = 3,
NINA_STATUS_CONNECT_FAILED = 4,
NINA_STATUS_CONNECTION_LOST = 5,
NINA_STATUS_DISCONNECTED = 6,
NINA_STATUS_AP_LISTENING = 7,
NINA_STATUS_AP_CONNECTED = 8,
NINA_STATUS_AP_FAILED = 9
} nina_status_t;
typedef struct {
uint8_t ip_addr[NINA_IPV4_ADDR_LEN];
uint8_t subnet_addr[NINA_IPV4_ADDR_LEN];
@@ -85,6 +109,8 @@ typedef int (*nina_scan_callback_t)(nina_scan_result_t *, void *);
int nina_init(void);
int nina_deinit(void);
int nina_connection_status(void);
int nina_connection_reason(void);
int nina_connect(const char *ssid, uint8_t security, const char *key, uint16_t channel);
int nina_start_ap(const char *ssid, uint8_t security, const char *key, uint16_t channel);
int nina_disconnect(void);