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:
parent
83455a3fa1
commit
8ea51b3efc
8 changed files with 67 additions and 170 deletions
|
|
@ -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
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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:
|
||||
|
|
|
|||
|
|
@ -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));
|
||||
|
|
|
|||
|
|
@ -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))
|
||||
|
|
|
|||
|
|
@ -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:
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue