diff --git a/net/socket/getsockopt.c b/net/socket/getsockopt.c index 11932ba1b8..f6c5862b23 100644 --- a/net/socket/getsockopt.c +++ b/net/socket/getsockopt.c @@ -103,37 +103,47 @@ static int psock_socketlevel_option(FAR struct socket *psock, int option, return -EINVAL; } -#ifdef CONFIG_NET_USRSOCK - if (psock->s_type == SOCK_USRSOCK_TYPE) - { - FAR struct usrsock_conn_s *conn = psock->s_conn; - - DEBUGASSERT(conn); - - /* Some of the socket options are handled from this function. */ - - switch (option) - { - case SO_TYPE: /* Type can be read from NuttX psock structure. */ - case SO_RCVTIMEO: /* Rx timeouts can be handled at NuttX side, thus - * simplify daemon implementation. */ - case SO_SNDTIMEO: /* Rx timeouts can be handled at NuttX side, thus - * simplify daemon implementation. */ - break; - - default: /* Other options are passed to usrsock daemon. */ - { - return usrsock_getsockopt(conn, SOL_SOCKET, - option, value, value_len); - } - } - } -#endif - /* Process the option */ switch (option) { + /* The following are valid only if the OS CLOCK feature is enabled */ + + case SO_RCVTIMEO: + case SO_SNDTIMEO: + { + socktimeo_t timeo; + + /* Verify that option is the size of an 'int'. Should also check + * that 'value' is properly aligned for an 'int' + */ + + if (*value_len < sizeof(struct timeval)) + { + return -EINVAL; + } + + /* Get the timeout value. This is a atomic operation and should + * require no special operation. + */ + + if (option == SO_RCVTIMEO) + { + timeo = psock->s_rcvtimeo; + } + else + { + timeo = psock->s_sndtimeo; + } + + /* Then return the timeout value to the caller */ + + net_dsec2timeval(timeo, (struct timeval *)value); + *value_len = sizeof(struct timeval); + } + break; + +#ifndef CONFIG_NET_USRSOCK case SO_ACCEPTCONN: /* Reports whether socket listening is enabled */ if (*value_len < sizeof(int)) { @@ -231,42 +241,6 @@ static int psock_socketlevel_option(FAR struct socket *psock, int option, } break; - /* The following are valid only if the OS CLOCK feature is enabled */ - - case SO_RCVTIMEO: - case SO_SNDTIMEO: - { - socktimeo_t timeo; - - /* Verify that option is the size of an 'int'. Should also check - * that 'value' is properly aligned for an 'int' - */ - - if (*value_len < sizeof(struct timeval)) - { - return -EINVAL; - } - - /* Get the timeout value. This is a atomic operation and should - * require no special operation. - */ - - if (option == SO_RCVTIMEO) - { - timeo = psock->s_rcvtimeo; - } - else - { - timeo = psock->s_sndtimeo; - } - - /* Then return the timeout value to the caller */ - - net_dsec2timeval(timeo, (struct timeval *)value); - *value_len = sizeof(struct timeval); - } - break; - case SO_ERROR: /* Reports and clears error status. */ { if (*value_len != sizeof(int)) @@ -301,6 +275,7 @@ static int psock_socketlevel_option(FAR struct socket *psock, int option, case SO_RCVLOWAT: /* Sets the minimum number of bytes to input */ case SO_SNDBUF: /* Sets send buffer size */ case SO_SNDLOWAT: /* Sets the minimum number of bytes to output */ +#endif default: return -ENOPROTOOPT; @@ -360,7 +335,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 = OK; + int ret; /* Verify that the sockfd corresponds to valid, allocated socket */ @@ -403,6 +378,16 @@ int psock_getsockopt(FAR struct socket *psock, int level, int option, break; } +#ifdef CONFIG_NET_USRSOCK + /* Try usrsock further if the protocol not available */ + + if (ret == -ENOPROTOOPT && psock->s_type == SOCK_USRSOCK_TYPE) + { + ret = usrsock_getsockopt(psock->s_conn, level, + option, value, value_len); + } +#endif + return ret; } diff --git a/net/socket/setsockopt.c b/net/socket/setsockopt.c index bddd9c6414..74e62a422a 100644 --- a/net/socket/setsockopt.c +++ b/net/socket/setsockopt.c @@ -98,32 +98,6 @@ static int psock_socketlevel_option(FAR struct socket *psock, int option, return -EINVAL; } -#ifdef CONFIG_NET_USRSOCK - if (psock->s_type == SOCK_USRSOCK_TYPE) - { - FAR struct usrsock_conn_s *conn = psock->s_conn; - - DEBUGASSERT(conn); - - /* Some of the socket options are handled from this function. */ - - switch (option) - { - case SO_RCVTIMEO: /* Rx timeouts can be handled at NuttX side, thus - * simplify daemon implementation. */ - case SO_SNDTIMEO: /* Rx timeouts can be handled at NuttX side, thus - * simplify daemon implementation. */ - break; - - default: /* Other options are passed to usrsock daemon. */ - { - return usrsock_setsockopt(conn, SOL_SOCKET, option, value, - value_len); - } - } - } -#endif - /* Process the option */ switch (option) @@ -133,6 +107,51 @@ static int psock_socketlevel_option(FAR struct socket *psock, int option, * is outside of the scope of setsockopt. */ + case SO_RCVTIMEO: + case SO_SNDTIMEO: + { + FAR struct timeval *tv = (FAR struct timeval *)value; + socktimeo_t timeo; + + /* Verify that option is the size of an 'struct timeval'. */ + + if (tv == NULL || value_len != sizeof(struct timeval)) + { + return -EINVAL; + } + + /* Get the timeout value. Any microsecond remainder will be + * forced to the next larger, whole decisecond value. + */ + + timeo = (socktimeo_t)net_timeval2dsec(tv, TV2DS_CEIL); + + /* Save the timeout value */ + + if (option == SO_RCVTIMEO) + { + psock->s_rcvtimeo = timeo; + } + else + { + psock->s_sndtimeo = timeo; + } + + /* Set/clear the corresponding enable/disable bit */ + + if (timeo) + { + _SO_CLROPT(psock->s_options, option); + } + else + { + _SO_SETOPT(psock->s_options, option); + } + } + break; + +#ifndef CONFIG_NET_USRSOCK + 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 */ @@ -196,49 +215,6 @@ static int psock_socketlevel_option(FAR struct socket *psock, int option, return tcp_setsockopt(psock, option, value, value_len); #endif - case SO_RCVTIMEO: - case SO_SNDTIMEO: - { - FAR struct timeval *tv = (FAR struct timeval *)value; - socktimeo_t timeo; - - /* Verify that option is the size of an 'struct timeval'. */ - - if (tv == NULL || value_len != sizeof(struct timeval)) - { - return -EINVAL; - } - - /* Get the timeout value. Any microsecond remainder will be - * forced to the next larger, whole decisecond value. - */ - - timeo = (socktimeo_t)net_timeval2dsec(tv, TV2DS_CEIL); - - /* Save the timeout value */ - - if (option == SO_RCVTIMEO) - { - psock->s_rcvtimeo = timeo; - } - else - { - psock->s_sndtimeo = timeo; - } - - /* Set/clear the corresponding enable/disable bit */ - - if (timeo) - { - _SO_CLROPT(psock->s_options, option); - } - else - { - _SO_SETOPT(psock->s_options, option); - } - } - break; - #ifdef CONFIG_NET_SOLINGER case SO_LINGER: /* Lingers on a close() if data is present */ { @@ -316,6 +292,7 @@ static int psock_socketlevel_option(FAR struct socket *psock, int option, case SO_ERROR: /* Reports and clears error status. */ case SO_TYPE: /* Reports the socket type */ +#endif default: return -ENOPROTOOPT; } @@ -434,6 +411,16 @@ int psock_setsockopt(FAR struct socket *psock, int level, int option, break; } +#ifdef CONFIG_NET_USRSOCK + /* Try usrsock further if the protocol not available */ + + if (ret == -ENOPROTOOPT && psock->s_type == SOCK_USRSOCK_TYPE) + { + ret = usrsock_setsockopt(psock->s_conn, level, + option, value, value_len); + } +#endif + return ret; }