This is an automated email from the ASF dual-hosted git repository. xiaoxiang781216 pushed a commit to branch master in repository https://gitbox.apache.org/repos/asf/nuttx.git
commit c6878db03188169e847f67f10dabc75057e0b2d4 Author: OceanfromXiaomi <[email protected]> AuthorDate: Thu Nov 27 12:03:31 2025 +0800 net/utils: extract cmsg_store_timestamp helper Extract a common cmsg_store_timestamp() helper that checks SO_TIMESTAMP/SO_TIMESTAMPNS via s_options and appends the appropriate cmsg. Replaces per-protocol timestamp formatting in CAN, PKT, and UDP receive paths. Signed-off-by: OceanfromXiaomi <[email protected]> --- net/can/can_recvmsg.c | 106 +++++++++++++++++++++++-------------------------- net/pkt/pkt_recvmsg.c | 60 ++-------------------------- net/udp/udp_recvfrom.c | 19 ++------- net/utils/net_cmsg.c | 37 ++++++++++++++++- net/utils/utils.h | 22 +++++++++- 5 files changed, 114 insertions(+), 130 deletions(-) diff --git a/net/can/can_recvmsg.c b/net/can/can_recvmsg.c index 82fdb3a1f51..8dd4879ab3c 100644 --- a/net/can/can_recvmsg.c +++ b/net/can/can_recvmsg.c @@ -63,12 +63,9 @@ struct can_recvfrom_s { FAR struct can_conn_s *pr_conn; /* Connection associated with the socket */ FAR struct devif_callback_s *pr_cb; /* Reference to callback instance */ + FAR struct msghdr *pr_msg; /* Pointer to receive buffer */ sem_t pr_sem; /* Semaphore signals recv completion */ - size_t pr_buflen; /* Length of receive buffer */ - FAR uint8_t *pr_buffer; /* Pointer to receive buffer */ ssize_t pr_recvlen; /* The received length */ - size_t pr_msglen; /* Length of msg buffer */ - FAR uint8_t *pr_msgbuf; /* Pointer to msg buffer */ int pr_result; /* Success:OK, failure:negated errno */ }; @@ -76,6 +73,37 @@ struct can_recvfrom_s * Private Functions ****************************************************************************/ +/**************************************************************************** + * Name: can_recvfrom_initialize + * + * Description: + * Initialize the state structure + * + * Input Parameters: + * conn The CAN connection of interest + * msg Receive info and buffer for receive data + * pstate A pointer to the state structure to be initialized + * + * Returned Value: + * None + * + * Assumptions: + * + ****************************************************************************/ + +static void can_recvfrom_initialize(FAR struct can_conn_s *conn, + FAR struct msghdr *msg, + FAR struct can_recvfrom_s *pstate) +{ + /* Initialize the state structure. */ + + memset(pstate, 0, sizeof(struct can_recvfrom_s)); + nxsem_init(&pstate->pr_sem, 0, 0); + + pstate->pr_conn = conn; + pstate->pr_msg = msg; +} + /**************************************************************************** * Name: can_add_recvlen * @@ -102,8 +130,6 @@ static inline void can_add_recvlen(FAR struct can_recvfrom_s *pstate, } pstate->pr_recvlen += recvlen; - pstate->pr_buffer += recvlen; - pstate->pr_buflen -= recvlen; } /**************************************************************************** @@ -129,34 +155,20 @@ static size_t can_recvfrom_newdata(FAR struct net_driver_s *dev, { unsigned int offset; size_t recvlen; -#ifdef CONFIG_NET_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)) - { - struct timeval tv; - - tv.tv_sec = dev->d_iob->io_time.tv_sec; - tv.tv_usec = dev->d_iob->io_time.tv_nsec / 1000; - memcpy(pstate->pr_msgbuf, &tv, sizeof(struct timeval)); - } +#ifdef CONFIG_NET_TIMESTAMP + cmsg_store_timestamp(pstate->pr_msg, &dev->d_iob->io_time, + pstate->pr_conn->sconn.s_options); #endif - if (dev->d_len > pstate->pr_buflen) - { - recvlen = pstate->pr_buflen; - } - else - { - recvlen = dev->d_len; - } + recvlen = MIN(pstate->pr_msg->msg_iov->iov_len, dev->d_len); /* Copy the new packet data into the user buffer */ offset = (dev->d_appdata - dev->d_iob->io_data) - dev->d_iob->io_offset; - recvlen = iob_copyout(pstate->pr_buffer, dev->d_iob, recvlen, offset); + recvlen = iob_copyout(pstate->pr_msg->msg_iov->iov_base, + dev->d_iob, recvlen, offset); /* Trim the copied buffers */ @@ -241,30 +253,28 @@ static inline int can_readahead(struct can_recvfrom_s *pstate) * buffer. */ - pstate->pr_recvlen = -1; + pstate->pr_recvlen = -ENODATA; - if (pstate->pr_buflen > 0 && + if (pstate->pr_msg->msg_iov->iov_len > 0 && (iob = iob_remove_queue(&conn->readahead)) != NULL) { DEBUGASSERT(iob->io_pktlen > 0); #ifdef CONFIG_NET_TIMESTAMP - if (_SO_GETOPT(conn->sconn.s_options, SO_TIMESTAMP) && - pstate->pr_msglen == sizeof(struct timeval)) - { - struct timeval tv; - - tv.tv_sec = iob->io_time.tv_sec; - tv.tv_usec = iob->io_time.tv_nsec / 1000; - memcpy(pstate->pr_msgbuf, &tv, sizeof(struct timeval)); - } + cmsg_store_timestamp(pstate->pr_msg, &iob->io_time, + conn->sconn.s_options); #endif /* Transfer that buffered data from the I/O buffer chain into * the user buffer. */ - recvlen = iob_copyout(pstate->pr_buffer, iob, pstate->pr_buflen, 0); + recvlen = iob_copyout(pstate->pr_msg->msg_iov->iov_base, + iob, pstate->pr_msg->msg_iov->iov_len, 0); + + /* Update the accumulated size of the data read */ + + pstate->pr_recvlen = recvlen; /* We should have taken all of the data from the I/O buffer chain, * so release it. There is no trimming needed, since One CAN/CANFD @@ -440,25 +450,7 @@ ssize_t can_recvmsg(FAR struct socket *psock, FAR struct msghdr *msg, /* Initialize the state structure. */ - memset(&state, 0, sizeof(struct can_recvfrom_s)); - nxsem_init(&state.pr_sem, 0, 0); /* Doesn't really fail */ - - state.pr_buflen = msg->msg_iov->iov_len; - state.pr_buffer = msg->msg_iov->iov_base; - -#ifdef CONFIG_NET_TIMESTAMP - if (_SO_GETOPT(conn->sconn.s_options, SO_TIMESTAMP)) - { - state.pr_msgbuf = cmsg_append(msg, SOL_SOCKET, SO_TIMESTAMP, - NULL, sizeof(struct timeval)); - if (state.pr_msgbuf != NULL) - { - state.pr_msglen = sizeof(struct timeval); - } - } -#endif - - state.pr_conn = conn; + can_recvfrom_initialize(conn, msg, &state); /* Handle any any CAN data already buffered in a read-ahead buffer. NOTE * that there may be read-ahead data to be retrieved even after the diff --git a/net/pkt/pkt_recvmsg.c b/net/pkt/pkt_recvmsg.c index 79489a9ca49..f3f675eddbe 100644 --- a/net/pkt/pkt_recvmsg.c +++ b/net/pkt/pkt_recvmsg.c @@ -65,46 +65,6 @@ struct pkt_recvfrom_s uint8_t pr_type; /* Protocol type */ }; -/**************************************************************************** - * Private Functions - ****************************************************************************/ - -/**************************************************************************** - * Name: pkt_store_cmsg_timestamp - * - * Description: - * Store the timestamp in the cmsg - * - * Input Parameters: - * pstate Recicve state information - * timestamp Timestamp information - * - * Returned Value: - * None - * - ****************************************************************************/ - -#ifdef CONFIG_NET_TIMESTAMP -static void pkt_store_cmsg_timestamp(FAR struct pkt_recvfrom_s *pstate, - FAR struct timespec *timestamp) -{ - FAR struct msghdr *msg = pstate->pr_msg; - struct timeval tv; - - if (_SO_GETOPT(pstate->pr_conn->sconn.s_options, SO_TIMESTAMPNS)) - { - cmsg_append(msg, SOL_SOCKET, SO_TIMESTAMPNS, timestamp, - sizeof(struct timespec)); - } - else - { - TIMESPEC_TO_TIMEVAL(&tv, timestamp); - cmsg_append(msg, SOL_SOCKET, SO_TIMESTAMP, &tv, - sizeof(struct timeval)); - } -} -#endif - /**************************************************************************** * Name: pkt_add_recvlen * @@ -158,13 +118,8 @@ static void pkt_recvfrom_newdata(FAR struct net_driver_s *dev, size_t recvlen; #ifdef CONFIG_NET_TIMESTAMP - /* Unpack stored timestamp if SO_TIMESTAMP socket option is enabled */ - - if (_SO_GETOPT(pstate->pr_conn->sconn.s_options, SO_TIMESTAMP) || - _SO_GETOPT(pstate->pr_conn->sconn.s_options, SO_TIMESTAMPNS)) - { - pkt_store_cmsg_timestamp(pstate, &dev->d_iob->io_time); - } + cmsg_store_timestamp(pstate->pr_msg, &dev->d_iob->io_time, + pstate->pr_conn->sconn.s_options); #endif recvlen = MIN(pstate->pr_msg->msg_iov->iov_len, dev->d_len); @@ -385,15 +340,8 @@ static inline void pkt_readahead(FAR struct pkt_recvfrom_s *pstate) DEBUGASSERT(iob->io_pktlen > 0); #ifdef CONFIG_NET_TIMESTAMP - /* Unpack stored timestamp if SO_TIMESTAMP/SO_TIMESTAMPNS socket option - * is enabled - */ - - if (_SO_GETOPT(conn->sconn.s_options, SO_TIMESTAMP) || - _SO_GETOPT(conn->sconn.s_options, SO_TIMESTAMPNS)) - { - pkt_store_cmsg_timestamp(pstate, &iob->io_time); - } + cmsg_store_timestamp(pstate->pr_msg, &iob->io_time, + conn->sconn.s_options); #endif /* Copy to user */ diff --git a/net/udp/udp_recvfrom.c b/net/udp/udp_recvfrom.c index 3514069fd07..a7357d78b87 100644 --- a/net/udp/udp_recvfrom.c +++ b/net/udp/udp_recvfrom.c @@ -67,19 +67,6 @@ struct udp_recvfrom_s * Private Functions ****************************************************************************/ -#ifdef CONFIG_NET_TIMESTAMP -static void udp_store_cmsg_timestamp(FAR struct udp_recvfrom_s *pstate, - FAR struct timespec *timestamp) -{ - FAR struct msghdr *msg = pstate->ir_msg; - struct timeval tv; - - TIMESPEC_TO_TIMEVAL(&tv, timestamp); - cmsg_append(msg, SOL_SOCKET, SO_TIMESTAMP, - &tv, sizeof(struct timeval)); -} -#endif - #ifdef CONFIG_NET_SOCKOPTS static void udp_recvpktinfo(FAR struct udp_recvfrom_s *pstate, FAR void *srcaddr, uint8_t ifindex) @@ -224,7 +211,8 @@ static inline void udp_readahead(struct udp_recvfrom_s *pstate) if (conn->timestamp) { - udp_store_cmsg_timestamp(pstate, &iob->io_time); + cmsg_store_timestamp(pstate->ir_msg, &iob->io_time, + conn->sconn.s_options); } #endif @@ -465,7 +453,8 @@ static uint32_t udp_eventhandler(FAR struct net_driver_s *dev, #ifdef CONFIG_NET_TIMESTAMP if (pstate->ir_conn->timestamp) { - udp_store_cmsg_timestamp(pstate, &dev->d_iob->io_time); + cmsg_store_timestamp(pstate->ir_msg, &dev->d_iob->io_time, + pstate->ir_conn->sconn.s_options); } #endif diff --git a/net/utils/net_cmsg.c b/net/utils/net_cmsg.c index c36c989c3ce..0cbfb41bc2e 100644 --- a/net/utils/net_cmsg.c +++ b/net/utils/net_cmsg.c @@ -28,6 +28,7 @@ #include <sys/socket.h> +#include "socket/socket.h" #include "utils/utils.h" /**************************************************************************** @@ -60,7 +61,7 @@ ****************************************************************************/ FAR void *cmsg_append(FAR struct msghdr *msg, int level, int type, - FAR void *value, int value_len) + FAR const void *value, int value_len) { FAR struct cmsghdr *cmsg; unsigned long cmsgspace = CMSG_SPACE(value_len); @@ -86,3 +87,37 @@ FAR void *cmsg_append(FAR struct msghdr *msg, int level, int type, return cmsgdata; } + +/**************************************************************************** + * Name: cmsg_store_timestamp + * + * Description: + * Store the timestamp in the cmsg + * + * Input Parameters: + * msg - Pointer to the msghdr containing ancillary data (CMSG). + * tstamp - Timestamp information. + * + * Returned Value: + * None + * + ****************************************************************************/ + +#ifdef CONFIG_NET_TIMESTAMP +void cmsg_store_timestamp(FAR struct msghdr *msg, + FAR const struct timespec *tstamp, sockopt_t opt) +{ + if (_SO_GETOPT(opt, SO_TIMESTAMP)) + { + struct timeval tv; + TIMESPEC_TO_TIMEVAL(&tv, tstamp); + cmsg_append(msg, SOL_SOCKET, SO_TIMESTAMP, &tv, + sizeof(struct timeval)); + } + else if (_SO_GETOPT(opt, SO_TIMESTAMPNS)) + { + cmsg_append(msg, SOL_SOCKET, SO_TIMESTAMPNS, tstamp, + sizeof(struct timespec)); + } +} +#endif /* CONFIG_NET_TIMESTAMP */ diff --git a/net/utils/utils.h b/net/utils/utils.h index 03fe8d15d2c..5b34ae2976c 100644 --- a/net/utils/utils.h +++ b/net/utils/utils.h @@ -668,7 +668,27 @@ uint16_t icmpv6_chksum(FAR struct net_driver_s *dev, unsigned int iplen); ****************************************************************************/ FAR void *cmsg_append(FAR struct msghdr *msg, int level, int type, - FAR void *value, int value_len); + FAR const void *value, int value_len); + +/**************************************************************************** + * Name: cmsg_store_timestamp + * + * Description: + * Store the timestamp in the cmsg + * + * Input Parameters: + * msg - Pointer to the msghdr containing ancillary data (CMSG). + * tstamp - Timestamp information. + * + * Returned Value: + * None + * + ****************************************************************************/ + +#ifdef CONFIG_NET_TIMESTAMP +void cmsg_store_timestamp(FAR struct msghdr *msg, + FAR const struct timespec *tstamp, sockopt_t opt); +#endif /* CONFIG_NET_TIMESTAMP */ #undef EXTERN #ifdef __cplusplus
