Skip to content

Commit e9e41d2

Browse files
committed
wip; scanning working except for AuthMode
get/set hostname power mgmt, ip config; compiles wip compiles SSID connection working fix authmode in scanned results getaddrinfo fix incorrect const in socket recv API wip: progress on socket ops wip wip; removing heap ops; still need to do sock ops HTTP fetches work wip ssl HTTPS fetching works wip: manage nina client and server UDP working both ways
1 parent b90b69c commit e9e41d2

58 files changed

Lines changed: 2413 additions & 2714 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

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

Lines changed: 459 additions & 600 deletions
Large diffs are not rendered by default.

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

Lines changed: 50 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -9,21 +9,64 @@
99
#include "py/obj.h"
1010

1111
#include "common-hal/socketpool/SocketPool.h"
12+
#include "shared-bindings/wifi/Radio.h"
13+
14+
typedef enum {
15+
SOCKET_CLOSED = 0,
16+
SOCKET_LISTEN = 1,
17+
SOCKET_SYN_SENT = 2,
18+
SOCKET_SYN_RCVD = 3,
19+
SOCKET_ESTABLISHED = 4,
20+
SOCKET_FIN_WAIT_1 = 5,
21+
SOCKET_FIN_WAIT_2 = 6,
22+
SOCKET_CLOSE_WAIT = 7,
23+
SOCKET_CLOSING = 8,
24+
SOCKET_LAST_ACK = 9,
25+
SOCKET_TIME_WAIT = 10,
26+
} airlift_socket_status_t;
1227

1328
typedef struct ssl_sslsocket_obj ssl_sslsocket_obj_t;
1429

1530
typedef struct {
1631
mp_obj_base_t base;
17-
int num;
18-
int type;
19-
int family;
20-
int ipproto;
21-
bool connected;
22-
socketpool_socketpool_obj_t *pool;
32+
socketpool_socketpool_obj_t *socketpool;
2333
ssl_sslsocket_obj_t *ssl_socket;
24-
mp_uint_t timeout_ms;
34+
mp_uint_t timeout_ms; // SOCKET_BLOCK_FOREVER is (mp_uint_t)-1.
35+
size_t hostname_len;
36+
uint8_t hostname[MAX_HOSTNAME_LENGTH + 1];
37+
mp_uint_t port;
38+
uint8_t num;
39+
uint8_t type;
40+
uint8_t family;
41+
uint8_t proto;
42+
bool connected;
43+
bool bound;
44+
bool client_started;
45+
bool server_started;
2546
} socketpool_socket_obj_t;
2647

48+
#define AIRLIFT_SOCKET_DEFAULT_TIMEOUT (3000)
49+
50+
#define IPPROTO_IP 0
51+
#define IPPROTO_ICMP 1
52+
#define IPPROTO_TCP 6
53+
#define IPPROTO_UDP 17
54+
55+
#define AF_UNSPEC 0
56+
#define AF_INET 2
57+
58+
#define SOCK_STREAM 1
59+
#define SOCK_DGRAM 2
60+
#define SOCK_RAW 3
61+
62+
// Used both internally and by AirLift.
63+
#define NO_SOCKET 255
64+
2765
void socket_user_reset(void);
2866
// Unblock workflow socket select thread (platform specific)
2967
void socketpool_socket_poll_resume(void);
68+
69+
void socketpool_socket_start_client_mode(socketpool_socket_obj_t *self, const char *host, size_t hostlen, uint32_t port, airlift_conn_mode_t mode);
70+
void socketpool_socket_stop_client(socketpool_socket_obj_t *self);
71+
72+
void socketpool_socket_start_server_mode(socketpool_socket_obj_t *self, airlift_conn_mode_t mode);

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

Lines changed: 72 additions & 103 deletions
Original file line numberDiff line numberDiff line change
@@ -8,117 +8,86 @@
88
#include "common-hal/socketpool/Socket.h"
99

1010
#include "py/runtime.h"
11+
#include "shared-bindings/ipaddress/IPv4Address.h"
1112
#include "shared-bindings/wifi/__init__.h"
1213
#include "common-hal/socketpool/__init__.h"
1314

1415
void common_hal_socketpool_socketpool_construct(socketpool_socketpool_obj_t *self, mp_obj_t radio) {
15-
// if (radio != MP_OBJ_FROM_PTR(&common_hal_wifi_radio_obj)) {
16-
// mp_raise_ValueError(MP_ERROR_TEXT("SocketPool can only be used with wifi.radio"));
17-
// }
16+
if (radio != MP_OBJ_FROM_PTR(&common_hal_wifi_radio_obj)) {
17+
mp_raise_ValueError(MP_ERROR_TEXT("SocketPool can only be used with wifi.radio"));
18+
}
19+
// Not really needed, but more convenient.
20+
self->radio = radio;
1821
}
1922

2023
// common_hal_socketpool_socket is in socketpool/Socket.c to centralize open socket tracking.
2124

22-
// int socketpool_getaddrinfo_common(const char *host, int service, const struct addrinfo *hints, struct addrinfo **res) {
23-
// // As of 2022, the version of lwip in esp-idf does not handle the
24-
// // trailing-dot syntax of domain names, so emulate it.
25-
// // Remove this once https://github.com/espressif/esp-idf/issues/10013 has
26-
// // been implemented
27-
// if (host) {
28-
// size_t strlen_host = strlen(host);
29-
// if (strlen_host && host[strlen_host - 1] == '.') {
30-
// mp_obj_t nodot = mp_obj_new_str(host, strlen_host - 1);
31-
// host = mp_obj_str_get_str(nodot);
32-
// }
33-
// }
34-
35-
// char service_buf[6];
36-
// snprintf(service_buf, sizeof(service_buf), "%d", service);
37-
38-
// return lwip_getaddrinfo(host, service_buf, hints, res);
39-
// }
40-
41-
// static mp_obj_t format_address(const struct sockaddr *addr, int family) {
42-
// char ip_str[IPADDR_STRLEN_MAX]; // big enough for any supported address type
43-
// const struct sockaddr_in *a = (void *)addr;
44-
45-
// switch (family) {
46-
// #if CIRCUITPY_SOCKETPOOL_IPV6
47-
// case AF_INET6:
48-
// inet_ntop(family, &((const struct sockaddr_in6 *)a)->sin6_addr, ip_str, sizeof(ip_str));
49-
// break;
50-
// #endif
51-
// default:
52-
// case AF_INET:
53-
// inet_ntop(family, &((const struct sockaddr_in *)a)->sin_addr, ip_str, sizeof(ip_str));
54-
// break;
55-
// }
56-
// return mp_obj_new_str(ip_str, strlen(ip_str));
57-
// return mp_const_none;
58-
// }
59-
60-
// static mp_obj_t convert_sockaddr(const struct addrinfo *ai, int port) {
61-
// // #if CIRCUITPY_SOCKETPOOL_IPV6
62-
// // mp_int_t n_tuple = ai->ai_family == AF_INET6 ? 4 : 2;
63-
// // #else
64-
// // mp_int_t n_tuple = 2;
65-
// // #endif
66-
// // mp_obj_tuple_t *result = MP_OBJ_TO_PTR(mp_obj_new_tuple(n_tuple, NULL));
67-
// // result->items[0] = format_address(ai->ai_addr, ai->ai_family);
68-
// // result->items[1] = MP_OBJ_NEW_SMALL_INT(port);
69-
// // #if CIRCUITPY_SOCKETPOOL_IPV6
70-
// // if (ai->ai_family == AF_INET6) {
71-
// // const struct sockaddr_in6 *ai6 = (void *)ai->ai_addr;
72-
// // result->items[2] = MP_OBJ_NEW_SMALL_INT(ai6->sin6_flowinfo);
73-
// // result->items[3] = MP_OBJ_NEW_SMALL_INT(ai6->sin6_scope_id);
74-
// // }
75-
// // #endif
76-
// // return result;
77-
// return mp_const_none;
78-
// }
79-
80-
// static mp_obj_t convert_addrinfo(const struct addrinfo *ai, int port) {
81-
// // MP_STATIC_ASSERT(AF_INET == SOCKETPOOL_AF_INET);
82-
// // #if CIRCUITPY_SOCKETPOOL_IPV6
83-
// // MP_STATIC_ASSERT(AF_INET6 == SOCKETPOOL_AF_INET6);
84-
// // #endif
85-
// // // MP_STATIC_ASSERT(AF_UNSPEC == SOCKETPOOL_AF_UNSPEC);
86-
// // mp_obj_tuple_t *result = MP_OBJ_TO_PTR(mp_obj_new_tuple(5, NULL));
87-
// // result->items[0] = MP_OBJ_NEW_SMALL_INT(ai->ai_family);
88-
// // result->items[1] = MP_OBJ_NEW_SMALL_INT(ai->ai_socktype);
89-
// // result->items[2] = MP_OBJ_NEW_SMALL_INT(ai->ai_protocol);
90-
// // result->items[3] = ai->ai_canonname ? mp_obj_new_str(ai->ai_canonname, strlen(ai->ai_canonname)) : MP_OBJ_NEW_QSTR(MP_QSTR_);
91-
// // result->items[4] = convert_sockaddr(ai, port);
92-
// // return result;
93-
// return mp_const_none;
94-
// }
25+
bool socketpool_gethostbyname_ipv4(socketpool_socketpool_obj_t *self, const char *host, uint8_t ipv4[4]) {
26+
const uint8_t *req_host_params[1] = { (uint8_t *)host };
27+
size_t req_host_param_lengths[1] = { strlen(host) };
28+
29+
uint8_t result = 0;
30+
uint8_t *req_host_responses[1] = { &result };
31+
size_t req_host_response_lengths[1] = { 1 };
32+
33+
// If host is a numeric IP address, AirLift will just parse and return the address.
34+
35+
size_t num_responses = wifi_radio_send_command_get_response(self->radio, REQ_HOST_BY_NAME_CMD,
36+
req_host_params, req_host_param_lengths, LENGTHS_8, MP_ARRAY_SIZE(req_host_params),
37+
req_host_responses, req_host_response_lengths, LENGTHS_8, MP_ARRAY_SIZE(req_host_responses),
38+
AIRLIFT_DEFAULT_TIMEOUT_MS);
39+
40+
if (num_responses >= 1) {
41+
if (result == 0) {
42+
return false;
43+
}
44+
45+
uint8_t *get_host_responses[1] = { ipv4 };
46+
size_t get_host_response_lengths[1] = { IPV4_LENGTH };
47+
48+
// Now actually get the name.
49+
num_responses = wifi_radio_send_command_get_response(self->radio, GET_HOST_BY_NAME_CMD,
50+
NULL, NULL, LENGTHS_8, 0,
51+
get_host_responses, get_host_response_lengths, LENGTHS_8, MP_ARRAY_SIZE(get_host_responses),
52+
AIRLIFT_DEFAULT_TIMEOUT_MS);
53+
if (num_responses == 1) {
54+
return true;
55+
}
56+
}
57+
58+
return false;
59+
}
60+
61+
static mp_obj_t socketpool_socketpool_gethostbyname_str(socketpool_socketpool_obj_t *self, const char *host) {
62+
uint8_t ipv4[4] = { 0 };
63+
64+
if (!socketpool_gethostbyname_ipv4(self, host, ipv4)) {
65+
// Could not resolve or parse hostname.
66+
return mp_const_none;
67+
}
68+
69+
vstr_t vstr;
70+
mp_print_t print;
71+
vstr_init_print(&vstr, 16, &print);
72+
mp_printf(&print, "%d.%d.%d.%d", ipv4[0], ipv4[1], ipv4[2], ipv4[3]);
73+
return mp_obj_new_str_from_vstr(&vstr);
74+
}
9575

9676
mp_obj_t common_hal_socketpool_getaddrinfo_raise(socketpool_socketpool_obj_t *self, const char *host, int port, int family, int type, int proto, int flags) {
97-
// const struct addrinfo hints = {
98-
// .ai_flags = flags,
99-
// .ai_family = family,
100-
// .ai_protocol = proto,
101-
// .ai_socktype = type,
102-
// };
103-
//
104-
// struct addrinfo *res = NULL;
105-
// int err = socketpool_getaddrinfo_common(host, port, &hints, &res);
106-
// if (err != 0 || res == NULL) {
107-
// common_hal_socketpool_socketpool_raise_gaierror_noname();
108-
// }
109-
//
110-
// nlr_buf_t nlr;
111-
// if (nlr_push(&nlr) == 0) {
112-
// mp_obj_t result = mp_obj_new_list(0, NULL);
113-
// for (struct addrinfo *ai = res; ai; ai = ai->ai_next) {
114-
// mp_obj_list_append(result, convert_addrinfo(ai, port));
115-
// }
116-
// nlr_pop();
117-
// lwip_freeaddrinfo(res);
118-
// return result;
119-
// } else {
120-
// lwip_freeaddrinfo(res);
121-
// nlr_raise(MP_OBJ_FROM_PTR(nlr.ret_val));
122-
// }
123-
return mp_const_none;
77+
mp_obj_t ip_str = socketpool_socketpool_gethostbyname_str(self, host);
78+
if (ip_str == mp_const_none) {
79+
// Could not resolve hostname.
80+
common_hal_socketpool_socketpool_raise_gaierror_noname();
81+
}
82+
83+
mp_obj_tuple_t *tuple = MP_OBJ_TO_PTR(mp_obj_new_tuple(5, NULL));
84+
tuple->items[0] = MP_OBJ_NEW_SMALL_INT(SOCKETPOOL_AF_INET);
85+
tuple->items[1] = MP_OBJ_NEW_SMALL_INT(SOCKETPOOL_SOCK_STREAM);
86+
tuple->items[2] = MP_OBJ_NEW_SMALL_INT(0);
87+
tuple->items[3] = MP_OBJ_NEW_QSTR(MP_QSTR_);
88+
mp_obj_tuple_t *sockaddr = MP_OBJ_TO_PTR(mp_obj_new_tuple(2, NULL));
89+
sockaddr->items[0] = ip_str;
90+
sockaddr->items[1] = MP_OBJ_NEW_SMALL_INT(port);
91+
tuple->items[4] = MP_OBJ_FROM_PTR(sockaddr);
92+
return mp_obj_new_list(1, (mp_obj_t *)&tuple);
12493
}

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

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,11 @@
77
#pragma once
88

99
#include "py/obj.h"
10+
#include "shared-bindings/wifi/Radio.h"
1011

1112
typedef struct {
1213
mp_obj_base_t base;
14+
wifi_radio_obj_t *radio;
1315
} socketpool_socketpool_obj_t;
16+
17+
bool socketpool_gethostbyname_ipv4(socketpool_socketpool_obj_t *self, const char *host, uint8_t ipv4[IPV4_LENGTH]);

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,5 +9,5 @@
99
#include "common-hal/socketpool/Socket.h"
1010

1111
void socketpool_user_reset(void) {
12-
// socket_user_reset();
12+
socket_user_reset();
1313
}

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

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,3 @@
55
// SPDX-License-Identifier: MIT
66

77
#pragma once
8-
9-
struct addrinfo;
10-
11-
// int socketpool_getaddrinfo_common(const char *host, int service, const struct addrinfo *hints, struct addrinfo **res);
12-
// void socketpool_resolve_host_or_throw(int family, int type, const char *hostname, struct sockaddr_storage *addr, int port);

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

Lines changed: 8 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -11,34 +11,28 @@
1111
#include "py/stream.h"
1212

1313
void common_hal_ssl_sslcontext_construct(ssl_sslcontext_obj_t *self) {
14-
// common_hal_ssl_sslcontext_set_default_verify_paths(self);
14+
common_hal_ssl_sslcontext_set_default_verify_paths(self);
1515
}
1616

1717
void common_hal_ssl_sslcontext_load_verify_locations(ssl_sslcontext_obj_t *self,
1818
const char *cadata) {
19-
// self->crt_bundle_attach = NULL;
20-
// self->use_global_ca_store = false;
21-
// self->cacert_buf = (const unsigned char *)cadata;
22-
// self->cacert_bytes = *cadata ? strlen(cadata) + 1 : 0;
19+
mp_raise_NotImplementedError(NULL);
2320
}
2421

2522
void common_hal_ssl_sslcontext_set_default_verify_paths(ssl_sslcontext_obj_t *self) {
26-
// self->crt_bundle_attach = crt_bundle_attach;
27-
// self->use_global_ca_store = true;
28-
// self->cacert_buf = NULL;
29-
// self->cacert_bytes = 0;
23+
// The default paths are what's built in to NINA-FW, so nothing need be done.
3024
}
3125

3226
bool common_hal_ssl_sslcontext_get_check_hostname(ssl_sslcontext_obj_t *self) {
33-
// return self->check_name;
34-
return false;
27+
return true;
3528
}
3629

3730
void common_hal_ssl_sslcontext_set_check_hostname(ssl_sslcontext_obj_t *self, bool value) {
38-
// self->check_name = value;
31+
if (!value) {
32+
mp_raise_ValueError_varg(MP_ERROR_TEXT("%q must be %q"), MP_QSTR_check_hostname, MP_QSTR_true);
33+
}
3934
}
4035

4136
void common_hal_ssl_sslcontext_load_cert_chain(ssl_sslcontext_obj_t *self, mp_buffer_info_t *cert_buf, mp_buffer_info_t *key_buf) {
42-
// self->cert_buf = *cert_buf;
43-
// self->key_buf = *key_buf;
37+
mp_raise_NotImplementedError(NULL);
4438
}

devices/airlift/common-hal/ssl/SSLContext.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,8 +10,8 @@
1010

1111
typedef struct {
1212
mp_obj_base_t base;
13-
bool check_name, use_global_ca_store;
14-
const unsigned char *cacert_buf;
13+
// bool check_name, use_global_ca_store;
14+
// const unsigned char *cacert_buf;
1515
// size_t cacert_bytes;
1616
// int (*crt_bundle_attach)(mbedtls_ssl_config *conf);
1717
// mp_buffer_info_t cert_buf, key_buf;

0 commit comments

Comments
 (0)