net/can: Save simple options to socket_conn_s

like other protocols(e.g. ip, tcp, udp)

Signed-off-by: Xiang Xiao <xiaoxiang@xiaomi.com>
This commit is contained in:
Xiang Xiao 2024-04-07 00:24:50 +08:00 committed by Xiang Xiao
parent 83455a3fa1
commit 8ea51b3efc
8 changed files with 67 additions and 170 deletions

View file

@ -104,22 +104,11 @@ struct can_conn_s
struct can_poll_s pollinfo[4]; /* FIXME make dynamic */
#ifdef CONFIG_NET_CANPROTO_OPTIONS
int32_t loopback;
int32_t recv_own_msgs;
# ifdef CONFIG_NET_CAN_CANFD
int32_t fd_frames;
# endif
struct can_filter filters[CONFIG_NET_CAN_RAW_FILTER_MAX];
int32_t filter_count;
# ifdef CONFIG_NET_CAN_ERRORS
can_err_mask_t err_mask;
# endif
# ifdef CONFIG_NET_CAN_RAW_TX_DEADLINE
int32_t tx_deadline;
# endif
#endif
#ifdef CONFIG_NET_TIMESTAMP
int32_t timestamp; /* Socket timestamp enabled/disabled */
#endif
};

View file

@ -140,7 +140,7 @@ uint16_t can_callback(FAR struct net_driver_s *dev,
* create timestamp and copy to iob
*/
if (conn->timestamp)
if (_SO_GETOPT(conn->sconn.s_options, SO_TIMESTAMP))
{
struct timeval tv;
FAR struct timespec *ts = (FAR struct timespec *)&tv;

View file

@ -83,19 +83,6 @@ int can_getsockopt(FAR struct socket *psock, int level, int option,
DEBUGASSERT(value != NULL && value_len != NULL);
conn = 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;
@ -140,8 +127,8 @@ int can_getsockopt(FAR struct socket *psock, int level, int option,
}
break;
case CAN_RAW_ERR_FILTER:
#ifdef CONFIG_NET_CAN_ERRORS
case CAN_RAW_ERR_FILTER:
if (*value_len < sizeof(can_err_mask_t))
{
return -EINVAL;
@ -152,87 +139,35 @@ int can_getsockopt(FAR struct socket *psock, int level, int option,
*mask = conn->err_mask;
*value_len = sizeof(can_err_mask_t);
}
#endif
break;
#endif
case CAN_RAW_LOOPBACK:
if (*value_len < sizeof(conn->loopback))
{
/* REVISIT: POSIX says that we should truncate the value if it
* is larger than value_len. That just doesn't make sense
* to me in this case.
*/
ret = -EINVAL;
}
else
{
FAR int32_t *loopback = (FAR int32_t *)value;
*loopback = conn->loopback;
*value_len = sizeof(conn->loopback);
}
break;
case CAN_RAW_RECV_OWN_MSGS:
if (*value_len < sizeof(conn->recv_own_msgs))
{
/* REVISIT: POSIX says that we should truncate the value if it
* is larger than value_len. That just doesn't make sense
* to me in this case.
*/
ret = -EINVAL;
}
else
{
FAR int32_t *recv_own_msgs = (FAR int32_t *)value;
*recv_own_msgs = conn->recv_own_msgs;
*value_len = sizeof(conn->recv_own_msgs);
}
break;
#ifdef CONFIG_NET_CAN_CANFD
case CAN_RAW_FD_FRAMES:
if (*value_len < sizeof(conn->fd_frames))
{
/* REVISIT: POSIX says that we should truncate the value if it
* is larger than value_len. That just doesn't make sense
* to me in this case.
*/
ret = -EINVAL;
}
else
{
FAR int32_t *fd_frames = (FAR int32_t *)value;
*fd_frames = conn->fd_frames;
*value_len = sizeof(conn->fd_frames);
}
break;
#endif
case CAN_RAW_JOIN_FILTERS:
break;
#ifdef CONFIG_NET_CAN_RAW_TX_DEADLINE
case CAN_RAW_TX_DEADLINE:
if (*value_len < sizeof(conn->tx_deadline))
{
/* REVISIT: POSIX says that we should truncate the value if it
* is larger than value_len. That just doesn't make sense
* to me in this case.
*/
ret = -EINVAL;
}
else
{
FAR int32_t *tx_deadline = (FAR int32_t *)value;
*tx_deadline = conn->tx_deadline;
*value_len = sizeof(conn->tx_deadline);
}
break;
#endif
/* 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;
}
/* Sample the current options. This is atomic operation and so
* should not require any special steps for thread safety. We
* this outside of the macro because you can never be sure what
* a macro will do.
*/
*(FAR int *)value = _SO_GETOPT(conn->sconn.s_options, option);
*value_len = sizeof(int);
break;
#if CONFIG_NET_RECV_BUFSIZE > 0
case SO_RCVBUF:

View file

@ -131,9 +131,10 @@ static size_t can_recvfrom_newdata(FAR struct net_driver_s *dev,
{
unsigned int offset;
size_t recvlen;
#ifdef CONFIG_NET_TIMESTAMP
if (pstate->pr_conn->timestamp &&
FAR struct can_conn_s *conn = pstate->pr_conn;
if (_SO_GETOPT(conn->sconn.s_options, SO_TIMESTAMP) &&
pstate->pr_msglen == sizeof(struct timeval))
{
iob_copyout(pstate->pr_msgbuf, dev->d_iob, sizeof(struct timeval),
@ -266,7 +267,8 @@ static inline int can_readahead(struct can_recvfrom_s *pstate)
#endif
#ifdef CONFIG_NET_TIMESTAMP
if (conn->timestamp && pstate->pr_msglen == sizeof(struct timeval))
if (_SO_GETOPT(conn->sconn.s_options, SO_TIMESTAMP) &&
pstate->pr_msglen == sizeof(struct timeval))
{
iob_copyout(pstate->pr_msgbuf, iob, sizeof(struct timeval),
-CONFIG_NET_LL_GUARDSIZE);
@ -313,7 +315,7 @@ static inline int can_readahead(struct can_recvfrom_s *pstate)
/* do not pass frames with DLC > 8 to a legacy socket */
#if defined(CONFIG_NET_CANPROTO_OPTIONS) && defined(CONFIG_NET_CAN_CANFD)
if (!conn->fd_frames)
if (!_SO_GETOPT(conn->sconn.s_options, CAN_RAW_FD_FRAMES))
#endif
{
if (recvlen > sizeof(struct can_frame))
@ -398,14 +400,15 @@ static uint16_t can_recvfrom_eventhandler(FAR struct net_driver_s *dev,
/* do not pass frames with DLC > 8 to a legacy socket */
#if defined(CONFIG_NET_CANPROTO_OPTIONS) && defined(CONFIG_NET_CAN_CANFD)
if (!conn->fd_frames)
if (!_SO_GETOPT(conn->sconn.s_options, CAN_RAW_FD_FRAMES))
#endif
{
#ifdef CONFIG_NET_TIMESTAMP
if ((conn->timestamp && (dev->d_len >
sizeof(struct can_frame) + sizeof(struct timeval)))
|| (!conn->timestamp && (dev->d_len >
sizeof(struct can_frame))))
if ((_SO_GETOPT(conn->sconn.s_options, SO_TIMESTAMP) &&
dev->d_len > sizeof(struct can_frame) +
sizeof(struct timeval)) ||
(!_SO_GETOPT(conn->sconn.s_options, SO_TIMESTAMP) &&
dev->d_len > sizeof(struct can_frame)))
#else
if (dev->d_len > sizeof(struct can_frame))
#endif
@ -534,7 +537,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->timestamp)
if (_SO_GETOPT(conn->sconn.s_options, SO_TIMESTAMP))
{
state.pr_msgbuf = cmsg_append(msg, SOL_SOCKET, SO_TIMESTAMP,
NULL, sizeof(struct timeval));

View file

@ -202,7 +202,7 @@ ssize_t can_sendmsg(FAR struct socket *psock, FAR struct msghdr *msg,
}
#if defined(CONFIG_NET_CANPROTO_OPTIONS) && defined(CONFIG_NET_CAN_CANFD)
if (conn->fd_frames)
if (_SO_GETOPT(conn->sconn.s_options, CAN_RAW_FD_FRAMES))
{
if (msg->msg_iov->iov_len != CANFD_MTU &&
msg->msg_iov->iov_len != CAN_MTU)
@ -236,7 +236,7 @@ ssize_t can_sendmsg(FAR struct socket *psock, FAR struct msghdr *msg,
if (msg->msg_controllen > sizeof(struct cmsghdr))
{
FAR struct cmsghdr *cmsg = CMSG_FIRSTHDR(msg);
if (conn->tx_deadline &&
if (_SO_GETOPT(conn->sconn.s_options, CAN_RAW_TX_DEADLINE) &&
cmsg->cmsg_level == SOL_CAN_RAW &&
cmsg->cmsg_type == CAN_RAW_TX_DEADLINE &&
cmsg->cmsg_len == sizeof(struct timeval))

View file

@ -81,32 +81,6 @@ int can_setsockopt(FAR struct socket *psock, int level, int option,
conn = 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;
@ -152,63 +126,53 @@ int can_setsockopt(FAR struct socket *psock, int level, int option,
}
break;
case CAN_RAW_ERR_FILTER:
#ifdef CONFIG_NET_CAN_ERRORS
case CAN_RAW_ERR_FILTER:
if (value_len != sizeof(can_err_mask_t))
{
return -EINVAL;
}
conn->err_mask = *(FAR can_err_mask_t *)value & CAN_ERR_MASK;
#endif
break;
#endif
case CAN_RAW_LOOPBACK:
if (value_len != sizeof(conn->loopback))
{
return -EINVAL;
}
conn->loopback = *(FAR int32_t *)value;
break;
case CAN_RAW_RECV_OWN_MSGS:
if (value_len != sizeof(conn->recv_own_msgs))
{
return -EINVAL;
}
conn->recv_own_msgs = *(FAR int32_t *)value;
break;
#ifdef CONFIG_NET_CAN_CANFD
case CAN_RAW_FD_FRAMES:
if (value_len != sizeof(conn->fd_frames))
{
return -EINVAL;
}
conn->fd_frames = *(FAR int32_t *)value;
break;
#endif
case CAN_RAW_JOIN_FILTERS:
break;
#ifdef CONFIG_NET_CAN_RAW_TX_DEADLINE
case CAN_RAW_TX_DEADLINE:
if (value_len != sizeof(conn->tx_deadline))
#endif
/* 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;
}
conn->tx_deadline = *(FAR int32_t *)value;
/* Lock the network so that we have exclusive access to the socket
* options.
*/
net_lock();
/* Set or clear the option bit */
if (*(FAR int *)value)
{
_SO_SETOPT(conn->sconn.s_options, option);
}
else
{
_SO_CLROPT(conn->sconn.s_options, option);
}
net_unlock();
break;
#endif
#if CONFIG_NET_RECV_BUFSIZE > 0
case SO_RCVBUF:

View file

@ -154,6 +154,9 @@ static int psock_socketlevel_option(FAR struct socket *psock, int option,
* periodic transmission of probes */
case SO_OOBINLINE: /* Leaves received out-of-band data inline */
case SO_REUSEADDR: /* Allow reuse of local addresses */
#ifdef CONFIG_NET_TIMESTAMP
case SO_TIMESTAMP: /* Generates a timestamp for each incoming packet */
#endif
{
sockopt_t optionset;

View file

@ -137,6 +137,9 @@ static int psock_socketlevel_option(FAR struct socket *psock, int option,
* periodic transmission of probes */
case SO_OOBINLINE: /* Leaves received out-of-band data inline */
case SO_REUSEADDR: /* Allow reuse of local addresses */
#ifdef CONFIG_NET_TIMESTAMP
case SO_TIMESTAMP: /* Generates a timestamp for each incoming packet */
#endif
{
int setting;