You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@nuttx.apache.org by xi...@apache.org on 2023/04/26 16:31:04 UTC
[nuttx] branch master updated: net/can: fix can mssage corruption if enable NET_TIMESTAMP
This is an automated email from the ASF dual-hosted git repository.
xiaoxiang pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/nuttx.git
The following commit(s) were added to refs/heads/master by this push:
new 2eb9abc3d8 net/can: fix can mssage corruption if enable NET_TIMESTAMP
2eb9abc3d8 is described below
commit 2eb9abc3d862a460a6a059f456cb83f80a8258cf
Author: chao an <an...@xiaomi.com>
AuthorDate: Wed Apr 26 21:29:15 2023 +0800
net/can: fix can mssage corruption if enable NET_TIMESTAMP
Timestamp location in can message has changed,
In the original logic timestamp is saved at the end of the data segment:
io_data
-------------------------------------------------
| CAN message | Time Stamp |
-------------------------------------------------
|<--------------- io_len ---------------->|
In the new structure timestamps will reuse NET_LL_GUARDSIZE to isolate CAN messages:
io_data io_offset
-------------------------------------------------
| Time Stamp | CAN message |
-------------------------------------------------
|<-------- io_len --------->|
This PR will:
1. Increase NET_LL_GUARDSIZE to 16 (sizeof(struct timeval)) if NET_CAN && NET_TIMESTAMP are enabled
2. Apply timestamp to adapt to the new structure
Signed-off-by: chao an <an...@xiaomi.com>
---
net/Kconfig | 1 +
net/can/can_callback.c | 3 +-
net/can/can_recvmsg.c | 126 +++++++------------------------------------------
3 files changed, 20 insertions(+), 110 deletions(-)
diff --git a/net/Kconfig b/net/Kconfig
index 0d11685b83..21d813b645 100644
--- a/net/Kconfig
+++ b/net/Kconfig
@@ -119,6 +119,7 @@ config NET_GUARDSIZE
config NET_LL_GUARDSIZE
int "Data Link Layer(L2) Guard size of Network buffer(IOB)"
+ default 16 if NET_CAN && NET_TIMESTAMP
default 14 if NET_ETHERNET
default 0
---help---
diff --git a/net/can/can_callback.c b/net/can/can_callback.c
index c69a1dcbfb..d8ebfc6550 100644
--- a/net/can/can_callback.c
+++ b/net/can/can_callback.c
@@ -148,7 +148,8 @@ uint16_t can_callback(FAR struct net_driver_s *dev,
tv.tv_usec = ts->tv_nsec / 1000;
len = iob_trycopyin(dev->d_iob, (FAR uint8_t *)&tv,
- sizeof(struct timeval), 0, false);
+ sizeof(struct timeval),
+ -CONFIG_NET_LL_GUARDSIZE, false);
if (len != sizeof(struct timeval))
{
dev->d_len = 0;
diff --git a/net/can/can_recvmsg.c b/net/can/can_recvmsg.c
index 451a33112c..2a11b66337 100644
--- a/net/can/can_recvmsg.c
+++ b/net/can/can_recvmsg.c
@@ -125,6 +125,15 @@ 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 &&
+ pstate->pr_msglen == sizeof(struct timeval))
+ {
+ iob_copyout(pstate->pr_msgbuf, dev->d_iob, sizeof(struct timeval),
+ -CONFIG_NET_LL_GUARDSIZE);
+ }
+#endif
+
if (dev->d_len > pstate->pr_buflen)
{
recvlen = pstate->pr_buflen;
@@ -224,6 +233,14 @@ static inline int can_readahead(struct can_recvfrom_s *pstate)
{
DEBUGASSERT(iob->io_pktlen > 0);
+#ifdef CONFIG_NET_TIMESTAMP
+ if (conn->timestamp && pstate->pr_msglen == sizeof(struct timeval))
+ {
+ iob_copyout(pstate->pr_msgbuf, iob, sizeof(struct timeval),
+ -CONFIG_NET_LL_GUARDSIZE);
+ }
+#endif
+
/* Transfer that buffered data from the I/O buffer chain into
* the user buffer.
*/
@@ -279,79 +296,6 @@ static inline int can_readahead(struct can_recvfrom_s *pstate)
return 0;
}
-/****************************************************************************
- * Name: can_readahead
- *
- * Description:
- * Copy the read-ahead data from the packet
- *
- * Input Parameters:
- * pstate recvfrom state structure
- *
- * Returned Value:
- * None
- *
- * Assumptions:
- * The network is locked.
- *
- ****************************************************************************/
-
-#ifdef CONFIG_NET_TIMESTAMP
-static inline int can_readahead_timestamp(struct can_conn_s *conn,
- FAR uint8_t *buffer)
-{
- FAR struct iob_s *iob;
- int recvlen;
-
- if ((iob = iob_peek_queue(&conn->readahead)) != NULL)
- {
- DEBUGASSERT(iob->io_pktlen > 0);
-
- /* Transfer that buffered data from the I/O buffer chain into
- * the user buffer.
- */
-
- recvlen = iob_copyout(buffer, iob, sizeof(struct timeval), 0);
-
- /* If we took all of the data from the I/O buffer chain is empty, then
- * release it. If there is still data available in the I/O buffer
- * chain, then just trim the data that we have taken from the
- * beginning of the I/O buffer chain.
- */
-
- if (recvlen >= iob->io_pktlen)
- {
- FAR struct iob_s *tmp;
-
- /* Remove the I/O buffer chain from the head of the read-ahead
- * buffer queue.
- */
-
- tmp = iob_remove_queue(&conn->readahead);
- DEBUGASSERT(tmp == iob);
- UNUSED(tmp);
-
- /* And free the I/O buffer chain */
-
- iob_free_chain(iob);
- }
- else
- {
- /* The bytes that we have received from the head of the I/O
- * buffer chain (probably changing the head of the I/O
- * buffer queue).
- */
-
- iob_trimhead_queue(&conn->readahead, recvlen);
- }
-
- return recvlen;
- }
-
- return 0;
-}
-#endif
-
#ifdef CONFIG_NET_CANPROTO_OPTIONS
static int can_recv_filter(struct can_conn_s *conn, canid_t id)
{
@@ -431,25 +375,6 @@ static uint16_t can_recvfrom_eventhandler(FAR struct net_driver_s *dev,
can_newdata(dev, pstate);
-#ifdef CONFIG_NET_TIMESTAMP
- if (conn->timestamp)
- {
- if (pstate->pr_msglen == sizeof(struct timeval))
- {
- can_readahead_timestamp(conn, pstate->pr_msgbuf);
- }
- else
- {
- /* We still have to consume the data
- * otherwise IOB gets full
- */
-
- uint8_t dummy_buf[sizeof(struct timeval)];
- can_readahead_timestamp(conn, (uint8_t *)&dummy_buf);
- }
- }
-#endif
-
/* We are finished. */
/* Don't allow any further call backs. */
@@ -596,23 +521,6 @@ ssize_t can_recvmsg(FAR struct socket *psock, FAR struct msghdr *msg,
ret = can_readahead(&state);
if (ret > 0)
{
-#ifdef CONFIG_NET_TIMESTAMP
- if (conn->timestamp)
- {
- if (state.pr_msglen == sizeof(struct timeval))
- {
- can_readahead_timestamp(conn, state.pr_msgbuf);
- }
- else
- {
- /* We still have to consume the data otherwise IOB gets full */
-
- uint8_t dummy_buf[sizeof(struct timeval)];
- can_readahead_timestamp(conn, (uint8_t *)&dummy_buf);
- }
- }
-#endif
-
goto errout_with_state;
}