Skip to content

Commit e5e4b0c

Browse files
committed
Implement new routines in raspberrypi port
1 parent 2385aa6 commit e5e4b0c

File tree

7 files changed

+167
-85
lines changed

7 files changed

+167
-85
lines changed

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

Lines changed: 52 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
#include "supervisor/port.h"
2222
#include "supervisor/shared/tick.h"
2323
#include "supervisor/workflow.h"
24+
#include "common-hal/socketpool/__init__.h"
2425

2526
#include "lwip/dns.h"
2627
#include "lwip/err.h"
@@ -36,6 +37,36 @@
3637

3738
#include "sdk/src/rp2_common/pico_cyw43_arch/include/pico/cyw43_arch.h"
3839

40+
mp_obj_t socketpool_ip_addr_to_str(const ip_addr_t *addr) {
41+
char ip_str[IPADDR_STRLEN_MAX]; // big enough for any supported address type
42+
switch (IP_GET_TYPE(addr)) {
43+
#if CIRCUITPY_SOCKETPOOL_IPV6
44+
case IPADDR_TYPE_V6:
45+
ip6addr_ntoa_r(ip_2_ip6(addr), ip_str, sizeof(ip_str));
46+
break;
47+
#endif
48+
default:
49+
ip4addr_ntoa_r(ip_2_ip4(addr), ip_str, sizeof(ip_str));
50+
}
51+
return mp_obj_new_str(ip_str, strlen(ip_str));
52+
}
53+
54+
static mp_obj_t socketpool_ip_addr_and_port_to_tuple(const ip_addr_t *addr, int port) {
55+
mp_obj_t args[CIRCUITPY_SOCKETPOOL_IPV6 ? 4 : 2] = {
56+
socketpool_ip_addr_to_str(addr),
57+
MP_OBJ_NEW_SMALL_INT(port),
58+
};
59+
int n = 2;
60+
#if CIRCUITPY_SOCKETPOOL_IPV6
61+
if (IP_GET_TYPE(addr) == IPADDR_TYPE_V6) {
62+
items[2] = MP_OBJ_NEW_SMALL_INT(0); // sin6_flowinfo
63+
items[3] = MP_OBJ_NEW_SMALL_INT(ip_2_ip6(addr)->zone);
64+
n = 4;
65+
}
66+
#endif
67+
return mp_obj_new_tuple(n, args);
68+
}
69+
3970
#define MICROPY_PY_LWIP_SOCK_RAW (1)
4071

4172
#if 0 // print debugging info
@@ -380,7 +411,7 @@ static mp_uint_t lwip_raw_udp_send(socketpool_socket_obj_t *socket, const byte *
380411
}
381412

382413
// Helper function for recv/recvfrom to handle raw/UDP packets
383-
static mp_uint_t lwip_raw_udp_receive(socketpool_socket_obj_t *socket, byte *buf, mp_uint_t len, byte *ip, uint32_t *port, int *_errno) {
414+
static mp_uint_t lwip_raw_udp_receive(socketpool_socket_obj_t *socket, byte *buf, mp_uint_t len, mp_obj_t *peer_out, int *_errno) {
384415

385416
if (socket->incoming.pbuf == NULL) {
386417
if (socket->timeout == 0) {
@@ -400,9 +431,8 @@ static mp_uint_t lwip_raw_udp_receive(socketpool_socket_obj_t *socket, byte *buf
400431
}
401432
}
402433

403-
if (ip != NULL) {
404-
memcpy(ip, &socket->peer, sizeof(socket->peer));
405-
*port = socket->peer_port;
434+
if (peer_out != NULL) {
435+
*peer_out = socketpool_ip_addr_and_port_to_tuple(&socket->peer, socket->peer_port);
406436
}
407437

408438
struct pbuf *p = socket->incoming.pbuf;
@@ -726,7 +756,7 @@ socketpool_socket_obj_t *common_hal_socketpool_socket(socketpool_socketpool_obj_
726756
return socket;
727757
}
728758

729-
int socketpool_socket_accept(socketpool_socket_obj_t *self, uint8_t *ip, uint32_t *port, socketpool_socket_obj_t *accepted) {
759+
int socketpool_socket_accept(socketpool_socket_obj_t *self, mp_obj_t *peer_out, socketpool_socket_obj_t *accepted) {
730760
if (self->type != MOD_NETWORK_SOCK_STREAM) {
731761
return -MP_EOPNOTSUPP;
732762
}
@@ -808,20 +838,21 @@ int socketpool_socket_accept(socketpool_socket_obj_t *self, uint8_t *ip, uint32_
808838
MICROPY_PY_LWIP_EXIT
809839

810840
// output values
811-
memcpy(ip, &(accepted->pcb.tcp->remote_ip), NETUTILS_IPV4ADDR_BUFSIZE);
812-
*port = (mp_uint_t)accepted->pcb.tcp->remote_port;
841+
if (peer_out) {
842+
*peer_out = socketpool_ip_addr_and_port_to_tuple(&accepted->pcb.tcp->remote_ip, accepted->pcb.tcp->remote_port);
843+
}
813844

814845
return 1;
815846
}
816847

817848
socketpool_socket_obj_t *common_hal_socketpool_socket_accept(socketpool_socket_obj_t *socket,
818-
uint8_t *ip, uint32_t *port) {
849+
mp_obj_t *peer_out) {
819850
// Create new socket object, do it here because we must not raise an out-of-memory
820851
// exception when the LWIP concurrency lock is held
821852
socketpool_socket_obj_t *accepted = m_new_ll_obj_with_finaliser(socketpool_socket_obj_t);
822853
socketpool_socket_reset(accepted);
823854

824-
int ret = socketpool_socket_accept(socket, ip, port, accepted);
855+
int ret = socketpool_socket_accept(socket, peer_out, accepted);
825856

826857
if (ret <= 0) {
827858
m_del_obj(socketpool_socket_obj_t, accepted);
@@ -852,7 +883,7 @@ size_t common_hal_socketpool_socket_bind(socketpool_socket_obj_t *socket,
852883
ip_addr_t bind_addr;
853884
const ip_addr_t *bind_addr_ptr = &bind_addr;
854885
if (hostlen > 0) {
855-
socketpool_resolve_host_raise(socket->pool, host, &bind_addr);
886+
socketpool_resolve_host_raise(host, &bind_addr);
856887
} else {
857888
bind_addr_ptr = IP_ANY_TYPE;
858889
}
@@ -941,7 +972,7 @@ void common_hal_socketpool_socket_connect(socketpool_socket_obj_t *socket,
941972

942973
// get address
943974
ip_addr_t dest;
944-
socketpool_resolve_host_raise(socket->pool, host, &dest);
975+
socketpool_resolve_host_raise(host, &dest);
945976

946977
err_t err = ERR_ARG;
947978
switch (socket->type) {
@@ -966,7 +997,7 @@ void common_hal_socketpool_socket_connect(socketpool_socket_obj_t *socket,
966997
mp_raise_OSError(error_lookup_table[-err]);
967998
}
968999
socket->peer_port = (mp_uint_t)port;
969-
memcpy(socket->peer, &dest, sizeof(socket->peer));
1000+
memcpy(&socket->peer, &dest, sizeof(socket->peer));
9701001
MICROPY_PY_LWIP_EXIT
9711002

9721003
// And now we wait...
@@ -1054,22 +1085,25 @@ bool common_hal_socketpool_socket_listen(socketpool_socket_obj_t *socket, int ba
10541085
}
10551086

10561087
mp_uint_t common_hal_socketpool_socket_recvfrom_into(socketpool_socket_obj_t *socket,
1057-
uint8_t *buf, uint32_t len, uint8_t *ip, uint32_t *port) {
1088+
uint8_t *buf, uint32_t len, mp_obj_t *peer_out) {
10581089
int _errno;
10591090

10601091
mp_uint_t ret = 0;
10611092
switch (socket->type) {
10621093
case SOCKETPOOL_SOCK_STREAM: {
1063-
memcpy(ip, &socket->peer, sizeof(socket->peer));
1064-
*port = (mp_uint_t)socket->peer_port;
1094+
// output values
1095+
if (peer_out) {
1096+
*peer_out = socketpool_ip_addr_and_port_to_tuple(&socket->peer, socket->peer_port);
1097+
}
1098+
10651099
ret = lwip_tcp_receive(socket, (byte *)buf, len, &_errno);
10661100
break;
10671101
}
10681102
case SOCKETPOOL_SOCK_DGRAM:
10691103
#if MICROPY_PY_LWIP_SOCK_RAW
10701104
case SOCKETPOOL_SOCK_RAW:
10711105
#endif
1072-
ret = lwip_raw_udp_receive(socket, (byte *)buf, len, ip, port, &_errno);
1106+
ret = lwip_raw_udp_receive(socket, (byte *)buf, len, peer_out, &_errno);
10731107
break;
10741108
}
10751109
if (ret == (unsigned)-1) {
@@ -1092,7 +1126,7 @@ int socketpool_socket_recv_into(socketpool_socket_obj_t *socket,
10921126
#if MICROPY_PY_LWIP_SOCK_RAW
10931127
case SOCKETPOOL_SOCK_RAW:
10941128
#endif
1095-
ret = lwip_raw_udp_receive(socket, (byte *)buf, len, NULL, NULL, &_errno);
1129+
ret = lwip_raw_udp_receive(socket, (byte *)buf, len, NULL, &_errno);
10961130
break;
10971131
}
10981132
if (ret == (unsigned)-1) {
@@ -1143,7 +1177,7 @@ mp_uint_t common_hal_socketpool_socket_sendto(socketpool_socket_obj_t *socket,
11431177
const char *host, size_t hostlen, uint32_t port, const uint8_t *buf, uint32_t len) {
11441178
int _errno;
11451179
ip_addr_t ip;
1146-
socketpool_resolve_host_raise(socket->pool, host, &ip);
1180+
socketpool_resolve_host_raise(host, &ip);
11471181

11481182
mp_uint_t ret = 0;
11491183
switch (socket->type) {

ports/raspberrypi/common-hal/socketpool/Socket.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ typedef struct _lwip_socket_obj_t {
3535
} connection;
3636
} incoming;
3737
mp_obj_t callback;
38-
byte peer[4];
38+
ip_addr_t peer;
3939
mp_uint_t peer_port;
4040
mp_uint_t timeout;
4141
uint16_t recv_offset;

ports/raspberrypi/common-hal/socketpool/SocketPool.c

Lines changed: 2 additions & 63 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
// SPDX-License-Identifier: MIT
66

77
#include "shared-bindings/socketpool/SocketPool.h"
8+
#include "common-hal/socketpool/__init__.h"
89
#include "common-hal/socketpool/Socket.h"
910
#include "shared/runtime/interrupt_char.h"
1011
#include "py/runtime.h"
@@ -21,72 +22,10 @@ void common_hal_socketpool_socketpool_construct(socketpool_socketpool_obj_t *sel
2122

2223
// common_hal_socketpool_socket is in socketpool/Socket.c to centralize open socket tracking.
2324

24-
typedef struct _getaddrinfo_state_t {
25-
volatile int status;
26-
volatile ip_addr_t ipaddr;
27-
} getaddrinfo_state_t;
28-
29-
static void lwip_getaddrinfo_cb(const char *name, const ip_addr_t *ipaddr, void *arg) {
30-
getaddrinfo_state_t *state = arg;
31-
if (ipaddr != NULL) {
32-
state->status = 1;
33-
state->ipaddr = *ipaddr;
34-
} else {
35-
// error
36-
state->status = -2;
37-
}
38-
}
39-
40-
static int socketpool_resolve_host(socketpool_socketpool_obj_t *self, const char *host, ip_addr_t *addr) {
41-
42-
getaddrinfo_state_t state;
43-
state.status = 0;
44-
45-
MICROPY_PY_LWIP_ENTER
46-
err_t ret = dns_gethostbyname(host, (ip_addr_t *)&state.ipaddr, lwip_getaddrinfo_cb, &state);
47-
MICROPY_PY_LWIP_EXIT
48-
49-
switch (ret) {
50-
case ERR_OK:
51-
// cached
52-
state.status = 1;
53-
break;
54-
case ERR_INPROGRESS:
55-
while (state.status == 0) {
56-
RUN_BACKGROUND_TASKS;
57-
if (mp_hal_is_interrupted()) {
58-
break;
59-
}
60-
}
61-
break;
62-
default:
63-
state.status = ret;
64-
}
65-
66-
if (state.status < 0) {
67-
return state.status;
68-
// TODO: CPython raises gaierror, we raise with native lwIP negative error
69-
// values, to differentiate from normal errno's at least in such way.
70-
mp_raise_OSError(state.status);
71-
}
72-
73-
*addr = state.ipaddr;
74-
return 0;
75-
}
76-
77-
void socketpool_resolve_host_raise(socketpool_socketpool_obj_t *self, const char *host, ip_addr_t *addr) {
78-
int result = socketpool_resolve_host(self, host, addr);
79-
if (result < 0) {
80-
printf("socket_resolve_host() returned %d\n", result);
81-
common_hal_socketpool_socketpool_raise_gaierror_noname();
82-
mp_raise_OSError(-result);
83-
}
84-
}
85-
8625
mp_obj_t common_hal_socketpool_socketpool_gethostbyname(socketpool_socketpool_obj_t *self, const char *host) {
8726

8827
ip_addr_t addr;
89-
socketpool_resolve_host_raise(self, host, &addr);
28+
socketpool_resolve_host_raise(host, &addr);
9029

9130
char ip_str[IP4ADDR_STRLEN_MAX];
9231
inet_ntoa_r(addr, ip_str, IP4ADDR_STRLEN_MAX);

ports/raspberrypi/common-hal/socketpool/SocketPool.h

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,5 +13,3 @@
1313
typedef struct {
1414
mp_obj_base_t base;
1515
} socketpool_socketpool_obj_t;
16-
17-
void socketpool_resolve_host_raise(socketpool_socketpool_obj_t *self, const char *host, ip_addr_t *addr);

ports/raspberrypi/common-hal/socketpool/__init__.c

Lines changed: 69 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,10 +4,78 @@
44
//
55
// SPDX-License-Identifier: MIT
66

7+
#include "py/runtime.h"
8+
#include "shared/runtime/interrupt_char.h"
9+
710
#include "shared-bindings/socketpool/__init__.h"
11+
#include "shared-bindings/socketpool/SocketPool.h"
12+
#include "shared-bindings/wifi/__init__.h"
13+
#include "common-hal/socketpool/__init__.h"
14+
15+
#include "lwip/dns.h"
16+
#include "lwip/inet.h"
817

9-
#include "common-hal/socketpool/Socket.h"
1018

1119
void socketpool_user_reset(void) {
1220
socket_user_reset();
1321
}
22+
23+
typedef struct _getaddrinfo_state_t {
24+
volatile int status;
25+
volatile ip_addr_t ipaddr;
26+
} getaddrinfo_state_t;
27+
28+
static void lwip_getaddrinfo_cb(const char *name, const ip_addr_t *ipaddr, void *arg) {
29+
getaddrinfo_state_t *state = arg;
30+
if (ipaddr != NULL) {
31+
state->status = 1;
32+
state->ipaddr = *ipaddr;
33+
} else {
34+
// error
35+
state->status = -2;
36+
}
37+
}
38+
39+
40+
static int socketpool_resolve_host(const char *host, ip_addr_t *addr) {
41+
42+
getaddrinfo_state_t state;
43+
state.status = 0;
44+
45+
MICROPY_PY_LWIP_ENTER
46+
err_t ret = dns_gethostbyname(host, (ip_addr_t *)&state.ipaddr, lwip_getaddrinfo_cb, &state);
47+
MICROPY_PY_LWIP_EXIT
48+
49+
switch (ret) {
50+
case ERR_OK:
51+
// cached
52+
state.status = 1;
53+
break;
54+
case ERR_INPROGRESS:
55+
while (state.status == 0) {
56+
RUN_BACKGROUND_TASKS;
57+
if (mp_hal_is_interrupted()) {
58+
break;
59+
}
60+
}
61+
break;
62+
default:
63+
state.status = ret;
64+
}
65+
66+
if (state.status < 0) {
67+
return state.status;
68+
}
69+
70+
*addr = state.ipaddr;
71+
return 0;
72+
}
73+
74+
void socketpool_resolve_host_raise(const char *host, ip_addr_t *addr) {
75+
int result = socketpool_resolve_host(host, addr);
76+
if (result < 0) {
77+
printf("socket_resolve_host() returned %d\n", result);
78+
common_hal_socketpool_socketpool_raise_gaierror_noname();
79+
mp_raise_OSError(-result);
80+
}
81+
}

ports/raspberrypi/common-hal/socketpool/__init__.h

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

77
#pragma once
8+
9+
#include "lwip/ip_addr.h"
10+
11+
mp_obj_t socketpool_ip_addr_to_str(const ip_addr_t *addr);
12+
void socketpool_resolve_host_raise(const char *host, ip_addr_t *addr);

0 commit comments

Comments
 (0)