cc3200: Refactor and clean-up socket closing code.

This commit is contained in:
Daniel Campora 2015-07-10 11:32:53 +02:00
parent ecb7f9fe58
commit cf814b2d34
4 changed files with 15 additions and 49 deletions

View File

@ -43,16 +43,17 @@ typedef struct _mod_network_nic_type_t {
typedef struct _mod_network_socket_base_t { typedef struct _mod_network_socket_base_t {
union { union {
struct { struct {
// this order is important so that fileno gets > 0 once
// the socket descriptor is assigned after being created.
uint8_t domain; uint8_t domain;
int8_t fileno;
uint8_t type; uint8_t type;
uint8_t proto; uint8_t proto;
int8_t fileno;
} u_param; } u_param;
int16_t sd; int16_t sd;
}; };
bool has_timeout; bool has_timeout;
bool cert_req; bool cert_req;
bool closed;
} mod_network_socket_base_t; } mod_network_socket_base_t;
typedef struct _mod_network_socket_obj_t { typedef struct _mod_network_socket_obj_t {

View File

@ -138,7 +138,6 @@ STATIC mp_obj_t socket_make_new(mp_obj_t type_in, mp_uint_t n_args, mp_uint_t n_
s->sock_base.u_param.fileno = -1; s->sock_base.u_param.fileno = -1;
s->sock_base.has_timeout = false; s->sock_base.has_timeout = false;
s->sock_base.cert_req = false; s->sock_base.cert_req = false;
s->sock_base.closed = false;
if (n_args > 0) { if (n_args > 0) {
s->sock_base.u_param.domain = mp_obj_get_int(args[0]); s->sock_base.u_param.domain = mp_obj_get_int(args[0]);
@ -158,7 +157,6 @@ STATIC mp_obj_t socket_make_new(mp_obj_t type_in, mp_uint_t n_args, mp_uint_t n_
if (wlan_socket_socket(s, &_errno) != 0) { if (wlan_socket_socket(s, &_errno) != 0) {
nlr_raise(mp_obj_new_exception_arg1(&mp_type_OSError, MP_OBJ_NEW_SMALL_INT(-_errno))); nlr_raise(mp_obj_new_exception_arg1(&mp_type_OSError, MP_OBJ_NEW_SMALL_INT(-_errno)));
} }
return s; return s;
} }

View File

@ -1151,25 +1151,20 @@ STATIC const mp_cb_methods_t wlan_cb_methods = {
int wlan_gethostbyname(const char *name, mp_uint_t len, uint8_t *out_ip, uint8_t family) { int wlan_gethostbyname(const char *name, mp_uint_t len, uint8_t *out_ip, uint8_t family) {
uint32_t ip; uint32_t ip;
int result = sl_NetAppDnsGetHostByName((_i8 *)name, (_u16)len, (_u32*)&ip, (_u8)family); int result = sl_NetAppDnsGetHostByName((_i8 *)name, (_u16)len, (_u32*)&ip, (_u8)family);
out_ip[0] = ip; out_ip[0] = ip;
out_ip[1] = ip >> 8; out_ip[1] = ip >> 8;
out_ip[2] = ip >> 16; out_ip[2] = ip >> 16;
out_ip[3] = ip >> 24; out_ip[3] = ip >> 24;
return result; return result;
} }
int wlan_socket_socket(mod_network_socket_obj_t *s, int *_errno) { int wlan_socket_socket(mod_network_socket_obj_t *s, int *_errno) {
// open the socket
int16_t sd = sl_Socket(s->sock_base.u_param.domain, s->sock_base.u_param.type, s->sock_base.u_param.proto); int16_t sd = sl_Socket(s->sock_base.u_param.domain, s->sock_base.u_param.type, s->sock_base.u_param.proto);
// save the socket descriptor
s->sock_base.sd = sd;
if (sd < 0) { if (sd < 0) {
*_errno = sd; *_errno = sd;
return -1; return -1;
} }
s->sock_base.sd = sd;
return 0; return 0;
} }
@ -1177,10 +1172,9 @@ void wlan_socket_close(mod_network_socket_obj_t *s) {
// this is to prevent the finalizer to close a socket that failed when being created // this is to prevent the finalizer to close a socket that failed when being created
if (s->sock_base.sd >= 0) { if (s->sock_base.sd >= 0) {
modusocket_socket_delete(s->sock_base.sd); modusocket_socket_delete(s->sock_base.sd);
// TODO check return value and raise an exception if applicable
sl_Close(s->sock_base.sd); sl_Close(s->sock_base.sd);
s->sock_base.sd = -1;
} }
s->sock_base.closed = true;
} }
int wlan_socket_bind(mod_network_socket_obj_t *s, byte *ip, mp_uint_t port, int *_errno) { int wlan_socket_bind(mod_network_socket_obj_t *s, byte *ip, mp_uint_t port, int *_errno) {
@ -1218,7 +1212,6 @@ int wlan_socket_accept(mod_network_socket_obj_t *s, mod_network_socket_obj_t *s2
// return ip and port // return ip and port
UNPACK_SOCKADDR(addr, ip, *port); UNPACK_SOCKADDR(addr, ip, *port);
return 0; return 0;
} }
@ -1241,38 +1234,15 @@ int wlan_socket_send(mod_network_socket_obj_t *s, const byte *buf, mp_uint_t len
*_errno = bytes; *_errno = bytes;
return -1; return -1;
} }
return bytes; return bytes;
} }
int wlan_socket_recv(mod_network_socket_obj_t *s, byte *buf, mp_uint_t len, int *_errno) { int wlan_socket_recv(mod_network_socket_obj_t *s, byte *buf, mp_uint_t len, int *_errno) {
// check if the socket is open int ret = sl_Recv(s->sock_base.sd, buf, MIN(len, WLAN_MAX_RX_SIZE), 0);
if (s->sock_base.closed) {
// socket is closed, but the there might be data remaining in the buffer, so check
fd_set rfds;
FD_ZERO(&rfds);
FD_SET(s->sock_base.sd, &rfds);
timeval tv;
tv.tv_sec = 0;
tv.tv_usec = 2;
int nfds = sl_Select(s->sock_base.sd + 1, &rfds, NULL, NULL, &tv);
if (nfds == -1 || !FD_ISSET(s->sock_base.sd, &rfds)) {
// no data waiting, so close the socket and return 0 data
wlan_socket_close(s);
return 0;
}
}
// cap length at WLAN_MAX_RX_SIZE
len = MIN(len, WLAN_MAX_RX_SIZE);
// do the recv
int ret = sl_Recv(s->sock_base.sd, buf, len, 0);
if (ret < 0) { if (ret < 0) {
*_errno = ret; *_errno = ret;
return -1; return -1;
} }
return ret; return ret;
} }
@ -1289,7 +1259,7 @@ int wlan_socket_sendto( mod_network_socket_obj_t *s, const byte *buf, mp_uint_t
int wlan_socket_recvfrom(mod_network_socket_obj_t *s, byte *buf, mp_uint_t len, byte *ip, mp_uint_t *port, int *_errno) { int wlan_socket_recvfrom(mod_network_socket_obj_t *s, byte *buf, mp_uint_t len, byte *ip, mp_uint_t *port, int *_errno) {
sockaddr addr; sockaddr addr;
socklen_t addr_len = sizeof(addr); socklen_t addr_len = sizeof(addr);
mp_int_t ret = sl_RecvFrom(s->sock_base.sd, buf, len, 0, &addr, &addr_len); mp_int_t ret = sl_RecvFrom(s->sock_base.sd, buf, MIN(len, WLAN_MAX_RX_SIZE), 0, &addr, &addr_len);
if (ret < 0) { if (ret < 0) {
*_errno = ret; *_errno = ret;
return -1; return -1;
@ -1355,12 +1325,6 @@ int wlan_socket_ioctl (mod_network_socket_obj_t *s, mp_uint_t request, mp_uint_t
// set fds if needed // set fds if needed
if (flags & MP_IOCTL_POLL_RD) { if (flags & MP_IOCTL_POLL_RD) {
FD_SET(sd, &rfds); FD_SET(sd, &rfds);
// A socked that just closed is available for reading. A call to
// recv() returns 0 which is consistent with BSD.
if (s->sock_base.closed) {
ret |= MP_IOCTL_POLL_RD;
}
} }
if (flags & MP_IOCTL_POLL_WR) { if (flags & MP_IOCTL_POLL_WR) {
FD_SET(sd, &wfds); FD_SET(sd, &wfds);

View File

@ -107,12 +107,15 @@ void TASK_Servers (void *pvParameters) {
servers_data.do_disable = false; servers_data.do_disable = false;
servers_data.enabled = false; servers_data.enabled = false;
} }
else if (servers_data.do_reset && servers_data.enabled) { else if (servers_data.do_reset) {
// resetting the servers is needed to prevent half-open sockets
servers_data.do_reset = false;
if (servers_data.enabled) {
telnet_reset(); telnet_reset();
ftp_reset(); ftp_reset();
servers_data.do_reset = false; }
// resetting the servers is needed to preven half-open sockets // and we should also close all user sockets. We do it here
// and we should also close all user sockets // for convinience and to save on code size.
modusocket_close_all_user_sockets(); modusocket_close_all_user_sockets();
} }