net/get/setsockopt: add si_get/setsockopt interface to simply get/setsockopt
move private option to protocol sockif Signed-off-by: dongjiuzhu1 <dongjiuzhu1@xiaomi.com>
This commit is contained in:
parent
c5704eb1e7
commit
e6f8ccda4a
14 changed files with 620 additions and 486 deletions
|
|
@ -166,6 +166,12 @@ struct sock_intf_s
|
||||||
CODE int (*si_ioctl)(FAR struct socket *psock,
|
CODE int (*si_ioctl)(FAR struct socket *psock,
|
||||||
int cmd, unsigned long arg);
|
int cmd, unsigned long arg);
|
||||||
CODE int (*si_socketpair)(FAR struct socket *psocks[2]);
|
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
|
#ifdef CONFIG_NET_SENDFILE
|
||||||
CODE ssize_t (*si_sendfile)(FAR struct socket *psock,
|
CODE ssize_t (*si_sendfile)(FAR struct socket *psock,
|
||||||
FAR struct file *infile, FAR off_t *offset,
|
FAR struct file *infile, FAR off_t *offset,
|
||||||
|
|
@ -210,9 +216,6 @@ struct socket_conn_s
|
||||||
#ifdef CONFIG_NET_SOLINGER
|
#ifdef CONFIG_NET_SOLINGER
|
||||||
socktimeo_t s_linger; /* Linger timeout value (in deciseconds) */
|
socktimeo_t s_linger; /* Linger timeout value (in deciseconds) */
|
||||||
#endif
|
#endif
|
||||||
#ifdef CONFIG_NET_TIMESTAMP
|
|
||||||
int32_t s_timestamp; /* Socket timestamp enabled/disabled */
|
|
||||||
#endif
|
|
||||||
#ifdef CONFIG_NET_BINDTODEVICE
|
#ifdef CONFIG_NET_BINDTODEVICE
|
||||||
uint8_t s_boundto; /* Index of the interface we are bound to.
|
uint8_t s_boundto; /* Index of the interface we are bound to.
|
||||||
* Unbound: 0, Bound: 1-MAX_IFINDEX */
|
* Unbound: 0, Bound: 1-MAX_IFINDEX */
|
||||||
|
|
|
||||||
|
|
@ -111,6 +111,9 @@ struct can_conn_s
|
||||||
int32_t tx_deadline;
|
int32_t tx_deadline;
|
||||||
# endif
|
# endif
|
||||||
#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:
|
* Input Parameters:
|
||||||
* psock Socket structure of socket to operate on
|
* psock Socket structure of socket to operate on
|
||||||
|
* level Protocol level to set the option
|
||||||
* option identifies the option to set
|
* option identifies the option to set
|
||||||
* value Points to the argument value
|
* value Points to the argument value
|
||||||
* value_len The length of 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
|
#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);
|
FAR const void *value, socklen_t value_len);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
@ -399,7 +403,7 @@ int can_setsockopt(FAR struct socket *psock, int option,
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
|
|
||||||
#ifdef CONFIG_NET_CANPROTO_OPTIONS
|
#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);
|
FAR void *value, FAR socklen_t *value_len);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -123,7 +123,7 @@ uint16_t can_callback(FAR struct net_driver_s *dev,
|
||||||
#ifdef CONFIG_NET_TIMESTAMP
|
#ifdef CONFIG_NET_TIMESTAMP
|
||||||
/* TIMESTAMP sockopt is activated, create timestamp and copy to iob */
|
/* TIMESTAMP sockopt is activated, create timestamp and copy to iob */
|
||||||
|
|
||||||
if (conn->sconn.s_timestamp)
|
if (conn->timestamp)
|
||||||
{
|
{
|
||||||
struct timespec *ts = (struct timespec *)
|
struct timespec *ts = (struct timespec *)
|
||||||
&dev->d_appdata[dev->d_len];
|
&dev->d_appdata[dev->d_len];
|
||||||
|
|
|
||||||
|
|
@ -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 void *value, FAR socklen_t *value_len)
|
||||||
{
|
{
|
||||||
FAR struct can_conn_s *conn;
|
FAR struct can_conn_s *conn;
|
||||||
|
|
@ -84,6 +84,24 @@ int can_getsockopt(FAR struct socket *psock, int option,
|
||||||
psock->s_conn != NULL);
|
psock->s_conn != NULL);
|
||||||
conn = (FAR struct can_conn_s *)psock->s_conn;
|
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)
|
if (psock->s_type != SOCK_RAW)
|
||||||
{
|
{
|
||||||
nerr("ERROR: Not a RAW CAN socket\n");
|
nerr("ERROR: Not a RAW CAN socket\n");
|
||||||
|
|
|
||||||
|
|
@ -434,9 +434,9 @@ static uint16_t can_recvfrom_eventhandler(FAR struct net_driver_s *dev,
|
||||||
#endif
|
#endif
|
||||||
{
|
{
|
||||||
#ifdef CONFIG_NET_TIMESTAMP
|
#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)))
|
sizeof(struct can_frame) + sizeof(struct timeval)))
|
||||||
|| (!conn->sconn.s_timestamp && (dev->d_len >
|
|| (!conn->timestamp && (dev->d_len >
|
||||||
sizeof(struct can_frame))))
|
sizeof(struct can_frame))))
|
||||||
#else
|
#else
|
||||||
if (dev->d_len > sizeof(struct can_frame))
|
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);
|
can_newdata(dev, pstate);
|
||||||
|
|
||||||
#ifdef CONFIG_NET_TIMESTAMP
|
#ifdef CONFIG_NET_TIMESTAMP
|
||||||
if (conn->sconn.s_timestamp)
|
if (conn->timestamp)
|
||||||
{
|
{
|
||||||
if (pstate->pr_msglen == sizeof(struct timeval))
|
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;
|
state.pr_buffer = msg->msg_iov->iov_base;
|
||||||
|
|
||||||
#ifdef CONFIG_NET_TIMESTAMP
|
#ifdef CONFIG_NET_TIMESTAMP
|
||||||
if (conn->sconn.s_timestamp && msg->msg_controllen >=
|
if (conn->timestamp && msg->msg_controllen >=
|
||||||
(sizeof(struct cmsghdr) + sizeof(struct timeval)))
|
(sizeof(struct cmsghdr) + sizeof(struct timeval)))
|
||||||
{
|
{
|
||||||
struct cmsghdr *cmsg = CMSG_FIRSTHDR(msg);
|
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)
|
if (ret > 0)
|
||||||
{
|
{
|
||||||
#ifdef CONFIG_NET_TIMESTAMP
|
#ifdef CONFIG_NET_TIMESTAMP
|
||||||
if (conn->sconn.s_timestamp)
|
if (conn->timestamp)
|
||||||
{
|
{
|
||||||
if (state.pr_msglen == sizeof(struct timeval))
|
if (state.pr_msglen == sizeof(struct timeval))
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -58,6 +58,7 @@
|
||||||
*
|
*
|
||||||
* Input Parameters:
|
* Input Parameters:
|
||||||
* psock Socket structure of socket to operate on
|
* psock Socket structure of socket to operate on
|
||||||
|
* level Protocol level to set the option
|
||||||
* option identifies the option to set
|
* option identifies the option to set
|
||||||
* value Points to the argument value
|
* value Points to the argument value
|
||||||
* value_len The length of 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 const void *value, socklen_t value_len)
|
||||||
{
|
{
|
||||||
FAR struct can_conn_s *conn;
|
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;
|
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)
|
if (psock->s_type != SOCK_RAW)
|
||||||
{
|
{
|
||||||
nerr("ERROR: Not a RAW CAN socket\n");
|
nerr("ERROR: Not a RAW CAN socket\n");
|
||||||
|
|
|
||||||
|
|
@ -84,7 +84,13 @@ const struct sock_intf_s g_can_sockif =
|
||||||
can_poll_local, /* si_poll */
|
can_poll_local, /* si_poll */
|
||||||
can_sendmsg, /* si_sendmsg */
|
can_sendmsg, /* si_sendmsg */
|
||||||
can_recvmsg, /* si_recvmsg */
|
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
|
||||||
};
|
};
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
|
|
|
||||||
|
|
@ -91,6 +91,12 @@ static ssize_t inet_recvmsg(FAR struct socket *psock,
|
||||||
static int inet_ioctl(FAR struct socket *psock,
|
static int inet_ioctl(FAR struct socket *psock,
|
||||||
int cmd, unsigned long arg);
|
int cmd, unsigned long arg);
|
||||||
static int inet_socketpair(FAR struct socket *psocks[2]);
|
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
|
#ifdef CONFIG_NET_SENDFILE
|
||||||
static ssize_t inet_sendfile(FAR struct socket *psock,
|
static ssize_t inet_sendfile(FAR struct socket *psock,
|
||||||
FAR struct file *infile, FAR off_t *offset,
|
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_close, /* si_close */
|
||||||
inet_ioctl, /* si_ioctl */
|
inet_ioctl, /* si_ioctl */
|
||||||
inet_socketpair /* si_socketpair */
|
inet_socketpair /* si_socketpair */
|
||||||
|
#ifdef CONFIG_NET_SOCKOPTS
|
||||||
|
, inet_getsockopt /* si_getsockopt */
|
||||||
|
, inet_setsockopt /* si_setsockopt */
|
||||||
|
#endif
|
||||||
#ifdef CONFIG_NET_SENDFILE
|
#ifdef CONFIG_NET_SENDFILE
|
||||||
,
|
, inet_sendfile /* si_sendfile */
|
||||||
inet_sendfile /* si_sendfile */
|
|
||||||
#endif
|
#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
|
* Name: inet_listen
|
||||||
*
|
*
|
||||||
|
|
|
||||||
|
|
@ -33,11 +33,7 @@
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
|
|
||||||
#include "socket/socket.h"
|
#include "socket/socket.h"
|
||||||
#include "tcp/tcp.h"
|
|
||||||
#include "udp/udp.h"
|
|
||||||
#include "usrsock/usrsock.h"
|
|
||||||
#include "utils/utils.h"
|
#include "utils/utils.h"
|
||||||
#include "can/can.h"
|
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
* Private Functions
|
* Private Functions
|
||||||
|
|
@ -128,39 +124,18 @@ static int psock_socketlevel_option(FAR struct socket *psock, int option,
|
||||||
net_dsec2timeval(timeo, (struct timeval *)value);
|
net_dsec2timeval(timeo, (struct timeval *)value);
|
||||||
*value_len = sizeof(struct timeval);
|
*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 */
|
case SO_ACCEPTCONN: /* Reports whether socket listening is enabled */
|
||||||
if (*value_len < sizeof(int))
|
{
|
||||||
{
|
if (*value_len < sizeof(int))
|
||||||
return -EINVAL;
|
{
|
||||||
}
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
|
||||||
*(FAR int *)value = _SS_ISLISTENING(conn->s_flags);
|
*(FAR int *)value = _SS_ISLISTENING(conn->s_flags);
|
||||||
*value_len = sizeof(int);
|
*value_len = sizeof(int);
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
/* The following options take a point to an integer boolean value.
|
/* 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_BROADCAST: /* Permits sending of broadcast messages */
|
||||||
case SO_DEBUG: /* Enables recording of debugging information */
|
case SO_DEBUG: /* Enables recording of debugging information */
|
||||||
case SO_DONTROUTE: /* Requests outgoing messages bypass standard routing */
|
case SO_DONTROUTE: /* Requests outgoing messages bypass standard routing */
|
||||||
#ifndef CONFIG_NET_TCPPROTO_OPTIONS
|
|
||||||
case SO_KEEPALIVE: /* Verifies TCP connections active by enabling the
|
case SO_KEEPALIVE: /* Verifies TCP connections active by enabling the
|
||||||
* periodic transmission of probes */
|
* periodic transmission of probes */
|
||||||
#endif
|
|
||||||
case SO_OOBINLINE: /* Leaves received out-of-band data inline */
|
case SO_OOBINLINE: /* Leaves received out-of-band data inline */
|
||||||
case SO_REUSEADDR: /* Allow reuse of local addresses */
|
case SO_REUSEADDR: /* Allow reuse of local addresses */
|
||||||
{
|
{
|
||||||
|
|
@ -201,23 +174,6 @@ static int psock_socketlevel_option(FAR struct socket *psock, int option,
|
||||||
}
|
}
|
||||||
break;
|
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 */
|
case SO_TYPE: /* Reports the socket type */
|
||||||
{
|
{
|
||||||
/* Verify that option is the size of an 'int'. Should also check
|
/* 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;
|
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:
|
default:
|
||||||
return -ENOPROTOOPT;
|
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,
|
int psock_getsockopt(FAR struct socket *psock, int level, int option,
|
||||||
FAR void *value, FAR socklen_t *value_len)
|
FAR void *value, FAR socklen_t *value_len)
|
||||||
{
|
{
|
||||||
int ret;
|
int ret = -ENOPROTOOPT;
|
||||||
|
|
||||||
/* Verify that the sockfd corresponds to valid, allocated socket */
|
/* 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;
|
return -EBADF;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Handle retrieval of the socket option according to the level at which
|
/* Perform the socket interface operation */
|
||||||
* option should be applied.
|
|
||||||
*/
|
|
||||||
|
|
||||||
switch (level)
|
if (psock->s_sockif->si_getsockopt != NULL)
|
||||||
{
|
{
|
||||||
case SOL_SOCKET: /* Socket-level options (see include/sys/socket.h) */
|
ret = psock->s_sockif->si_getsockopt(psock, level, option,
|
||||||
ret = psock_socketlevel_option(psock, option, value, value_len);
|
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;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef CONFIG_NET_USRSOCK
|
/* Try socket level if the socket interface operation is not available */
|
||||||
/* Try usrsock further if the protocol not available */
|
|
||||||
|
|
||||||
if (ret == -ENOPROTOOPT && psock->s_type == SOCK_USRSOCK_TYPE)
|
if (ret == -ENOPROTOOPT && level == SOL_SOCKET)
|
||||||
{
|
{
|
||||||
ret = usrsock_getsockopt(psock->s_conn, level,
|
ret = psock_socketlevel_option(psock, option, value, value_len);
|
||||||
option, value, value_len);
|
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -34,15 +34,11 @@
|
||||||
#include <arch/irq.h>
|
#include <arch/irq.h>
|
||||||
|
|
||||||
#include <nuttx/net/net.h>
|
#include <nuttx/net/net.h>
|
||||||
|
#include <nuttx/net/netdev.h>
|
||||||
#include <netdev/netdev.h>
|
#include <netdev/netdev.h>
|
||||||
|
|
||||||
#include "socket/socket.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 "utils/utils.h"
|
||||||
#include "can/can.h"
|
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
* Public Functions
|
* Public Functions
|
||||||
|
|
@ -134,27 +130,14 @@ static int psock_socketlevel_option(FAR struct socket *psock, int option,
|
||||||
{
|
{
|
||||||
_SO_SETOPT(conn->s_options, option);
|
_SO_SETOPT(conn->s_options, option);
|
||||||
}
|
}
|
||||||
|
|
||||||
return OK;
|
|
||||||
}
|
}
|
||||||
}
|
break;
|
||||||
|
|
||||||
#ifdef CONFIG_NET_USRSOCK
|
|
||||||
if (psock->s_type == SOCK_USRSOCK_TYPE)
|
|
||||||
{
|
|
||||||
return -ENOPROTOOPT;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
switch (option)
|
|
||||||
{
|
|
||||||
case SO_BROADCAST: /* Permits sending of broadcast messages */
|
case SO_BROADCAST: /* Permits sending of broadcast messages */
|
||||||
case SO_DEBUG: /* Enables recording of debugging information */
|
case SO_DEBUG: /* Enables recording of debugging information */
|
||||||
case SO_DONTROUTE: /* Requests outgoing messages bypass standard routing */
|
case SO_DONTROUTE: /* Requests outgoing messages bypass standard routing */
|
||||||
#ifndef CONFIG_NET_TCPPROTO_OPTIONS
|
|
||||||
case SO_KEEPALIVE: /* Verifies TCP connections active by enabling the
|
case SO_KEEPALIVE: /* Verifies TCP connections active by enabling the
|
||||||
* periodic transmission of probes */
|
* periodic transmission of probes */
|
||||||
#endif
|
|
||||||
case SO_OOBINLINE: /* Leaves received out-of-band data inline */
|
case SO_OOBINLINE: /* Leaves received out-of-band data inline */
|
||||||
case SO_REUSEADDR: /* Allow reuse of local addresses */
|
case SO_REUSEADDR: /* Allow reuse of local addresses */
|
||||||
{
|
{
|
||||||
|
|
@ -194,212 +177,6 @@ static int psock_socketlevel_option(FAR struct socket *psock, int option,
|
||||||
}
|
}
|
||||||
break;
|
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
|
#ifdef CONFIG_NET_BINDTODEVICE
|
||||||
/* Handle the SO_BINDTODEVICE socket-level option.
|
/* 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,
|
int psock_setsockopt(FAR struct socket *psock, int level, int option,
|
||||||
FAR const void *value, socklen_t value_len)
|
FAR const void *value, socklen_t value_len)
|
||||||
{
|
{
|
||||||
int ret;
|
int ret = -ENOPROTOOPT;
|
||||||
|
|
||||||
/* Verify that the sockfd corresponds to valid, allocated socket */
|
/* 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;
|
return -EBADF;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Handle setting of the socket option according to the level at which
|
/* Perform the socket interface operation */
|
||||||
* option should be applied.
|
|
||||||
*/
|
|
||||||
|
|
||||||
switch (level)
|
if (psock->s_sockif->si_setsockopt != NULL)
|
||||||
{
|
{
|
||||||
case SOL_SOCKET: /* Socket-level options (see include/sys/socket.h) */
|
ret = psock->s_sockif->si_setsockopt(psock, level, option,
|
||||||
ret = psock_socketlevel_option(psock, option, value, value_len);
|
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;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef CONFIG_NET_USRSOCK
|
/* Try socket level if the socket interface operation is not available */
|
||||||
/* Try usrsock further if the protocol not available */
|
|
||||||
|
|
||||||
if (ret == -ENOPROTOOPT && psock->s_type == SOCK_USRSOCK_TYPE)
|
if (ret == -ENOPROTOOPT && level == SOL_SOCKET)
|
||||||
{
|
{
|
||||||
ret = usrsock_setsockopt(psock->s_conn, level,
|
ret = psock_socketlevel_option(psock, option, value, value_len);
|
||||||
option, value, value_len);
|
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -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.
|
* See <sys/socket.h> a complete list of values for the 'option' argument.
|
||||||
*
|
*
|
||||||
* Input Parameters:
|
* Input Parameters:
|
||||||
* conn usrsock socket connection structure
|
* psock Socket structure of the socket to query
|
||||||
* level Protocol level to set the option
|
* level Protocol level to set the option
|
||||||
* option identifies the option to get
|
* option identifies the option to get
|
||||||
* value Points to the argument value
|
* 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 usrsock_getsockopt(FAR struct socket *psock, int level, int option,
|
||||||
int option, FAR void *value,
|
FAR void *value, FAR socklen_t *value_len);
|
||||||
FAR socklen_t *value_len);
|
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
* Name: usrsock_setsockopt
|
* 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.
|
* See <sys/socket.h> a complete list of values for the 'option' argument.
|
||||||
*
|
*
|
||||||
* Input Parameters:
|
* Input Parameters:
|
||||||
* conn usrsock socket connection structure
|
* psock Socket structure of the socket to query
|
||||||
* level Protocol level to set the option
|
* level Protocol level to set the option
|
||||||
* option identifies the option to set
|
* option identifies the option to set
|
||||||
* value Points to the argument value
|
* 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 usrsock_setsockopt(FAR struct socket *psock, int level, int option,
|
||||||
int option, FAR const void *value,
|
FAR const void *value, socklen_t value_len);
|
||||||
FAR socklen_t value_len);
|
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
* Name: usrsock_getsockname
|
* Name: usrsock_getsockname
|
||||||
|
|
|
||||||
|
|
@ -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.
|
* See <sys/socket.h> a complete list of values for the 'option' argument.
|
||||||
*
|
*
|
||||||
* Input Parameters:
|
* Input Parameters:
|
||||||
* conn usrsock socket connection structure
|
* psock Socket structure of the socket to query
|
||||||
* level Protocol level to set the option
|
* level Protocol level to set the option
|
||||||
* option identifies the option to get
|
* option identifies the option to get
|
||||||
* value Points to the argument value
|
* 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 usrsock_getsockopt(FAR struct socket *psock, int level, int option,
|
||||||
int level, int option,
|
|
||||||
FAR void *value, FAR socklen_t *value_len)
|
FAR void *value, FAR socklen_t *value_len)
|
||||||
{
|
{
|
||||||
|
FAR struct usrsock_conn_s *conn = psock->s_conn;
|
||||||
struct usrsock_data_reqstate_s state =
|
struct usrsock_data_reqstate_s state =
|
||||||
{
|
{
|
||||||
};
|
};
|
||||||
|
|
@ -179,6 +179,22 @@ int usrsock_getsockopt(FAR struct usrsock_conn_s *conn,
|
||||||
struct iovec inbufs[1];
|
struct iovec inbufs[1];
|
||||||
int ret;
|
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();
|
net_lock();
|
||||||
|
|
||||||
if (conn->state == USRSOCK_CONN_STATE_UNINITIALIZED ||
|
if (conn->state == USRSOCK_CONN_STATE_UNINITIALIZED ||
|
||||||
|
|
|
||||||
|
|
@ -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.
|
* See <sys/socket.h> a complete list of values for the 'option' argument.
|
||||||
*
|
*
|
||||||
* Input Parameters:
|
* Input Parameters:
|
||||||
* conn usrsock socket connection structure
|
* psock Socket structure of the socket to query
|
||||||
* level Protocol level to set the option
|
* level Protocol level to set the option
|
||||||
* option identifies the option to set
|
* option identifies the option to set
|
||||||
* value Points to the argument value
|
* 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 usrsock_setsockopt(FAR struct socket *psock, int level, int option,
|
||||||
int level, int option,
|
FAR const void *value, socklen_t value_len)
|
||||||
FAR const void *value, FAR socklen_t value_len)
|
|
||||||
{
|
{
|
||||||
|
FAR struct usrsock_conn_s *conn = psock->s_conn;
|
||||||
struct usrsock_reqstate_s state =
|
struct usrsock_reqstate_s state =
|
||||||
{
|
{
|
||||||
};
|
};
|
||||||
|
|
@ -168,6 +168,18 @@ int usrsock_setsockopt(FAR struct usrsock_conn_s *conn,
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
DEBUGASSERT(conn);
|
DEBUGASSERT(conn);
|
||||||
|
if (level == SOL_SOCKET)
|
||||||
|
{
|
||||||
|
if (option == SO_RCVTIMEO || option == SO_SNDTIMEO)
|
||||||
|
{
|
||||||
|
return -ENOPROTOOPT;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
net_lock();
|
net_lock();
|
||||||
|
|
||||||
if (conn->state == USRSOCK_CONN_STATE_UNINITIALIZED ||
|
if (conn->state == USRSOCK_CONN_STATE_UNINITIALIZED ||
|
||||||
|
|
|
||||||
|
|
@ -66,7 +66,12 @@ const struct sock_intf_s g_usrsock_sockif =
|
||||||
usrsock_sendmsg, /* si_sendmsg */
|
usrsock_sendmsg, /* si_sendmsg */
|
||||||
usrsock_recvmsg, /* si_recvmsg */
|
usrsock_recvmsg, /* si_recvmsg */
|
||||||
usrsock_sockif_close, /* si_close */
|
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
|
||||||
};
|
};
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue