Skip to content

Commit 8c7f994

Browse files
committed
getting closer on HTTPS server
1 parent 9208d68 commit 8c7f994

File tree

5 files changed

+104
-35
lines changed

5 files changed

+104
-35
lines changed

devices/airlift/common-hal/socketpool/Socket.c

Lines changed: 95 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -165,7 +165,7 @@ static bool socketpool_socket_get_connection_info(socketpool_socket_obj_t *self,
165165

166166

167167

168-
static airlift_socket_status_t socketpool_socket_status(socketpool_socket_obj_t *self) {
168+
static airlift_client_socket_status_t client_socket_status(socketpool_socket_obj_t *self) {
169169
const uint8_t *params[1] = { &self->num };
170170
size_t param_lengths[1] = { 1 };
171171

@@ -185,43 +185,88 @@ static airlift_socket_status_t socketpool_socket_status(socketpool_socket_obj_t
185185
return result;
186186
}
187187

188-
int socketpool_socket_accept(socketpool_socket_obj_t *self, mp_obj_t *peer_out, socketpool_socket_obj_t *accepted) {
189-
if (self->type != SOCK_STREAM) {
190-
return -MP_EOPNOTSUPP;
191-
}
192-
193-
if (common_hal_socketpool_socket_get_closed(self)) {
194-
return -MP_EBADF;
195-
}
196-
188+
static bool server_socket_status(socketpool_socket_obj_t *self) {
197189
const uint8_t *params[1] = { &self->num };
198190
size_t param_lengths[1] = { 1 };
199191

200-
uint8_t accept_socket_num;
201-
uint8_t *responses[1] = { &accept_socket_num };
192+
uint8_t result;
193+
uint8_t *responses[1] = { &result };
202194
size_t response_lengths[1] = { 1 };
203195

204-
size_t num_responses = wifi_radio_send_command_get_response(self->socketpool->radio, AVAIL_DATA_TCP_CMD,
196+
// GET_STATE_TCP_CMD is a misnomer. It only checks whether there's a tcpserver for the socket.
197+
size_t num_responses = wifi_radio_send_command_get_response(self->socketpool->radio, GET_STATE_TCP_CMD,
205198
params, param_lengths, LENGTHS_8, MP_ARRAY_SIZE(params),
206199
responses, response_lengths, LENGTHS_8, MP_ARRAY_SIZE(responses),
207200
AIRLIFT_DEFAULT_TIMEOUT_MS);
208201

209202
if (num_responses == 0) {
210203
raise_failed();
211204
}
212-
if (accept_socket_num == NO_SOCKET) {
213-
return -EBADF;
205+
206+
return result == 1;
207+
}
208+
209+
int socketpool_socket_accept(socketpool_socket_obj_t *self, mp_obj_t *peer_out, socketpool_socket_obj_t *accepted) {
210+
if (self->type != SOCK_STREAM) {
211+
return -MP_EOPNOTSUPP;
212+
}
213+
214+
if (!server_socket_status(self)) {
215+
return -MP_ENOTCONN;
214216
}
215217

216-
return accept_socket_num;
218+
const uint8_t *params[1] = { &self->num };
219+
size_t param_lengths[1] = { 1 };
220+
221+
uint16_t accept_socket_num;
222+
uint8_t *responses[1] = { (uint8_t *)&accept_socket_num };
223+
size_t response_lengths[1] = { sizeof(accept_socket_num) };
224+
225+
const uint64_t start_time = supervisor_ticks_ms64();
226+
while (true) {
227+
// When passed a server socket, AVAIL_DATA_TCP_CMD returns the socket number on which to read data.
228+
// For client and UDP sockets, it returns the number of bytes available. (Quite a difference!)
229+
size_t num_responses = wifi_radio_send_command_get_response(self->socketpool->radio, AVAIL_DATA_TCP_CMD,
230+
params, param_lengths, LENGTHS_8, MP_ARRAY_SIZE(params),
231+
responses, response_lengths, LENGTHS_8, MP_ARRAY_SIZE(responses),
232+
AIRLIFT_DEFAULT_TIMEOUT_MS);
233+
234+
if (num_responses == 0) {
235+
raise_failed();
236+
}
237+
238+
if (accept_socket_num != NO_SOCKET) {
239+
return accept_socket_num;
240+
}
241+
242+
if (self->timeout_ms == 0) {
243+
// Non-blocking raises a different exception than a timeout.
244+
return -MP_EAGAIN;
245+
}
246+
if ((self->timeout_ms != SOCKET_BLOCK_FOREVER &&
247+
supervisor_ticks_ms64() - start_time >= self->timeout_ms) ||
248+
mp_hal_is_interrupted()) {
249+
return -MP_ETIMEDOUT;
250+
}
251+
252+
RUN_BACKGROUND_TASKS;
253+
// Give the AirLift some time to do work instead of asking again immediately.
254+
mp_hal_delay_ms(50);
255+
}
217256
}
218257

258+
219259
socketpool_socket_obj_t *common_hal_socketpool_socket_accept(socketpool_socket_obj_t *self, mp_obj_t *peer_out) {
220260
socketpool_socket_obj_t *accepted = mp_obj_malloc_with_finaliser(socketpool_socket_obj_t, NULL);
221261
socketpool_socket_reset(accepted);
222262

223263
int ret = socketpool_socket_accept(self, peer_out, accepted);
224264
if (ret < 0) {
265+
if (ret == -MP_ETIMEDOUT) {
266+
// There is a specific subclass for timeouts.
267+
mp_raise_msg(&mp_type_TimeoutError, NULL);
268+
}
269+
// Otherwise, raise a general OSError. Includes EAGAIN.
225270
mp_raise_OSError(-ret);
226271
}
227272

@@ -238,16 +283,27 @@ int common_hal_socketpool_socket_bind(socketpool_socket_obj_t *self,
238283
mp_raise_OSError(MP_EINVAL);
239284
}
240285

241-
// Validate the host name (which might a numeric IP string) to an IPv4 address first.
286+
// Validate the host name (which might be a numeric IP string) to an IPv4 address first.
242287
uint8_t ipv4[IPV4_LENGTH];
243288
if (!socketpool_gethostbyname_ipv4(self->socketpool, host, ipv4)) {
244289
// Could not resolve hostname.
245290
common_hal_socketpool_socketpool_raise_gaierror_noname();
246291
}
247292

293+
const uint8_t zero_ipv4[IPV4_LENGTH] = { 0 };
294+
uint8_t self_ipv4[IPV4_LENGTH];
295+
ipv4_uint32_to_bytes(wifi_radio_get_ipv4_address(self->socketpool->radio), self_ipv4);
296+
297+
// The bound host's IP must be this host: 0.0.0.0 or wifi.radio.ipv4_address.
298+
if (memcmp(ipv4, zero_ipv4, IPV4_LENGTH) != 0 &&
299+
memcmp(ipv4, self_ipv4, IPV4_LENGTH) != 0) {
300+
// Same as CPython.
301+
mp_raise_OSError(99); // EADDRNOTAVAIL (sometimes 125!)
302+
}
248303
self->bound = true;
249304
memcpy(self->hostname, host, hostlen);
250305
self->hostname_len = hostlen;
306+
self->port = port;
251307
return 0;
252308
}
253309

@@ -256,9 +312,7 @@ void socketpool_socket_close(socketpool_socket_obj_t *self) {
256312
socketpool_socket_stop_client(self);
257313
}
258314

259-
if (self->server_started) {
260-
// TODO: how to shut down server?
261-
}
315+
// Re server_started: there is no way to shut down a server.
262316
}
263317

264318
void common_hal_socketpool_socket_close(socketpool_socket_obj_t *self) {
@@ -342,12 +396,13 @@ void socketpool_socket_start_server_mode(socketpool_socket_obj_t *self, airlift_
342396
return;
343397
}
344398

399+
uint8_t zero_ipv4[IPV4_LENGTH] = { 0 };
345400
uint8_t port_bytes[2];
346401
be_uint16_to_uint8_bytes((uint16_t)self->port, port_bytes);
347402
uint8_t conn_mode = mode;
348403

349-
const uint8_t *params[5] = { self->hostname, port_bytes, &self->num, &conn_mode };
350-
size_t param_lengths[5] = { self->hostname_len, 4, 2, 1, 1 };
404+
const uint8_t *params[4] = { zero_ipv4, port_bytes, &self->num, &conn_mode };
405+
size_t param_lengths[4] = { 4, 2, 1, 1 };
351406

352407
uint8_t result;
353408
uint8_t *responses[1] = { &result };
@@ -371,11 +426,23 @@ void common_hal_socketpool_socket_connect(socketpool_socket_obj_t *self,
371426
}
372427

373428
bool common_hal_socketpool_socket_get_closed(socketpool_socket_obj_t *self) {
374-
return socketpool_socket_status(self) == SOCKET_CLOSED;
429+
if (self->client_started) {
430+
return client_socket_status(self) == SOCKET_CLOSED;
431+
} else if (self->server_started) {
432+
return !server_socket_status(self);
433+
} else {
434+
return false;
435+
}
375436
}
376437

377438
bool common_hal_socketpool_socket_get_connected(socketpool_socket_obj_t *self) {
378-
return socketpool_socket_status(self) == SOCKET_ESTABLISHED;
439+
if (self->client_started) {
440+
return client_socket_status(self) == SOCKET_ESTABLISHED;
441+
} else if (self->server_started) {
442+
return server_socket_status(self);
443+
} else {
444+
return false;
445+
}
379446
}
380447

381448
bool common_hal_socketpool_socket_listen(socketpool_socket_obj_t *self, int backlog) {
@@ -447,8 +514,10 @@ int socketpool_socket_recv_into(socketpool_socket_obj_t *self, uint8_t *buf, uin
447514
mp_hal_is_interrupted()) {
448515
return 0;
449516
}
517+
450518
RUN_BACKGROUND_TASKS;
451-
mp_hal_delay_ms(500);
519+
// Give the AirLift some time to do work instead of asking again immediately.
520+
mp_hal_delay_ms(50);
452521
}
453522
}
454523

@@ -542,7 +611,7 @@ mp_int_t common_hal_socketpool_socket_get_type(socketpool_socket_obj_t *self) {
542611

543612

544613
int common_hal_socketpool_socket_setsockopt(socketpool_socket_obj_t *self, int level, int optname, const void *value, size_t optlen) {
545-
//// mp_raise_NotImplementedError(NULL); // TODO
614+
// TODO: not sure any of this can be implemented.
546615
return 0;
547616
}
548617

devices/airlift/common-hal/socketpool/Socket.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ typedef enum {
2323
SOCKET_CLOSING = 8,
2424
SOCKET_LAST_ACK = 9,
2525
SOCKET_TIME_WAIT = 10,
26-
} airlift_socket_status_t;
26+
} airlift_client_socket_status_t;
2727

2828
typedef struct ssl_sslsocket_obj ssl_sslsocket_obj_t;
2929

devices/airlift/common-hal/ssl/SSLSocket.c

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,6 @@ void common_hal_ssl_sslsocket_bind(ssl_sslsocket_obj_t *self, mp_obj_t addr_in)
5555
}
5656

5757
void common_hal_ssl_sslsocket_close(ssl_sslsocket_obj_t *self) {
58-
// TODO: MORE??
5958
common_hal_socketpool_socket_close(self->socket);
6059
}
6160

devices/airlift/common-hal/wifi/Radio.c

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@
2929

3030

3131
// Print out SPI traffic with AirLift.
32-
#define DEBUG_AIRLIFT 1
32+
#define DEBUG_AIRLIFT 0
3333

3434
#if DEBUG_AIRLIFT
3535
static const char *command_name(uint8_t command) {
@@ -420,7 +420,6 @@ size_t wifi_radio_wait_response_cmd(wifi_radio_obj_t *self, uint8_t cmd,
420420
response_lengths[i] = read_length;
421421

422422
// Read and discard bytes that didn't fit in buffer.
423-
// TODO report error?
424423
if (read_length > response_lengths[i]) {
425424
#if DEBUG_AIRLIFT
426425
PLAT_PRINTF("<!! response %d too long. expected %d, got %d\n", i, response_lengths[i], response_length);

shared-bindings/socketpool/Socket.c

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,9 @@ static MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(socketpool_socket___exit___obj, 4, 4,
5757
//| def accept(self) -> Tuple[Socket, Tuple[str, int]]:
5858
//| """Accept a connection on a listening socket of type SOCK_STREAM,
5959
//| creating a new socket of type SOCK_STREAM.
60-
//| Returns a tuple of (new_socket, remote_address)"""
60+
//| Returns a tuple of ``(new_socket, remote_address)``,
61+
//| where remote address is a tuple of ``(host, port)``.
62+
//| """
6163
//|
6264
static mp_obj_t _socketpool_socket_accept(mp_obj_t self_in) {
6365
socketpool_socket_obj_t *self = MP_OBJ_TO_PTR(self_in);
@@ -72,7 +74,7 @@ static MP_DEFINE_CONST_FUN_OBJ_1(socketpool_socket_accept_obj, _socketpool_socke
7274
//| def bind(self, address: Tuple[str, int]) -> None:
7375
//| """Bind a socket to an address
7476
//|
75-
//| :param ~tuple address: tuple of (remote_address, remote_port)"""
77+
//| :param ~tuple address: tuple of ``(host, port)``"""
7678
//| ...
7779
//|
7880
static mp_obj_t socketpool_socket_bind(mp_obj_t self_in, mp_obj_t addr_in) {
@@ -110,7 +112,7 @@ static MP_DEFINE_CONST_FUN_OBJ_1(socketpool_socket_close_obj, _socketpool_socket
110112
//| def connect(self, address: Tuple[str, int]) -> None:
111113
//| """Connect a socket to a remote address
112114
//|
113-
//| :param ~tuple address: tuple of (remote_address, remote_port)"""
115+
//| :param ~tuple address: tuple of ``(host, port)``"""
114116
//| ...
115117
//|
116118
static mp_obj_t socketpool_socket_connect(mp_obj_t self_in, mp_obj_t addr_in) {
@@ -154,7 +156,7 @@ static MP_DEFINE_CONST_FUN_OBJ_2(socketpool_socket_listen_obj, socketpool_socket
154156
//| Returns a tuple containing
155157
//|
156158
//| * the number of bytes received into the given buffer
157-
//| * a remote_address, which is a tuple of ip address and port number
159+
//| * a remote_address, which is a tuple of ``("ip_address", port)``.
158160
//|
159161
//| :param object buffer: buffer to read into"""
160162
//| ...
@@ -289,7 +291,7 @@ static MP_DEFINE_CONST_FUN_OBJ_2(socketpool_socket_sendall_obj, _socketpool_sock
289291
//| Suits sockets of type SOCK_DGRAM
290292
//|
291293
//| :param ~bytes bytes: some bytes to send
292-
//| :param ~tuple address: tuple of (remote_address, remote_port)"""
294+
//| :param ~tuple address: tuple of ``(host, port)``"""
293295
//| ...
294296
//|
295297
static mp_obj_t socketpool_socket_sendto(mp_obj_t self_in, mp_obj_t data_in, mp_obj_t addr_in) {

0 commit comments

Comments
 (0)