Skip to content

Commit 701e80a

Browse files
committed
Make socket reads interruptable
1 parent 80b15f6 commit 701e80a

File tree

9 files changed

+82
-17
lines changed

9 files changed

+82
-17
lines changed

ports/esp32s2/common-hal/socketpool/Socket.c

Lines changed: 24 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -55,9 +55,13 @@ bool common_hal_socketpool_socket_connect(socketpool_socket_obj_t* self, const c
5555
int flags;
5656
esp_err_t err = esp_tls_get_and_clear_last_error(self->tcp->error_handle, &esp_tls_code, &flags);
5757

58-
// mp_raise_espidf_MemoryError
59-
mp_raise_OSError_msg_varg(translate("Unhandled ESP TLS error %d %d %x"), esp_tls_code, flags, err);
58+
if (err == ESP_ERR_MBEDTLS_SSL_SETUP_FAILED) {
59+
mp_raise_espidf_MemoryError();
60+
} else {
61+
mp_raise_OSError_msg_varg(translate("Unhandled ESP TLS error %d %d %x"), esp_tls_code, flags, err);
62+
}
6063
}
64+
6165
return self->connected;
6266
}
6367

@@ -78,23 +82,35 @@ mp_uint_t common_hal_socketpool_socket_recv_into(socketpool_socket_obj_t* self,
7882
size_t received = 0;
7983
ssize_t last_read = 1;
8084
uint64_t start_ticks = supervisor_ticks_ms64();
85+
int sockfd;
86+
esp_err_t err = esp_tls_get_conn_sockfd(self->tcp, &sockfd);
87+
if (err != ESP_OK) {
88+
mp_raise_OSError(MP_EBADF);
89+
}
8190
while (received < len &&
8291
last_read > 0 &&
8392
(self->timeout_ms == 0 || supervisor_ticks_ms64() - start_ticks <= self->timeout_ms) &&
8493
!mp_hal_is_interrupted()) {
8594
RUN_BACKGROUND_TASKS;
8695
size_t available = esp_tls_get_bytes_avail(self->tcp);
87-
ESP_EARLY_LOGW(TAG, "available %d", available);
96+
if (available == 0) {
97+
// This reads the raw socket buffer and is used for non-TLS connections
98+
// and between encrypted TLS blocks.
99+
int status = lwip_ioctl(sockfd, FIONREAD, &available);
100+
if (status < 0) {
101+
// ESP_EARLY_LOGW(TAG, "ioctl fail. socket %d status %d errno %d available %d", sockfd, status, errno, available);
102+
last_read = status;
103+
break;
104+
}
105+
}
106+
// ESP_EARLY_LOGW(TAG, "available %d", available);
88107
size_t remaining = len - received;
89108
if (available > remaining) {
90109
available = remaining;
91110
}
92-
if (true || available > 0) {
93-
if (available == 0) {
94-
available = len - received;
95-
}
111+
if (available > 0) {
96112
last_read = esp_tls_conn_read(self->tcp, (void*) buf + received, available);
97-
ESP_EARLY_LOGW(TAG, "read %d out of %d", last_read, available);
113+
// ESP_EARLY_LOGW(TAG, "read %d out of %d", last_read, available);
98114
received += last_read;
99115
}
100116
}

ports/esp32s2/common-hal/wifi/Radio.c

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -105,7 +105,7 @@ void common_hal_wifi_radio_stop_scanning_networks(wifi_radio_obj_t *self) {
105105
self->current_scan = NULL;
106106
}
107107

108-
bool common_hal_wifi_radio_connect(wifi_radio_obj_t *self, uint8_t* ssid, size_t ssid_len, uint8_t* password, size_t password_len, uint8_t channel, mp_float_t timeout) {
108+
wifi_radio_error_t common_hal_wifi_radio_connect(wifi_radio_obj_t *self, uint8_t* ssid, size_t ssid_len, uint8_t* password, size_t password_len, uint8_t channel, mp_float_t timeout) {
109109
// check enabled
110110
wifi_config_t* config = &self->sta_config;
111111
memcpy(&config->sta.ssid, ssid, ssid_len);
@@ -116,6 +116,8 @@ bool common_hal_wifi_radio_connect(wifi_radio_obj_t *self, uint8_t* ssid, size_t
116116
config->sta.password[password_len] = 0;
117117
config->sta.channel = channel;
118118
esp_wifi_set_config(ESP_IF_WIFI_STA, config);
119+
self->starting_retries = 5;
120+
self->retries_left = 5;
119121
esp_wifi_connect();
120122

121123
EventBits_t bits;
@@ -128,9 +130,14 @@ bool common_hal_wifi_radio_connect(wifi_radio_obj_t *self, uint8_t* ssid, size_t
128130
0);
129131
} while ((bits & (WIFI_CONNECTED_BIT | WIFI_DISCONNECTED_BIT)) == 0 && !mp_hal_is_interrupted());
130132
if ((bits & WIFI_DISCONNECTED_BIT) != 0) {
131-
return false;
133+
if (self->last_disconnect_reason == WIFI_REASON_AUTH_FAIL) {
134+
return WIFI_RADIO_ERROR_AUTH;
135+
} else if (self->last_disconnect_reason == WIFI_REASON_NO_AP_FOUND) {
136+
return WIFI_RADIO_ERROR_NO_AP_FOUND;
137+
}
138+
return WIFI_RADIO_ERROR_UNKNOWN;
132139
}
133-
return true;
140+
return WIFI_RADIO_ERROR_NONE;
134141
}
135142

136143
mp_obj_t common_hal_wifi_radio_get_ipv4_address(wifi_radio_obj_t *self) {

ports/esp32s2/common-hal/wifi/Radio.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,9 @@ typedef struct {
5050
bool started;
5151
bool ap_mode;
5252
bool sta_mode;
53+
uint8_t retries_left;
54+
uint8_t starting_retries;
55+
uint8_t last_disconnect_reason;
5356
} wifi_radio_obj_t;
5457

5558
#endif // MICROPY_INCLUDED_ESP32S2_COMMON_HAL_WIFI_RADIO_H

ports/esp32s2/common-hal/wifi/__init__.c

Lines changed: 17 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -54,11 +54,24 @@ static void event_handler(void* arg, esp_event_base_t event_base,
5454
ESP_EARLY_LOGW(TAG, "disconnected");
5555
wifi_event_sta_disconnected_t* d = (wifi_event_sta_disconnected_t*) event_data;
5656
uint8_t reason = d->reason;
57-
if (reason != WIFI_REASON_ASSOC_LEAVE) {
58-
// reconnect
59-
}
6057
ESP_EARLY_LOGW(TAG, "reason %d 0x%02x", reason, reason);
58+
if (radio->retries_left > 0 &&
59+
(reason == WIFI_REASON_AUTH_EXPIRE ||
60+
reason == WIFI_REASON_ASSOC_EXPIRE ||
61+
reason == WIFI_REASON_CONNECTION_FAIL ||
62+
reason == WIFI_REASON_4WAY_HANDSHAKE_TIMEOUT)) {
63+
radio->retries_left--;
64+
ESP_EARLY_LOGI(TAG, "Retrying connect. %d retries remaining", radio->retries_left);
65+
esp_wifi_connect();
66+
return;
67+
}
68+
69+
radio->last_disconnect_reason = reason;
6170
xEventGroupSetBits(radio->event_group_handle, WIFI_DISCONNECTED_BIT);
71+
72+
// if (reason != WIFI_REASON_ASSOC_LEAVE) {
73+
// // reconnect
74+
// }
6275
} else if (event_id == WIFI_EVENT_STA_AUTHMODE_CHANGE) {
6376
}
6477
}
@@ -78,6 +91,7 @@ static void event_handler(void* arg, esp_event_base_t event_base,
7891
// } else
7992
if (event_base == IP_EVENT && event_id == IP_EVENT_STA_GOT_IP) {
8093
ESP_EARLY_LOGW(TAG, "got ip");
94+
radio->retries_left = radio->starting_retries;
8195
xEventGroupSetBits(radio->event_group_handle, WIFI_CONNECTED_BIT);
8296
}
8397
}

ports/esp32s2/sdkconfig.defaults

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -452,7 +452,7 @@ CONFIG_LWIP_MAX_SOCKETS=10
452452
# CONFIG_LWIP_SO_LINGER is not set
453453
CONFIG_LWIP_SO_REUSE=y
454454
CONFIG_LWIP_SO_REUSE_RXTOALL=y
455-
# CONFIG_LWIP_SO_RCVBUF is not set
455+
CONFIG_LWIP_SO_RCVBUF=y
456456
# CONFIG_LWIP_NETBUF_RECVINFO is not set
457457
CONFIG_LWIP_IP4_FRAG=y
458458
CONFIG_LWIP_IP6_FRAG=y

py/runtime.c

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1602,6 +1602,10 @@ NORETURN void mp_raise_OSError_msg_varg(const compressed_string_t *fmt, ...) {
16021602
va_end(argptr);
16031603
}
16041604

1605+
NORETURN void mp_raise_ConnectionError(const compressed_string_t *msg) {
1606+
mp_raise_msg(&mp_type_ConnectionError, msg);
1607+
}
1608+
16051609
NORETURN void mp_raise_BrokenPipeError(void) {
16061610
nlr_raise(mp_obj_new_exception_arg1(&mp_type_BrokenPipeError, MP_OBJ_NEW_SMALL_INT(MP_EPIPE)));
16071611
}

py/runtime.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -166,6 +166,7 @@ NORETURN void mp_raise_OSError(int errno_);
166166
NORETURN void mp_raise_OSError_errno_str(int errno_, mp_obj_t str);
167167
NORETURN void mp_raise_OSError_msg(const compressed_string_t *msg);
168168
NORETURN void mp_raise_OSError_msg_varg(const compressed_string_t *fmt, ...);
169+
NORETURN void mp_raise_ConnectionError(const compressed_string_t *msg);
169170
NORETURN void mp_raise_BrokenPipeError(void);
170171
NORETURN void mp_raise_NotImplementedError(const compressed_string_t *msg);
171172
NORETURN void mp_raise_NotImplementedError_varg(const compressed_string_t *fmt, ...);

shared-bindings/wifi/Radio.c

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -136,9 +136,21 @@ STATIC mp_obj_t wifi_radio_connect(size_t n_args, const mp_obj_t *pos_args, mp_m
136136
password.len = 0;
137137
if (args[ARG_password].u_obj != MP_OBJ_NULL) {
138138
mp_get_buffer_raise(args[ARG_password].u_obj, &password, MP_BUFFER_READ);
139+
if (password.len > 0 && (password.len < 8 || password.len > 63)) {
140+
mp_raise_ValueError(translate("WiFi password must be between 8 and 63 characters."));
141+
}
139142
}
140143

141-
return mp_obj_new_bool(common_hal_wifi_radio_connect(self, ssid.buf, ssid.len, password.buf, password.len, args[ARG_channel].u_int, timeout));
144+
wifi_radio_error_t error = common_hal_wifi_radio_connect(self, ssid.buf, ssid.len, password.buf, password.len, args[ARG_channel].u_int, timeout);
145+
if (error == WIFI_RADIO_ERROR_AUTH) {
146+
mp_raise_ConnectionError(translate("Authentication failure"));
147+
} else if (error == WIFI_RADIO_ERROR_NO_AP_FOUND) {
148+
mp_raise_ConnectionError(translate("No network with that ssid"));
149+
} else if (error != WIFI_RADIO_ERROR_NONE) {
150+
mp_raise_ConnectionError(translate("Unknown failure"));
151+
}
152+
153+
return mp_const_none;
142154
}
143155
STATIC MP_DEFINE_CONST_FUN_OBJ_KW(wifi_radio_connect_obj, 1, wifi_radio_connect);
144156

shared-bindings/wifi/Radio.h

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,14 @@
3535

3636
const mp_obj_type_t wifi_radio_type;
3737

38+
39+
typedef enum {
40+
WIFI_RADIO_ERROR_NONE,
41+
WIFI_RADIO_ERROR_UNKNOWN,
42+
WIFI_RADIO_ERROR_AUTH,
43+
WIFI_RADIO_ERROR_NO_AP_FOUND
44+
} wifi_radio_error_t;
45+
3846
extern bool common_hal_wifi_radio_get_enabled(wifi_radio_obj_t *self);
3947
extern void common_hal_wifi_radio_set_enabled(wifi_radio_obj_t *self, bool enabled);
4048

@@ -43,7 +51,7 @@ extern mp_obj_t common_hal_wifi_radio_get_mac_address(wifi_radio_obj_t *self);
4351
extern mp_obj_t common_hal_wifi_radio_start_scanning_networks(wifi_radio_obj_t *self);
4452
extern void common_hal_wifi_radio_stop_scanning_networks(wifi_radio_obj_t *self);
4553

46-
extern bool common_hal_wifi_radio_connect(wifi_radio_obj_t *self, uint8_t* ssid, size_t ssid_len, uint8_t* password, size_t password_len, uint8_t channel, mp_float_t timeout);
54+
extern wifi_radio_error_t common_hal_wifi_radio_connect(wifi_radio_obj_t *self, uint8_t* ssid, size_t ssid_len, uint8_t* password, size_t password_len, uint8_t channel, mp_float_t timeout);
4755

4856
extern mp_obj_t common_hal_wifi_radio_get_ipv4_address(wifi_radio_obj_t *self);
4957

0 commit comments

Comments
 (0)