Skip to content

Commit cd2c425

Browse files
mniestrojcarlescufi
authored andcommitted
drivers: nsos: support setsockopt(SO_RCVTIMEO)
Handle timeout on receive that is configured using SO_RCVTIMEO. Signed-off-by: Marcin Niestroj <[email protected]>
1 parent a3f2b5f commit cd2c425

File tree

3 files changed

+56
-1
lines changed

3 files changed

+56
-1
lines changed

drivers/net/nsos_adapt.c

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -651,6 +651,22 @@ int nsos_adapt_setsockopt(int fd, int nsos_mid_level, int nsos_mid_optname,
651651
return nsos_adapt_setsockopt_int(fd, SOL_SOCKET, SO_PRIORITY,
652652
nsos_mid_optval, nsos_mid_optlen);
653653

654+
case NSOS_MID_SO_RCVTIMEO: {
655+
const struct nsos_mid_timeval *nsos_mid_tv = nsos_mid_optval;
656+
struct timeval tv = {
657+
.tv_sec = nsos_mid_tv->tv_sec,
658+
.tv_usec = nsos_mid_tv->tv_usec,
659+
};
660+
int ret;
661+
662+
ret = setsockopt(fd, SOL_SOCKET, SO_RCVTIMEO,
663+
&tv, sizeof(tv));
664+
if (ret < 0) {
665+
return -errno_to_nsos_mid(errno);
666+
}
667+
668+
return 0;
669+
}
654670
case NSOS_MID_SO_RCVBUF:
655671
return nsos_adapt_setsockopt_int(fd, SOL_SOCKET, SO_RCVBUF,
656672
nsos_mid_optval, nsos_mid_optlen);

drivers/net/nsos_socket.h

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,8 @@
77
#ifndef __DRIVERS_NET_NSOS_SOCKET_H__
88
#define __DRIVERS_NET_NSOS_SOCKET_H__
99

10+
#include <stdint.h>
11+
1012
/**
1113
* @name Socket level options (NSOS_MID_SOL_SOCKET)
1214
* @{
@@ -78,6 +80,11 @@
7880
/** Socket TX time (when the data should be sent) */
7981
#define NSOS_MID_SO_TXTIME 61
8082

83+
struct nsos_mid_timeval {
84+
int64_t tv_sec;
85+
int64_t tv_usec;
86+
};
87+
8188
/** @} */
8289

8390
#endif /* __DRIVERS_NET_NSOS_SOCKET_H__ */

drivers/net/nsos_sockets.c

Lines changed: 33 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,8 @@ struct nsos_socket {
4242
struct nsos_mid_pollfd pollfd;
4343
struct k_poll_signal poll;
4444

45+
k_timeout_t recv_timeout;
46+
4547
sys_dnode_t node;
4648
};
4749

@@ -180,6 +182,7 @@ static int nsos_socket_create(int family, int type, int proto)
180182
}
181183

182184
sock->fd = fd;
185+
sock->recv_timeout = K_FOREVER;
183186

184187
sock->pollfd.fd = nsos_adapt_socket(family_mid, type_mid, proto_mid);
185188
if (sock->pollfd.fd < 0) {
@@ -550,7 +553,7 @@ static int nsos_wait_for_pollin(struct nsos_socket *sock)
550553
return ret;
551554
}
552555

553-
ret = k_poll(poll_events, ARRAY_SIZE(poll_events), K_FOREVER);
556+
ret = k_poll(poll_events, ARRAY_SIZE(poll_events), sock->recv_timeout);
554557
if (ret != 0 && ret != -EAGAIN && ret != -EINTR) {
555558
return ret;
556559
}
@@ -1067,6 +1070,35 @@ static int nsos_setsockopt(void *obj, int level, int optname,
10671070

10681071
return 0;
10691072
}
1073+
case SO_RCVTIMEO: {
1074+
const struct zsock_timeval *tv = optval;
1075+
struct nsos_mid_timeval nsos_mid_tv;
1076+
int err;
1077+
1078+
if (optlen != sizeof(struct zsock_timeval)) {
1079+
errno = EINVAL;
1080+
return -1;
1081+
}
1082+
1083+
nsos_mid_tv.tv_sec = tv->tv_sec;
1084+
nsos_mid_tv.tv_usec = tv->tv_usec;
1085+
1086+
err = nsos_adapt_setsockopt(sock->pollfd.fd, NSOS_MID_SOL_SOCKET,
1087+
NSOS_MID_SO_RCVTIMEO, &nsos_mid_tv,
1088+
sizeof(nsos_mid_tv));
1089+
if (err) {
1090+
errno = errno_from_nsos_mid(-err);
1091+
return -1;
1092+
}
1093+
1094+
if (tv->tv_sec == 0 && tv->tv_usec == 0) {
1095+
sock->recv_timeout = K_FOREVER;
1096+
} else {
1097+
sock->recv_timeout = K_USEC(tv->tv_sec * 1000000LL + tv->tv_usec);
1098+
}
1099+
1100+
return 0;
1101+
}
10701102
case SO_RCVBUF:
10711103
return nsos_setsockopt_int(sock,
10721104
NSOS_MID_SOL_SOCKET, NSOS_MID_SO_RCVBUF,

0 commit comments

Comments
 (0)