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:
committed by
Damien George
parent
8a91c71966
commit
b9c1e4c205
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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);
|
||||
|
||||
Reference in New Issue
Block a user