extmod/modnetwork: Remove modnetwork socket u_state member.

To simplify the socket state.

The CC3K driver (see drivers/cc3000/inc/socket.h and src/socket.c) has
socket() returning an INT16 so there is now enough room to store it
directly in the fileno member.
This commit is contained in:
iabdalkader 2021-09-14 21:21:09 +02:00 committed by Damien George
parent f9d573a4ac
commit d9749f90ad
4 changed files with 68 additions and 69 deletions

View File

@ -72,15 +72,11 @@ typedef struct _mod_network_socket_obj_t {
mp_obj_base_t base;
mp_obj_t nic;
mod_network_nic_type_t *nic_type;
union {
struct {
uint8_t domain;
uint8_t type;
int8_t fileno;
uint8_t bound;
} u_param;
mp_uint_t u_state;
};
uint32_t domain : 5;
uint32_t type : 5;
uint32_t proto : 5;
uint32_t bound : 1;
int32_t fileno : 16;
#if MICROPY_PY_USOCKET_EXTENDED_STATE
// Extended socket state for NICs/ports that need it.
int32_t timeout;

View File

@ -51,16 +51,17 @@ STATIC mp_obj_t socket_make_new(const mp_obj_type_t *type, size_t n_args, size_t
s->base.type = &socket_type;
s->nic = MP_OBJ_NULL;
s->nic_type = NULL;
s->u_param.domain = MOD_NETWORK_AF_INET;
s->u_param.type = MOD_NETWORK_SOCK_STREAM;
s->u_param.fileno = -1;
s->u_param.bound = false;
s->domain = MOD_NETWORK_AF_INET;
s->type = MOD_NETWORK_SOCK_STREAM;
s->proto = 0;
s->bound = false;
s->fileno = -1;
if (n_args >= 1) {
s->u_param.domain = mp_obj_get_int(args[0]);
s->domain = mp_obj_get_int(args[0]);
if (n_args >= 2) {
s->u_param.type = mp_obj_get_int(args[1]);
s->type = mp_obj_get_int(args[1]);
if (n_args >= 4) {
s->u_param.fileno = mp_obj_get_int(args[3]);
s->fileno = mp_obj_get_int(args[3]);
}
}
}

View File

@ -136,13 +136,13 @@ STATIC int cc3k_gethostbyname(mp_obj_t nic, const char *name, mp_uint_t len, uin
}
STATIC int cc3k_socket_socket(mod_network_socket_obj_t *socket, int *_errno) {
if (socket->u_param.domain != MOD_NETWORK_AF_INET) {
if (socket->domain != MOD_NETWORK_AF_INET) {
*_errno = MP_EAFNOSUPPORT;
return -1;
}
mp_uint_t type;
switch (socket->u_param.type) {
switch (socket->type) {
case MOD_NETWORK_SOCK_STREAM:
type = SOCK_STREAM;
break;
@ -168,23 +168,23 @@ STATIC int cc3k_socket_socket(mod_network_socket_obj_t *socket, int *_errno) {
cc3k_reset_fd_closed_state(fd);
// store state of this socket
socket->u_state = fd;
socket->fileno = fd;
// make accept blocking by default
int optval = SOCK_OFF;
socklen_t optlen = sizeof(optval);
CC3000_EXPORT(setsockopt)(socket->u_state, SOL_SOCKET, SOCKOPT_ACCEPT_NONBLOCK, &optval, optlen);
CC3000_EXPORT(setsockopt)(socket->fileno, SOL_SOCKET, SOCKOPT_ACCEPT_NONBLOCK, &optval, optlen);
return 0;
}
STATIC void cc3k_socket_close(mod_network_socket_obj_t *socket) {
CC3000_EXPORT(closesocket)(socket->u_state);
CC3000_EXPORT(closesocket)(socket->fileno);
}
STATIC int cc3k_socket_bind(mod_network_socket_obj_t *socket, byte *ip, mp_uint_t port, int *_errno) {
MAKE_SOCKADDR(addr, ip, port)
int ret = CC3000_EXPORT(bind)(socket->u_state, &addr, sizeof(addr));
int ret = CC3000_EXPORT(bind)(socket->fileno, &addr, sizeof(addr));
if (ret != 0) {
*_errno = ret;
return -1;
@ -193,7 +193,7 @@ STATIC int cc3k_socket_bind(mod_network_socket_obj_t *socket, byte *ip, mp_uint_
}
STATIC int cc3k_socket_listen(mod_network_socket_obj_t *socket, mp_int_t backlog, int *_errno) {
int ret = CC3000_EXPORT(listen)(socket->u_state, backlog);
int ret = CC3000_EXPORT(listen)(socket->fileno, backlog);
if (ret != 0) {
*_errno = ret;
return -1;
@ -206,7 +206,7 @@ STATIC int cc3k_socket_accept(mod_network_socket_obj_t *socket, mod_network_sock
int fd;
sockaddr addr;
socklen_t addr_len = sizeof(addr);
if ((fd = CC3000_EXPORT(accept)(socket->u_state, &addr, &addr_len)) < 0) {
if ((fd = CC3000_EXPORT(accept)(socket->fileno, &addr, &addr_len)) < 0) {
if (fd == SOC_IN_PROGRESS) {
*_errno = MP_EAGAIN;
} else {
@ -219,7 +219,7 @@ STATIC int cc3k_socket_accept(mod_network_socket_obj_t *socket, mod_network_sock
cc3k_reset_fd_closed_state(fd);
// store state in new socket object
socket2->u_state = fd;
socket2->fileno = fd;
// return ip and port
// it seems CC3000 returns little endian for accept??
@ -235,7 +235,7 @@ STATIC int cc3k_socket_accept(mod_network_socket_obj_t *socket, mod_network_sock
STATIC int cc3k_socket_connect(mod_network_socket_obj_t *socket, byte *ip, mp_uint_t port, int *_errno) {
MAKE_SOCKADDR(addr, ip, port)
int ret = CC3000_EXPORT(connect)(socket->u_state, &addr, sizeof(addr));
int ret = CC3000_EXPORT(connect)(socket->fileno, &addr, sizeof(addr));
if (ret != 0) {
*_errno = CC3000_EXPORT(errno);
return -1;
@ -244,8 +244,8 @@ STATIC int cc3k_socket_connect(mod_network_socket_obj_t *socket, byte *ip, mp_ui
}
STATIC mp_uint_t cc3k_socket_send(mod_network_socket_obj_t *socket, const byte *buf, mp_uint_t len, int *_errno) {
if (cc3k_get_fd_closed_state(socket->u_state)) {
CC3000_EXPORT(closesocket)(socket->u_state);
if (cc3k_get_fd_closed_state(socket->fileno)) {
CC3000_EXPORT(closesocket)(socket->fileno);
*_errno = MP_EPIPE;
return -1;
}
@ -255,7 +255,7 @@ STATIC mp_uint_t cc3k_socket_send(mod_network_socket_obj_t *socket, const byte *
mp_int_t bytes = 0;
while (bytes < len) {
int n = MIN((len - bytes), MAX_TX_PACKET);
n = CC3000_EXPORT(send)(socket->u_state, (uint8_t *)buf + bytes, n, 0);
n = CC3000_EXPORT(send)(socket->fileno, (uint8_t *)buf + bytes, n, 0);
if (n <= 0) {
*_errno = CC3000_EXPORT(errno);
return -1;
@ -268,18 +268,18 @@ STATIC mp_uint_t cc3k_socket_send(mod_network_socket_obj_t *socket, const byte *
STATIC mp_uint_t cc3k_socket_recv(mod_network_socket_obj_t *socket, byte *buf, mp_uint_t len, int *_errno) {
// check the socket is open
if (cc3k_get_fd_closed_state(socket->u_state)) {
if (cc3k_get_fd_closed_state(socket->fileno)) {
// socket is closed, but CC3000 may have some data remaining in buffer, so check
fd_set rfds;
FD_ZERO(&rfds);
FD_SET(socket->u_state, &rfds);
FD_SET(socket->fileno, &rfds);
cc3000_timeval tv;
tv.tv_sec = 0;
tv.tv_usec = 1;
int nfds = CC3000_EXPORT(select)(socket->u_state + 1, &rfds, NULL, NULL, &tv);
if (nfds == -1 || !FD_ISSET(socket->u_state, &rfds)) {
int nfds = CC3000_EXPORT(select)(socket->fileno + 1, &rfds, NULL, NULL, &tv);
if (nfds == -1 || !FD_ISSET(socket->fileno, &rfds)) {
// no data waiting, so close socket and return 0 data
CC3000_EXPORT(closesocket)(socket->u_state);
CC3000_EXPORT(closesocket)(socket->fileno);
return 0;
}
}
@ -288,7 +288,7 @@ STATIC mp_uint_t cc3k_socket_recv(mod_network_socket_obj_t *socket, byte *buf, m
len = MIN(len, MAX_RX_PACKET);
// do the recv
int ret = CC3000_EXPORT(recv)(socket->u_state, buf, len, 0);
int ret = CC3000_EXPORT(recv)(socket->fileno, buf, len, 0);
if (ret < 0) {
*_errno = CC3000_EXPORT(errno);
return -1;
@ -299,7 +299,7 @@ STATIC mp_uint_t cc3k_socket_recv(mod_network_socket_obj_t *socket, byte *buf, m
STATIC mp_uint_t cc3k_socket_sendto(mod_network_socket_obj_t *socket, const byte *buf, mp_uint_t len, byte *ip, mp_uint_t port, int *_errno) {
MAKE_SOCKADDR(addr, ip, port)
int ret = CC3000_EXPORT(sendto)(socket->u_state, (byte *)buf, len, 0, (sockaddr *)&addr, sizeof(addr));
int ret = CC3000_EXPORT(sendto)(socket->fileno, (byte *)buf, len, 0, (sockaddr *)&addr, sizeof(addr));
if (ret < 0) {
*_errno = CC3000_EXPORT(errno);
return -1;
@ -310,7 +310,7 @@ STATIC mp_uint_t cc3k_socket_sendto(mod_network_socket_obj_t *socket, const byte
STATIC mp_uint_t cc3k_socket_recvfrom(mod_network_socket_obj_t *socket, byte *buf, mp_uint_t len, byte *ip, mp_uint_t *port, int *_errno) {
sockaddr addr;
socklen_t addr_len = sizeof(addr);
mp_int_t ret = CC3000_EXPORT(recvfrom)(socket->u_state, buf, len, 0, &addr, &addr_len);
mp_int_t ret = CC3000_EXPORT(recvfrom)(socket->fileno, buf, len, 0, &addr, &addr_len);
if (ret < 0) {
*_errno = CC3000_EXPORT(errno);
return -1;
@ -320,7 +320,7 @@ STATIC mp_uint_t cc3k_socket_recvfrom(mod_network_socket_obj_t *socket, byte *bu
}
STATIC int cc3k_socket_setsockopt(mod_network_socket_obj_t *socket, mp_uint_t level, mp_uint_t opt, const void *optval, mp_uint_t optlen, int *_errno) {
int ret = CC3000_EXPORT(setsockopt)(socket->u_state, level, opt, optval, optlen);
int ret = CC3000_EXPORT(setsockopt)(socket->fileno, level, opt, optval, optlen);
if (ret < 0) {
*_errno = CC3000_EXPORT(errno);
return -1;
@ -340,14 +340,14 @@ STATIC int cc3k_socket_settimeout(mod_network_socket_obj_t *socket, mp_uint_t ti
// set blocking mode
optval = SOCK_OFF;
}
ret = CC3000_EXPORT(setsockopt)(socket->u_state, SOL_SOCKET, SOCKOPT_RECV_NONBLOCK, &optval, optlen);
ret = CC3000_EXPORT(setsockopt)(socket->fileno, SOL_SOCKET, SOCKOPT_RECV_NONBLOCK, &optval, optlen);
if (ret == 0) {
ret = CC3000_EXPORT(setsockopt)(socket->u_state, SOL_SOCKET, SOCKOPT_ACCEPT_NONBLOCK, &optval, optlen);
ret = CC3000_EXPORT(setsockopt)(socket->fileno, SOL_SOCKET, SOCKOPT_ACCEPT_NONBLOCK, &optval, optlen);
}
} else {
// set timeout
socklen_t optlen = sizeof(timeout_ms);
ret = CC3000_EXPORT(setsockopt)(socket->u_state, SOL_SOCKET, SOCKOPT_RECV_TIMEOUT, &timeout_ms, optlen);
ret = CC3000_EXPORT(setsockopt)(socket->fileno, SOL_SOCKET, SOCKOPT_RECV_TIMEOUT, &timeout_ms, optlen);
}
if (ret != 0) {
@ -363,7 +363,7 @@ STATIC int cc3k_socket_ioctl(mod_network_socket_obj_t *socket, mp_uint_t request
if (request == MP_STREAM_POLL) {
mp_uint_t flags = arg;
ret = 0;
int fd = socket->u_state;
int fd = socket->fileno;
// init fds
fd_set rfds, wfds, xfds;

View File

@ -99,33 +99,33 @@ STATIC int wiznet5k_gethostbyname(mp_obj_t nic, const char *name, mp_uint_t len,
}
STATIC int wiznet5k_socket_socket(mod_network_socket_obj_t *socket, int *_errno) {
if (socket->u_param.domain != MOD_NETWORK_AF_INET) {
if (socket->domain != MOD_NETWORK_AF_INET) {
*_errno = MP_EAFNOSUPPORT;
return -1;
}
switch (socket->u_param.type) {
switch (socket->type) {
case MOD_NETWORK_SOCK_STREAM:
socket->u_param.type = Sn_MR_TCP;
socket->type = Sn_MR_TCP;
break;
case MOD_NETWORK_SOCK_DGRAM:
socket->u_param.type = Sn_MR_UDP;
socket->type = Sn_MR_UDP;
break;
default:
*_errno = MP_EINVAL;
return -1;
}
if (socket->u_param.fileno == -1) {
if (socket->fileno == -1) {
// get first unused socket number
for (mp_uint_t sn = 0; sn < _WIZCHIP_SOCK_NUM_; sn++) {
if ((wiznet5k_obj.socket_used & (1 << sn)) == 0) {
wiznet5k_obj.socket_used |= (1 << sn);
socket->u_param.fileno = sn;
socket->fileno = sn;
break;
}
}
if (socket->u_param.fileno == -1) {
if (socket->fileno == -1) {
// too many open sockets
*_errno = MP_EMFILE;
return -1;
@ -137,13 +137,13 @@ STATIC int wiznet5k_socket_socket(mod_network_socket_obj_t *socket, int *_errno)
// So, we defer the open until we know what kind of socket we want.
// use "domain" to indicate that this socket has not yet been opened
socket->u_param.domain = 0;
socket->domain = 0;
return 0;
}
STATIC void wiznet5k_socket_close(mod_network_socket_obj_t *socket) {
uint8_t sn = (uint8_t)socket->u_param.fileno;
uint8_t sn = (uint8_t)socket->fileno;
if (sn < _WIZCHIP_SOCK_NUM_) {
wiznet5k_obj.socket_used &= ~(1 << sn);
WIZCHIP_EXPORT(close)(sn);
@ -152,7 +152,7 @@ STATIC void wiznet5k_socket_close(mod_network_socket_obj_t *socket) {
STATIC int wiznet5k_socket_bind(mod_network_socket_obj_t *socket, byte *ip, mp_uint_t port, int *_errno) {
// open the socket in server mode (if port != 0)
mp_int_t ret = WIZCHIP_EXPORT(socket)(socket->u_param.fileno, socket->u_param.type, port, 0);
mp_int_t ret = WIZCHIP_EXPORT(socket)(socket->fileno, socket->type, port, 0);
if (ret < 0) {
wiznet5k_socket_close(socket);
*_errno = -ret;
@ -160,14 +160,14 @@ STATIC int wiznet5k_socket_bind(mod_network_socket_obj_t *socket, byte *ip, mp_u
}
// indicate that this socket has been opened
socket->u_param.domain = 1;
socket->domain = 1;
// success
return 0;
}
STATIC int wiznet5k_socket_listen(mod_network_socket_obj_t *socket, mp_int_t backlog, int *_errno) {
mp_int_t ret = WIZCHIP_EXPORT(listen)(socket->u_param.fileno);
mp_int_t ret = WIZCHIP_EXPORT(listen)(socket->fileno);
if (ret < 0) {
wiznet5k_socket_close(socket);
*_errno = -ret;
@ -178,17 +178,19 @@ STATIC int wiznet5k_socket_listen(mod_network_socket_obj_t *socket, mp_int_t bac
STATIC int wiznet5k_socket_accept(mod_network_socket_obj_t *socket, mod_network_socket_obj_t *socket2, byte *ip, mp_uint_t *port, int *_errno) {
for (;;) {
int sr = getSn_SR((uint8_t)socket->u_param.fileno);
int sr = getSn_SR((uint8_t)socket->fileno);
if (sr == SOCK_ESTABLISHED) {
socket2->u_param = socket->u_param;
getSn_DIPR((uint8_t)socket2->u_param.fileno, ip);
*port = getSn_PORT(socket2->u_param.fileno);
socket2->domain = socket->domain;
socket2->type = socket->type;
socket2->fileno = socket->fileno;
getSn_DIPR((uint8_t)socket2->fileno, ip);
*port = getSn_PORT(socket2->fileno);
// WIZnet turns the listening socket into the client socket, so we
// need to re-bind and re-listen on another socket for the server.
// TODO handle errors, especially no-more-sockets error
socket->u_param.domain = MOD_NETWORK_AF_INET;
socket->u_param.fileno = -1;
socket->domain = MOD_NETWORK_AF_INET;
socket->fileno = -1;
int _errno2;
if (wiznet5k_socket_socket(socket, &_errno2) != 0) {
// printf("(bad resocket %d)\n", _errno2);
@ -217,7 +219,7 @@ STATIC int wiznet5k_socket_connect(mod_network_socket_obj_t *socket, byte *ip, m
// now connect
MP_THREAD_GIL_EXIT();
mp_int_t ret = WIZCHIP_EXPORT(connect)(socket->u_param.fileno, ip, port);
mp_int_t ret = WIZCHIP_EXPORT(connect)(socket->fileno, ip, port);
MP_THREAD_GIL_ENTER();
if (ret < 0) {
@ -232,7 +234,7 @@ STATIC int wiznet5k_socket_connect(mod_network_socket_obj_t *socket, byte *ip, m
STATIC mp_uint_t wiznet5k_socket_send(mod_network_socket_obj_t *socket, const byte *buf, mp_uint_t len, int *_errno) {
MP_THREAD_GIL_EXIT();
mp_int_t ret = WIZCHIP_EXPORT(send)(socket->u_param.fileno, (byte *)buf, len);
mp_int_t ret = WIZCHIP_EXPORT(send)(socket->fileno, (byte *)buf, len);
MP_THREAD_GIL_ENTER();
// TODO convert Wiz errno's to POSIX ones
@ -246,7 +248,7 @@ STATIC mp_uint_t wiznet5k_socket_send(mod_network_socket_obj_t *socket, const by
STATIC mp_uint_t wiznet5k_socket_recv(mod_network_socket_obj_t *socket, byte *buf, mp_uint_t len, int *_errno) {
MP_THREAD_GIL_EXIT();
mp_int_t ret = WIZCHIP_EXPORT(recv)(socket->u_param.fileno, buf, len);
mp_int_t ret = WIZCHIP_EXPORT(recv)(socket->fileno, buf, len);
MP_THREAD_GIL_ENTER();
// TODO convert Wiz errno's to POSIX ones
@ -259,7 +261,7 @@ STATIC mp_uint_t wiznet5k_socket_recv(mod_network_socket_obj_t *socket, byte *bu
}
STATIC mp_uint_t wiznet5k_socket_sendto(mod_network_socket_obj_t *socket, const byte *buf, mp_uint_t len, byte *ip, mp_uint_t port, int *_errno) {
if (socket->u_param.domain == 0) {
if (socket->domain == 0) {
// socket not opened; use "bind" function to open the socket in client mode
if (wiznet5k_socket_bind(socket, ip, 0, _errno) != 0) {
return -1;
@ -267,7 +269,7 @@ STATIC mp_uint_t wiznet5k_socket_sendto(mod_network_socket_obj_t *socket, const
}
MP_THREAD_GIL_EXIT();
mp_int_t ret = WIZCHIP_EXPORT(sendto)(socket->u_param.fileno, (byte *)buf, len, ip, port);
mp_int_t ret = WIZCHIP_EXPORT(sendto)(socket->fileno, (byte *)buf, len, ip, port);
MP_THREAD_GIL_ENTER();
if (ret < 0) {
@ -281,7 +283,7 @@ STATIC mp_uint_t wiznet5k_socket_sendto(mod_network_socket_obj_t *socket, const
STATIC mp_uint_t wiznet5k_socket_recvfrom(mod_network_socket_obj_t *socket, byte *buf, mp_uint_t len, byte *ip, mp_uint_t *port, int *_errno) {
uint16_t port2;
MP_THREAD_GIL_EXIT();
mp_int_t ret = WIZCHIP_EXPORT(recvfrom)(socket->u_param.fileno, buf, len, ip, &port2);
mp_int_t ret = WIZCHIP_EXPORT(recvfrom)(socket->fileno, buf, len, ip, &port2);
MP_THREAD_GIL_ENTER();
*port = port2;
if (ret < 0) {
@ -307,7 +309,7 @@ STATIC int wiznet5k_socket_settimeout(mod_network_socket_obj_t *socket, mp_uint_
if (timeout_ms == 0) {
// set non-blocking mode
uint8_t arg = SOCK_IO_NONBLOCK;
WIZCHIP_EXPORT(ctlsocket)(socket->u_param.fileno, CS_SET_IOMODE, &arg);
WIZCHIP_EXPORT(ctlsocket)(socket->fileno, CS_SET_IOMODE, &arg);
}
*/
}
@ -315,10 +317,10 @@ STATIC int wiznet5k_socket_settimeout(mod_network_socket_obj_t *socket, mp_uint_
STATIC int wiznet5k_socket_ioctl(mod_network_socket_obj_t *socket, mp_uint_t request, mp_uint_t arg, int *_errno) {
if (request == MP_STREAM_POLL) {
int ret = 0;
if (arg & MP_STREAM_POLL_RD && getSn_RX_RSR(socket->u_param.fileno) != 0) {
if (arg & MP_STREAM_POLL_RD && getSn_RX_RSR(socket->fileno) != 0) {
ret |= MP_STREAM_POLL_RD;
}
if (arg & MP_STREAM_POLL_WR && getSn_TX_FSR(socket->u_param.fileno) != 0) {
if (arg & MP_STREAM_POLL_WR && getSn_TX_FSR(socket->fileno) != 0) {
ret |= MP_STREAM_POLL_WR;
}
return ret;