You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@nuttx.apache.org by xi...@apache.org on 2021/03/07 09:46:06 UTC
[incubator-nuttx] 03/03: net/socket_rpmsg: add net socket rpmsg
support
This is an automated email from the ASF dual-hosted git repository.
xiaoxiang pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/incubator-nuttx.git
commit 70442d1f9d1bb56926f64f2edb81650cb464d798
Author: ligd <li...@xiaomi.com>
AuthorDate: Thu Nov 5 20:30:49 2020 +0800
net/socket_rpmsg: add net socket rpmsg support
Change-Id: Ie23ee4c0052cf2fc66972ea9bc5f11c070fbcf8a
Signed-off-by: chao.an <an...@xiaomi.com>
---
boards/sim/sim/sim/configs/rpproxy/defconfig | 3 +
boards/sim/sim/sim/configs/rpserver/defconfig | 5 +
include/netpacket/rpmsg.h | 42 +
include/sys/socket.h | 2 +
net/Kconfig | 1 +
net/Makefile | 1 +
net/rpmsg/Kconfig | 32 +
net/rpmsg/Make.defs | 32 +
net/rpmsg/rpmsg.h | 53 ++
net/rpmsg/rpmsg_sockif.c | 1192 +++++++++++++++++++++++++
net/socket/net_sockif.c | 7 +
net/socket/socket.c | 2 +-
12 files changed, 1371 insertions(+), 1 deletion(-)
diff --git a/boards/sim/sim/sim/configs/rpproxy/defconfig b/boards/sim/sim/sim/configs/rpproxy/defconfig
index d780f6f..d8b7b35 100644
--- a/boards/sim/sim/sim/configs/rpproxy/defconfig
+++ b/boards/sim/sim/sim/configs/rpproxy/defconfig
@@ -13,7 +13,9 @@ CONFIG_ARCH_CHIP="sim"
CONFIG_ARCH_SIM=y
CONFIG_BOARDCTL_POWEROFF=y
CONFIG_BUILTIN=y
+CONFIG_DEBUG_SYMBOLS=y
CONFIG_DEV_SIMPLE_ADDRENV=y
+CONFIG_EXAMPLES_RPMSGSOCKET=y
CONFIG_FS_HOSTFS=y
CONFIG_FS_HOSTFS_RPMSG=y
CONFIG_FS_PROCFS=y
@@ -26,6 +28,7 @@ CONFIG_NETDB_DNSCLIENT_RECV_TIMEOUT=3
CONFIG_NETDB_DNSSERVER_IPv4ADDR=0x771d1d1d
CONFIG_NETUTILS_USRSOCK_RPMSG=y
CONFIG_NET_ICMP_NO_STACK=y
+CONFIG_NET_RPMSG=y
CONFIG_NET_SOCKOPTS=y
CONFIG_NET_TCP_NO_STACK=y
CONFIG_NET_UDP_NO_STACK=y
diff --git a/boards/sim/sim/sim/configs/rpserver/defconfig b/boards/sim/sim/sim/configs/rpserver/defconfig
index f4f2d5d..cce43dd 100644
--- a/boards/sim/sim/sim/configs/rpserver/defconfig
+++ b/boards/sim/sim/sim/configs/rpserver/defconfig
@@ -12,7 +12,9 @@ CONFIG_ARCH_CHIP="sim"
CONFIG_ARCH_SIM=y
CONFIG_BOARDCTL_POWEROFF=y
CONFIG_BUILTIN=y
+CONFIG_DEBUG_SYMBOLS=y
CONFIG_DEV_SIMPLE_ADDRENV=y
+CONFIG_EXAMPLES_RPMSGSOCKET=y
CONFIG_FS_HOSTFS=y
CONFIG_FS_HOSTFS_RPMSG_SERVER=y
CONFIG_FS_PROCFS=y
@@ -34,6 +36,7 @@ CONFIG_NET_BROADCAST=y
CONFIG_NET_ICMP=y
CONFIG_NET_ICMP_SOCKET=y
CONFIG_NET_LOOPBACK=y
+CONFIG_NET_RPMSG=y
CONFIG_NET_SOCKOPTS=y
CONFIG_NET_STATISTICS=y
CONFIG_NET_TCP=y
@@ -55,6 +58,7 @@ CONFIG_SCHED_CHILD_STATUS=y
CONFIG_SCHED_HAVE_PARENT=y
CONFIG_SCHED_HPWORK=y
CONFIG_SCHED_WAITPID=y
+CONFIG_SIG_DEFAULT=y
CONFIG_SIM_M32=y
CONFIG_SIM_NET_BRIDGE=y
CONFIG_SIM_RPTUN_MASTER=y
@@ -67,5 +71,6 @@ CONFIG_SYSTEM_CUTERM=y
CONFIG_SYSTEM_CUTERM_DEFAULT_DEVICE="/dev/ttyproxy"
CONFIG_SYSTEM_NSH=y
CONFIG_SYSTEM_PING=y
+CONFIG_TTY_SIGINT=y
CONFIG_USERMAIN_STACKSIZE=4096
CONFIG_USER_ENTRYPOINT="nsh_main"
diff --git a/include/netpacket/rpmsg.h b/include/netpacket/rpmsg.h
new file mode 100644
index 0000000..1dfd47d
--- /dev/null
+++ b/include/netpacket/rpmsg.h
@@ -0,0 +1,42 @@
+/****************************************************************************
+ * include/netpacket/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 __INCLUDE_NETPACKET_RPMSG_H
+#define __INCLUDE_NETPACKET_RPMSG_H
+
+/****************************************************************************
+ * Pre-processor Definitions
+ ****************************************************************************/
+
+#define RPMSG_SOCKET_CPU_SIZE 16
+#define RPMSG_SOCKET_NAME_SIZE 32
+
+/****************************************************************************
+ * Public Type Definitions
+ ****************************************************************************/
+
+struct sockaddr_rpmsg
+{
+ sa_family_t rp_family;
+ char rp_cpu[RPMSG_SOCKET_CPU_SIZE];
+ char rp_name[RPMSG_SOCKET_NAME_SIZE];
+};
+
+#endif /* __INCLUDE_NETPACKET_RPMSG_H */
diff --git a/include/sys/socket.h b/include/sys/socket.h
index ba89a87..1d58cf1 100644
--- a/include/sys/socket.h
+++ b/include/sys/socket.h
@@ -50,6 +50,7 @@
#define PF_BLUETOOTH 31 /* Bluetooth sockets */
#define PF_IEEE802154 36 /* Low level IEEE 802.15.4 radio frame interface */
#define PF_PKTRADIO 64 /* Low level packet radio interface */
+#define PF_RPMSG 65 /* Remote core communication */
/* Supported Address Families. Opengroup.org requires only AF_UNSPEC,
* AF_UNIX, AF_INET and AF_INET6.
@@ -67,6 +68,7 @@
#define AF_BLUETOOTH PF_BLUETOOTH
#define AF_IEEE802154 PF_IEEE802154
#define AF_PKTRADIO PF_PKTRADIO
+#define AF_RPMSG PF_RPMSG
/* The socket created by socket() has the indicated type, which specifies
* the communication semantics.
diff --git a/net/Kconfig b/net/Kconfig
index a8ff4ae..a3d5720 100644
--- a/net/Kconfig
+++ b/net/Kconfig
@@ -303,6 +303,7 @@ source "net/socket/Kconfig"
source "net/inet/Kconfig"
source "net/pkt/Kconfig"
source "net/local/Kconfig"
+source "net/rpmsg/Kconfig"
source "net/can/Kconfig"
source "net/netlink/Kconfig"
source "net/tcp/Kconfig"
diff --git a/net/Makefile b/net/Makefile
index c63eae6..3e627e4 100644
--- a/net/Makefile
+++ b/net/Makefile
@@ -36,6 +36,7 @@ include neighbor/Make.defs
include igmp/Make.defs
include pkt/Make.defs
include local/Make.defs
+include rpmsg/Make.defs
include mld/Make.defs
include can/Make.defs
include netlink/Make.defs
diff --git a/net/rpmsg/Kconfig b/net/rpmsg/Kconfig
new file mode 100644
index 0000000..4dca6f9
--- /dev/null
+++ b/net/rpmsg/Kconfig
@@ -0,0 +1,32 @@
+#
+# For a description of the syntax of this configuration file,
+# see the file kconfig-language.txt in the NuttX tools repository.
+#
+
+menu "Rpmsg Socket Support"
+ depends on NET
+
+config NET_RPMSG
+ bool "Rpmsg domain (remote) sockets"
+ select MM_CIRCBUF
+ default n
+ ---help---
+ Enable or disable Rpmsg (aka remote) sockets.
+
+if NET_RPMSG
+
+config NET_RPMSG_RXBUF_SIZE
+ int "Rpmsg socket rx buffer size"
+ default 1024
+ ---help---
+ Socket rpmsg rx buffer size, for recv slowly
+
+config NET_RPMSG_NPOLLWAITERS
+ int "Rpmsg socket number of poll waiters"
+ default 4
+ ---help---
+ Socket rpmsg number of poll waiters
+
+endif # NET_RPMSG
+
+endmenu # Rpmsg Domain Sockets
diff --git a/net/rpmsg/Make.defs b/net/rpmsg/Make.defs
new file mode 100644
index 0000000..cde7e6f
--- /dev/null
+++ b/net/rpmsg/Make.defs
@@ -0,0 +1,32 @@
+############################################################################
+# net/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.
+#
+############################################################################
+
+# Rpmsg domain socket source files
+
+ifeq ($(CONFIG_NET_RPMSG),y)
+
+NET_CSRCS += rpmsg_sockif.c
+
+# Include rpmsg domain socket build support
+
+DEPPATH += --dep-path rpmsg
+VPATH += :rpmsg
+
+endif # CONFIG_NET_RPMSG
diff --git a/net/rpmsg/rpmsg.h b/net/rpmsg/rpmsg.h
new file mode 100644
index 0000000..8d41bc9
--- /dev/null
+++ b/net/rpmsg/rpmsg.h
@@ -0,0 +1,53 @@
+/****************************************************************************
+ * net/rpmsg/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 __NET_RPMSG_RPMSG_H
+#define __NET_RPMSG_RPMSG_H
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include <nuttx/config.h>
+#include <nuttx/net/net.h>
+
+#ifdef CONFIG_NET_RPMSG
+
+/****************************************************************************
+ * Public Data
+ ****************************************************************************/
+
+#ifdef __cplusplus
+# define EXTERN extern "C"
+extern "C"
+{
+#else
+# define EXTERN extern
+#endif
+
+EXTERN const struct sock_intf_s g_rpmsg_sockif;
+
+#undef EXTERN
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* CONFIG_NET_RPMSG */
+#endif /* __NET_RPMSG_RPMSG_H */
diff --git a/net/rpmsg/rpmsg_sockif.c b/net/rpmsg/rpmsg_sockif.c
new file mode 100644
index 0000000..c66ec35
--- /dev/null
+++ b/net/rpmsg/rpmsg_sockif.c
@@ -0,0 +1,1192 @@
+/****************************************************************************
+ * net/rpmsg/rpmsg_sockif.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 <nuttx/config.h>
+
+#include <poll.h>
+#include <stdio.h>
+#include <string.h>
+
+#include <nuttx/kmalloc.h>
+#include <nuttx/mm/circbuf.h>
+#include <nuttx/rptun/openamp.h>
+#include <nuttx/semaphore.h>
+
+#include <netinet/in.h>
+#include <netpacket/rpmsg.h>
+
+#include "socket/socket.h"
+
+/****************************************************************************
+ * Pre-processor Definitions
+ ****************************************************************************/
+
+#ifndef MIN
+# define MIN(a, b) ((a) < (b) ? (a) : (b))
+#endif
+
+#define RPMSG_SOCKET_CMD_SYNC 1
+#define RPMSG_SOCKET_CMD_DATA 2
+
+/****************************************************************************
+ * Private Types
+ ****************************************************************************/
+
+begin_packed_struct struct rpmsg_socket_sync_s
+{
+ uint32_t cmd;
+ uint32_t size;
+} end_packed_struct;
+
+begin_packed_struct struct rpmsg_socket_data_s
+{
+ uint32_t cmd;
+ uint32_t pos;
+
+ /* Act data len, don't include len itself when SOCK_DGRAM */
+
+ uint32_t len;
+ char data[0];
+} end_packed_struct;
+
+struct rpmsg_socket_conn_s
+{
+ struct rpmsg_endpoint ept;
+
+ struct sockaddr_rpmsg rpaddr;
+ uint16_t crefs;
+
+ FAR struct pollfd *fds[CONFIG_NET_RPMSG_NPOLLWAITERS];
+
+ sem_t sendsem;
+ sem_t sendlock;
+
+ sem_t recvsem;
+ sem_t recvlock;
+
+ FAR void *recvdata;
+ uint32_t recvlen;
+ FAR struct circbuf_s recvbuf;
+
+ FAR struct rpmsg_socket_conn_s *next;
+
+ /* server listen-scoket listening: backlog > 0;
+ * server listen-scoket closed: backlog = -1;
+ * others: backlog = 0;
+ */
+
+ int backlog;
+
+ /* Flow control, descript send side */
+
+ uint32_t sendsize;
+ uint32_t sendpos;
+ uint32_t ackpos;
+
+ /* Flow control, descript recv side */
+
+ uint32_t recvpos;
+ uint32_t lastpos;
+};
+
+/****************************************************************************
+ * Private Function Prototypes
+ ****************************************************************************/
+
+static int rpmsg_socket_setup(FAR struct socket *psock, int protocol);
+static sockcaps_t rpmsg_socket_sockcaps(FAR struct socket *psock);
+static void rpmsg_socket_addref(FAR struct socket *psock);
+static int rpmsg_socket_bind(FAR struct socket *psock,
+ FAR const struct sockaddr *addr, socklen_t addrlen);
+static int rpmsg_socket_getsockname(FAR struct socket *psock,
+ FAR struct sockaddr *addr, FAR socklen_t *addrlen);
+static int rpmsg_socket_getconnname(FAR struct socket *psock,
+ FAR struct sockaddr *addr, FAR socklen_t *addrlen);
+static int rpmsg_socket_listen(FAR struct socket *psock, int backlog);
+static int rpmsg_socket_connect(FAR struct socket *psock,
+ FAR const struct sockaddr *addr, socklen_t addrlen);
+static int rpmsg_socket_accept(FAR struct socket *psock,
+ FAR struct sockaddr *addr, FAR socklen_t *addrlen,
+ FAR struct socket *newsock);
+static int rpmsg_socket_poll(FAR struct socket *psock,
+ FAR struct pollfd *fds, bool setup);
+static ssize_t rpmsg_socket_sendmsg(FAR struct socket *psock,
+ FAR struct msghdr *msg, int flags);
+static ssize_t rpmsg_socket_recvmsg(FAR struct socket *psock,
+ FAR struct msghdr *msg, int flags);
+static int rpmsg_socket_close(FAR struct socket *psock);
+
+/****************************************************************************
+ * Public Data
+ ****************************************************************************/
+
+const struct sock_intf_s g_rpmsg_sockif =
+{
+ rpmsg_socket_setup, /* si_setup */
+ rpmsg_socket_sockcaps, /* si_sockcaps */
+ rpmsg_socket_addref, /* si_addref */
+ rpmsg_socket_bind, /* si_bind */
+ rpmsg_socket_getsockname, /* si_getsockname */
+ rpmsg_socket_getconnname, /* si_getconnname */
+ rpmsg_socket_listen, /* si_listen */
+ rpmsg_socket_connect, /* si_connect */
+ rpmsg_socket_accept, /* si_accept */
+ rpmsg_socket_poll, /* si_poll */
+ rpmsg_socket_sendmsg, /* si_sendmsg */
+ rpmsg_socket_recvmsg, /* si_recvmsg */
+ rpmsg_socket_close /* si_close */
+};
+
+/****************************************************************************
+ * Private Data
+ ****************************************************************************/
+
+static unsigned int g_rpmsg_id;
+
+/****************************************************************************
+ * Private Functions
+ ****************************************************************************/
+
+static inline void rpmsg_socket_lock(FAR sem_t *sem)
+{
+ net_lockedwait_uninterruptible(sem);
+}
+
+static inline void rpmsg_socket_unlock(FAR sem_t *sem)
+{
+ nxsem_post(sem);
+}
+
+static inline void rpmsg_socket_post(FAR sem_t *sem)
+{
+ int semcount;
+
+ nxsem_get_value(sem, &semcount);
+ if (semcount < 1)
+ {
+ nxsem_post(sem);
+ }
+}
+
+static void rpmsg_socket_pollnotify(FAR struct rpmsg_socket_conn_s *conn,
+ pollevent_t eventset)
+{
+ int i;
+
+ for (i = 0; i < CONFIG_NET_RPMSG_NPOLLWAITERS; i++)
+ {
+ FAR struct pollfd *fds = conn->fds[i];
+
+ if (fds)
+ {
+ fds->revents |= (fds->events & eventset);
+
+ if (fds->revents != 0)
+ {
+ rpmsg_socket_post(fds->sem);
+ }
+ }
+ }
+}
+
+static FAR struct rpmsg_socket_conn_s *rpmsg_socket_alloc(void)
+{
+ FAR struct rpmsg_socket_conn_s *conn;
+
+ conn = kmm_zalloc(sizeof(struct rpmsg_socket_conn_s));
+ if (!conn)
+ {
+ return NULL;
+ }
+
+ circbuf_init(&conn->recvbuf, NULL, 0);
+
+ nxsem_init(&conn->sendlock, 0, 1);
+ nxsem_init(&conn->recvlock, 0, 1);
+ nxsem_init(&conn->sendsem, 0, 0);
+ nxsem_init(&conn->recvsem, 0, 0);
+ nxsem_set_protocol(&conn->sendsem, SEM_PRIO_NONE);
+ nxsem_set_protocol(&conn->recvsem, SEM_PRIO_NONE);
+
+ conn->crefs = 1;
+ return conn;
+}
+
+static void rpmsg_socket_free(FAR struct rpmsg_socket_conn_s *conn)
+{
+ circbuf_uninit(&conn->recvbuf);
+
+ nxsem_destroy(&conn->recvlock);
+ nxsem_destroy(&conn->sendlock);
+ nxsem_destroy(&conn->sendsem);
+ nxsem_destroy(&conn->recvsem);
+
+ kmm_free(conn);
+}
+
+static int rpmsg_socket_wakeup(FAR struct rpmsg_socket_conn_s *conn)
+{
+ struct rpmsg_socket_data_s msg;
+ uint32_t space;
+ int ret = 0;
+
+ space = conn->recvpos - conn->lastpos;
+
+ if (space > circbuf_size(&conn->recvbuf) / 2)
+ {
+ msg.cmd = RPMSG_SOCKET_CMD_DATA;
+ msg.pos = conn->recvpos;
+ msg.len = 0;
+ ret = rpmsg_send(&conn->ept, &msg, sizeof(msg));
+ if (ret >= 0)
+ {
+ conn->lastpos = conn->recvpos;
+ }
+ }
+
+ return ret;
+}
+
+static int rpmsg_socket_sync(FAR struct rpmsg_socket_conn_s *conn,
+ unsigned int timeout)
+{
+ struct rpmsg_socket_sync_s msg;
+ int ret;
+
+ msg.cmd = RPMSG_SOCKET_CMD_SYNC;
+ msg.size = circbuf_size(&conn->recvbuf);
+
+ ret = rpmsg_send(&conn->ept, &msg, sizeof(msg));
+ if (ret < 0)
+ {
+ return ret;
+ }
+
+ if (conn->sendsize == 0)
+ {
+ ret = net_timedwait(&conn->sendsem, timeout);
+ }
+
+ return ret;
+}
+
+static inline uint32_t rpmsg_socket_get_space(
+ FAR struct rpmsg_socket_conn_s *conn)
+{
+ return conn->sendsize - (conn->sendpos - conn->ackpos);
+}
+
+static int rpmsg_socket_ept_cb(FAR struct rpmsg_endpoint *ept,
+ FAR void *data, size_t len, uint32_t src,
+ FAR void *priv)
+{
+ FAR struct rpmsg_socket_conn_s *conn = ept->priv;
+ FAR struct rpmsg_socket_sync_s *head = data;
+
+ if (head->cmd == RPMSG_SOCKET_CMD_SYNC)
+ {
+ conn->sendsize = head->size;
+ rpmsg_socket_post(&conn->sendsem);
+ }
+ else
+ {
+ FAR struct rpmsg_socket_data_s *msg = data;
+ FAR uint8_t *buf = (FAR uint8_t *)msg->data;
+
+ rpmsg_socket_lock(&conn->sendlock);
+
+ conn->ackpos = msg->pos;
+
+ if (rpmsg_socket_get_space(conn) > 0)
+ {
+ rpmsg_socket_post(&conn->sendsem);
+ rpmsg_socket_pollnotify(conn, POLLOUT);
+ }
+
+ rpmsg_socket_unlock(&conn->sendlock);
+
+ if (len > sizeof(*msg))
+ {
+ len -= sizeof(*msg);
+
+ DEBUGASSERT(len == msg->len || len == msg->len + sizeof(uint32_t));
+
+ rpmsg_socket_lock(&conn->recvlock);
+
+ if (conn->recvdata)
+ {
+ conn->recvlen = MIN(conn->recvlen, msg->len);
+
+ if (len == msg->len)
+ {
+ /* SOCOK_STREAM */
+
+ conn->recvpos += conn->recvlen;
+ memcpy(conn->recvdata, buf, conn->recvlen);
+ buf += conn->recvlen;
+ len -= conn->recvlen;
+ }
+ else
+ {
+ /* SOCOK_DGRAM */
+
+ conn->recvpos += len;
+ memcpy(conn->recvdata, buf + sizeof(uint32_t),
+ conn->recvlen);
+ len = 0;
+ }
+
+ conn->recvdata = NULL;
+ nxsem_post(&conn->recvsem);
+ }
+
+ if (len > 0)
+ {
+ ssize_t written;
+
+ written = circbuf_write(&conn->recvbuf, buf, len);
+ if (written != len)
+ {
+ nerr("circbuf_write overflow, %d, %d\n", written, len);
+ }
+
+ rpmsg_socket_pollnotify(conn, POLLIN);
+ }
+
+ rpmsg_socket_unlock(&conn->recvlock);
+ }
+ }
+
+ return 0;
+}
+
+static inline void rpmsg_socket_destroy_ept(
+ FAR struct rpmsg_socket_conn_s *conn)
+{
+ if (conn && conn->ept.rdev)
+ {
+ if (conn->backlog)
+ {
+ /* Listen socket */
+
+ conn->backlog = -1;
+ }
+
+ rpmsg_destroy_ept(&conn->ept);
+ rpmsg_socket_post(&conn->sendsem);
+ rpmsg_socket_post(&conn->recvsem);
+ rpmsg_socket_pollnotify(conn, POLLIN | POLLOUT);
+ }
+}
+
+static void rpmsg_socket_ns_unbind(FAR struct rpmsg_endpoint *ept)
+{
+ rpmsg_socket_destroy_ept(ept->priv);
+}
+
+static void rpmsg_socket_device_created(FAR struct rpmsg_device *rdev,
+ FAR void *priv)
+{
+ FAR struct rpmsg_socket_conn_s *conn = priv;
+
+ if (conn->ept.rdev)
+ {
+ return;
+ }
+
+ if (strcmp(conn->rpaddr.rp_cpu, rpmsg_get_cpuname(rdev)) == 0)
+ {
+ conn->ept.priv = conn;
+
+ rpmsg_create_ept(&conn->ept, rdev, conn->rpaddr.rp_name,
+ RPMSG_ADDR_ANY, RPMSG_ADDR_ANY,
+ rpmsg_socket_ept_cb, rpmsg_socket_ns_unbind);
+ }
+}
+
+static void rpmsg_socket_device_destroy(FAR struct rpmsg_device *rdev,
+ FAR void *priv)
+{
+ FAR struct rpmsg_socket_conn_s *conn = priv;
+
+ if (strcmp(conn->rpaddr.rp_cpu, rpmsg_get_cpuname(rdev)) == 0)
+ {
+ rpmsg_socket_destroy_ept(conn);
+ }
+}
+
+static void rpmsg_socket_ns_bind(FAR struct rpmsg_device *rdev,
+ FAR void *priv, FAR const char *name,
+ uint32_t dest)
+{
+ FAR struct rpmsg_socket_conn_s *server = priv;
+ FAR struct rpmsg_socket_conn_s *tmp;
+ FAR struct rpmsg_socket_conn_s *new;
+ int ret;
+ int i = 0;
+
+ if (strncmp(name, server->rpaddr.rp_name,
+ strlen(server->rpaddr.rp_name)))
+ {
+ return;
+ }
+
+ if (strlen(server->rpaddr.rp_cpu) &&
+ strcmp(server->rpaddr.rp_cpu, rpmsg_get_cpuname(rdev)))
+ {
+ /* Bind specific CPU, then only listen that CPU */
+
+ return;
+ }
+
+ for (tmp = server; tmp->next; tmp = tmp->next)
+ {
+ if (++i > server->backlog)
+ {
+ return;
+ }
+ }
+
+ new = rpmsg_socket_alloc();
+ if (!new)
+ {
+ return;
+ }
+
+ ret = circbuf_resize(&new->recvbuf, CONFIG_NET_RPMSG_RXBUF_SIZE);
+ if (ret < 0)
+ {
+ rpmsg_socket_free(new);
+ return;
+ }
+
+ new->ept.priv = new;
+ ret = rpmsg_create_ept(&new->ept, rdev, name,
+ RPMSG_ADDR_ANY, dest,
+ rpmsg_socket_ept_cb, rpmsg_socket_ns_unbind);
+ if (ret < 0)
+ {
+ rpmsg_socket_free(new);
+ return;
+ }
+
+ strcpy(new->rpaddr.rp_cpu, rpmsg_get_cpuname(rdev));
+ strcpy(new->rpaddr.rp_name, name);
+
+ tmp->next = new;
+
+ rpmsg_socket_post(&server->recvsem);
+ rpmsg_socket_pollnotify(server, POLLIN);
+}
+
+static int rpmsg_socket_getaddr(FAR struct rpmsg_socket_conn_s *conn,
+ FAR struct sockaddr *addr,
+ FAR socklen_t *addrlen)
+{
+ if (!addr || *addrlen < sizeof(struct sockaddr_rpmsg))
+ {
+ return -EINVAL;
+ }
+
+ memcpy(addr, &conn->rpaddr, sizeof(struct sockaddr_rpmsg));
+ *addrlen = sizeof(struct sockaddr_rpmsg);
+
+ return 0;
+}
+
+static int rpmsg_socket_setaddr(FAR struct rpmsg_socket_conn_s *conn,
+ FAR const struct sockaddr *addr,
+ socklen_t addrlen, bool suffix)
+{
+ FAR struct sockaddr_rpmsg *rpaddr = (FAR struct sockaddr_rpmsg *)addr;
+
+ if (rpaddr->rp_family != AF_RPMSG ||
+ addrlen != sizeof(struct sockaddr_rpmsg))
+ {
+ return -EINVAL;
+ }
+
+ memcpy(&conn->rpaddr, rpaddr, sizeof(struct sockaddr_rpmsg));
+
+ if (suffix)
+ {
+ size_t len;
+
+ rpaddr = &conn->rpaddr;
+ len = strlen(rpaddr->rp_name);
+ snprintf(&rpaddr->rp_name[len], RPMSG_SOCKET_NAME_SIZE - len - 1,
+ "%u", g_rpmsg_id++);
+ }
+
+ return 0;
+}
+
+static int rpmsg_socket_setup(FAR struct socket *psock, int protocol)
+{
+ FAR struct rpmsg_socket_conn_s *conn;
+
+ conn = rpmsg_socket_alloc();
+ if (!conn)
+ {
+ return -ENOMEM;
+ }
+
+ psock->s_conn = conn;
+ return 0;
+}
+
+static sockcaps_t rpmsg_socket_sockcaps(FAR struct socket *psock)
+{
+ return SOCKCAP_NONBLOCKING;
+}
+
+static void rpmsg_socket_addref(FAR struct socket *psock)
+{
+ FAR struct rpmsg_socket_conn_s *conn = psock->s_conn;
+
+ conn->crefs++;
+}
+
+static int rpmsg_socket_bind(FAR struct socket *psock,
+ FAR const struct sockaddr *addr,
+ socklen_t addrlen)
+{
+ return rpmsg_socket_setaddr(psock->s_conn, addr, addrlen, false);
+}
+
+static int rpmsg_socket_getsockname(FAR struct socket *psock,
+ FAR struct sockaddr *addr,
+ FAR socklen_t *addrlen)
+{
+ return rpmsg_socket_getaddr(psock->s_conn, addr, addrlen);
+}
+
+static int rpmsg_socket_getconnname(FAR struct socket *psock,
+ FAR struct sockaddr *addr,
+ FAR socklen_t *addrlen)
+{
+ return rpmsg_socket_getsockname(psock, addr, addrlen);
+}
+
+static int rpmsg_socket_listen(FAR struct socket *psock, int backlog)
+{
+ FAR struct rpmsg_socket_conn_s *server = psock->s_conn;
+
+ if (psock->s_type != SOCK_STREAM)
+ {
+ return -ENOSYS;
+ }
+
+ if (!_SS_ISBOUND(psock->s_flags) || backlog <= 0)
+ {
+ return -EINVAL;
+ }
+
+ server->backlog = backlog;
+ return rpmsg_register_callback(server,
+ NULL,
+ NULL,
+ rpmsg_socket_ns_bind);
+}
+
+static int rpmsg_socket_connect_internal(FAR struct socket *psock)
+{
+ FAR struct rpmsg_socket_conn_s *conn = psock->s_conn;
+ unsigned int timeout;
+ unsigned int tc;
+ int ret;
+
+ ret = circbuf_resize(&conn->recvbuf, CONFIG_NET_RPMSG_RXBUF_SIZE);
+ if (ret < 0)
+ {
+ return ret;
+ }
+
+ ret = rpmsg_register_callback(conn,
+ rpmsg_socket_device_created,
+ rpmsg_socket_device_destroy,
+ NULL);
+ if (ret < 0)
+ {
+ return ret;
+ }
+
+ ret = -ETIMEDOUT;
+ timeout = _SO_TIMEOUT(psock->s_rcvtimeo);
+
+ for (tc = 0; tc < timeout * 1000; )
+ {
+ ret = rpmsg_socket_sync(conn, timeout);
+ if (ret != RPMSG_ERR_ADDR)
+ {
+ break;
+ }
+
+ if (timeout != UINT_MAX)
+ {
+ tc += RPMSG_TICK_COUNT;
+ }
+ }
+
+ if (ret < 0)
+ {
+ rpmsg_unregister_callback(conn,
+ rpmsg_socket_device_created,
+ rpmsg_socket_device_destroy,
+ NULL);
+ }
+
+ return ret;
+}
+
+static int rpmsg_socket_connect(FAR struct socket *psock,
+ FAR const struct sockaddr *addr,
+ socklen_t addrlen)
+{
+ FAR struct rpmsg_socket_conn_s *conn = psock->s_conn;
+ int ret;
+
+ if (_SS_ISCONNECTED(psock->s_flags))
+ {
+ return -EISCONN;
+ }
+
+ ret = rpmsg_socket_setaddr(conn, addr, addrlen,
+ psock->s_type == SOCK_STREAM);
+ if (ret < 0)
+ {
+ return ret;
+ }
+
+ return rpmsg_socket_connect_internal(psock);
+}
+
+static int rpmsg_socket_accept(FAR struct socket *psock,
+ FAR struct sockaddr *addr,
+ FAR socklen_t *addrlen,
+ FAR struct socket *newsock)
+{
+ FAR struct rpmsg_socket_conn_s *server = psock->s_conn;
+ int ret = 0;
+
+ if (server->backlog == -1)
+ {
+ return -ECONNRESET;
+ }
+
+ if (!_SS_ISLISTENING(psock->s_flags))
+ {
+ return -EINVAL;
+ }
+
+ while (1)
+ {
+ if (server->next)
+ {
+ FAR struct rpmsg_socket_conn_s *conn = server->next;
+
+ server->next = conn->next;
+ conn->next = NULL;
+
+ rpmsg_socket_sync(conn, _SO_TIMEOUT(psock->s_rcvtimeo));
+
+ rpmsg_register_callback(conn,
+ rpmsg_socket_device_created,
+ rpmsg_socket_device_destroy,
+ NULL);
+
+ newsock->s_domain = psock->s_domain;
+ newsock->s_sockif = psock->s_sockif;
+ newsock->s_type = SOCK_STREAM;
+ newsock->s_conn = conn;
+
+ rpmsg_socket_getaddr(conn, addr, addrlen);
+
+ break;
+ }
+ else
+ {
+ if (_SS_ISNONBLOCK(psock->s_flags))
+ {
+ ret = -EAGAIN;
+ break;
+ }
+ else
+ {
+ ret = net_lockedwait(&server->recvsem);
+ if (server->backlog == -1)
+ {
+ ret = -ECONNRESET;
+ }
+
+ if (ret < 0)
+ {
+ break;
+ }
+ }
+ }
+ }
+
+ return ret;
+}
+
+static int rpmsg_socket_poll(FAR struct socket *psock,
+ FAR struct pollfd *fds, bool setup)
+{
+ FAR struct rpmsg_socket_conn_s *conn = psock->s_conn;
+ pollevent_t eventset = 0;
+ int ret = 0;
+ int i;
+
+ if (setup)
+ {
+ for (i = 0; i < CONFIG_NET_RPMSG_NPOLLWAITERS; i++)
+ {
+ /* Find an available slot */
+
+ if (!conn->fds[i])
+ {
+ /* Bind the poll structure and this slot */
+
+ conn->fds[i] = fds;
+ fds->priv = &conn->fds[i];
+ break;
+ }
+ }
+
+ if (i >= CONFIG_NET_RPMSG_NPOLLWAITERS)
+ {
+ fds->priv = NULL;
+ ret = -EBUSY;
+ goto errout;
+ }
+
+ /* Immediately notify on any of the requested events */
+
+ if (_SS_ISLISTENING(psock->s_flags))
+ {
+ if (conn->backlog == -1)
+ {
+ ret = -ECONNRESET;
+ goto errout;
+ }
+
+ if (conn->next)
+ {
+ eventset |= (fds->events & POLLIN);
+ }
+ }
+ else if (_SS_ISCONNECTED(psock->s_flags))
+ {
+ if (!conn->ept.rdev)
+ {
+ ret = -ECONNRESET;
+ goto errout;
+ }
+
+ rpmsg_socket_lock(&conn->sendlock);
+
+ if (rpmsg_socket_get_space(conn) > 0)
+ {
+ eventset |= (fds->events & POLLOUT);
+ }
+
+ rpmsg_socket_unlock(&conn->sendlock);
+
+ rpmsg_socket_lock(&conn->recvlock);
+
+ if (!circbuf_is_empty(&conn->recvbuf))
+ {
+ eventset |= (fds->events & POLLIN);
+ }
+
+ rpmsg_socket_unlock(&conn->recvlock);
+ }
+ else
+ {
+ ret = -EPERM;
+ goto errout;
+ }
+
+ if (eventset)
+ {
+ rpmsg_socket_pollnotify(conn, eventset);
+ }
+ }
+ else if (fds->priv != NULL)
+ {
+ for (i = 0; i < CONFIG_NET_RPMSG_NPOLLWAITERS; i++)
+ {
+ if (fds == conn->fds[i])
+ {
+ conn->fds[i] = NULL;
+ fds->priv = NULL;
+ break;
+ }
+ }
+ }
+
+errout:
+ return ret;
+}
+
+static ssize_t rpmsg_socket_send_continuous(FAR struct socket *psock,
+ FAR const void *buf,
+ size_t len)
+{
+ FAR struct rpmsg_socket_conn_s *conn = psock->s_conn;
+ FAR const char *cur = buf;
+ size_t written = 0;
+ int ret = 0;
+
+ rpmsg_socket_lock(&conn->sendlock);
+
+ while (written < len)
+ {
+ uint32_t block = MIN(len - written, rpmsg_socket_get_space(conn));
+ FAR struct rpmsg_socket_data_s *msg;
+ uint32_t ipcsize;
+
+ if (block == 0)
+ {
+ if (!_SS_ISNONBLOCK(psock->s_flags))
+ {
+ rpmsg_socket_unlock(&conn->sendlock);
+
+ ret = net_timedwait(&conn->sendsem,
+ _SO_TIMEOUT(psock->s_sndtimeo));
+ if (!conn->ept.rdev)
+ {
+ ret = -ECONNRESET;
+ }
+
+ rpmsg_socket_lock(&conn->sendlock);
+
+ if (ret < 0)
+ {
+ break;
+ }
+ }
+ else
+ {
+ ret = -EAGAIN;
+ break;
+ }
+ }
+
+ msg = rpmsg_get_tx_payload_buffer(&conn->ept, &ipcsize, true);
+ if (!msg)
+ {
+ ret = -EINVAL;
+ break;
+ }
+
+ block = MIN(block, ipcsize - sizeof(*msg));
+
+ msg->cmd = RPMSG_SOCKET_CMD_DATA;
+ msg->pos = conn->recvpos;
+ msg->len = block;
+ memcpy(msg->data, cur, block);
+
+ conn->lastpos = conn->recvpos;
+ conn->sendpos += msg->len;
+
+ ret = rpmsg_send_nocopy(&conn->ept, msg, block + sizeof(*msg));
+ if (ret < 0)
+ {
+ break;
+ }
+
+ written += block;
+ cur += block;
+ }
+
+ rpmsg_socket_unlock(&conn->sendlock);
+
+ return written ? written : ret;
+}
+
+static ssize_t rpmsg_socket_send_single(FAR struct socket *psock,
+ FAR const void *buf, size_t len)
+{
+ FAR struct rpmsg_socket_conn_s *conn = psock->s_conn;
+ FAR struct rpmsg_socket_data_s *msg;
+ uint32_t total = len + sizeof(*msg) + sizeof(uint32_t);
+ uint32_t ipcsize;
+ int ret;
+
+ if (total > conn->sendsize)
+ {
+ return -EFBIG;
+ }
+
+ rpmsg_socket_lock(&conn->sendlock);
+
+ while (total - sizeof(*msg) > rpmsg_socket_get_space(conn))
+ {
+ if (!_SS_ISNONBLOCK(psock->s_flags))
+ {
+ rpmsg_socket_unlock(&conn->sendlock);
+
+ ret = net_timedwait(&conn->sendsem,
+ _SO_TIMEOUT(psock->s_sndtimeo));
+ if (!conn->ept.rdev)
+ {
+ ret = -ECONNRESET;
+ }
+
+ rpmsg_socket_lock(&conn->sendlock);
+
+ if (ret < 0)
+ {
+ goto out;
+ }
+ }
+ else
+ {
+ ret = -EAGAIN;
+ goto out;
+ }
+ }
+
+ msg = rpmsg_get_tx_payload_buffer(&conn->ept, &ipcsize, true);
+ if (!msg)
+ {
+ ret = -EINVAL;
+ goto out;
+ }
+
+ if (total > ipcsize)
+ {
+ total = ipcsize;
+ len = ipcsize - sizeof(*msg) + sizeof(uint32_t);
+ }
+
+ /* SOCK_DGRAM need write len to buffer */
+
+ msg->cmd = RPMSG_SOCKET_CMD_DATA;
+ msg->pos = conn->recvpos;
+ msg->len = len;
+ memcpy(msg->data, &len, sizeof(uint32_t));
+ memcpy(msg->data + sizeof(uint32_t), buf, len);
+
+ conn->lastpos = conn->recvpos;
+ conn->sendpos += len + sizeof(uint32_t);
+
+ ret = rpmsg_send_nocopy(&conn->ept, msg, total);
+out:
+ rpmsg_socket_unlock(&conn->sendlock);
+ return ret > 0 ? len : ret;
+}
+
+static ssize_t rpmsg_socket_send_internal(FAR struct socket *psock,
+ FAR const void *buf,
+ size_t len, int flags)
+{
+ FAR struct rpmsg_socket_conn_s *conn = psock->s_conn;
+
+ if (!conn->ept.rdev)
+ {
+ /* return ECONNRESET if lower IPC closed */
+
+ return -ECONNRESET;
+ }
+
+ if (psock->s_type == SOCK_STREAM)
+ {
+ return rpmsg_socket_send_continuous(psock, buf, len);
+ }
+ else
+ {
+ return rpmsg_socket_send_single(psock, buf, len);
+ }
+}
+
+static ssize_t rpmsg_socket_sendmsg(FAR struct socket *psock,
+ FAR struct msghdr *msg, int flags)
+{
+ const FAR void *buf = msg->msg_iov->iov_base;
+ size_t len = msg->msg_iov->iov_len;
+ const FAR struct sockaddr *to = msg->msg_name;
+ socklen_t tolen = msg->msg_namelen;
+ ssize_t ret;
+
+ /* Validity check, only single iov supported */
+
+ if (msg->msg_iovlen != 1)
+ {
+ return -ENOTSUP;
+ }
+
+ if (!_SS_ISCONNECTED(psock->s_flags))
+ {
+ if (to == NULL)
+ {
+ return -ENOTCONN;
+ }
+
+ ret = rpmsg_socket_connect(psock, to, tolen);
+ if (ret < 0)
+ {
+ return ret;
+ }
+ }
+
+ return rpmsg_socket_send_internal(psock, buf, len, flags);
+}
+
+static ssize_t rpmsg_socket_recvmsg(FAR struct socket *psock,
+ FAR struct msghdr *msg, int flags)
+{
+ FAR void *buf = msg->msg_iov->iov_base;
+ size_t len = msg->msg_iov->iov_len;
+ FAR struct sockaddr *from = msg->msg_name;
+ FAR socklen_t *fromlen = &msg->msg_namelen;
+ FAR struct rpmsg_socket_conn_s *conn = psock->s_conn;
+ ssize_t ret;
+
+ if (psock->s_type == SOCK_DGRAM && _SS_ISBOUND(psock->s_flags)
+ && !_SS_ISCONNECTED(psock->s_flags))
+ {
+ ret = rpmsg_socket_connect_internal(psock);
+ if (ret < 0)
+ {
+ return ret;
+ }
+
+ psock->s_flags |= _SF_CONNECTED;
+ }
+
+ if (!_SS_ISCONNECTED(psock->s_flags))
+ {
+ return -EISCONN;
+ }
+
+ rpmsg_socket_lock(&conn->recvlock);
+
+ if (psock->s_type == SOCK_DGRAM)
+ {
+ uint32_t datalen;
+
+ ret = circbuf_read(&conn->recvbuf, &datalen, sizeof(uint32_t));
+ if (ret > 0)
+ {
+ ret = circbuf_read(&conn->recvbuf, buf, MIN(datalen, len));
+ if (ret > 0 && datalen > ret)
+ {
+ circbuf_skip(&conn->recvbuf, datalen - ret);
+ }
+
+ conn->recvpos += datalen + sizeof(uint32_t);
+ }
+ }
+ else
+ {
+ ret = circbuf_read(&conn->recvbuf, buf, len);
+ conn->recvpos += ret > 0 ? ret : 0;
+ }
+
+ if (ret > 0)
+ {
+ rpmsg_socket_wakeup(conn);
+ goto out;
+ }
+
+ if (!conn->ept.rdev)
+ {
+ /* return EOF if lower IPC closed */
+
+ ret = 0;
+ goto out;
+ }
+
+ if (_SS_ISNONBLOCK(psock->s_flags))
+ {
+ ret = -EAGAIN;
+ goto out;
+ }
+
+ conn->recvdata = buf;
+ conn->recvlen = len;
+
+ rpmsg_socket_unlock(&conn->recvlock);
+
+ ret = net_timedwait(&conn->recvsem, _SO_TIMEOUT(psock->s_rcvtimeo));
+ if (!conn->ept.rdev)
+ {
+ ret = -ECONNRESET;
+ }
+
+ rpmsg_socket_lock(&conn->recvlock);
+
+ if (!conn->recvdata)
+ {
+ ret = conn->recvlen;
+ rpmsg_socket_wakeup(conn);
+ }
+ else
+ {
+ conn->recvdata = NULL;
+ }
+
+out:
+ rpmsg_socket_unlock(&conn->recvlock);
+
+ if (ret > 0)
+ {
+ rpmsg_socket_getaddr(conn, from, fromlen);
+ }
+
+ return ret;
+}
+
+static int rpmsg_socket_close(FAR struct socket *psock)
+{
+ FAR struct rpmsg_socket_conn_s *conn = psock->s_conn;
+
+ if (conn->crefs > 1)
+ {
+ conn->crefs--;
+ return 0;
+ }
+
+ if (conn->backlog)
+ {
+ rpmsg_unregister_callback(conn,
+ NULL,
+ NULL,
+ rpmsg_socket_ns_bind);
+ }
+ else
+ {
+ rpmsg_unregister_callback(conn,
+ rpmsg_socket_device_created,
+ rpmsg_socket_device_destroy,
+ NULL);
+ }
+
+ rpmsg_socket_destroy_ept(conn);
+ rpmsg_socket_free(conn);
+ return 0;
+}
diff --git a/net/socket/net_sockif.c b/net/socket/net_sockif.c
index efdae05..ea8ccdc 100644
--- a/net/socket/net_sockif.c
+++ b/net/socket/net_sockif.c
@@ -32,6 +32,7 @@
#include "inet/inet.h"
#include "local/local.h"
+#include "rpmsg/rpmsg.h"
#include "can/can.h"
#include "netlink/netlink.h"
#include "pkt/pkt.h"
@@ -120,6 +121,12 @@ net_sockif(sa_family_t family, int type, int protocol)
break;
#endif
+#ifdef CONFIG_NET_RPMSG
+ case PF_RPMSG:
+ sockif = &g_rpmsg_sockif;
+ break;
+#endif
+
default:
nerr("ERROR: Address family unsupported: %d\n", family);
}
diff --git a/net/socket/socket.c b/net/socket/socket.c
index 281e015..5041ab4 100644
--- a/net/socket/socket.c
+++ b/net/socket/socket.c
@@ -100,7 +100,7 @@ int psock_socket(int domain, int type, int protocol,
psock->s_type = type;
#ifdef CONFIG_NET_USRSOCK
- if (domain != PF_LOCAL && domain != PF_UNSPEC)
+ if (domain != PF_LOCAL && domain != PF_UNSPEC && domain != PF_RPMSG)
{
/* Handle special setup for USRSOCK sockets (user-space networking
* stack).