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 2022/11/23 07:02:02 UTC
[incubator-nuttx] 01/02: net/get/setsockopt: add si_get/setsockopt interface to simply get/setsockopt
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 e6f8ccda4a7e533effc8483a2d2a53f7839d4d62
Author: dongjiuzhu1 <do...@xiaomi.com>
AuthorDate: Tue Nov 22 21:15:06 2022 +0800
net/get/setsockopt: add si_get/setsockopt interface to simply get/setsockopt
move private option to protocol sockif
Signed-off-by: dongjiuzhu1 <do...@xiaomi.com>
---
include/nuttx/net/net.h | 9 +-
net/can/can.h | 8 +-
net/can/can_callback.c | 2 +-
net/can/can_getsockopt.c | 20 +-
net/can/can_recvmsg.c | 10 +-
net/can/can_setsockopt.c | 34 ++-
net/can/can_sockif.c | 8 +-
net/inet/inet_sockif.c | 471 ++++++++++++++++++++++++++++++++++++++-
net/socket/getsockopt.c | 198 ++--------------
net/socket/setsockopt.c | 283 +----------------------
net/usrsock/usrsock.h | 14 +-
net/usrsock/usrsock_getsockopt.c | 22 +-
net/usrsock/usrsock_setsockopt.c | 20 +-
net/usrsock/usrsock_sockif.c | 7 +-
14 files changed, 620 insertions(+), 486 deletions(-)
diff --git a/include/nuttx/net/net.h b/include/nuttx/net/net.h
index cc7fab801e..bdabcbaf83 100644
--- a/include/nuttx/net/net.h
+++ b/include/nuttx/net/net.h
@@ -166,6 +166,12 @@ struct sock_intf_s
CODE int (*si_ioctl)(FAR struct socket *psock,
int cmd, unsigned long arg);
CODE int (*si_socketpair)(FAR struct socket *psocks[2]);
+#ifdef CONFIG_NET_SOCKOPTS
+ CODE int (*si_getsockopt)(FAR struct socket *psock, int level,
+ int option, FAR void *value, FAR socklen_t *value_len);
+ CODE int (*si_setsockopt)(FAR struct socket *psock, int level,
+ int option, FAR const void *value, socklen_t value_len);
+#endif
#ifdef CONFIG_NET_SENDFILE
CODE ssize_t (*si_sendfile)(FAR struct socket *psock,
FAR struct file *infile, FAR off_t *offset,
@@ -210,9 +216,6 @@ struct socket_conn_s
#ifdef CONFIG_NET_SOLINGER
socktimeo_t s_linger; /* Linger timeout value (in deciseconds) */
#endif
-#ifdef CONFIG_NET_TIMESTAMP
- int32_t s_timestamp; /* Socket timestamp enabled/disabled */
-#endif
#ifdef CONFIG_NET_BINDTODEVICE
uint8_t s_boundto; /* Index of the interface we are bound to.
* Unbound: 0, Bound: 1-MAX_IFINDEX */
diff --git a/net/can/can.h b/net/can/can.h
index d317fea6f7..b1180c11aa 100644
--- a/net/can/can.h
+++ b/net/can/can.h
@@ -111,6 +111,9 @@ struct can_conn_s
int32_t tx_deadline;
# endif
#endif
+#ifdef CONFIG_NET_TIMESTAMP
+ int32_t timestamp; /* Socket timestamp enabled/disabled */
+#endif
};
/****************************************************************************
@@ -353,6 +356,7 @@ void can_readahead_signal(FAR struct can_conn_s *conn);
*
* Input Parameters:
* psock Socket structure of socket to operate on
+ * level Protocol level to set the option
* option identifies the option to set
* value Points to the argument value
* value_len The length of the argument value
@@ -365,7 +369,7 @@ void can_readahead_signal(FAR struct can_conn_s *conn);
****************************************************************************/
#ifdef CONFIG_NET_CANPROTO_OPTIONS
-int can_setsockopt(FAR struct socket *psock, int option,
+int can_setsockopt(FAR struct socket *psock, int level, int option,
FAR const void *value, socklen_t value_len);
#endif
@@ -399,7 +403,7 @@ int can_setsockopt(FAR struct socket *psock, int option,
****************************************************************************/
#ifdef CONFIG_NET_CANPROTO_OPTIONS
-int can_getsockopt(FAR struct socket *psock, int option,
+int can_getsockopt(FAR struct socket *psock, int level, int option,
FAR void *value, FAR socklen_t *value_len);
#endif
diff --git a/net/can/can_callback.c b/net/can/can_callback.c
index 394c1d51ac..a5f3e17937 100644
--- a/net/can/can_callback.c
+++ b/net/can/can_callback.c
@@ -123,7 +123,7 @@ uint16_t can_callback(FAR struct net_driver_s *dev,
#ifdef CONFIG_NET_TIMESTAMP
/* TIMESTAMP sockopt is activated, create timestamp and copy to iob */
- if (conn->sconn.s_timestamp)
+ if (conn->timestamp)
{
struct timespec *ts = (struct timespec *)
&dev->d_appdata[dev->d_len];
diff --git a/net/can/can_getsockopt.c b/net/can/can_getsockopt.c
index 17a4b18850..af6253ca3a 100644
--- a/net/can/can_getsockopt.c
+++ b/net/can/can_getsockopt.c
@@ -74,7 +74,7 @@
*
****************************************************************************/
-int can_getsockopt(FAR struct socket *psock, int option,
+int can_getsockopt(FAR struct socket *psock, int level, int option,
FAR void *value, FAR socklen_t *value_len)
{
FAR struct can_conn_s *conn;
@@ -84,6 +84,24 @@ int can_getsockopt(FAR struct socket *psock, int option,
psock->s_conn != NULL);
conn = (FAR struct can_conn_s *)psock->s_conn;
+#ifdef CONFIG_NET_TIMESTAMP
+ if (level == SOL_SOCKET && option == SO_TIMESTAMP)
+ {
+ if (*value_len != sizeof(int32_t))
+ {
+ return -EINVAL;
+ }
+
+ *(FAR int32_t *)value = conn->timestamp;
+ return OK;
+ }
+#endif
+
+ if (level != SOL_CAN_RAW)
+ {
+ return -ENOPROTOOPT;
+ }
+
if (psock->s_type != SOCK_RAW)
{
nerr("ERROR: Not a RAW CAN socket\n");
diff --git a/net/can/can_recvmsg.c b/net/can/can_recvmsg.c
index 189505f717..8ef711de8b 100644
--- a/net/can/can_recvmsg.c
+++ b/net/can/can_recvmsg.c
@@ -434,9 +434,9 @@ static uint16_t can_recvfrom_eventhandler(FAR struct net_driver_s *dev,
#endif
{
#ifdef CONFIG_NET_TIMESTAMP
- if ((conn->sconn.s_timestamp && (dev->d_len >
+ if ((conn->timestamp && (dev->d_len >
sizeof(struct can_frame) + sizeof(struct timeval)))
- || (!conn->sconn.s_timestamp && (dev->d_len >
+ || (!conn->timestamp && (dev->d_len >
sizeof(struct can_frame))))
#else
if (dev->d_len > sizeof(struct can_frame))
@@ -454,7 +454,7 @@ static uint16_t can_recvfrom_eventhandler(FAR struct net_driver_s *dev,
can_newdata(dev, pstate);
#ifdef CONFIG_NET_TIMESTAMP
- if (conn->sconn.s_timestamp)
+ if (conn->timestamp)
{
if (pstate->pr_msglen == sizeof(struct timeval))
{
@@ -587,7 +587,7 @@ ssize_t can_recvmsg(FAR struct socket *psock, FAR struct msghdr *msg,
state.pr_buffer = msg->msg_iov->iov_base;
#ifdef CONFIG_NET_TIMESTAMP
- if (conn->sconn.s_timestamp && msg->msg_controllen >=
+ if (conn->timestamp && msg->msg_controllen >=
(sizeof(struct cmsghdr) + sizeof(struct timeval)))
{
struct cmsghdr *cmsg = CMSG_FIRSTHDR(msg);
@@ -619,7 +619,7 @@ ssize_t can_recvmsg(FAR struct socket *psock, FAR struct msghdr *msg,
if (ret > 0)
{
#ifdef CONFIG_NET_TIMESTAMP
- if (conn->sconn.s_timestamp)
+ if (conn->timestamp)
{
if (state.pr_msglen == sizeof(struct timeval))
{
diff --git a/net/can/can_setsockopt.c b/net/can/can_setsockopt.c
index 2b43c1de98..efa87ef9d5 100644
--- a/net/can/can_setsockopt.c
+++ b/net/can/can_setsockopt.c
@@ -58,6 +58,7 @@
*
* Input Parameters:
* psock Socket structure of socket to operate on
+ * level Protocol level to set the option
* option identifies the option to set
* value Points to the argument value
* value_len The length of the argument value
@@ -69,7 +70,7 @@
*
****************************************************************************/
-int can_setsockopt(FAR struct socket *psock, int option,
+int can_setsockopt(FAR struct socket *psock, int level, int option,
FAR const void *value, socklen_t value_len)
{
FAR struct can_conn_s *conn;
@@ -81,6 +82,37 @@ int can_setsockopt(FAR struct socket *psock, int option,
conn = (FAR struct can_conn_s *)psock->s_conn;
+#ifdef CONFIG_NET_TIMESTAMP
+
+ /* Generates a timestamp for each incoming packet */
+
+ if (level == SOL_SOCKET && option == SO_TIMESTAMP)
+ {
+ /* Verify that option is at least the size of an integer. */
+
+ if (value_len < sizeof(int32_t))
+ {
+ return -EINVAL;
+ }
+
+ /* Lock the network so that we have exclusive access to the socket
+ * options.
+ */
+
+ net_lock();
+
+ conn->timestamp = *((FAR int32_t *)value);
+
+ net_unlock();
+ return OK;
+ }
+#endif
+
+ if (level != SOL_CAN_RAW)
+ {
+ return -ENOPROTOOPT;
+ }
+
if (psock->s_type != SOCK_RAW)
{
nerr("ERROR: Not a RAW CAN socket\n");
diff --git a/net/can/can_sockif.c b/net/can/can_sockif.c
index 3e9ccc27b0..3fb1623a2f 100644
--- a/net/can/can_sockif.c
+++ b/net/can/can_sockif.c
@@ -84,7 +84,13 @@ const struct sock_intf_s g_can_sockif =
can_poll_local, /* si_poll */
can_sendmsg, /* si_sendmsg */
can_recvmsg, /* si_recvmsg */
- can_close /* si_close */
+ can_close, /* si_close */
+ NULL, /* si_ioctl */
+ NULL /* si_socketpair */
+#if defined(CONFIG_NET_SOCKOPTS) && defined(CONFIG_NET_CANPROTO_OPTIONS)
+ , can_getsockopt /* si_getsockopt */
+ , can_setsockopt /* si_setsockopt */
+#endif
};
/****************************************************************************
diff --git a/net/inet/inet_sockif.c b/net/inet/inet_sockif.c
index c198c14c87..a7b1030a80 100644
--- a/net/inet/inet_sockif.c
+++ b/net/inet/inet_sockif.c
@@ -91,6 +91,12 @@ static ssize_t inet_recvmsg(FAR struct socket *psock,
static int inet_ioctl(FAR struct socket *psock,
int cmd, unsigned long arg);
static int inet_socketpair(FAR struct socket *psocks[2]);
+#ifdef CONFIG_NET_SOCKOPTS
+static int inet_getsockopt(FAR struct socket *psock, int level,
+ int option, FAR void *value, FAR socklen_t *value_len);
+static int inet_setsockopt(FAR struct socket *psock, int level,
+ int option, FAR const void *value, socklen_t value_len);
+#endif
#ifdef CONFIG_NET_SENDFILE
static ssize_t inet_sendfile(FAR struct socket *psock,
FAR struct file *infile, FAR off_t *offset,
@@ -118,9 +124,12 @@ static const struct sock_intf_s g_inet_sockif =
inet_close, /* si_close */
inet_ioctl, /* si_ioctl */
inet_socketpair /* si_socketpair */
+#ifdef CONFIG_NET_SOCKOPTS
+ , inet_getsockopt /* si_getsockopt */
+ , inet_setsockopt /* si_setsockopt */
+#endif
#ifdef CONFIG_NET_SENDFILE
- ,
- inet_sendfile /* si_sendfile */
+ , inet_sendfile /* si_sendfile */
#endif
};
@@ -562,6 +571,464 @@ static int inet_getpeername(FAR struct socket *psock,
}
}
+#ifdef CONFIG_NET_SOCKOPTS
+
+/****************************************************************************
+ * Name: inet_get_socketlevel_option
+ *
+ * Description:
+ * inet_get_socketlevel_option() retrieve the value for the option
+ * specified by the 'option' argument for the socket specified by the
+ * 'psock' argument. If the size of the option value is greater than
+ * 'value_len', the value stored in the object pointed to by the 'value'
+ * argument will be silently truncated. Otherwise, the length pointed to
+ * by the 'value_len' argument will be modified to indicate the actual
+ * length of the 'value'.
+ *
+ * The 'level' argument specifies the protocol level of the option. To
+ * retrieve options at the socket level, specify the level argument as
+ * SOL_SOCKET; to retrieve options at the TCP-protocol level, the level
+ * argument is SOL_TCP.
+ *
+ * See <sys/socket.h> a complete list of values for the socket-level
+ * 'option' argument. Protocol-specific options are are protocol specific
+ * header files (such as netinet/tcp.h for the case of the TCP protocol).
+ *
+ * Input Parameters:
+ * psock Socket structure of the socket to query
+ * level Protocol level to set the option
+ * option identifies the option to get
+ * value Points to the argument value
+ * value_len The length of the argument value
+ *
+ * Returned Value:
+ * Returns zero (OK) on success. On failure, it returns a negated errno
+ * value to indicate the nature of the error. See psock_getsockopt() for
+ * the complete list of appropriate return error codes.
+ *
+ ****************************************************************************/
+
+static int inet_get_socketlevel_option(FAR struct socket *psock, int option,
+ FAR void *value,
+ FAR socklen_t *value_len)
+{
+ switch (option)
+ {
+#if CONFIG_NET_RECV_BUFSIZE > 0
+ case SO_RCVBUF: /* Reports receive buffer size */
+ {
+ if (*value_len != sizeof(int))
+ {
+ return -EINVAL;
+ }
+
+#if defined(CONFIG_NET_TCP) && !defined(CONFIG_NET_TCP_NO_STACK)
+ if (psock->s_type == SOCK_STREAM)
+ {
+ FAR struct tcp_conn_s *tcp = psock->s_conn;
+ *(FAR int *)value = tcp->rcv_bufs;
+ }
+ else
+#endif
+#if defined(CONFIG_NET_UDP) && !defined(CONFIG_NET_UDP_NO_STACK)
+ if (psock->s_type == SOCK_DGRAM)
+ {
+ FAR struct udp_conn_s *udp = psock->s_conn;
+ *(FAR int *)value = udp->rcvbufs;
+ }
+ else
+#endif
+ {
+ return -ENOPROTOOPT;
+ }
+ }
+ break;
+#endif
+
+#if CONFIG_NET_SEND_BUFSIZE > 0
+ case SO_SNDBUF: /* Reports send buffer size */
+ {
+ if (*value_len != sizeof(int))
+ {
+ return -EINVAL;
+ }
+
+#if defined(CONFIG_NET_TCP) && !defined(CONFIG_NET_TCP_NO_STACK)
+ if (psock->s_type == SOCK_STREAM)
+ {
+ FAR struct tcp_conn_s *tcp = psock->s_conn;
+ *(FAR int *)value = tcp->snd_bufs;
+ }
+ else
+#endif
+#if defined(CONFIG_NET_UDP) && !defined(CONFIG_NET_UDP_NO_STACK)
+ if (psock->s_type == SOCK_DGRAM)
+ {
+ FAR struct udp_conn_s *udp = psock->s_conn;
+
+ /* Save the send buffer size */
+
+ *(FAR int *)value = udp->sndbufs;
+ }
+ else
+#endif
+ {
+ return -ENOPROTOOPT;
+ }
+ }
+ break;
+#endif
+
+#ifdef CONFIG_NET_TCPPROTO_OPTIONS
+ case SO_KEEPALIVE:
+ {
+ /* Any connection-oriented protocol could potentially support
+ * SO_KEEPALIVE. However, this option is currently only available
+ * for TCP/IP.
+ *
+ * NOTE: SO_KEEPALIVE is not really a socket-level option; it is a
+ * protocol-level option. A given TCP connection may service
+ * multiple sockets (via dup'ing of the socket). There is, however,
+ * still only one connection to be monitored and that is a global
+ * attribute across all of the clones that may use the underlying
+ * connection.
+ */
+
+ /* Verifies TCP connections active by enabling the periodic
+ * transmission of probes.
+ */
+
+ return tcp_getsockopt(psock, option, value, value_len);
+ }
+#endif
+
+ default:
+ return -ENOPROTOOPT;
+ }
+
+ return OK;
+}
+
+/****************************************************************************
+ * Name: inet_getsockopt
+ *
+ * Description:
+ * inet_getsockopt() retrieve the value for the option specified by the
+ * 'option' argument at the protocol level specified by the 'level'
+ * argument. If the size of the option value is greater than 'value_len',
+ * the value stored in the object pointed to by the 'value' argument will
+ * be silently truncated. Otherwise, the length pointed to by the
+ * 'value_len' argument will be modified to indicate the actual length
+ * of the 'value'.
+ *
+ * The 'level' argument specifies the protocol level of the option. To
+ * retrieve options at the socket level, specify the level argument as
+ * SOL_SOCKET.
+ *
+ * See <sys/socket.h> a complete list of values for the 'option' argument.
+ *
+ * Input Parameters:
+ * psock Socket structure of the socket to query
+ * level Protocol level to set the option
+ * option identifies the option to get
+ * value Points to the argument value
+ * value_len The length of the argument value
+ *
+ ****************************************************************************/
+
+static int inet_getsockopt(FAR struct socket *psock, int level, int option,
+ FAR void *value, FAR socklen_t *value_len)
+{
+ if (level == SOL_SOCKET)
+ {
+ return inet_get_socketlevel_option(psock, option, value, value_len);
+ }
+#ifdef CONFIG_NET_TCPPROTO_OPTIONS
+ else if (level == IPPROTO_TCP)
+ {
+ return tcp_getsockopt(psock, option, value, value_len);
+ }
+#endif
+ else
+ {
+ return -ENOPROTOOPT;
+ }
+}
+
+/****************************************************************************
+ * Name: inet_set_socketlevel_option
+ *
+ * Description:
+ * inet_set_socketlevel_option() sets the socket-level option specified by
+ * the 'option' argument to the value pointed to by the 'value' argument
+ * for the socket specified by the 'psock' argument.
+ *
+ * See <sys/socket.h> a complete list of values for the socket level
+ * 'option' argument.
+ *
+ * Input Parameters:
+ * psock Socket structure of socket to operate on
+ * option identifies the option to set
+ * value Points to the argument value
+ * value_len The length of the argument value
+ *
+ * Returned Value:
+ * Returns zero (OK) on success. On failure, it returns a negated errno
+ * value to indicate the nature of the error. See psock_setcockopt() for
+ * the list of possible error values.
+ *
+ ****************************************************************************/
+
+static int inet_set_socketlevel_option(FAR struct socket *psock, int option,
+ FAR const void *value,
+ socklen_t value_len)
+{
+ switch (option)
+ {
+#ifdef CONFIG_NET_TCPPROTO_OPTIONS
+ case SO_KEEPALIVE:
+ {
+ /* Any connection-oriented protocol could potentially support
+ * SO_KEEPALIVE. However, this option is currently only available
+ * for TCP/IP.
+ *
+ * NOTE: SO_KEEPALIVE is not really a socket-level option; it is a
+ * protocol-level option. A given TCP connection may service
+ * multiple sockets (via dup'ing of the socket). There is, however,
+ * still only one connection to be monitored and that is a global
+ * attribute across all of the clones that may use the underlying
+ * connection.
+ */
+
+ /* Verifies TCP connections active by enabling the
+ * periodic transmission of probes
+ */
+
+ return tcp_setsockopt(psock, option, value, value_len);
+ }
+#endif
+
+#ifdef CONFIG_NET_SOLINGER
+ case SO_LINGER:
+ {
+ /* Lingers on a close() if data is present */
+
+ FAR struct socket_conn_s *conn = psock->s_conn;
+ FAR struct linger *setting;
+
+ /* Verify that option is at least the size of an 'struct linger'. */
+
+ if (value_len < sizeof(struct linger))
+ {
+ return -EINVAL;
+ }
+
+ /* Get the value. Is the option being set or cleared? */
+
+ setting = (FAR struct linger *)value;
+
+ /* Lock the network so that we have exclusive access to the socket
+ * options.
+ */
+
+ net_lock();
+
+ /* Set or clear the linger option bit and linger time
+ * (in deciseconds)
+ */
+
+ if (setting->l_onoff)
+ {
+ _SO_SETOPT(conn->s_options, option);
+ conn->s_linger = 10 * setting->l_linger;
+ }
+ else
+ {
+ _SO_CLROPT(conn->s_options, option);
+ conn->s_linger = 0;
+ }
+
+ net_unlock();
+ }
+ break;
+#endif
+
+#if CONFIG_NET_RECV_BUFSIZE > 0
+ case SO_RCVBUF: /* Sets receive buffer size */
+ {
+ int buffersize;
+
+ /* Verify that option is the size of an 'int'. Should also check
+ * that 'value' is properly aligned for an 'int'
+ */
+
+ if (value_len != sizeof(int))
+ {
+ return -EINVAL;
+ }
+
+ /* Get the value. Is the option being set or cleared? */
+
+ buffersize = *(FAR int *)value;
+ if (buffersize < 0)
+ {
+ return -EINVAL;
+ }
+
+ net_lock();
+
+#if defined(CONFIG_NET_TCP) && !defined(CONFIG_NET_TCP_NO_STACK)
+ if (psock->s_type == SOCK_STREAM)
+ {
+ FAR struct tcp_conn_s *tcp = psock->s_conn;
+
+ /* Save the receive buffer size */
+
+ tcp->rcv_bufs = buffersize;
+ }
+ else
+#endif
+#if defined(CONFIG_NET_UDP) && !defined(CONFIG_NET_UDP_NO_STACK)
+ if (psock->s_type == SOCK_DGRAM)
+ {
+ FAR struct udp_conn_s *udp = psock->s_conn;
+
+ /* Save the receive buffer size */
+
+ udp->rcvbufs = buffersize;
+ }
+ else
+#endif
+ {
+ net_unlock();
+ return -ENOPROTOOPT;
+ }
+
+ net_unlock();
+ }
+ break;
+#endif
+
+#if CONFIG_NET_SEND_BUFSIZE > 0
+ case SO_SNDBUF: /* Sets send buffer size */
+ {
+ int buffersize;
+
+ /* Verify that option is the size of an 'int'. Should also check
+ * that 'value' is properly aligned for an 'int'
+ */
+
+ if (value_len != sizeof(int))
+ {
+ return -EINVAL;
+ }
+
+ /* Get the value. Is the option being set or cleared? */
+
+ buffersize = *(FAR int *)value;
+
+ if (buffersize < 0)
+ {
+ return -EINVAL;
+ }
+
+ net_lock();
+
+#if defined(CONFIG_NET_TCP) && !defined(CONFIG_NET_TCP_NO_STACK)
+ if (psock->s_type == SOCK_STREAM)
+ {
+ FAR struct tcp_conn_s *tcp = psock->s_conn;
+
+ /* Save the send buffer size */
+
+ tcp->snd_bufs = buffersize;
+ }
+ else
+#endif
+#if defined(CONFIG_NET_UDP) && !defined(CONFIG_NET_UDP_NO_STACK)
+ if (psock->s_type == SOCK_DGRAM)
+ {
+ FAR struct udp_conn_s *udp = psock->s_conn;
+
+ /* Save the send buffer size */
+
+ udp->sndbufs = buffersize;
+ }
+ else
+#endif
+ {
+ net_unlock();
+ return -ENOPROTOOPT;
+ }
+
+ net_unlock();
+ }
+ break;
+#endif
+
+ default:
+ return -ENOPROTOOPT;
+ }
+
+ return OK;
+}
+
+/****************************************************************************
+ * Name: inet_setsockopt
+ *
+ * Description:
+ * inet_setsockopt() sets the option specified by the 'option' argument,
+ * at the protocol level specified by the 'level' argument, to the value
+ * pointed to by the 'value' argument for the connection.
+ *
+ * The 'level' argument specifies the protocol level of the option. To set
+ * options at the socket level, specify the level argument as SOL_SOCKET.
+ *
+ * See <sys/socket.h> a complete list of values for the 'option' argument.
+ *
+ * Input Parameters:
+ * psock Socket structure of the socket to query
+ * level Protocol level to set the option
+ * option identifies the option to set
+ * value Points to the argument value
+ * value_len The length of the argument value
+ *
+ ****************************************************************************/
+
+static int inet_setsockopt(FAR struct socket *psock, int level, int option,
+ FAR const void *value, socklen_t value_len)
+{
+ switch (level)
+ {
+ case SOL_SOCKET:
+ return inet_set_socketlevel_option(psock, option, value, value_len);
+
+#ifdef CONFIG_NET_TCPPROTO_OPTIONS
+ case IPPROTO_TCP:/* TCP protocol socket options (see include/netinet/tcp.h) */
+ return tcp_setsockopt(psock, option, value, value_len);
+#endif
+
+#ifdef CONFIG_NET_UDPPROTO_OPTIONS
+ case IPPROTO_UDP:/* UDP protocol socket options (see include/netinet/udp.h) */
+ return udp_setsockopt(psock, option, value, value_len);
+#endif
+
+#ifdef CONFIG_NET_IPv4
+ case IPPROTO_IP:/* TCP protocol socket options (see include/netinet/in.h) */
+ return ipv4_setsockopt(psock, option, value, value_len);
+#endif
+
+#ifdef CONFIG_NET_IPv6
+ case IPPROTO_IPV6:/* TCP protocol socket options (see include/netinet/in.h) */
+ return ipv6_setsockopt(psock, option, value, value_len);
+#endif
+ default:
+ return -ENOPROTOOPT;
+ }
+}
+
+#endif
+
/****************************************************************************
* Name: inet_listen
*
diff --git a/net/socket/getsockopt.c b/net/socket/getsockopt.c
index 4c3c75878c..f2f45e73e2 100644
--- a/net/socket/getsockopt.c
+++ b/net/socket/getsockopt.c
@@ -33,11 +33,7 @@
#include <errno.h>
#include "socket/socket.h"
-#include "tcp/tcp.h"
-#include "udp/udp.h"
-#include "usrsock/usrsock.h"
#include "utils/utils.h"
-#include "can/can.h"
/****************************************************************************
* Private Functions
@@ -128,39 +124,18 @@ static int psock_socketlevel_option(FAR struct socket *psock, int option,
net_dsec2timeval(timeo, (struct timeval *)value);
*value_len = sizeof(struct timeval);
}
+ break;
- return OK;
- }
-
-#ifdef CONFIG_NET_USRSOCK
- if (psock->s_type == SOCK_USRSOCK_TYPE)
- {
- if (option == SO_TYPE)
- {
- FAR struct usrsock_conn_s *uconn = psock->s_conn;
-
- /* Return the actual socket type */
-
- *(FAR int *)value = uconn->type;
- *value_len = sizeof(int);
-
- return OK;
- }
-
- return -ENOPROTOOPT;
- }
-#endif
-
- switch (option)
- {
case SO_ACCEPTCONN: /* Reports whether socket listening is enabled */
- if (*value_len < sizeof(int))
- {
- return -EINVAL;
- }
+ {
+ if (*value_len < sizeof(int))
+ {
+ return -EINVAL;
+ }
- *(FAR int *)value = _SS_ISLISTENING(conn->s_flags);
- *value_len = sizeof(int);
+ *(FAR int *)value = _SS_ISLISTENING(conn->s_flags);
+ *value_len = sizeof(int);
+ }
break;
/* The following options take a point to an integer boolean value.
@@ -171,10 +146,8 @@ static int psock_socketlevel_option(FAR struct socket *psock, int option,
case SO_BROADCAST: /* Permits sending of broadcast messages */
case SO_DEBUG: /* Enables recording of debugging information */
case SO_DONTROUTE: /* Requests outgoing messages bypass standard routing */
-#ifndef CONFIG_NET_TCPPROTO_OPTIONS
case SO_KEEPALIVE: /* Verifies TCP connections active by enabling the
* periodic transmission of probes */
-#endif
case SO_OOBINLINE: /* Leaves received out-of-band data inline */
case SO_REUSEADDR: /* Allow reuse of local addresses */
{
@@ -201,23 +174,6 @@ static int psock_socketlevel_option(FAR struct socket *psock, int option,
}
break;
-#ifdef CONFIG_NET_TCPPROTO_OPTIONS
- /* Any connection-oriented protocol could potentially support
- * SO_KEEPALIVE. However, this option is currently only available for
- * TCP/IP.
- *
- * NOTE: SO_KEEPALIVE is not really a socket-level option; it is a
- * protocol-level option. A given TCP connection may service multiple
- * sockets (via dup'ing of the socket). There is, however, still only
- * one connection to be monitored and that is a global attribute across
- * all of the clones that may use the underlying connection.
- */
-
- case SO_KEEPALIVE: /* Verifies TCP connections active by enabling the
- * periodic transmission of probes */
- return tcp_getsockopt(psock, option, value, value_len);
-#endif
-
case SO_TYPE: /* Reports the socket type */
{
/* Verify that option is the size of an 'int'. Should also check
@@ -248,97 +204,6 @@ static int psock_socketlevel_option(FAR struct socket *psock, int option,
}
break;
-#ifdef CONFIG_NET_TIMESTAMP
- case SO_TIMESTAMP:
- {
- if (*value_len != sizeof(int))
- {
- return -EINVAL;
- }
-
- *(FAR int *)value = (int)conn->s_timestamp;
- }
- break;
-#endif
-
-#if CONFIG_NET_RECV_BUFSIZE > 0
- case SO_RCVBUF: /* Reports receive buffer size */
- {
- if (*value_len != sizeof(int))
- {
- return -EINVAL;
- }
-
-#if defined(CONFIG_NET_TCP) && !defined(CONFIG_NET_TCP_NO_STACK)
- if (psock->s_type == SOCK_STREAM)
- {
- FAR struct tcp_conn_s *tcp;
-
- tcp = (FAR struct tcp_conn_s *)conn;
-
- *(FAR int *)value = tcp->rcv_bufs;
- }
- else
-#endif
-#if defined(CONFIG_NET_UDP) && !defined(CONFIG_NET_UDP_NO_STACK)
- if (psock->s_type == SOCK_DGRAM)
- {
- FAR struct udp_conn_s *udp;
-
- udp = (FAR struct udp_conn_s *)conn;
-
- *(FAR int *)value = udp->rcvbufs;
- }
- else
-#endif
- {
- return -ENOPROTOOPT;
- }
-
- break;
- }
-#endif
-
-#if CONFIG_NET_SEND_BUFSIZE > 0
- case SO_SNDBUF: /* Reports send buffer size */
- {
- if (*value_len != sizeof(int))
- {
- return -EINVAL;
- }
-
-#if defined(CONFIG_NET_TCP) && !defined(CONFIG_NET_TCP_NO_STACK)
- if (psock->s_type == SOCK_STREAM)
- {
- FAR struct tcp_conn_s *tcp;
-
- tcp = (FAR struct tcp_conn_s *)conn;
-
- *(FAR int *)value = tcp->snd_bufs;
- }
- else
-#endif
-#if defined(CONFIG_NET_UDP) && !defined(CONFIG_NET_UDP_NO_STACK)
- if (psock->s_type == SOCK_DGRAM)
- {
- FAR struct udp_conn_s *udp;
-
- udp = (FAR struct udp_conn_s *)conn;
-
- /* Save the send buffer size */
-
- *(FAR int *)value = udp->sndbufs;
- }
- else
-#endif
- {
- return -ENOPROTOOPT;
- }
-
- break;
- }
-#endif
-
default:
return -ENOPROTOOPT;
}
@@ -397,7 +262,7 @@ static int psock_socketlevel_option(FAR struct socket *psock, int option,
int psock_getsockopt(FAR struct socket *psock, int level, int option,
FAR void *value, FAR socklen_t *value_len)
{
- int ret;
+ int ret = -ENOPROTOOPT;
/* Verify that the sockfd corresponds to valid, allocated socket */
@@ -406,49 +271,20 @@ int psock_getsockopt(FAR struct socket *psock, int level, int option,
return -EBADF;
}
- /* Handle retrieval of the socket option according to the level at which
- * option should be applied.
- */
+ /* Perform the socket interface operation */
- switch (level)
+ if (psock->s_sockif->si_getsockopt != NULL)
{
- case SOL_SOCKET: /* Socket-level options (see include/sys/socket.h) */
- ret = psock_socketlevel_option(psock, option, value, value_len);
- break;
-
-#ifdef CONFIG_NET_TCPPROTO_OPTIONS
- case IPPROTO_TCP: /* TCP protocol socket options (see include/netinet/tcp.h) */
- ret = tcp_getsockopt(psock, option, value, value_len);
- break;
-#endif
-
-#ifdef CONFIG_NET_CANPROTO_OPTIONS
- case SOL_CAN_RAW:/* CAN protocol socket options (see include/netpacket/can.h) */
- ret = can_getsockopt(psock, option, value, value_len);
- break;
-#endif
-
- /* These levels are defined in sys/socket.h, but are not yet
- * implemented.
- */
-
- case IPPROTO_IP: /* TCP protocol socket options (see include/netinet/ip.h) */
- case IPPROTO_IPV6: /* TCP protocol socket options (see include/netinet/ip6.h) */
- case IPPROTO_UDP: /* TCP protocol socket options (see include/netinit/udp.h) */
- default: /* The provided level is invalid */
- ret = -ENOPROTOOPT;
- break;
+ ret = psock->s_sockif->si_getsockopt(psock, level, option,
+ value, value_len);
}
-#ifdef CONFIG_NET_USRSOCK
- /* Try usrsock further if the protocol not available */
+ /* Try socket level if the socket interface operation is not available */
- if (ret == -ENOPROTOOPT && psock->s_type == SOCK_USRSOCK_TYPE)
+ if (ret == -ENOPROTOOPT && level == SOL_SOCKET)
{
- ret = usrsock_getsockopt(psock->s_conn, level,
- option, value, value_len);
+ ret = psock_socketlevel_option(psock, option, value, value_len);
}
-#endif
return ret;
}
diff --git a/net/socket/setsockopt.c b/net/socket/setsockopt.c
index ba72e84696..a7ede25744 100644
--- a/net/socket/setsockopt.c
+++ b/net/socket/setsockopt.c
@@ -34,15 +34,11 @@
#include <arch/irq.h>
#include <nuttx/net/net.h>
+#include <nuttx/net/netdev.h>
#include <netdev/netdev.h>
#include "socket/socket.h"
-#include "inet/inet.h"
-#include "tcp/tcp.h"
-#include "udp/udp.h"
-#include "usrsock/usrsock.h"
#include "utils/utils.h"
-#include "can/can.h"
/****************************************************************************
* Public Functions
@@ -134,27 +130,14 @@ static int psock_socketlevel_option(FAR struct socket *psock, int option,
{
_SO_SETOPT(conn->s_options, option);
}
-
- return OK;
}
- }
-
-#ifdef CONFIG_NET_USRSOCK
- if (psock->s_type == SOCK_USRSOCK_TYPE)
- {
- return -ENOPROTOOPT;
- }
-#endif
+ break;
- switch (option)
- {
case SO_BROADCAST: /* Permits sending of broadcast messages */
case SO_DEBUG: /* Enables recording of debugging information */
case SO_DONTROUTE: /* Requests outgoing messages bypass standard routing */
-#ifndef CONFIG_NET_TCPPROTO_OPTIONS
case SO_KEEPALIVE: /* Verifies TCP connections active by enabling the
* periodic transmission of probes */
-#endif
case SO_OOBINLINE: /* Leaves received out-of-band data inline */
case SO_REUSEADDR: /* Allow reuse of local addresses */
{
@@ -194,212 +177,6 @@ static int psock_socketlevel_option(FAR struct socket *psock, int option,
}
break;
-#ifdef CONFIG_NET_TCPPROTO_OPTIONS
- /* Any connection-oriented protocol could potentially support
- * SO_KEEPALIVE. However, this option is currently only available for
- * TCP/IP.
- *
- * NOTE: SO_KEEPALIVE is not really a socket-level option; it is a
- * protocol-level option. A given TCP connection may service multiple
- * sockets (via dup'ing of the socket). There is, however, still only
- * one connection to be monitored and that is a global attribute across
- * all of the clones that may use the underlying connection.
- */
-
- case SO_KEEPALIVE: /* Verifies TCP connections active by enabling the
- * periodic transmission of probes */
- return tcp_setsockopt(psock, option, value, value_len);
-#endif
-
-#ifdef CONFIG_NET_SOLINGER
- case SO_LINGER: /* Lingers on a close() if data is present */
- {
- FAR struct linger *setting;
-
- /* Verify that option is at least the size of an 'struct linger'. */
-
- if (value_len < sizeof(FAR struct linger))
- {
- return -EINVAL;
- }
-
- /* Get the value. Is the option being set or cleared? */
-
- setting = (FAR struct linger *)value;
-
- /* Lock the network so that we have exclusive access to the socket
- * options.
- */
-
- net_lock();
-
- /* Set or clear the linger option bit and linger time
- * (in deciseconds)
- */
-
- if (setting->l_onoff)
- {
- _SO_SETOPT(conn->s_options, option);
- conn->s_linger = 10 * setting->l_linger;
- }
- else
- {
- _SO_CLROPT(conn->s_options, option);
- conn->s_linger = 0;
- }
-
- net_unlock();
- }
- break;
-#endif
-
-#ifdef CONFIG_NET_TIMESTAMP
- case SO_TIMESTAMP: /* Generates a timestamp for each incoming packet */
- {
- /* Verify that option is at least the size of an integer. */
-
- if (value_len < sizeof(FAR int32_t))
- {
- return -EINVAL;
- }
-
- /* Lock the network so that we have exclusive access to the socket
- * options.
- */
-
- net_lock();
-
- conn->s_timestamp = *((FAR int32_t *)value);
-
- net_unlock();
- }
- break;
-#endif
-
-#if CONFIG_NET_RECV_BUFSIZE > 0
- case SO_RCVBUF: /* Sets receive buffer size */
- {
- int buffersize;
-
- /* Verify that option is the size of an 'int'. Should also check
- * that 'value' is properly aligned for an 'int'
- */
-
- if (value_len != sizeof(int))
- {
- return -EINVAL;
- }
-
- /* Get the value. Is the option being set or cleared? */
-
- buffersize = *(FAR int *)value;
-
- if (buffersize < 0)
- {
- return -EINVAL;
- }
-
- net_lock();
-
-#if defined(CONFIG_NET_TCP) && !defined(CONFIG_NET_TCP_NO_STACK)
- if (psock->s_type == SOCK_STREAM)
- {
- FAR struct tcp_conn_s *tcp;
-
- tcp = (FAR struct tcp_conn_s *)conn;
-
- /* Save the receive buffer size */
-
- tcp->rcv_bufs = buffersize;
- }
- else
-#endif
-#if defined(CONFIG_NET_UDP) && !defined(CONFIG_NET_UDP_NO_STACK)
- if (psock->s_type == SOCK_DGRAM)
- {
- FAR struct udp_conn_s *udp;
-
- udp = (FAR struct udp_conn_s *)conn;
-
- /* Save the receive buffer size */
-
- udp->rcvbufs = buffersize;
- }
- else
-#endif
- {
- net_unlock();
- return -ENOPROTOOPT;
- }
-
- net_unlock();
-
- break;
- }
-#endif
-
-#if CONFIG_NET_SEND_BUFSIZE > 0
- case SO_SNDBUF: /* Sets send buffer size */
- {
- int buffersize;
-
- /* Verify that option is the size of an 'int'. Should also check
- * that 'value' is properly aligned for an 'int'
- */
-
- if (value_len != sizeof(int))
- {
- return -EINVAL;
- }
-
- /* Get the value. Is the option being set or cleared? */
-
- buffersize = *(FAR int *)value;
-
- if (buffersize < 0)
- {
- return -EINVAL;
- }
-
- net_lock();
-
-#if defined(CONFIG_NET_TCP) && !defined(CONFIG_NET_TCP_NO_STACK)
- if (psock->s_type == SOCK_STREAM)
- {
- FAR struct tcp_conn_s *tcp;
-
- tcp = (FAR struct tcp_conn_s *)conn;
-
- /* Save the send buffer size */
-
- tcp->snd_bufs = buffersize;
- }
- else
-#endif
-#if defined(CONFIG_NET_UDP) && !defined(CONFIG_NET_UDP_NO_STACK)
- if (psock->s_type == SOCK_DGRAM)
- {
- FAR struct udp_conn_s *udp;
-
- udp = (FAR struct udp_conn_s *)conn;
-
- /* Save the send buffer size */
-
- udp->sndbufs = buffersize;
- }
- else
-#endif
- {
- net_unlock();
- return -ENOPROTOOPT;
- }
-
- net_unlock();
-
- break;
- }
-#endif
-
#ifdef CONFIG_NET_BINDTODEVICE
/* Handle the SO_BINDTODEVICE socket-level option.
*
@@ -516,7 +293,7 @@ static int psock_socketlevel_option(FAR struct socket *psock, int option,
int psock_setsockopt(FAR struct socket *psock, int level, int option,
FAR const void *value, socklen_t value_len)
{
- int ret;
+ int ret = -ENOPROTOOPT;
/* Verify that the sockfd corresponds to valid, allocated socket */
@@ -525,60 +302,20 @@ int psock_setsockopt(FAR struct socket *psock, int level, int option,
return -EBADF;
}
- /* Handle setting of the socket option according to the level at which
- * option should be applied.
- */
+ /* Perform the socket interface operation */
- switch (level)
+ if (psock->s_sockif->si_setsockopt != NULL)
{
- case SOL_SOCKET: /* Socket-level options (see include/sys/socket.h) */
- ret = psock_socketlevel_option(psock, option, value, value_len);
- break;
-
-#ifdef CONFIG_NET_TCPPROTO_OPTIONS
- case IPPROTO_TCP:/* TCP protocol socket options (see include/netinet/tcp.h) */
- ret = tcp_setsockopt(psock, option, value, value_len);
- break;
-#endif
-
-#ifdef CONFIG_NET_UDPPROTO_OPTIONS
- case IPPROTO_UDP:/* UDP protocol socket options (see include/netinet/udp.h) */
- ret = udp_setsockopt(psock, option, value, value_len);
- break;
-#endif
-
-#ifdef CONFIG_NET_IPv4
- case IPPROTO_IP:/* TCP protocol socket options (see include/netinet/in.h) */
- ret = ipv4_setsockopt(psock, option, value, value_len);
- break;
-#endif
-
-#ifdef CONFIG_NET_IPv6
- case IPPROTO_IPV6:/* TCP protocol socket options (see include/netinet/in.h) */
- ret = ipv6_setsockopt(psock, option, value, value_len);
- break;
-#endif
-
-#ifdef CONFIG_NET_CANPROTO_OPTIONS
- case SOL_CAN_RAW: /* CAN protocol socket options (see include/netpacket/can.h) */
- ret = can_setsockopt(psock, option, value, value_len);
- break;
-#endif
-
- default: /* The provided level is invalid */
- ret = -ENOPROTOOPT;
- break;
+ ret = psock->s_sockif->si_setsockopt(psock, level, option,
+ value, value_len);
}
-#ifdef CONFIG_NET_USRSOCK
- /* Try usrsock further if the protocol not available */
+ /* Try socket level if the socket interface operation is not available */
- if (ret == -ENOPROTOOPT && psock->s_type == SOCK_USRSOCK_TYPE)
+ if (ret == -ENOPROTOOPT && level == SOL_SOCKET)
{
- ret = usrsock_setsockopt(psock->s_conn, level,
- option, value, value_len);
+ ret = psock_socketlevel_option(psock, option, value, value_len);
}
-#endif
return ret;
}
diff --git a/net/usrsock/usrsock.h b/net/usrsock/usrsock.h
index 061afc3b10..7cbb0fd7dd 100644
--- a/net/usrsock/usrsock.h
+++ b/net/usrsock/usrsock.h
@@ -546,7 +546,7 @@ ssize_t usrsock_recvmsg(FAR struct socket *psock, FAR struct msghdr *msg,
* See <sys/socket.h> a complete list of values for the 'option' argument.
*
* Input Parameters:
- * conn usrsock socket connection structure
+ * psock Socket structure of the socket to query
* level Protocol level to set the option
* option identifies the option to get
* value Points to the argument value
@@ -554,9 +554,8 @@ ssize_t usrsock_recvmsg(FAR struct socket *psock, FAR struct msghdr *msg,
*
****************************************************************************/
-int usrsock_getsockopt(FAR struct usrsock_conn_s *conn, int level,
- int option, FAR void *value,
- FAR socklen_t *value_len);
+int usrsock_getsockopt(FAR struct socket *psock, int level, int option,
+ FAR void *value, FAR socklen_t *value_len);
/****************************************************************************
* Name: usrsock_setsockopt
@@ -572,7 +571,7 @@ int usrsock_getsockopt(FAR struct usrsock_conn_s *conn, int level,
* See <sys/socket.h> a complete list of values for the 'option' argument.
*
* Input Parameters:
- * conn usrsock socket connection structure
+ * psock Socket structure of the socket to query
* level Protocol level to set the option
* option identifies the option to set
* value Points to the argument value
@@ -580,9 +579,8 @@ int usrsock_getsockopt(FAR struct usrsock_conn_s *conn, int level,
*
****************************************************************************/
-int usrsock_setsockopt(FAR struct usrsock_conn_s *conn, int level,
- int option, FAR const void *value,
- FAR socklen_t value_len);
+int usrsock_setsockopt(FAR struct socket *psock, int level, int option,
+ FAR const void *value, socklen_t value_len);
/****************************************************************************
* Name: usrsock_getsockname
diff --git a/net/usrsock/usrsock_getsockopt.c b/net/usrsock/usrsock_getsockopt.c
index 0b8b25e39e..07f57a26e8 100644
--- a/net/usrsock/usrsock_getsockopt.c
+++ b/net/usrsock/usrsock_getsockopt.c
@@ -160,7 +160,7 @@ static int do_getsockopt_request(FAR struct usrsock_conn_s *conn, int level,
* See <sys/socket.h> a complete list of values for the 'option' argument.
*
* Input Parameters:
- * conn usrsock socket connection structure
+ * psock Socket structure of the socket to query
* level Protocol level to set the option
* option identifies the option to get
* value Points to the argument value
@@ -168,10 +168,10 @@ static int do_getsockopt_request(FAR struct usrsock_conn_s *conn, int level,
*
****************************************************************************/
-int usrsock_getsockopt(FAR struct usrsock_conn_s *conn,
- int level, int option,
+int usrsock_getsockopt(FAR struct socket *psock, int level, int option,
FAR void *value, FAR socklen_t *value_len)
{
+ FAR struct usrsock_conn_s *conn = psock->s_conn;
struct usrsock_data_reqstate_s state =
{
};
@@ -179,6 +179,22 @@ int usrsock_getsockopt(FAR struct usrsock_conn_s *conn,
struct iovec inbufs[1];
int ret;
+ if (level == SOL_SOCKET)
+ {
+ if (option == SO_TYPE)
+ {
+ /* Return the actual socket type */
+
+ *(FAR int *)value = conn->type;
+ *value_len = sizeof(int);
+ return OK;
+ }
+ else
+ {
+ return -ENOPROTOOPT;
+ }
+ }
+
net_lock();
if (conn->state == USRSOCK_CONN_STATE_UNINITIALIZED ||
diff --git a/net/usrsock/usrsock_setsockopt.c b/net/usrsock/usrsock_setsockopt.c
index 70302f6c98..922da98e27 100644
--- a/net/usrsock/usrsock_setsockopt.c
+++ b/net/usrsock/usrsock_setsockopt.c
@@ -149,7 +149,7 @@ static int do_setsockopt_request(FAR struct usrsock_conn_s *conn,
* See <sys/socket.h> a complete list of values for the 'option' argument.
*
* Input Parameters:
- * conn usrsock socket connection structure
+ * psock Socket structure of the socket to query
* level Protocol level to set the option
* option identifies the option to set
* value Points to the argument value
@@ -157,10 +157,10 @@ static int do_setsockopt_request(FAR struct usrsock_conn_s *conn,
*
****************************************************************************/
-int usrsock_setsockopt(FAR struct usrsock_conn_s *conn,
- int level, int option,
- FAR const void *value, FAR socklen_t value_len)
+int usrsock_setsockopt(FAR struct socket *psock, int level, int option,
+ FAR const void *value, socklen_t value_len)
{
+ FAR struct usrsock_conn_s *conn = psock->s_conn;
struct usrsock_reqstate_s state =
{
};
@@ -168,6 +168,18 @@ int usrsock_setsockopt(FAR struct usrsock_conn_s *conn,
int ret;
DEBUGASSERT(conn);
+ if (level == SOL_SOCKET)
+ {
+ if (option == SO_RCVTIMEO || option == SO_SNDTIMEO)
+ {
+ return -ENOPROTOOPT;
+ }
+ else
+ {
+ return -EINVAL;
+ }
+ }
+
net_lock();
if (conn->state == USRSOCK_CONN_STATE_UNINITIALIZED ||
diff --git a/net/usrsock/usrsock_sockif.c b/net/usrsock/usrsock_sockif.c
index 5791ec6e68..6f83ca30fa 100644
--- a/net/usrsock/usrsock_sockif.c
+++ b/net/usrsock/usrsock_sockif.c
@@ -66,7 +66,12 @@ const struct sock_intf_s g_usrsock_sockif =
usrsock_sendmsg, /* si_sendmsg */
usrsock_recvmsg, /* si_recvmsg */
usrsock_sockif_close, /* si_close */
- usrsock_ioctl /* si_ioctl */
+ usrsock_ioctl, /* si_ioctl */
+ NULL /* si_socketpair */
+#ifdef CONFIG_NET_SOCKOPTS
+ , usrsock_getsockopt /* si_getsockopt */
+ , usrsock_setsockopt /* si_setsockopt */
+#endif
};
/****************************************************************************