drivers: net: nsos: implement poll() syscall
Use NSI_HW_EVENT() in order to periodically check for events in host sockets. Whenever there is a socket event ready to be processed by Zephyr, raise native_sim (newly introduced) CPU interrupt, so that Zephyr driver can signal readiness with k_poll(). Maintain a list of Zephyr poll() executions in Zephyr context. Iterate through them whenever there is some event to be processed. Signed-off-by: Marcin Niestroj <m.niestroj@emb.dev>
This commit is contained in:
parent
483c41d209
commit
8487fcca5b
|
@ -22,4 +22,6 @@
|
|||
|
||||
#include "nsi_cpu0_interrupts.h"
|
||||
|
||||
#define NSOS_IRQ 3
|
||||
|
||||
#endif /* BOARDS_POSIX_NATIVE_SIM_BOARD_SOC_H */
|
||||
|
|
|
@ -18,6 +18,10 @@ if(CONFIG_NET_NATIVE_OFFLOADED_SOCKETS)
|
|||
zephyr_library_sources(nsos_fcntl.c)
|
||||
zephyr_library_sources(nsos_netdb.c)
|
||||
zephyr_library_sources(nsos_sockets.c)
|
||||
target_compile_options(native_simulator BEFORE INTERFACE
|
||||
-I${BOARD_DIR}
|
||||
-DNSOS_EPOLL_WAIT_INTERVAL=${CONFIG_NET_NATIVE_OFFLOADED_SOCKETS_EPOLL_WAIT_INTERVAL}
|
||||
)
|
||||
target_sources(native_simulator INTERFACE nsos_adapt.c)
|
||||
target_sources(native_simulator INTERFACE nsos_errno.c)
|
||||
target_sources(native_simulator INTERFACE nsos_fcntl.c)
|
||||
|
|
|
@ -228,7 +228,7 @@ endif # NET_CAN
|
|||
# Native simulator offloaded sockets
|
||||
#
|
||||
|
||||
config NET_NATIVE_OFFLOADED_SOCKETS
|
||||
menuconfig NET_NATIVE_OFFLOADED_SOCKETS
|
||||
bool "Native Simulator offloaded sockets"
|
||||
depends on ARCH_POSIX
|
||||
depends on NATIVE_LIBRARY
|
||||
|
@ -240,4 +240,18 @@ config NET_NATIVE_OFFLOADED_SOCKETS
|
|||
This driver main advantage is that it is possible to use this driver without any
|
||||
additional setup on the host side, unlike with the native TAP Ethernet driver.
|
||||
|
||||
if NET_NATIVE_OFFLOADED_SOCKETS
|
||||
|
||||
config NET_NATIVE_OFFLOADED_SOCKETS_EPOLL_WAIT_INTERVAL
|
||||
int "Interval between epoll_wait() calls (in simulated microseconds)"
|
||||
default 1000
|
||||
help
|
||||
Number of simulated microseconds before next epoll_wait() call, when there were no pending
|
||||
events detected.
|
||||
|
||||
Decrease that value when lower network traffic latency is expected, at the expense of more
|
||||
CPU processing overhead.
|
||||
|
||||
endif # NET_NATIVE_OFFLOADED_SOCKETS
|
||||
|
||||
endif # NET_DRIVERS
|
||||
|
|
|
@ -74,6 +74,8 @@ struct nsos_mid_pollfd {
|
|||
int fd;
|
||||
short events;
|
||||
short revents;
|
||||
|
||||
void (*cb)(struct nsos_mid_pollfd *pollfd_mid);
|
||||
};
|
||||
|
||||
struct nsos_mid_addrinfo {
|
||||
|
@ -109,6 +111,8 @@ int nsos_adapt_sendto(int fd, const void *buf, size_t len, int flags,
|
|||
int nsos_adapt_recvfrom(int fd, void *buf, size_t len, int flags,
|
||||
struct nsos_mid_sockaddr *addr, size_t *addrlen);
|
||||
|
||||
void nsos_adapt_poll_add(struct nsos_mid_pollfd *pollfd);
|
||||
void nsos_adapt_poll_remove(struct nsos_mid_pollfd *pollfd);
|
||||
|
||||
int nsos_adapt_fcntl_getfl(int fd);
|
||||
int nsos_adapt_fcntl_setfl(int fd, int flags);
|
||||
|
|
|
@ -17,6 +17,7 @@
|
|||
#include <poll.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <sys/epoll.h>
|
||||
#include <sys/socket.h>
|
||||
#include <unistd.h>
|
||||
|
||||
|
@ -25,10 +26,21 @@
|
|||
#include "nsos_fcntl.h"
|
||||
#include "nsos_netdb.h"
|
||||
|
||||
#include "board_soc.h"
|
||||
#include "irq_ctrl.h"
|
||||
#include "nsi_hws_models_if.h"
|
||||
#include "nsi_tasks.h"
|
||||
#include "nsi_tracing.h"
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
static int nsos_epoll_fd;
|
||||
static int nsos_adapt_nfds;
|
||||
|
||||
#ifndef ARRAY_SIZE
|
||||
#define ARRAY_SIZE(array) (sizeof(array) / sizeof((array)[0]))
|
||||
#endif
|
||||
|
||||
#ifndef CONTAINER_OF
|
||||
#define CONTAINER_OF(ptr, type, field) \
|
||||
((type *)(((char *)(ptr)) - offsetof(type, field)))
|
||||
|
@ -456,6 +468,71 @@ int nsos_adapt_recvfrom(int fd, void *buf, size_t len, int flags,
|
|||
return ret;
|
||||
}
|
||||
|
||||
#define MAP_POLL_EPOLL(_event_from, _event_to) \
|
||||
if (events_from & (_event_from)) { \
|
||||
events_from &= ~(_event_from); \
|
||||
events_to |= _event_to; \
|
||||
}
|
||||
|
||||
static int nsos_poll_to_epoll_events(int events_from)
|
||||
{
|
||||
int events_to = 0;
|
||||
|
||||
MAP_POLL_EPOLL(POLLIN, EPOLLIN);
|
||||
MAP_POLL_EPOLL(POLLOUT, EPOLLOUT);
|
||||
MAP_POLL_EPOLL(POLLERR, EPOLLERR);
|
||||
|
||||
return events_to;
|
||||
}
|
||||
|
||||
static int nsos_epoll_to_poll_events(int events_from)
|
||||
{
|
||||
int events_to = 0;
|
||||
|
||||
MAP_POLL_EPOLL(EPOLLIN, POLLIN);
|
||||
MAP_POLL_EPOLL(EPOLLOUT, POLLOUT);
|
||||
MAP_POLL_EPOLL(EPOLLERR, POLLERR);
|
||||
|
||||
return events_to;
|
||||
}
|
||||
|
||||
#undef MAP_POLL_EPOLL
|
||||
|
||||
static uint64_t nsos_adapt_poll_time = NSI_NEVER;
|
||||
|
||||
void nsos_adapt_poll_add(struct nsos_mid_pollfd *pollfd)
|
||||
{
|
||||
struct epoll_event ev = {
|
||||
.data.ptr = pollfd,
|
||||
.events = nsos_poll_to_epoll_events(pollfd->events),
|
||||
};
|
||||
int err;
|
||||
|
||||
nsos_adapt_nfds++;
|
||||
|
||||
err = epoll_ctl(nsos_epoll_fd, EPOLL_CTL_ADD, pollfd->fd, &ev);
|
||||
if (err) {
|
||||
nsi_print_error_and_exit("error in EPOLL_CTL_ADD: errno=%d\n", errno);
|
||||
return;
|
||||
}
|
||||
|
||||
nsos_adapt_poll_time = nsi_hws_get_time() + 1;
|
||||
nsi_hws_find_next_event();
|
||||
}
|
||||
|
||||
void nsos_adapt_poll_remove(struct nsos_mid_pollfd *pollfd)
|
||||
{
|
||||
int err;
|
||||
|
||||
err = epoll_ctl(nsos_epoll_fd, EPOLL_CTL_DEL, pollfd->fd, NULL);
|
||||
if (err) {
|
||||
nsi_print_error_and_exit("error in EPOLL_CTL_ADD: errno=%d\n", errno);
|
||||
return;
|
||||
}
|
||||
|
||||
nsos_adapt_nfds--;
|
||||
}
|
||||
|
||||
struct nsos_addrinfo_wrap {
|
||||
struct nsos_mid_addrinfo addrinfo_mid;
|
||||
struct nsos_mid_sockaddr_storage addr_storage;
|
||||
|
@ -619,3 +696,54 @@ int nsos_adapt_fcntl_setfl(int fd, int flags)
|
|||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void nsos_adapt_init(void)
|
||||
{
|
||||
nsos_epoll_fd = epoll_create(1);
|
||||
if (nsos_epoll_fd < 0) {
|
||||
nsi_print_error_and_exit("error from epoll_create(): errno=%d\n", errno);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
NSI_TASK(nsos_adapt_init, HW_INIT, 500);
|
||||
|
||||
static void nsos_adapt_poll_triggered(void)
|
||||
{
|
||||
static struct epoll_event events[1024];
|
||||
int ret;
|
||||
|
||||
if (nsos_adapt_nfds == 0) {
|
||||
nsos_adapt_poll_time = NSI_NEVER;
|
||||
return;
|
||||
}
|
||||
|
||||
ret = epoll_wait(nsos_epoll_fd, events, ARRAY_SIZE(events), 0);
|
||||
if (ret < 0) {
|
||||
if (errno == EINTR) {
|
||||
nsi_print_warning("interrupted epoll_wait()\n");
|
||||
nsos_adapt_poll_time = nsi_hws_get_time() + 1;
|
||||
return;
|
||||
}
|
||||
|
||||
nsi_print_error_and_exit("error in nsos_adapt poll(): errno=%d\n", errno);
|
||||
|
||||
nsos_adapt_poll_time = NSI_NEVER;
|
||||
return;
|
||||
}
|
||||
|
||||
for (int i = 0; i < ret; i++) {
|
||||
struct nsos_mid_pollfd *pollfd = events[i].data.ptr;
|
||||
|
||||
pollfd->revents = nsos_epoll_to_poll_events(events[i].events);
|
||||
}
|
||||
|
||||
if (ret > 0) {
|
||||
hw_irq_ctrl_set_irq(NSOS_IRQ);
|
||||
nsos_adapt_poll_time = nsi_hws_get_time() + 1;
|
||||
} else {
|
||||
nsos_adapt_poll_time = nsi_hws_get_time() + NSOS_EPOLL_WAIT_INTERVAL;
|
||||
}
|
||||
}
|
||||
|
||||
NSI_HW_EVENT(nsos_adapt_poll_time, nsos_adapt_poll_triggered, 500);
|
||||
|
|
|
@ -13,6 +13,7 @@
|
|||
#undef _POSIX_C_SOURCE
|
||||
#define _POSIX_C_SOURCE 200809L
|
||||
|
||||
#include <soc.h>
|
||||
#include <string.h>
|
||||
#include <zephyr/net/ethernet.h>
|
||||
#include <zephyr/net/net_ip.h>
|
||||
|
@ -20,6 +21,7 @@
|
|||
#include <zephyr/net/socket_offload.h>
|
||||
#include <zephyr/posix/fcntl.h>
|
||||
#include <zephyr/sys/fdtable.h>
|
||||
#include <zephyr/sys/dlist.h>
|
||||
|
||||
#include "sockets_internal.h"
|
||||
#include "nsos.h"
|
||||
|
@ -29,11 +31,19 @@
|
|||
|
||||
#include "nsi_host_trampolines.h"
|
||||
|
||||
/* Increment by 1 to make sure we do not store the value of 0, which has
|
||||
* a special meaning in the fdtable subsys.
|
||||
*/
|
||||
#define FD_TO_OBJ(fd) ((void *)(intptr_t)((fd) + 1))
|
||||
#define OBJ_TO_FD(obj) (((int)(intptr_t)(obj)) - 1)
|
||||
BUILD_ASSERT(CONFIG_HEAP_MEM_POOL_SIZE > 0);
|
||||
|
||||
#define NSOS_IRQ_FLAGS (0)
|
||||
#define NSOS_IRQ_PRIORITY (2)
|
||||
|
||||
struct nsos_socket {
|
||||
struct nsos_mid_pollfd pollfd;
|
||||
struct k_poll_signal poll;
|
||||
|
||||
sys_dnode_t node;
|
||||
};
|
||||
|
||||
static sys_dlist_t nsos_sockets = SYS_DLIST_STATIC_INIT(&nsos_sockets);
|
||||
|
||||
static int socket_family_to_nsos_mid(int family, int *family_mid)
|
||||
{
|
||||
|
@ -132,7 +142,7 @@ static const struct socket_op_vtable nsos_socket_fd_op_vtable;
|
|||
static int nsos_socket_create(int family, int type, int proto)
|
||||
{
|
||||
int fd;
|
||||
int sock;
|
||||
struct nsos_socket *sock;
|
||||
int family_mid;
|
||||
int type_mid;
|
||||
int proto_mid;
|
||||
|
@ -161,16 +171,25 @@ static int nsos_socket_create(int family, int type, int proto)
|
|||
return -1;
|
||||
}
|
||||
|
||||
sock = nsos_adapt_socket(family_mid, type_mid, proto_mid);
|
||||
if (sock < 0) {
|
||||
errno = errno_from_nsos_mid(-sock);
|
||||
sock = k_malloc(sizeof(*sock));
|
||||
if (!sock) {
|
||||
errno = ENOMEM;
|
||||
goto free_fd;
|
||||
}
|
||||
|
||||
z_finalize_fd(fd, FD_TO_OBJ(sock), &nsos_socket_fd_op_vtable.fd_vtable);
|
||||
sock->pollfd.fd = nsos_adapt_socket(family_mid, type_mid, proto_mid);
|
||||
if (sock->pollfd.fd < 0) {
|
||||
errno = errno_from_nsos_mid(-sock->pollfd.fd);
|
||||
goto free_sock;
|
||||
}
|
||||
|
||||
z_finalize_fd(fd, sock, &nsos_socket_fd_op_vtable.fd_vtable);
|
||||
|
||||
return fd;
|
||||
|
||||
free_sock:
|
||||
k_free(sock);
|
||||
|
||||
free_fd:
|
||||
z_free_fd(fd);
|
||||
|
||||
|
@ -184,9 +203,10 @@ static int nsos_adapt_get_zephyr_errno(void)
|
|||
|
||||
static ssize_t nsos_read(void *obj, void *buf, size_t sz)
|
||||
{
|
||||
struct nsos_socket *sock = obj;
|
||||
int ret;
|
||||
|
||||
ret = nsi_host_read(OBJ_TO_FD(obj), buf, sz);
|
||||
ret = nsi_host_read(sock->pollfd.fd, buf, sz);
|
||||
if (ret < 0) {
|
||||
errno = nsos_adapt_get_zephyr_errno();
|
||||
}
|
||||
|
@ -196,9 +216,10 @@ static ssize_t nsos_read(void *obj, void *buf, size_t sz)
|
|||
|
||||
static ssize_t nsos_write(void *obj, const void *buf, size_t sz)
|
||||
{
|
||||
struct nsos_socket *sock = obj;
|
||||
int ret;
|
||||
|
||||
ret = nsi_host_write(OBJ_TO_FD(obj), buf, sz);
|
||||
ret = nsi_host_write(sock->pollfd.fd, buf, sz);
|
||||
if (ret < 0) {
|
||||
errno = nsos_adapt_get_zephyr_errno();
|
||||
}
|
||||
|
@ -208,9 +229,10 @@ static ssize_t nsos_write(void *obj, const void *buf, size_t sz)
|
|||
|
||||
static int nsos_close(void *obj)
|
||||
{
|
||||
struct nsos_socket *sock = obj;
|
||||
int ret;
|
||||
|
||||
ret = nsi_host_close(OBJ_TO_FD(obj));
|
||||
ret = nsi_host_close(sock->pollfd.fd);
|
||||
if (ret < 0) {
|
||||
errno = nsos_adapt_get_zephyr_errno();
|
||||
}
|
||||
|
@ -218,14 +240,100 @@ static int nsos_close(void *obj)
|
|||
return ret;
|
||||
}
|
||||
|
||||
static void pollcb(struct nsos_mid_pollfd *pollfd)
|
||||
{
|
||||
struct nsos_socket *sock = CONTAINER_OF(pollfd, struct nsos_socket, pollfd);
|
||||
|
||||
k_poll_signal_raise(&sock->poll, sock->pollfd.revents);
|
||||
}
|
||||
|
||||
static int nsos_poll_prepare(struct nsos_socket *sock, struct zsock_pollfd *pfd,
|
||||
struct k_poll_event **pev, struct k_poll_event *pev_end)
|
||||
{
|
||||
unsigned int signaled;
|
||||
int flags;
|
||||
|
||||
sock->pollfd.events = pfd->events;
|
||||
sock->pollfd.revents = 0;
|
||||
sock->pollfd.cb = pollcb;
|
||||
|
||||
if (*pev == pev_end) {
|
||||
errno = ENOMEM;
|
||||
return -1;
|
||||
}
|
||||
|
||||
k_poll_signal_init(&sock->poll);
|
||||
k_poll_event_init(*pev, K_POLL_TYPE_SIGNAL, K_POLL_MODE_NOTIFY_ONLY, &sock->poll);
|
||||
|
||||
sys_dlist_append(&nsos_sockets, &sock->node);
|
||||
|
||||
nsos_adapt_poll_add(&sock->pollfd);
|
||||
|
||||
/* Let other sockets use another k_poll_event */
|
||||
(*pev)++;
|
||||
|
||||
signaled = 0;
|
||||
flags = 0;
|
||||
|
||||
k_poll_signal_check(&sock->poll, &signaled, &flags);
|
||||
if (!signaled) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Events are ready, don't wait */
|
||||
return -EALREADY;
|
||||
}
|
||||
|
||||
static int nsos_poll_update(struct nsos_socket *sock, struct zsock_pollfd *pfd,
|
||||
struct k_poll_event **pev)
|
||||
{
|
||||
unsigned int signaled;
|
||||
int flags;
|
||||
|
||||
(*pev)++;
|
||||
|
||||
signaled = 0;
|
||||
flags = 0;
|
||||
|
||||
nsos_adapt_poll_remove(&sock->pollfd);
|
||||
sys_dlist_remove(&sock->node);
|
||||
|
||||
k_poll_signal_check(&sock->poll, &signaled, &flags);
|
||||
if (!signaled) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
pfd->revents = flags;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int nsos_ioctl(void *obj, unsigned int request, va_list args)
|
||||
{
|
||||
switch (request) {
|
||||
case ZFD_IOCTL_POLL_PREPARE:
|
||||
return -EXDEV;
|
||||
struct nsos_socket *sock = obj;
|
||||
|
||||
case ZFD_IOCTL_POLL_UPDATE:
|
||||
return -EOPNOTSUPP;
|
||||
switch (request) {
|
||||
case ZFD_IOCTL_POLL_PREPARE: {
|
||||
struct zsock_pollfd *pfd;
|
||||
struct k_poll_event **pev;
|
||||
struct k_poll_event *pev_end;
|
||||
|
||||
pfd = va_arg(args, struct zsock_pollfd *);
|
||||
pev = va_arg(args, struct k_poll_event **);
|
||||
pev_end = va_arg(args, struct k_poll_event *);
|
||||
|
||||
return nsos_poll_prepare(obj, pfd, pev, pev_end);
|
||||
}
|
||||
|
||||
case ZFD_IOCTL_POLL_UPDATE: {
|
||||
struct zsock_pollfd *pfd;
|
||||
struct k_poll_event **pev;
|
||||
|
||||
pfd = va_arg(args, struct zsock_pollfd *);
|
||||
pev = va_arg(args, struct k_poll_event **);
|
||||
|
||||
return nsos_poll_update(obj, pfd, pev);
|
||||
}
|
||||
|
||||
case ZFD_IOCTL_POLL_OFFLOAD:
|
||||
return -EOPNOTSUPP;
|
||||
|
@ -233,7 +341,7 @@ static int nsos_ioctl(void *obj, unsigned int request, va_list args)
|
|||
case F_GETFL: {
|
||||
int flags;
|
||||
|
||||
flags = nsos_adapt_fcntl_getfl(OBJ_TO_FD(obj));
|
||||
flags = nsos_adapt_fcntl_getfl(sock->pollfd.fd);
|
||||
|
||||
return fl_from_nsos_mid(flags);
|
||||
}
|
||||
|
@ -247,7 +355,7 @@ static int nsos_ioctl(void *obj, unsigned int request, va_list args)
|
|||
return -errno_from_nsos_mid(-ret);
|
||||
}
|
||||
|
||||
ret = nsos_adapt_fcntl_setfl(OBJ_TO_FD(obj), flags);
|
||||
ret = nsos_adapt_fcntl_setfl(sock->pollfd.fd, flags);
|
||||
|
||||
return -errno_from_nsos_mid(-ret);
|
||||
}
|
||||
|
@ -355,6 +463,7 @@ static int sockaddr_from_nsos_mid(struct sockaddr *addr, socklen_t *addrlen,
|
|||
|
||||
static int nsos_bind(void *obj, const struct sockaddr *addr, socklen_t addrlen)
|
||||
{
|
||||
struct nsos_socket *sock = obj;
|
||||
struct nsos_mid_sockaddr_storage addr_storage_mid;
|
||||
struct nsos_mid_sockaddr *addr_mid = (struct nsos_mid_sockaddr *)&addr_storage_mid;
|
||||
size_t addrlen_mid;
|
||||
|
@ -365,7 +474,7 @@ static int nsos_bind(void *obj, const struct sockaddr *addr, socklen_t addrlen)
|
|||
goto return_ret;
|
||||
}
|
||||
|
||||
ret = nsos_adapt_bind(OBJ_TO_FD(obj), addr_mid, addrlen_mid);
|
||||
ret = nsos_adapt_bind(sock->pollfd.fd, addr_mid, addrlen_mid);
|
||||
|
||||
return_ret:
|
||||
if (ret < 0) {
|
||||
|
@ -378,6 +487,7 @@ return_ret:
|
|||
|
||||
static int nsos_connect(void *obj, const struct sockaddr *addr, socklen_t addrlen)
|
||||
{
|
||||
struct nsos_socket *sock = obj;
|
||||
struct nsos_mid_sockaddr_storage addr_storage_mid;
|
||||
struct nsos_mid_sockaddr *addr_mid = (struct nsos_mid_sockaddr *)&addr_storage_mid;
|
||||
size_t addrlen_mid;
|
||||
|
@ -388,7 +498,7 @@ static int nsos_connect(void *obj, const struct sockaddr *addr, socklen_t addrle
|
|||
goto return_ret;
|
||||
}
|
||||
|
||||
ret = nsos_adapt_connect(OBJ_TO_FD(obj), addr_mid, addrlen_mid);
|
||||
ret = nsos_adapt_connect(sock->pollfd.fd, addr_mid, addrlen_mid);
|
||||
|
||||
return_ret:
|
||||
if (ret < 0) {
|
||||
|
@ -401,9 +511,10 @@ return_ret:
|
|||
|
||||
static int nsos_listen(void *obj, int backlog)
|
||||
{
|
||||
struct nsos_socket *sock = obj;
|
||||
int ret;
|
||||
|
||||
ret = nsos_adapt_listen(OBJ_TO_FD(obj), backlog);
|
||||
ret = nsos_adapt_listen(sock->pollfd.fd, backlog);
|
||||
if (ret < 0) {
|
||||
errno = errno_from_nsos_mid(-ret);
|
||||
return -1;
|
||||
|
@ -414,12 +525,16 @@ static int nsos_listen(void *obj, int backlog)
|
|||
|
||||
static int nsos_accept(void *obj, struct sockaddr *addr, socklen_t *addrlen)
|
||||
{
|
||||
struct nsos_socket *accept_sock = obj;
|
||||
struct nsos_mid_sockaddr_storage addr_storage_mid;
|
||||
struct nsos_mid_sockaddr *addr_mid = (struct nsos_mid_sockaddr *)&addr_storage_mid;
|
||||
size_t addrlen_mid = sizeof(addr_storage_mid);
|
||||
int adapt_fd;
|
||||
int zephyr_fd;
|
||||
struct nsos_socket *conn_sock;
|
||||
int ret;
|
||||
|
||||
ret = nsos_adapt_accept(OBJ_TO_FD(obj), addr_mid, &addrlen_mid);
|
||||
ret = nsos_adapt_accept(accept_sock->pollfd.fd, addr_mid, &addrlen_mid);
|
||||
if (ret < 0) {
|
||||
errno = errno_from_nsos_mid(-ret);
|
||||
return -1;
|
||||
|
@ -438,10 +553,21 @@ static int nsos_accept(void *obj, struct sockaddr *addr, socklen_t *addrlen)
|
|||
goto close_adapt_fd;
|
||||
}
|
||||
|
||||
z_finalize_fd(zephyr_fd, FD_TO_OBJ(adapt_fd), &nsos_socket_fd_op_vtable.fd_vtable);
|
||||
conn_sock = k_malloc(sizeof(*conn_sock));
|
||||
if (!conn_sock) {
|
||||
errno = ENOMEM;
|
||||
goto free_zephyr_fd;
|
||||
}
|
||||
|
||||
conn_sock->pollfd.fd = adapt_fd;
|
||||
|
||||
z_finalize_fd(zephyr_fd, conn_sock, &nsos_socket_fd_op_vtable.fd_vtable);
|
||||
|
||||
return zephyr_fd;
|
||||
|
||||
free_zephyr_fd:
|
||||
z_free_fd(zephyr_fd);
|
||||
|
||||
close_adapt_fd:
|
||||
nsi_host_close(adapt_fd);
|
||||
|
||||
|
@ -451,6 +577,7 @@ close_adapt_fd:
|
|||
static ssize_t nsos_sendto(void *obj, const void *buf, size_t len, int flags,
|
||||
const struct sockaddr *addr, socklen_t addrlen)
|
||||
{
|
||||
struct nsos_socket *sock = obj;
|
||||
struct nsos_mid_sockaddr_storage addr_storage_mid;
|
||||
struct nsos_mid_sockaddr *addr_mid = (struct nsos_mid_sockaddr *)&addr_storage_mid;
|
||||
size_t addrlen_mid = sizeof(addr_storage_mid);
|
||||
|
@ -469,7 +596,7 @@ static ssize_t nsos_sendto(void *obj, const void *buf, size_t len, int flags,
|
|||
goto return_ret;
|
||||
}
|
||||
|
||||
ret = nsos_adapt_sendto(OBJ_TO_FD(obj), buf, len, flags_mid,
|
||||
ret = nsos_adapt_sendto(sock->pollfd.fd, buf, len, flags_mid,
|
||||
addr_mid, addrlen_mid);
|
||||
|
||||
return_ret:
|
||||
|
@ -490,6 +617,7 @@ static ssize_t nsos_sendmsg(void *obj, const struct msghdr *msg, int flags)
|
|||
static ssize_t nsos_recvfrom(void *obj, void *buf, size_t len, int flags,
|
||||
struct sockaddr *addr, socklen_t *addrlen)
|
||||
{
|
||||
struct nsos_socket *sock = obj;
|
||||
struct nsos_mid_sockaddr_storage addr_storage_mid;
|
||||
struct nsos_mid_sockaddr *addr_mid = (struct nsos_mid_sockaddr *)&addr_storage_mid;
|
||||
size_t addrlen_mid = sizeof(addr_storage_mid);
|
||||
|
@ -503,7 +631,7 @@ static ssize_t nsos_recvfrom(void *obj, void *buf, size_t len, int flags,
|
|||
|
||||
flags_mid = ret;
|
||||
|
||||
ret = nsos_adapt_recvfrom(OBJ_TO_FD(obj), buf, len, flags_mid,
|
||||
ret = nsos_adapt_recvfrom(sock->pollfd.fd, buf, len, flags_mid,
|
||||
addr_mid, &addrlen_mid);
|
||||
if (ret < 0) {
|
||||
goto return_ret;
|
||||
|
@ -699,10 +827,25 @@ static const struct socket_dns_offload nsos_dns_ops = {
|
|||
.freeaddrinfo = nsos_freeaddrinfo,
|
||||
};
|
||||
|
||||
static void nsos_isr(const void *obj)
|
||||
{
|
||||
struct nsos_socket *sock;
|
||||
|
||||
SYS_DLIST_FOR_EACH_CONTAINER(&nsos_sockets, sock, node) {
|
||||
if (sock->pollfd.revents) {
|
||||
sock->pollfd.cb(&sock->pollfd);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static int nsos_socket_offload_init(const struct device *arg)
|
||||
{
|
||||
ARG_UNUSED(arg);
|
||||
|
||||
IRQ_CONNECT(NSOS_IRQ, NSOS_IRQ_PRIORITY,
|
||||
nsos_isr, NULL, NSOS_IRQ_FLAGS);
|
||||
irq_enable(NSOS_IRQ);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue