WINC1500: Fix timeout bugs.

* Setting timeout to 0 (from MicroPython) makes the socket blocking instead of non-blocking.
* Sockets were closed on recv/recvfrom timeout.
This commit is contained in:
iabdalkader 2019-09-12 00:04:46 +02:00
parent eff78c2990
commit f648107bb9
3 changed files with 40 additions and 12 deletions

View File

@ -10,7 +10,7 @@
*/
#include <string.h>
#include <stdarg.h>
#include <errno.h>
#include "mperrno.h"
#include "py/nlr.h"
#include "py/objtuple.h"
@ -356,7 +356,7 @@ static int py_winc_socket_socket(mod_network_socket_obj_t *socket, int *_errno)
uint8_t type;
if (socket->u_param.domain != MOD_NETWORK_AF_INET) {
*_errno = EAFNOSUPPORT;
*_errno = MP_EAFNOSUPPORT;
return -1;
}
@ -370,7 +370,7 @@ static int py_winc_socket_socket(mod_network_socket_obj_t *socket, int *_errno)
break;
default:
*_errno = EINVAL;
*_errno = MP_EINVAL;
return -1;
}
@ -455,7 +455,13 @@ static int py_winc_socket_connect(mod_network_socket_obj_t *socket, byte *ip, mp
static mp_uint_t py_winc_socket_send(mod_network_socket_obj_t *socket, const byte *buf, mp_uint_t len, int *_errno)
{
int ret = winc_socket_send(socket->fd, buf, len, socket->timeout);
if (ret < 0) {
if (ret == SOCK_ERR_TIMEOUT) {
// The socket is Not closed on timeout when calling
// WINC1500 functions that actually accept a timeout.
*_errno = MP_ETIMEDOUT;
return 0;
} else if (ret < 0) {
// Close the socket on any other errors.
*_errno = ret;
py_winc_socket_close(socket);
return -1;
@ -466,7 +472,13 @@ static mp_uint_t py_winc_socket_send(mod_network_socket_obj_t *socket, const byt
static mp_uint_t py_winc_socket_recv(mod_network_socket_obj_t *socket, byte *buf, mp_uint_t len, int *_errno)
{
int ret = winc_socket_recv(socket->fd, buf, len, &socket->sockbuf, socket->timeout);
if (ret < 0) {
if (ret == SOCK_ERR_TIMEOUT) {
// The socket is Not closed on timeout when calling
// WINC1500 functions that actually accept a timeout.
*_errno = MP_ETIMEDOUT;
return 0;
} else if (ret < 0) {
// Close the socket on any other errors.
*_errno = ret;
py_winc_socket_close(socket);
return -1;
@ -493,7 +505,13 @@ static mp_uint_t py_winc_socket_recvfrom(mod_network_socket_obj_t *socket,
sockaddr addr;
int ret = winc_socket_recvfrom(socket->fd, buf, len, &addr, socket->timeout);
UNPACK_SOCKADDR((&addr), ip, *port);
if (ret < 0) {
if (ret == SOCK_ERR_TIMEOUT) {
// The socket is Not closed on timeout when calling
// WINC1500 functions that actually accept a timeout.
*_errno = MP_ETIMEDOUT;
return 0;
} else if (ret < 0) {
// Close the socket on any other errors.
*_errno = ret;
py_winc_socket_close(socket);
return -1;
@ -515,13 +533,21 @@ static int py_winc_socket_setsockopt(mod_network_socket_obj_t *socket, mp_uint_t
static int py_winc_socket_settimeout(mod_network_socket_obj_t *socket, mp_uint_t timeout_ms, int *_errno)
{
if (timeout_ms == UINT32_MAX) {
// no timeout is given, set the socket to blocking mode.
timeout_ms = 0;
} else if (timeout_ms == 0) {
// non-blocking mode, set the timeout to a small number other than zero.
timeout_ms = 10;
} // otherwise, timeout is provided.
socket->timeout = timeout_ms;
return 0;
}
static int py_winc_socket_ioctl(mod_network_socket_obj_t *socket, mp_uint_t request, mp_uint_t arg, int *_errno)
{
*_errno = EIO;
*_errno = MP_EIO;
return -1;
}

View File

@ -18,6 +18,7 @@
#define WINC_MAX_PSK_LEN (65)
#define WINC_MAX_BOARD_NAME_LEN (33)
#define WINC_SOCKBUF_SIZE (1400)
#define WINC_REQUEST_TIMEOUT (5000)
#define MAKE_SOCKADDR(addr, ip, port) \
struct sockaddr addr; \

View File

@ -410,8 +410,9 @@ static int winc_async_request(uint8_t msg_type, void *ret, uint32_t timeout)
while (async_request_done == false) {
// Handle pending events from network controller.
m2m_wifi_handle_events(NULL);
// timeout == 0 in blocking mode.
if (timeout && ((HAL_GetTick() - tick_start) >= timeout)) {
return -ETIMEDOUT;
return SOCK_ERR_TIMEOUT;
}
}
@ -699,14 +700,14 @@ int winc_gethostbyname(const char *name, uint8_t *out_ip)
uint32_t ip=0;
ret = WINC1500_EXPORT(gethostbyname)((uint8_t*) name);
if (ret == SOCK_ERR_NO_ERROR) {
ret = winc_async_request(0, &ip, 5000);
ret = winc_async_request(0, &ip, WINC_REQUEST_TIMEOUT);
} else {
return -1;
}
if (ip == 0) {
// unknown host
return -ENOENT;
return ENOENT;
}
out_ip[0] = ip;
@ -733,7 +734,7 @@ int winc_socket_bind(int fd, sockaddr *addr)
int ret = WINC1500_EXPORT(bind)(fd, addr, sizeof(*addr));
if (ret == SOCK_ERR_NO_ERROR) {
// Do async request
ret = winc_async_request(SOCKET_MSG_BIND, &ret, 1000);
ret = winc_async_request(SOCKET_MSG_BIND, &ret, WINC_REQUEST_TIMEOUT);
}
return ret;
@ -745,7 +746,7 @@ int winc_socket_listen(int fd, uint32_t backlog)
int ret = WINC1500_EXPORT(listen)(fd, backlog);
if (ret == SOCK_ERR_NO_ERROR) {
// Do async request
ret = winc_async_request(SOCKET_MSG_LISTEN, &ret, 1000);
ret = winc_async_request(SOCKET_MSG_LISTEN, &ret, WINC_REQUEST_TIMEOUT);
}
return ret;