From e9421d557a1c5c8fbf68be052a38ec2c66042185 Mon Sep 17 00:00:00 2001 From: "Sergio R. Caprile" Date: Fri, 28 Oct 2022 18:55:10 -0300 Subject: [PATCH] Fix TI-RTOS port Sockets were not being put in non-blocking mode as the setsockopt() call wasn't using SOL_SOCKET Do not include errno.h but serrno.h, otherwise error codes are mangled... NDK functions use serrno, errno belongs to the compiler UDP sockets require binding to receive responses select() does not return write-ready on connect if the amount of bytes to write is below the "low-water mark". This parameter defaults to 2048, there was some code apparently setting this otherwise, with no success. Reworked the code to set this water mark at half the buffer size by just using plain getsockopt/setsockopt calls. For the record: TI typedef's void * SOCKET for internal use, INVALID_SOCKET is cast to (void *). Their BSD compatible socket interface expects and returns int; while Mongoose uses SOCKET... this generates lots of warnings 169 and 515, disabled in the examples --- mongoose.c | 20 ++++++++++++-------- mongoose.h | 6 +----- src/arch_tirtos.h | 6 +----- src/sock.c | 20 ++++++++++++-------- 4 files changed, 26 insertions(+), 26 deletions(-) diff --git a/mongoose.c b/mongoose.c index 303b219b..f0c3d0cd 100644 --- a/mongoose.c +++ b/mongoose.c @@ -4157,14 +4157,12 @@ static void mg_set_non_blocking_mode(SOCKET fd) { fcntl(fd, F_SETFL, O_NONBLOCK); #elif MG_ARCH == MG_ARCH_TIRTOS int val = 0; - setsockopt(fd, 0, SO_BLOCKING, &val, sizeof(val)); - int status = 0; - int res = SockStatus(fd, FDSTATUS_SEND, &status); - if (res == 0 && status > 0) { - val = status / 2; - int val_size = sizeof(val); - res = SockSet(fd, SOL_SOCKET, SO_SNDLOWAT, &val, val_size); - } + setsockopt(fd, SOL_SOCKET, SO_BLOCKING, &val, sizeof(val)); + // SPRU524J section 3.3.3 page 63, SO_SNDLOWAT + int sz = sizeof(val); + getsockopt(fd, SOL_SOCKET, SO_SNDBUF, &val, &sz); + val /= 2; // set send low-water mark at half send buffer size + setsockopt(fd, SOL_SOCKET, SO_SNDLOWAT, &val, sizeof(val)); #else fcntl(fd, F_SETFL, fcntl(fd, F_GETFL, 0) | O_NONBLOCK); // Non-blocking mode fcntl(fd, F_SETFD, FD_CLOEXEC); // Set close-on-exec @@ -4328,6 +4326,11 @@ void mg_connect_resolved(struct mg_connection *c) { mg_error(c, "socket(): %d", MG_SOCK_ERRNO); } else if (c->is_udp) { MG_EPOLL_ADD(c); +#if MG_ARCH == MG_ARCH_TIRTOS + union usa usa; // TI-RTOS NDK requires binding to receive on UDP sockets + socklen_t slen = tousa(&c->loc, &usa); + if (bind(c->fd, &usa.sa, slen) != 0) MG_ERROR(("bind: %d", MG_SOCK_ERRNO)); +#endif mg_call(c, MG_EV_RESOLVE, NULL); mg_call(c, MG_EV_CONNECT, NULL); } else { @@ -4347,6 +4350,7 @@ void mg_connect_resolved(struct mg_connection *c) { mg_error(c, "connect: %d", MG_SOCK_ERRNO); } } + (void) rc; } static SOCKET raccept(SOCKET sock, union usa *usa, socklen_t len) { diff --git a/mongoose.h b/mongoose.h index 3be7a093..d9bd8024 100644 --- a/mongoose.h +++ b/mongoose.h @@ -420,16 +420,12 @@ struct timeval { #include #include #include -#include -#include +#include #include #include -extern int SockStatus(SOCKET hSock, int request, int *results ); -extern int SockSet(SOCKET hSock, int Type, int Prop, void *pbuf, int size); - #endif diff --git a/src/arch_tirtos.h b/src/arch_tirtos.h index dfb6a5f4..6d411cbc 100644 --- a/src/arch_tirtos.h +++ b/src/arch_tirtos.h @@ -10,14 +10,10 @@ #include #include #include -#include -#include +#include #include #include -extern int SockStatus(SOCKET hSock, int request, int *results ); -extern int SockSet(SOCKET hSock, int Type, int Prop, void *pbuf, int size); - #endif diff --git a/src/sock.c b/src/sock.c index 6198ef8c..c1506e50 100644 --- a/src/sock.c +++ b/src/sock.c @@ -198,14 +198,12 @@ static void mg_set_non_blocking_mode(SOCKET fd) { fcntl(fd, F_SETFL, O_NONBLOCK); #elif MG_ARCH == MG_ARCH_TIRTOS int val = 0; - setsockopt(fd, 0, SO_BLOCKING, &val, sizeof(val)); - int status = 0; - int res = SockStatus(fd, FDSTATUS_SEND, &status); - if (res == 0 && status > 0) { - val = status / 2; - int val_size = sizeof(val); - res = SockSet(fd, SOL_SOCKET, SO_SNDLOWAT, &val, val_size); - } + setsockopt(fd, SOL_SOCKET, SO_BLOCKING, &val, sizeof(val)); + // SPRU524J section 3.3.3 page 63, SO_SNDLOWAT + int sz = sizeof(val); + getsockopt(fd, SOL_SOCKET, SO_SNDBUF, &val, &sz); + val /= 2; // set send low-water mark at half send buffer size + setsockopt(fd, SOL_SOCKET, SO_SNDLOWAT, &val, sizeof(val)); #else fcntl(fd, F_SETFL, fcntl(fd, F_GETFL, 0) | O_NONBLOCK); // Non-blocking mode fcntl(fd, F_SETFD, FD_CLOEXEC); // Set close-on-exec @@ -369,6 +367,11 @@ void mg_connect_resolved(struct mg_connection *c) { mg_error(c, "socket(): %d", MG_SOCK_ERRNO); } else if (c->is_udp) { MG_EPOLL_ADD(c); +#if MG_ARCH == MG_ARCH_TIRTOS + union usa usa; // TI-RTOS NDK requires binding to receive on UDP sockets + socklen_t slen = tousa(&c->loc, &usa); + if (bind(c->fd, &usa.sa, slen) != 0) MG_ERROR(("bind: %d", MG_SOCK_ERRNO)); +#endif mg_call(c, MG_EV_RESOLVE, NULL); mg_call(c, MG_EV_CONNECT, NULL); } else { @@ -388,6 +391,7 @@ void mg_connect_resolved(struct mg_connection *c) { mg_error(c, "connect: %d", MG_SOCK_ERRNO); } } + (void) rc; } static SOCKET raccept(SOCKET sock, union usa *usa, socklen_t len) {