Skip to content

Commit 2eb9abc

Browse files
anchaoxiaoxiang781216
authored andcommitted
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 <anchao@xiaomi.com>
1 parent df2925c commit 2eb9abc

File tree

3 files changed

+20
-110
lines changed

3 files changed

+20
-110
lines changed

net/Kconfig

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -119,6 +119,7 @@ config NET_GUARDSIZE
119119

120120
config NET_LL_GUARDSIZE
121121
int "Data Link Layer(L2) Guard size of Network buffer(IOB)"
122+
default 16 if NET_CAN && NET_TIMESTAMP
122123
default 14 if NET_ETHERNET
123124
default 0
124125
---help---

net/can/can_callback.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -148,7 +148,8 @@ uint16_t can_callback(FAR struct net_driver_s *dev,
148148
tv.tv_usec = ts->tv_nsec / 1000;
149149

150150
len = iob_trycopyin(dev->d_iob, (FAR uint8_t *)&tv,
151-
sizeof(struct timeval), 0, false);
151+
sizeof(struct timeval),
152+
-CONFIG_NET_LL_GUARDSIZE, false);
152153
if (len != sizeof(struct timeval))
153154
{
154155
dev->d_len = 0;

net/can/can_recvmsg.c

Lines changed: 17 additions & 109 deletions
Original file line numberDiff line numberDiff line change
@@ -125,6 +125,15 @@ static size_t can_recvfrom_newdata(FAR struct net_driver_s *dev,
125125
unsigned int offset;
126126
size_t recvlen;
127127

128+
#ifdef CONFIG_NET_TIMESTAMP
129+
if (pstate->pr_conn->timestamp &&
130+
pstate->pr_msglen == sizeof(struct timeval))
131+
{
132+
iob_copyout(pstate->pr_msgbuf, dev->d_iob, sizeof(struct timeval),
133+
-CONFIG_NET_LL_GUARDSIZE);
134+
}
135+
#endif
136+
128137
if (dev->d_len > pstate->pr_buflen)
129138
{
130139
recvlen = pstate->pr_buflen;
@@ -224,6 +233,14 @@ static inline int can_readahead(struct can_recvfrom_s *pstate)
224233
{
225234
DEBUGASSERT(iob->io_pktlen > 0);
226235

236+
#ifdef CONFIG_NET_TIMESTAMP
237+
if (conn->timestamp && pstate->pr_msglen == sizeof(struct timeval))
238+
{
239+
iob_copyout(pstate->pr_msgbuf, iob, sizeof(struct timeval),
240+
-CONFIG_NET_LL_GUARDSIZE);
241+
}
242+
#endif
243+
227244
/* Transfer that buffered data from the I/O buffer chain into
228245
* the user buffer.
229246
*/
@@ -279,79 +296,6 @@ static inline int can_readahead(struct can_recvfrom_s *pstate)
279296
return 0;
280297
}
281298

282-
/****************************************************************************
283-
* Name: can_readahead
284-
*
285-
* Description:
286-
* Copy the read-ahead data from the packet
287-
*
288-
* Input Parameters:
289-
* pstate recvfrom state structure
290-
*
291-
* Returned Value:
292-
* None
293-
*
294-
* Assumptions:
295-
* The network is locked.
296-
*
297-
****************************************************************************/
298-
299-
#ifdef CONFIG_NET_TIMESTAMP
300-
static inline int can_readahead_timestamp(struct can_conn_s *conn,
301-
FAR uint8_t *buffer)
302-
{
303-
FAR struct iob_s *iob;
304-
int recvlen;
305-
306-
if ((iob = iob_peek_queue(&conn->readahead)) != NULL)
307-
{
308-
DEBUGASSERT(iob->io_pktlen > 0);
309-
310-
/* Transfer that buffered data from the I/O buffer chain into
311-
* the user buffer.
312-
*/
313-
314-
recvlen = iob_copyout(buffer, iob, sizeof(struct timeval), 0);
315-
316-
/* If we took all of the data from the I/O buffer chain is empty, then
317-
* release it. If there is still data available in the I/O buffer
318-
* chain, then just trim the data that we have taken from the
319-
* beginning of the I/O buffer chain.
320-
*/
321-
322-
if (recvlen >= iob->io_pktlen)
323-
{
324-
FAR struct iob_s *tmp;
325-
326-
/* Remove the I/O buffer chain from the head of the read-ahead
327-
* buffer queue.
328-
*/
329-
330-
tmp = iob_remove_queue(&conn->readahead);
331-
DEBUGASSERT(tmp == iob);
332-
UNUSED(tmp);
333-
334-
/* And free the I/O buffer chain */
335-
336-
iob_free_chain(iob);
337-
}
338-
else
339-
{
340-
/* The bytes that we have received from the head of the I/O
341-
* buffer chain (probably changing the head of the I/O
342-
* buffer queue).
343-
*/
344-
345-
iob_trimhead_queue(&conn->readahead, recvlen);
346-
}
347-
348-
return recvlen;
349-
}
350-
351-
return 0;
352-
}
353-
#endif
354-
355299
#ifdef CONFIG_NET_CANPROTO_OPTIONS
356300
static int can_recv_filter(struct can_conn_s *conn, canid_t id)
357301
{
@@ -431,25 +375,6 @@ static uint16_t can_recvfrom_eventhandler(FAR struct net_driver_s *dev,
431375

432376
can_newdata(dev, pstate);
433377

434-
#ifdef CONFIG_NET_TIMESTAMP
435-
if (conn->timestamp)
436-
{
437-
if (pstate->pr_msglen == sizeof(struct timeval))
438-
{
439-
can_readahead_timestamp(conn, pstate->pr_msgbuf);
440-
}
441-
else
442-
{
443-
/* We still have to consume the data
444-
* otherwise IOB gets full
445-
*/
446-
447-
uint8_t dummy_buf[sizeof(struct timeval)];
448-
can_readahead_timestamp(conn, (uint8_t *)&dummy_buf);
449-
}
450-
}
451-
#endif
452-
453378
/* We are finished. */
454379

455380
/* Don't allow any further call backs. */
@@ -596,23 +521,6 @@ ssize_t can_recvmsg(FAR struct socket *psock, FAR struct msghdr *msg,
596521
ret = can_readahead(&state);
597522
if (ret > 0)
598523
{
599-
#ifdef CONFIG_NET_TIMESTAMP
600-
if (conn->timestamp)
601-
{
602-
if (state.pr_msglen == sizeof(struct timeval))
603-
{
604-
can_readahead_timestamp(conn, state.pr_msgbuf);
605-
}
606-
else
607-
{
608-
/* We still have to consume the data otherwise IOB gets full */
609-
610-
uint8_t dummy_buf[sizeof(struct timeval)];
611-
can_readahead_timestamp(conn, (uint8_t *)&dummy_buf);
612-
}
613-
}
614-
#endif
615-
616524
goto errout_with_state;
617525
}
618526

0 commit comments

Comments
 (0)