From fb638a13cc1a986a0b500d5e9fa3bbc4bfa37342 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=A2=81=E8=B6=85=E4=BC=97?= Date: Tue, 3 Jan 2023 10:50:39 +0800 Subject: [PATCH] remove userspace usrsock rpmsg client/server MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: 梁超众 --- netutils/usrsock_rpmsg/Kconfig | 40 - netutils/usrsock_rpmsg/Make.defs | 23 - netutils/usrsock_rpmsg/Makefile | 34 - netutils/usrsock_rpmsg/usrsock_rpmsg.h | 61 - netutils/usrsock_rpmsg/usrsock_rpmsg_client.c | 328 ----- netutils/usrsock_rpmsg/usrsock_rpmsg_server.c | 1198 ----------------- 6 files changed, 1684 deletions(-) delete mode 100644 netutils/usrsock_rpmsg/Kconfig delete mode 100644 netutils/usrsock_rpmsg/Make.defs delete mode 100644 netutils/usrsock_rpmsg/Makefile delete mode 100644 netutils/usrsock_rpmsg/usrsock_rpmsg.h delete mode 100644 netutils/usrsock_rpmsg/usrsock_rpmsg_client.c delete mode 100644 netutils/usrsock_rpmsg/usrsock_rpmsg_server.c diff --git a/netutils/usrsock_rpmsg/Kconfig b/netutils/usrsock_rpmsg/Kconfig deleted file mode 100644 index 83135a21e..000000000 --- a/netutils/usrsock_rpmsg/Kconfig +++ /dev/null @@ -1,40 +0,0 @@ -# -# For a description of the syntax of this configuration file, -# see the file kconfig-language.txt in the NuttX tools repository. -# - -config NETUTILS_USRSOCK_RPMSG - tristate "RPMSG usrsock" - default n - depends on NET && RPTUN - select EVENT_FD if !NET_USRSOCK - ---help--- - Enable usrsock through rpmsg channel. - -if NETUTILS_USRSOCK_RPMSG - -config NETUTILS_USRSOCK_RPMSG_PRIORITY - int "usrsock task priority" - default 80 - ---help--- - The priority for usrsock task. - -config NETUTILS_USRSOCK_RPMSG_STACKSIZE - int "usrsock task stack size" - default DEFAULT_TASK_STACKSIZE - ---help--- - The stack size allocated for the usrsock task. - -config NETUTILS_USRSOCK_NSOCK_DESCRIPTORS - int "The maximum number of socket descriptors for usrsock monitoring" - default 64 - ---help--- - The maximum number of socket description for usrsosck monitoring. - -config NETUTILS_USRSOCK_NIOVEC - int "The maximum number of I/O vector for reassemble buffer" - default 8 - ---help--- - The maximum number of I/O vector for reassemble buffer. - -endif # NETUTILS_USRSOCK_RPMSG diff --git a/netutils/usrsock_rpmsg/Make.defs b/netutils/usrsock_rpmsg/Make.defs deleted file mode 100644 index e435d667f..000000000 --- a/netutils/usrsock_rpmsg/Make.defs +++ /dev/null @@ -1,23 +0,0 @@ -############################################################################ -# apps/netutils/usrsock_rpmsg/Make.defs -# -# Licensed to the Apache Software Foundation (ASF) under one or more -# contributor license agreements. See the NOTICE file distributed with -# this work for additional information regarding copyright ownership. The -# ASF licenses this file to you under the Apache License, Version 2.0 (the -# "License"); you may not use this file except in compliance with the -# License. You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -# License for the specific language governing permissions and limitations -# under the License. -# -############################################################################ - -ifneq ($(CONFIG_NETUTILS_USRSOCK_RPMSG),) -CONFIGURED_APPS += $(APPDIR)/netutils/usrsock_rpmsg -endif diff --git a/netutils/usrsock_rpmsg/Makefile b/netutils/usrsock_rpmsg/Makefile deleted file mode 100644 index 07f9be810..000000000 --- a/netutils/usrsock_rpmsg/Makefile +++ /dev/null @@ -1,34 +0,0 @@ -############################################################################ -# apps/netutils/usrsock_rpmsg/Makefile -# -# Licensed to the Apache Software Foundation (ASF) under one or more -# contributor license agreements. See the NOTICE file distributed with -# this work for additional information regarding copyright ownership. The -# ASF licenses this file to you under the Apache License, Version 2.0 (the -# "License"); you may not use this file except in compliance with the -# License. You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -# License for the specific language governing permissions and limitations -# under the License. -# -############################################################################ - -include $(APPDIR)/Make.defs - -PROGNAME = usrsock -PRIORITY = CONFIG_NETUTILS_USRSOCK_RPMSG_PRIORITY -STACKSIZE = CONFIG_NETUTILS_USRSOCK_RPMSG_STACKSIZE - -ifeq ($(CONFIG_NET_USRSOCK),y) -MAINSRC := usrsock_rpmsg_client.c -else -MAINSRC := usrsock_rpmsg_server.c -endif -MODULE = $(CONFIG_NETUTILS_USRSOCK_RPMSG) - -include $(APPDIR)/Application.mk diff --git a/netutils/usrsock_rpmsg/usrsock_rpmsg.h b/netutils/usrsock_rpmsg/usrsock_rpmsg.h deleted file mode 100644 index 3eb956b0b..000000000 --- a/netutils/usrsock_rpmsg/usrsock_rpmsg.h +++ /dev/null @@ -1,61 +0,0 @@ -/**************************************************************************** - * apps/netutils/usrsock_rpmsg/usrsock_rpmsg.h - * - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. The - * ASF licenses this file to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance with the - * License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the - * License for the specific language governing permissions and limitations - * under the License. - * - ****************************************************************************/ - -#ifndef __APPS_NETUTILS_USRSOCK_RPMSG_H -#define __APPS_NETUTILS_USRSOCK_RPMSG_H - -/**************************************************************************** - * Included Files - ****************************************************************************/ - -#include - -/**************************************************************************** - * Pre-processor definitions - ****************************************************************************/ - -#define USRSOCK_RPMSG_EPT_NAME "rpmsg-usrsock" - -#define USRSOCK_RPMSG_DNS_REQUEST USRSOCK_REQUEST__MAX -#define USRSOCK_RPMSG_DNS_EVENT 127 - -/**************************************************************************** - * Public Types - ****************************************************************************/ - -/* DNS request message */ - -begin_packed_struct struct usrsock_rpmsg_dns_request_s -{ - struct usrsock_request_common_s head; - - uint16_t addrlen; -} end_packed_struct; - -/* DNS event message */ - -begin_packed_struct struct usrsock_rpmsg_dns_event_s -{ - struct usrsock_message_common_s head; - - uint16_t addrlen; -} end_packed_struct; - -#endif /* __APPS_NETUTILS_USRSOCK_RPMSG_H */ diff --git a/netutils/usrsock_rpmsg/usrsock_rpmsg_client.c b/netutils/usrsock_rpmsg/usrsock_rpmsg_client.c deleted file mode 100644 index 731cf976b..000000000 --- a/netutils/usrsock_rpmsg/usrsock_rpmsg_client.c +++ /dev/null @@ -1,328 +0,0 @@ -/**************************************************************************** - * apps/netutils/usrsock_rpmsg/usrsock_rpmsg_client.c - * - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. The - * ASF licenses this file to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance with the - * License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the - * License for the specific language governing permissions and limitations - * under the License. - * - ****************************************************************************/ - -/**************************************************************************** - * Included Files - ****************************************************************************/ - -#include - -#include -#include -#include -#include -#include - -#include -#include -#include - -#include "usrsock_rpmsg.h" - -/**************************************************************************** - * Private Types - ****************************************************************************/ - -struct usrsock_rpmsg_s -{ - struct rpmsg_endpoint ept; - const char *cpuname; - pid_t pid; - sem_t sem; - struct file file; -}; - -/**************************************************************************** - * Private Function Prototypes - ****************************************************************************/ - -static int usrsock_rpmsg_dns_handler(struct rpmsg_endpoint *ept, void *data, - size_t len, uint32_t src, void *priv); -static int usrsock_rpmsg_default_handler(struct rpmsg_endpoint *ept, - void *data, size_t len, - uint32_t src, void *priv_); - -static void usrsock_rpmsg_device_created(struct rpmsg_device *rdev, - void *priv_); -static void usrsock_rpmsg_device_destroy(struct rpmsg_device *rdev, - void *priv_); -static int usrsock_rpmsg_ept_cb(struct rpmsg_endpoint *ept, void *data, - size_t len, uint32_t src, void *priv); - -static void usrsock_rpmsg_ns_unbind(struct rpmsg_endpoint *ept); - -#ifdef CONFIG_NETDB_DNSCLIENT -static int usrsock_rpmsg_send_dns_request(void *arg, - struct sockaddr *addr, - socklen_t addrlen); -#endif - -/**************************************************************************** - * Private Functions - ****************************************************************************/ - -static void usrsock_rpmsg_device_created(struct rpmsg_device *rdev, - void *priv_) -{ - struct usrsock_rpmsg_s *priv = priv_; - int ret; - - if (!strcmp(priv->cpuname, rpmsg_get_cpuname(rdev))) - { - priv->ept.priv = priv; - - ret = rpmsg_create_ept(&priv->ept, rdev, USRSOCK_RPMSG_EPT_NAME, - RPMSG_ADDR_ANY, RPMSG_ADDR_ANY, - usrsock_rpmsg_ept_cb, usrsock_rpmsg_ns_unbind); - if (ret == 0) - { -#ifdef CONFIG_NETDB_DNSCLIENT - dns_register_notify(usrsock_rpmsg_send_dns_request, priv); -#endif - sem_post(&priv->sem); - } - } -} - -static void usrsock_rpmsg_device_destroy(struct rpmsg_device *rdev, - void *priv_) -{ - struct usrsock_rpmsg_s *priv = priv_; - - if (!strcmp(priv->cpuname, rpmsg_get_cpuname(rdev))) - { - rpmsg_destroy_ept(&priv->ept); - kill(priv->pid, SIGUSR1); - } -} - -static int usrsock_rpmsg_dns_handler(struct rpmsg_endpoint *ept, void *data, - size_t len, uint32_t src, void *priv) -{ -#ifdef CONFIG_NETDB_DNSCLIENT - struct usrsock_rpmsg_dns_event_s *dns = data; - - dns_add_nameserver((struct sockaddr *)(dns + 1), dns->addrlen); -#endif - - return 0; -} - -static int usrsock_rpmsg_default_handler(struct rpmsg_endpoint *ept, - void *data, size_t len, - uint32_t src, void *priv_) -{ - struct usrsock_rpmsg_s *priv = priv_; - - while (len > 0) - { - ssize_t ret = file_write(&priv->file, data, len); - if (ret < 0) - { - return ret; - } - - data += ret; - len -= ret; - } - - return 0; -} - -static int usrsock_rpmsg_ept_cb(struct rpmsg_endpoint *ept, void *data, - size_t len, uint32_t src, void *priv) -{ - struct usrsock_message_common_s *common = data; - int ret; - - switch (common->msgid) - { - case USRSOCK_RPMSG_DNS_EVENT: - ret = usrsock_rpmsg_dns_handler(ept, data, len, src, priv); - break; - default: - ret = usrsock_rpmsg_default_handler(ept, data, len, src, priv); - break; - } - - return ret; -} - -#ifdef CONFIG_NETDB_DNSCLIENT -static int usrsock_rpmsg_send_dns_request(void *arg, - struct sockaddr *addr, - socklen_t addrlen) -{ - struct usrsock_rpmsg_s *priv = arg; - struct rpmsg_endpoint *ept = &priv->ept; - struct usrsock_rpmsg_dns_request_s *dns; - uint32_t len; - - dns = rpmsg_get_tx_payload_buffer(ept, &len, true); - - dns->head.reqid = USRSOCK_RPMSG_DNS_REQUEST; - dns->head.xid = 0; - dns->head.reserved = 0; - dns->addrlen = addrlen; - memcpy(dns + 1, addr, addrlen); - - return rpmsg_send_nocopy(ept, dns, sizeof(*dns) + addrlen); -} -#endif - -static void usrsock_rpmsg_ns_unbind(struct rpmsg_endpoint *ept) -{ -#ifdef CONFIG_NETDB_DNSCLIENT - dns_unregister_notify(usrsock_rpmsg_send_dns_request, ept->priv); -#endif -} - -/**************************************************************************** - * Public Functions - ****************************************************************************/ - -int main(int argc, char *argv[]) -{ - struct usrsock_rpmsg_s priv = - { - }; - - int ret; - - if (argv[1] == NULL) - { - return -EINVAL; - } - - priv.cpuname = argv[1]; - priv.pid = getpid(); - - sem_init(&priv.sem, 0, 0); - sem_setprotocol(&priv.sem, SEM_PRIO_NONE); - - sigrelse(SIGUSR1); - - ret = rpmsg_register_callback(&priv, - usrsock_rpmsg_device_created, - usrsock_rpmsg_device_destroy, - NULL, - NULL); - if (ret < 0) - { - goto destroy_sem; - } - - while (1) - { - /* Wait until the rpmsg channel is ready */ - - do - { - ret = sem_wait(&priv.sem); - if (ret < 0) - { - ret = -errno; - } - } - while (ret == -EINTR); - - if (ret < 0) - { - goto unregister_callback; - } - - /* Open the kernel channel */ - - ret = file_open(&priv.file, "/dev/usrsock", O_RDWR); - if (ret < 0) - { - ret = -errno; - goto destroy_ept; - } - - /* Forward the packet from kernel to remote */ - - while (1) - { - struct pollfd pfd; - FAR void *buf; - uint32_t len; - - /* Wait the packet ready */ - - memset(&pfd, 0, sizeof(struct pollfd)); - pfd.ptr = &priv.file; - pfd.events = POLLIN | POLLFILE; - ret = poll(&pfd, 1, -1); - if (ret < 0) - { - ret = -errno; - break; - } - - /* Read the packet from kernel */ - - buf = rpmsg_get_tx_payload_buffer(&priv.ept, &len, true); - if (!buf) - { - ret = -ENOMEM; - break; - } - - ret = file_read(&priv.file, buf, len); - if (ret < 0) - { - break; - } - - /* Send the packet to remote */ - - ret = rpmsg_send_nocopy(&priv.ept, buf, ret); - if (ret < 0) - { - break; - } - } - - /* Reclaim the resource */ - - file_close(&priv.file); - - if (is_rpmsg_ept_ready(&priv.ept)) - { - goto destroy_ept; - } - - /* The remote side crash, loop to wait it restore */ - } - -destroy_ept: - rpmsg_destroy_ept(&priv.ept); - -unregister_callback: - rpmsg_unregister_callback(&priv, - usrsock_rpmsg_device_created, - usrsock_rpmsg_device_destroy, - NULL, - NULL); -destroy_sem: - sem_destroy(&priv.sem); - return ret; -} diff --git a/netutils/usrsock_rpmsg/usrsock_rpmsg_server.c b/netutils/usrsock_rpmsg/usrsock_rpmsg_server.c deleted file mode 100644 index fbaa25e45..000000000 --- a/netutils/usrsock_rpmsg/usrsock_rpmsg_server.c +++ /dev/null @@ -1,1198 +0,0 @@ -/**************************************************************************** - * apps/netutils/usrsock_rpmsg/usrsock_rpmsg_server.c - * - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. The - * ASF licenses this file to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance with the - * License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the - * License for the specific language governing permissions and limitations - * under the License. - * - ****************************************************************************/ - -/**************************************************************************** - * Included Files - ****************************************************************************/ - -#include - -#include -#include -#include -#include - -#include -#include - -#include -#include -#include -#ifdef CONFIG_NETDEV_WIRELESS_IOCTL -# include -#endif -#include "usrsock_rpmsg.h" - -/**************************************************************************** - * Pre-processor Definitions - ****************************************************************************/ - -#define EXTRA_IOV_LEN 10 - -/**************************************************************************** - * Private Types - ****************************************************************************/ - -struct usrsock_rpmsg_s -{ - struct file *eventfp; - pthread_mutex_t mutex; - pthread_cond_t cond; - struct iovec iov[CONFIG_NETUTILS_USRSOCK_NIOVEC]; - struct socket socks[CONFIG_NETUTILS_USRSOCK_NSOCK_DESCRIPTORS]; - struct rpmsg_endpoint *epts[CONFIG_NETUTILS_USRSOCK_NSOCK_DESCRIPTORS]; - struct pollfd pfds[CONFIG_NETUTILS_USRSOCK_NSOCK_DESCRIPTORS + 1]; -}; - -/**************************************************************************** - * Private Function Prototypes - ****************************************************************************/ - -static bool usrsock_rpmsg_available(struct socket *psock, int cmd); - -static int usrsock_rpmsg_send_ack(struct rpmsg_endpoint *ept, - uint16_t events, - uint64_t xid, int32_t result); -static int usrsock_rpmsg_send_data_ack(struct rpmsg_endpoint *ept, - struct usrsock_message_datareq_ack_s *ack, - uint16_t events, - uint64_t xid, int32_t result, - uint16_t valuelen, - uint16_t valuelen_nontrunc, - int32_t datalen); -static int usrsock_rpmsg_send_event(struct rpmsg_endpoint *ept, - int16_t usockid, uint16_t events); - -static int usrsock_rpmsg_socket_handler(struct rpmsg_endpoint *ept, - void *data, size_t len, - uint32_t src, void *priv_); -static int usrsock_rpmsg_close_handler(struct rpmsg_endpoint *ept, - void *data, size_t len, - uint32_t src, void *priv_); -static int usrsock_rpmsg_connect_handler(struct rpmsg_endpoint *ept, - void *data, size_t len, - uint32_t src, void *priv_); -static int usrsock_rpmsg_sendto_handler(struct rpmsg_endpoint *ept, - void *data, size_t len, - uint32_t src, void *priv_); -static int usrsock_rpmsg_recvfrom_handler(struct rpmsg_endpoint *ept, - void *data, size_t len, - uint32_t src, void *priv_); -static int usrsock_rpmsg_setsockopt_handler(struct rpmsg_endpoint *ept, - void *data, size_t len, - uint32_t src, void *priv_); -static int usrsock_rpmsg_getsockopt_handler(struct rpmsg_endpoint *ept, - void *data, size_t len, - uint32_t src, void *priv_); -static int usrsock_rpmsg_getsockname_handler(struct rpmsg_endpoint *ept, - void *data, size_t len, - uint32_t src, void *priv_); -static int usrsock_rpmsg_getpeername_handler(struct rpmsg_endpoint *ept, - void *data, size_t len, - uint32_t src, void *priv_); -static int usrsock_rpmsg_bind_handler(struct rpmsg_endpoint *ept, - void *data, size_t len, - uint32_t src, void *priv_); -static int usrsock_rpmsg_listen_handler(struct rpmsg_endpoint *ept, - void *data, size_t len, - uint32_t src, void *priv_); -static int usrsock_rpmsg_accept_handler(struct rpmsg_endpoint *ept, - void *data, size_t len, - uint32_t src, void *priv_); -static int usrsock_rpmsg_ioctl_handler(struct rpmsg_endpoint *ept, - void *data, size_t len, - uint32_t src, void *priv_); -static int usrsock_rpmsg_dns_handler(struct rpmsg_endpoint *ept, - void *data, size_t len, - uint32_t src, void *priv_); - -static bool usrsock_rpmsg_ns_match(struct rpmsg_device *rdev, void *priv_, - const char *name, uint32_t dest); -static void usrsock_rpmsg_ns_bind(struct rpmsg_device *rdev, void *priv_, - const char *name, uint32_t dest); -static void usrsock_rpmsg_ns_unbind(struct rpmsg_endpoint *ept); -static int usrsock_rpmsg_ept_cb(struct rpmsg_endpoint *ept, void *data, - size_t len, uint32_t src, void *priv); - -static int usrsock_rpmsg_notify_poll(struct usrsock_rpmsg_s *priv); -static int usrsock_rpmsg_prepare_poll(struct usrsock_rpmsg_s *priv, - struct pollfd *pfds); -static bool usrsock_rpmsg_process_poll(struct usrsock_rpmsg_s *priv, - struct pollfd *pfds, int count); - -/**************************************************************************** - * Private Data - ****************************************************************************/ - -static const rpmsg_ept_cb g_usrsock_rpmsg_handler[] = -{ - [USRSOCK_REQUEST_SOCKET] = usrsock_rpmsg_socket_handler, - [USRSOCK_REQUEST_CLOSE] = usrsock_rpmsg_close_handler, - [USRSOCK_REQUEST_CONNECT] = usrsock_rpmsg_connect_handler, - [USRSOCK_REQUEST_SENDTO] = usrsock_rpmsg_sendto_handler, - [USRSOCK_REQUEST_RECVFROM] = usrsock_rpmsg_recvfrom_handler, - [USRSOCK_REQUEST_SETSOCKOPT] = usrsock_rpmsg_setsockopt_handler, - [USRSOCK_REQUEST_GETSOCKOPT] = usrsock_rpmsg_getsockopt_handler, - [USRSOCK_REQUEST_GETSOCKNAME] = usrsock_rpmsg_getsockname_handler, - [USRSOCK_REQUEST_GETPEERNAME] = usrsock_rpmsg_getpeername_handler, - [USRSOCK_REQUEST_BIND] = usrsock_rpmsg_bind_handler, - [USRSOCK_REQUEST_LISTEN] = usrsock_rpmsg_listen_handler, - [USRSOCK_REQUEST_ACCEPT] = usrsock_rpmsg_accept_handler, - [USRSOCK_REQUEST_IOCTL] = usrsock_rpmsg_ioctl_handler, - [USRSOCK_RPMSG_DNS_REQUEST] = usrsock_rpmsg_dns_handler, -}; - -/**************************************************************************** - * Private Functions - ****************************************************************************/ - -static bool usrsock_rpmsg_available(struct socket *psock, int cmd) -{ - int len; - - if (psock_ioctl(psock, cmd, &len, sizeof(len)) == 0) - { - if (len > 0) - { - return true; - } - } - - return false; -} - -static int usrsock_rpmsg_send_ack(struct rpmsg_endpoint *ept, - uint16_t events, - uint64_t xid, int32_t result) -{ - struct usrsock_message_req_ack_s ack; - - ack.head.msgid = USRSOCK_MESSAGE_RESPONSE_ACK; - ack.head.flags = (result == -EINPROGRESS); - ack.head.events = events; - - ack.xid = xid; - ack.result = result == -EINPROGRESS ? 0 : result; - - return rpmsg_send(ept, &ack, sizeof(ack)); -} - -static int usrsock_rpmsg_send_data_ack(struct rpmsg_endpoint *ept, - struct usrsock_message_datareq_ack_s *ack, - uint16_t events, - uint64_t xid, int32_t result, - uint16_t valuelen, - uint16_t valuelen_nontrunc, - int32_t datalen) -{ - ack->reqack.head.msgid = USRSOCK_MESSAGE_RESPONSE_DATA_ACK; - ack->reqack.head.flags = 0; - ack->reqack.head.events = events; - - ack->reqack.xid = xid; - ack->reqack.result = result; - - if (result < 0) - { - result = 0; - valuelen = 0; - valuelen_nontrunc = 0; - datalen = 0; - } - else if (valuelen > valuelen_nontrunc) - { - valuelen = valuelen_nontrunc; - } - - ack->valuelen = valuelen; - ack->valuelen_nontrunc = valuelen_nontrunc; - - return rpmsg_send_nocopy(ept, ack, sizeof(*ack) + valuelen + datalen); -} - -static int usrsock_rpmsg_send_event(struct rpmsg_endpoint *ept, - int16_t usockid, uint16_t events) -{ - struct usrsock_message_socket_event_s event; - - event.head.msgid = USRSOCK_MESSAGE_SOCKET_EVENT; - event.head.flags = USRSOCK_MESSAGE_FLAG_EVENT; - event.head.events = events; - - event.usockid = usockid; - - return rpmsg_send(ept, &event, sizeof(event)); -} - -static int usrsock_rpmsg_socket_handler(struct rpmsg_endpoint *ept, - void *data, size_t len, - uint32_t src, void *priv_) -{ - struct usrsock_request_socket_s *req = data; - struct usrsock_rpmsg_s *priv = priv_; - uint16_t events = 0; - int i; - int retr; - int ret = -ENFILE; - - for (i = 0; i < CONFIG_NETUTILS_USRSOCK_NSOCK_DESCRIPTORS; i++) - { - pthread_mutex_lock(&priv->mutex); - if (priv->socks[i].s_conn == NULL) - { - ret = psock_socket(req->domain, req->type | SOCK_NONBLOCK, - req->protocol, &priv->socks[i]); - pthread_mutex_unlock(&priv->mutex); - if (ret >= 0) - { - priv->epts[i] = ept; - ret = i; /* Return index as the usockid */ - if (req->type != SOCK_STREAM && req->type != SOCK_SEQPACKET) - { - events = USRSOCK_EVENT_SENDTO_READY; - } - } - - break; - } - - pthread_mutex_unlock(&priv->mutex); - } - - retr = usrsock_rpmsg_send_ack(ept, events, req->head.xid, ret); - if (retr >= 0 && ret >= 0 && - req->type != SOCK_STREAM && req->type != SOCK_SEQPACKET) - { - pthread_mutex_lock(&priv->mutex); - priv->pfds[ret].ptr = &priv->socks[ret]; - priv->pfds[ret].events = POLLIN; - usrsock_rpmsg_notify_poll(priv); - pthread_mutex_unlock(&priv->mutex); - } - - return retr; -} - -static int usrsock_rpmsg_close_handler(struct rpmsg_endpoint *ept, - void *data, size_t len, - uint32_t src, void *priv_) -{ - struct usrsock_request_close_s *req = data; - struct usrsock_rpmsg_s *priv = priv_; - int ret = -EBADF; - - if (req->usockid >= 0 && - req->usockid < CONFIG_NETUTILS_USRSOCK_NSOCK_DESCRIPTORS) - { - pthread_mutex_lock(&priv->mutex); - priv->pfds[req->usockid].ptr = NULL; - priv->epts[req->usockid] = NULL; - - /* Signal and wait the poll thread to wakeup */ - - usrsock_rpmsg_notify_poll(priv); - pthread_cond_wait(&priv->cond, &priv->mutex); - pthread_mutex_unlock(&priv->mutex); - - /* It's safe to close sock here */ - - ret = psock_close(&priv->socks[req->usockid]); - } - - return usrsock_rpmsg_send_ack(ept, 0, req->head.xid, ret); -} - -static int usrsock_rpmsg_connect_handler(struct rpmsg_endpoint *ept, - void *data, size_t len, - uint32_t src, void *priv_) -{ - struct usrsock_request_connect_s *req = data; - struct usrsock_rpmsg_s *priv = priv_; - bool inprogress = false; - int retr; - int ret = -EBADF; - - if (req->usockid >= 0 && - req->usockid < CONFIG_NETUTILS_USRSOCK_NSOCK_DESCRIPTORS) - { - ret = psock_connect(&priv->socks[req->usockid], - (const struct sockaddr *)(req + 1), req->addrlen); - } - - retr = usrsock_rpmsg_send_ack(ept, 0, req->head.xid, ret); - if (ret == -EINPROGRESS) - { - inprogress = true; - ret = 0; - } - - if (retr >= 0 && ret >= 0 && priv->pfds[req->usockid].ptr == NULL) - { - pthread_mutex_lock(&priv->mutex); - priv->pfds[req->usockid].ptr = &priv->socks[req->usockid]; - priv->pfds[req->usockid].events = POLLIN; - if (inprogress) - { - priv->pfds[req->usockid].events |= POLLOUT; - } - - usrsock_rpmsg_notify_poll(priv); - pthread_mutex_unlock(&priv->mutex); - if (!inprogress) - { - retr = usrsock_rpmsg_send_event(ept, - req->usockid, USRSOCK_EVENT_SENDTO_READY); - } - } - - return retr; -} - -static int usrsock_rpmsg_sendto_handler(struct rpmsg_endpoint *ept, - void *data, size_t len, - uint32_t src, void *priv_) -{ - struct usrsock_request_sendto_s *req; - struct usrsock_rpmsg_s *priv = priv_; - uint16_t events = 0; - ssize_t ret = -EBADF; - size_t total; - int retr; - int i; - - if (priv->iov[0].iov_base) - { - size_t hlen; - struct msghdr msg = - { - }; - - req = priv->iov[0].iov_base; - hlen = sizeof(*req) + req->addrlen; - - total = len; - for (i = 0; i < CONFIG_NETUTILS_USRSOCK_NIOVEC; i++) - { - if (!priv->iov[i].iov_base) - { - priv->iov[i].iov_base = data; - priv->iov[i].iov_len = len; - rpmsg_hold_rx_buffer(ept, data); - break; - } - - total += priv->iov[i].iov_len; - } - - if (i == CONFIG_NETUTILS_USRSOCK_NIOVEC) - { - ret = -ENOMEM; - goto out; - } - - /* Partial packet ? continue to fetch */ - - if (req->buflen > total - hlen) - { - return 0; - } - else if (req->buflen < total - hlen) - { - ret = -EINVAL; - goto out; - } - - /* Skip the sendto header from I/O vector */ - - priv->iov[0].iov_base = (char *)priv->iov[0].iov_base + hlen; - priv->iov[0].iov_len -= hlen; - - msg.msg_name = req->addrlen ? (void *)(req + 1) : NULL; - msg.msg_namelen = req->addrlen; - msg.msg_iov = priv->iov; - msg.msg_iovlen = i + 1; - - ret = psock_sendmsg(&priv->socks[req->usockid], &msg, req->flags); - - /* Recover the I/O vector */ - - priv->iov[0].iov_base = (char *)priv->iov[0].iov_base - hlen; - priv->iov[0].iov_len += hlen; - } - else - { - req = data; - - if (req->usockid >= 0 && - req->usockid < CONFIG_NETUTILS_USRSOCK_NSOCK_DESCRIPTORS) - { - total = sizeof(*req) + req->addrlen + req->buflen; - if (total > len) - { - priv->iov[0].iov_base = data; - priv->iov[0].iov_len = len; - - rpmsg_hold_rx_buffer(ept, data); - return 0; - } - else - { - ret = psock_sendto(&priv->socks[req->usockid], - (const char *)(req + 1) + req->addrlen, req->buflen, - req->flags, - req->addrlen ? (const struct sockaddr *)(req + 1) : NULL, - req->addrlen); - } - } - } - -out: - if (ret > 0 && - usrsock_rpmsg_available(&priv->socks[req->usockid], FIONSPACE)) - { - events |= USRSOCK_EVENT_SENDTO_READY; - } - - retr = usrsock_rpmsg_send_ack(ept, events, req->head.xid, ret); - if (retr >= 0 && events == 0) - { - pthread_mutex_lock(&priv->mutex); - priv->pfds[req->usockid].events |= POLLOUT; - usrsock_rpmsg_notify_poll(priv); - pthread_mutex_unlock(&priv->mutex); - } - - if (priv->iov[0].iov_base) - { - for (i = 0; i < CONFIG_NETUTILS_USRSOCK_NIOVEC; i++) - { - if (priv->iov[i].iov_base == NULL) - { - break; - } - - rpmsg_release_rx_buffer(ept, priv->iov[i].iov_base); - priv->iov[i].iov_base = NULL; - priv->iov[i].iov_len = 0; - } - } - - return retr; -} - -static int usrsock_rpmsg_recvfrom_handler(struct rpmsg_endpoint *ept, - void *data, size_t len_, - uint32_t src, void *priv_) -{ - struct usrsock_request_recvfrom_s *req = data; - struct usrsock_message_datareq_ack_s *ack; - struct usrsock_rpmsg_s *priv = priv_; - socklen_t outaddrlen = req->max_addrlen; - socklen_t inaddrlen = req->max_addrlen; - size_t buflen = req->max_buflen; - ssize_t ret = -EBADF; - uint16_t events = 0; - uint32_t len = buflen; - int retr; - size_t totlen = 0; - struct iovec iov[EXTRA_IOV_LEN]; - uint8_t i = 0; - - ack = rpmsg_get_tx_payload_buffer(ept, &len, true); - if (sizeof(*ack) + inaddrlen + buflen < len) - { - len = sizeof(*ack) + inaddrlen + buflen; - } - - memset(iov, 0, sizeof(iov)); - if (req->usockid >= 0 && - req->usockid < CONFIG_NETUTILS_USRSOCK_NSOCK_DESCRIPTORS) - { - ret = psock_recvfrom(&priv->socks[req->usockid], - (void *)(ack + 1) + inaddrlen, len - sizeof(*ack) - inaddrlen, - req->flags, - outaddrlen ? (struct sockaddr *)(ack + 1) : NULL, - outaddrlen ? &outaddrlen : NULL); - totlen = ret; - if (ret > 0) - { - if (outaddrlen < inaddrlen) - { - memcpy((void *)(ack + 1) + outaddrlen, - (void *)(ack + 1) + inaddrlen, ret); - } - - while (totlen < buflen && i < EXTRA_IOV_LEN) - { - if (!usrsock_rpmsg_available(&priv->socks[req->usockid], - FIONREAD)) - { - break; - } - - iov[i].iov_base = rpmsg_get_tx_payload_buffer(ept, - &len, - false); - if (!iov[i].iov_base) - { - events |= USRSOCK_EVENT_RECVFROM_AVAIL; - break; - } - - if (buflen - totlen < len) - { - len = buflen - totlen; - } - - /* Should never wait */ - - iov[i].iov_len = psock_recvfrom( - &priv->socks[req->usockid], - iov[i].iov_base, len, - req->flags | MSG_DONTWAIT, - NULL, NULL); - if ((ssize_t)iov[i].iov_len > 0) - { - totlen += iov[i].iov_len; - if (iov[i].iov_len < len) - { - break; - } - } - else - { - iov[i].iov_len = 0; - events |= USRSOCK_EVENT_RECVFROM_AVAIL; - break; - } - - i++; - } - } - } - - retr = usrsock_rpmsg_send_data_ack(ept, - ack, events, req->head.xid, - totlen, inaddrlen, outaddrlen, - ret); - for (i = 0; i < EXTRA_IOV_LEN; i++) - { - if (!iov[i].iov_base) - { - break; - } - - if (!iov[i].iov_len || retr <= 0) - { - /* FIXME: free rpmsg buffer */ - - break; - } - - ret = rpmsg_send_nocopy(ept, - iov[i].iov_base, iov[i].iov_len); - } - - if (retr >= 0 && events == 0) - { - pthread_mutex_lock(&priv->mutex); - priv->pfds[req->usockid].events |= POLLIN; - usrsock_rpmsg_notify_poll(priv); - pthread_mutex_unlock(&priv->mutex); - } - - return retr; -} - -static int usrsock_rpmsg_setsockopt_handler(struct rpmsg_endpoint *ept, - void *data, size_t len, - uint32_t src, void *priv_) -{ - struct usrsock_request_setsockopt_s *req = data; - struct usrsock_rpmsg_s *priv = priv_; - int ret = -EBADF; - - if (req->usockid >= 0 && - req->usockid < CONFIG_NETUTILS_USRSOCK_NSOCK_DESCRIPTORS) - { - ret = psock_setsockopt(&priv->socks[req->usockid], - req->level, req->option, req + 1, req->valuelen); - } - - return usrsock_rpmsg_send_ack(ept, 0, req->head.xid, ret); -} - -static int usrsock_rpmsg_getsockopt_handler(struct rpmsg_endpoint *ept, - void *data, size_t len_, - uint32_t src, void *priv_) -{ - struct usrsock_request_getsockopt_s *req = data; - struct usrsock_message_datareq_ack_s *ack; - struct usrsock_rpmsg_s *priv = priv_; - socklen_t optlen = req->max_valuelen; - int ret = -EBADF; - uint32_t len; - - ack = rpmsg_get_tx_payload_buffer(ept, &len, true); - if (req->usockid >= 0 && - req->usockid < CONFIG_NETUTILS_USRSOCK_NSOCK_DESCRIPTORS) - { - ret = psock_getsockopt(&priv->socks[req->usockid], - req->level, req->option, ack + 1, &optlen); - } - - return usrsock_rpmsg_send_data_ack(ept, - ack, 0, req->head.xid, ret, optlen, optlen, ret); -} - -static int usrsock_rpmsg_getsockname_handler(struct rpmsg_endpoint *ept, - void *data, size_t len_, - uint32_t src, void *priv_) -{ - struct usrsock_request_getsockname_s *req = data; - struct usrsock_message_datareq_ack_s *ack; - struct usrsock_rpmsg_s *priv = priv_; - socklen_t outaddrlen = req->max_addrlen; - socklen_t inaddrlen = req->max_addrlen; - int ret = -EBADF; - uint32_t len; - - ack = rpmsg_get_tx_payload_buffer(ept, &len, true); - if (req->usockid >= 0 && - req->usockid < CONFIG_NETUTILS_USRSOCK_NSOCK_DESCRIPTORS) - { - ret = psock_getsockname(&priv->socks[req->usockid], - (struct sockaddr *)(ack + 1), &outaddrlen); - } - - return usrsock_rpmsg_send_data_ack(ept, - ack, 0, req->head.xid, ret, inaddrlen, outaddrlen, ret); -} - -static int usrsock_rpmsg_getpeername_handler(struct rpmsg_endpoint *ept, - void *data, size_t len_, - uint32_t src, void *priv_) -{ - struct usrsock_request_getpeername_s *req = data; - struct usrsock_message_datareq_ack_s *ack; - struct usrsock_rpmsg_s *priv = priv_; - socklen_t outaddrlen = req->max_addrlen; - socklen_t inaddrlen = req->max_addrlen; - int ret = -EBADF; - uint32_t len; - - ack = rpmsg_get_tx_payload_buffer(ept, &len, true); - if (req->usockid >= 0 && - req->usockid < CONFIG_NETUTILS_USRSOCK_NSOCK_DESCRIPTORS) - { - ret = psock_getpeername(&priv->socks[req->usockid], - (struct sockaddr *)(ack + 1), &outaddrlen); - } - - return usrsock_rpmsg_send_data_ack(ept, - ack, 0, req->head.xid, ret, inaddrlen, outaddrlen, ret); -} - -static int usrsock_rpmsg_bind_handler(struct rpmsg_endpoint *ept, - void *data, size_t len, - uint32_t src, void *priv_) -{ - struct usrsock_request_bind_s *req = data; - struct usrsock_rpmsg_s *priv = priv_; - int ret = -EBADF; - - if (req->usockid >= 0 && - req->usockid < CONFIG_NETUTILS_USRSOCK_NSOCK_DESCRIPTORS) - { - ret = psock_bind(&priv->socks[req->usockid], - (const struct sockaddr *)(req + 1), req->addrlen); - } - - return usrsock_rpmsg_send_ack(ept, 0, req->head.xid, ret); -} - -static int usrsock_rpmsg_listen_handler(struct rpmsg_endpoint *ept, - void *data, size_t len, - uint32_t src, void *priv_) -{ - struct usrsock_request_listen_s *req = data; - struct usrsock_rpmsg_s *priv = priv_; - int retr; - int ret = -EBADF; - - if (req->usockid >= 0 && - req->usockid < CONFIG_NETUTILS_USRSOCK_NSOCK_DESCRIPTORS) - { - ret = psock_listen(&priv->socks[req->usockid], req->backlog); - } - - retr = usrsock_rpmsg_send_ack(ept, 0, req->head.xid, ret); - if (retr >= 0 && ret >= 0) - { - pthread_mutex_lock(&priv->mutex); - priv->pfds[req->usockid].ptr = &priv->socks[req->usockid]; - priv->pfds[req->usockid].events = POLLIN; - usrsock_rpmsg_notify_poll(priv); - pthread_mutex_unlock(&priv->mutex); - } - - return retr; -} - -static int usrsock_rpmsg_accept_handler(struct rpmsg_endpoint *ept, - void *data, size_t len_, - uint32_t src, void *priv_) -{ - struct usrsock_request_accept_s *req = data; - struct usrsock_message_datareq_ack_s *ack; - struct usrsock_rpmsg_s *priv = priv_; - socklen_t outaddrlen = req->max_addrlen; - socklen_t inaddrlen = req->max_addrlen; - int ret = -EBADF; - uint32_t len; - int i = 0; - int retr; - - ack = rpmsg_get_tx_payload_buffer(ept, &len, true); - if (req->usockid >= 0 && - req->usockid < CONFIG_NETUTILS_USRSOCK_NSOCK_DESCRIPTORS) - { - ret = -ENFILE; /* Assume no free socket handler */ - for (i = 0; i < CONFIG_NETUTILS_USRSOCK_NSOCK_DESCRIPTORS; i++) - { - pthread_mutex_lock(&priv->mutex); - if (priv->socks[i].s_conn == NULL) - { - ret = psock_accept(&priv->socks[req->usockid], - outaddrlen ? (struct sockaddr *)(ack + 1) : NULL, - outaddrlen ? &outaddrlen : NULL, &priv->socks[i]); - pthread_mutex_unlock(&priv->mutex); - if (ret >= 0) - { - int nonblock = 1; - - psock_ioctl(&priv->socks[i], FIONBIO, &nonblock); - priv->epts[i] = ept; - - /* Append index as usockid to the payload */ - - if (outaddrlen <= inaddrlen) - { - *(int16_t *)((void *)(ack + 1) + outaddrlen) = i; - } - else - { - *(int16_t *)((void *)(ack + 1) + inaddrlen) = i; - } - - ret = sizeof(int16_t); /* Return usockid size */ - } - - break; - } - - pthread_mutex_unlock(&priv->mutex); - } - } - - retr = usrsock_rpmsg_send_data_ack(ept, - ack, 0, req->head.xid, ret, inaddrlen, outaddrlen, ret); - if (retr >= 0 && ret >= 0) - { - pthread_mutex_lock(&priv->mutex); - priv->pfds[i].ptr = &priv->socks[i]; - priv->pfds[i].events = POLLIN; - priv->pfds[req->usockid].events |= POLLIN; - usrsock_rpmsg_notify_poll(priv); - pthread_mutex_unlock(&priv->mutex); - usrsock_rpmsg_send_event(ept, i, USRSOCK_EVENT_SENDTO_READY); - } - - return retr; -} - -static int usrsock_rpmsg_ioctl_handler(struct rpmsg_endpoint *ept, - void *data, size_t len_, - uint32_t src, void *priv_) -{ - struct usrsock_request_ioctl_s *req = data; - struct usrsock_message_datareq_ack_s *ack; - struct usrsock_rpmsg_s *priv = priv_; -#ifdef CONFIG_NETDEV_WIRELESS_IOCTL - struct iwreq *wlreq; - struct iwreq *wlack; -#endif - int ret = -EBADF; - uint32_t len; - - ack = rpmsg_get_tx_payload_buffer(ept, &len, true); - if (req->usockid >= 0 && - req->usockid < CONFIG_NETUTILS_USRSOCK_NSOCK_DESCRIPTORS) - { - memcpy(ack + 1, req + 1, len_ - sizeof(*req)); -#ifdef CONFIG_NETDEV_WIRELESS_IOCTL - wlreq = (struct iwreq *)(req + 1); - wlack = (struct iwreq *)(ack + 1); - if (WL_IS80211POINTERCMD(req->cmd) && wlreq->u.data.pointer) - { - wlack->u.data.pointer = wlack + 1; - } -#endif - - ret = psock_ioctl(&priv->socks[req->usockid], - req->cmd, (unsigned long)(ack + 1)); - -#ifdef CONFIG_NETDEV_WIRELESS_IOCTL - if (WL_IS80211POINTERCMD(req->cmd) && wlreq->u.data.pointer) - { - if (ret >= 0) - { - ret = wlreq->u.data.length; - } - - wlack->u.data.pointer = wlreq->u.data.pointer; - } -#endif - } - - return usrsock_rpmsg_send_data_ack(ept, - ack, 0, req->head.xid, ret, req->arglen, req->arglen, ret); -} - -static int usrsock_rpmsg_dns_handler(struct rpmsg_endpoint *ept, void *data, - size_t len, uint32_t src, void *priv_) -{ -#ifdef CONFIG_NETDB_DNSCLIENT - struct usrsock_rpmsg_dns_request_s *dns = data; - - dns_add_nameserver((struct sockaddr *)(dns + 1), dns->addrlen); -#endif - - return 0; -} - -#ifdef CONFIG_NETDB_DNSCLIENT -static int usrsock_rpmsg_send_dns_event(void *arg, - struct sockaddr *addr, - socklen_t addrlen) -{ - struct rpmsg_endpoint *ept = arg; - struct usrsock_rpmsg_dns_event_s *dns; - uint32_t len; - - dns = rpmsg_get_tx_payload_buffer(ept, &len, true); - - dns->head.msgid = USRSOCK_RPMSG_DNS_EVENT; - dns->head.flags = USRSOCK_MESSAGE_FLAG_EVENT; - - dns->addrlen = addrlen; - memcpy(dns + 1, addr, addrlen); - - return rpmsg_send_nocopy(ept, dns, sizeof(*dns) + addrlen); -} -#endif - -static bool usrsock_rpmsg_ns_match(struct rpmsg_device *rdev, void *priv_, - const char *name, uint32_t dest) -{ - return !strcmp(name, USRSOCK_RPMSG_EPT_NAME); -} - -static void usrsock_rpmsg_ns_bind(struct rpmsg_device *rdev, void *priv_, - const char *name, uint32_t dest) -{ - struct usrsock_rpmsg_s *priv = priv_; - struct rpmsg_endpoint *ept; - int ret; - - ept = zalloc(sizeof(struct rpmsg_endpoint)); - if (!ept) - { - return; - } - - ept->priv = priv; - - ret = rpmsg_create_ept(ept, rdev, USRSOCK_RPMSG_EPT_NAME, - RPMSG_ADDR_ANY, dest, - usrsock_rpmsg_ept_cb, usrsock_rpmsg_ns_unbind); - if (ret) - { - free(ept); - return; - } - -#ifdef CONFIG_NETDB_DNSCLIENT - dns_register_notify(usrsock_rpmsg_send_dns_event, ept); -#endif -} - -static void usrsock_rpmsg_ns_unbind(struct rpmsg_endpoint *ept) -{ - struct usrsock_rpmsg_s *priv = ept->priv; - struct socket *socks[CONFIG_NETUTILS_USRSOCK_NSOCK_DESCRIPTORS]; - int count = 0; - int i; - -#ifdef CONFIG_NETDB_DNSCLIENT - dns_unregister_notify(usrsock_rpmsg_send_dns_event, ept); -#endif - - /* Collect all socks belong to the dead client */ - - for (i = 0; i < CONFIG_NETUTILS_USRSOCK_NSOCK_DESCRIPTORS; i++) - { - if (priv->epts[i] == ept) - { - socks[count++] = &priv->socks[i]; - priv->pfds[i].ptr = NULL; - priv->epts[i] = NULL; - } - } - - /* Signal and wait the poll thread to wakeup */ - - pthread_mutex_lock(&priv->mutex); - usrsock_rpmsg_notify_poll(priv); - pthread_cond_wait(&priv->cond, &priv->mutex); - pthread_mutex_unlock(&priv->mutex); - - /* It's safe to close all socks here */ - - for (i = 0; i < count; i++) - { - psock_close(socks[i]); - } - - rpmsg_destroy_ept(ept); -} - -static int usrsock_rpmsg_ept_cb(struct rpmsg_endpoint *ept, void *data, - size_t len, uint32_t src, void *priv_) -{ - struct usrsock_request_common_s *common = data; - struct usrsock_rpmsg_s *priv = priv_; - - if (priv->iov[0].iov_base) - { - return usrsock_rpmsg_sendto_handler(ept, data, len, src, priv); - } - else if (common->reqid >= 0 && common->reqid <= USRSOCK_REQUEST__MAX) - { - return g_usrsock_rpmsg_handler[common->reqid](ept, data, len, - src, priv); - } - - return -EINVAL; -} - -static int usrsock_rpmsg_notify_poll(struct usrsock_rpmsg_s *priv) -{ - eventfd_t value = 1ULL; - - return file_write(priv->eventfp, &value, sizeof(value)); -} - -static int usrsock_rpmsg_prepare_poll(struct usrsock_rpmsg_s *priv, - struct pollfd *pfds) -{ - int count = 0; - int i; - - pthread_mutex_lock(&priv->mutex); - - /* Signal the worker it's safe to close sock */ - - pthread_cond_signal(&priv->cond); - - for (i = 0; i < CONFIG_NETUTILS_USRSOCK_NSOCK_DESCRIPTORS; i++) - { - if (priv->pfds[i].ptr) - { - pfds[count] = priv->pfds[i]; - pfds[count++].events |= POLLSOCK; - } - } - - pfds[count].ptr = priv->eventfp; - pfds[count++].events = POLLIN | POLLFILE; - - pthread_mutex_unlock(&priv->mutex); - - return count; -} - -static bool usrsock_rpmsg_process_poll(struct usrsock_rpmsg_s *priv, - struct pollfd *pfds, int count) -{ - bool prepare = false; - int i; - - for (i = 0; i < count; i++) - { - pthread_mutex_lock(&priv->mutex); - - if (pfds[i].ptr == priv->eventfp) - { - if (pfds[i].revents & POLLIN) - { - eventfd_t value; - - file_read(priv->eventfp, &value, sizeof(value)); - prepare = true; - } - } - else - { - int j; - - j = (struct socket *)pfds[i].ptr - priv->socks; - - if (priv->epts[j] != NULL) - { - int events = 0; - - if (pfds[i].revents & POLLIN) - { - events |= USRSOCK_EVENT_RECVFROM_AVAIL; - - /* Stop poll in until recv get called */ - - pfds[i].events &= ~POLLIN; - priv->pfds[j].events &= ~POLLIN; - } - - if (pfds[i].revents & POLLOUT) - { - events |= USRSOCK_EVENT_SENDTO_READY; - - /* Stop poll out until send get called */ - - pfds[i].events &= ~POLLOUT; - priv->pfds[j].events &= ~POLLOUT; - } - - if (pfds[i].revents & (POLLHUP | POLLERR)) - { - events |= USRSOCK_EVENT_REMOTE_CLOSED; - - /* Check data that has not been recv */ - - if (usrsock_rpmsg_available(&priv->socks[j], FIONREAD)) - { - events |= USRSOCK_EVENT_RECVFROM_AVAIL; - } - - /* Stop poll at all */ - - pfds[i].ptr = NULL; - priv->pfds[j].ptr = NULL; - prepare = true; - } - - if (events != 0) - { - usrsock_rpmsg_send_event(priv->epts[j], j, events); - } - } - } - - pthread_mutex_unlock(&priv->mutex); - } - - return prepare; -} - -/**************************************************************************** - * Public Functions - ****************************************************************************/ - -int main(int argc, char *argv[]) -{ - struct pollfd pfds[CONFIG_NETUTILS_USRSOCK_NSOCK_DESCRIPTORS + 1]; - struct usrsock_rpmsg_s *priv; - bool prepare = true; - int ret; - int fd; - - priv = calloc(1, sizeof(*priv)); - if (priv == NULL) - { - return -ENOMEM; - } - - pthread_mutex_init(&priv->mutex, NULL); - pthread_cond_init(&priv->cond, NULL); - - fd = eventfd(0, 0); - if (fd < 0) - { - ret = -errno; - goto free_priv; - } - - ret = fs_getfilep(fd, &priv->eventfp); - if (ret < 0) - { - goto free_fd; - } - - ret = rpmsg_register_callback(priv, - NULL, - NULL, - usrsock_rpmsg_ns_match, - usrsock_rpmsg_ns_bind); - if (ret < 0) - { - goto free_fd; - } - - while (1) - { - /* Collect all socks which need monitor */ - - if (prepare) - { - ret = usrsock_rpmsg_prepare_poll(priv, pfds); - } - - /* Monitor the state change from them */ - - if (poll(pfds, ret, -1) > 0) - { - /* Process all changed socks */ - - prepare = usrsock_rpmsg_process_poll(priv, pfds, ret); - } - } - - rpmsg_unregister_callback(priv, - NULL, - NULL, - usrsock_rpmsg_ns_match, - usrsock_rpmsg_ns_bind); -free_fd: - close(fd); -free_priv: - pthread_cond_destroy(&priv->cond); - pthread_mutex_destroy(&priv->mutex); - free(priv); - return ret; -}