mirror of
https://github.com/apache/nuttx.git
synced 2026-05-27 19:36:35 +08:00
net/socketcan: move rx filter down to can_input;
rx filter from recvmsg down to can_input, before packet delivery; Signed-off-by: wangjinjing1 <wangjinjing1@xiaomi.com>
This commit is contained in:
@@ -167,6 +167,59 @@ void can_free(FAR struct can_conn_s *conn)
|
|||||||
NET_BUFPOOL_UNLOCK(g_can_connections);
|
NET_BUFPOOL_UNLOCK(g_can_connections);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* Name: can_recv_filter
|
||||||
|
*
|
||||||
|
* Description:
|
||||||
|
* filter incoming packet
|
||||||
|
*
|
||||||
|
* Input Parameters:
|
||||||
|
* conn - A pointer to the CAN connection structure
|
||||||
|
* id - The CAN identifier
|
||||||
|
*
|
||||||
|
* Returned Value: 0 - Filter not passed, 1 - Filter passed
|
||||||
|
*
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
#ifdef CONFIG_NET_CANPROTO_OPTIONS
|
||||||
|
static int can_recv_filter(FAR struct can_conn_s *conn, canid_t id)
|
||||||
|
{
|
||||||
|
uint32_t i;
|
||||||
|
|
||||||
|
#ifdef CONFIG_NET_CAN_ERRORS
|
||||||
|
/* error message frame */
|
||||||
|
|
||||||
|
if ((id & CAN_ERR_FLAG) != 0)
|
||||||
|
{
|
||||||
|
return id & conn->err_mask ? 1 : 0;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
for (i = 0; i < conn->filter_count; i++)
|
||||||
|
{
|
||||||
|
if (conn->filters[i].can_id & CAN_INV_FILTER)
|
||||||
|
{
|
||||||
|
if ((id & conn->filters[i].can_mask) !=
|
||||||
|
((conn->filters[i].can_id & ~CAN_INV_FILTER) &
|
||||||
|
conn->filters[i].can_mask))
|
||||||
|
{
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if ((id & conn->filters[i].can_mask) ==
|
||||||
|
(conn->filters[i].can_id & conn->filters[i].can_mask))
|
||||||
|
{
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
* Name: can_nextconn()
|
* Name: can_nextconn()
|
||||||
*
|
*
|
||||||
@@ -209,11 +262,22 @@ FAR struct can_conn_s *can_nextconn(FAR struct can_conn_s *conn)
|
|||||||
FAR struct can_conn_s *can_active(FAR struct net_driver_s *dev,
|
FAR struct can_conn_s *can_active(FAR struct net_driver_s *dev,
|
||||||
FAR struct can_conn_s *conn)
|
FAR struct can_conn_s *conn)
|
||||||
{
|
{
|
||||||
|
#ifdef CONFIG_NET_CANPROTO_OPTIONS
|
||||||
|
canid_t can_id;
|
||||||
|
memcpy(&can_id, NETLLBUF, sizeof(canid_t));
|
||||||
|
#endif
|
||||||
|
|
||||||
while ((conn = can_nextconn(conn)) != NULL)
|
while ((conn = can_nextconn(conn)) != NULL)
|
||||||
{
|
{
|
||||||
if ((conn->dev == NULL && _SS_ISBOUND(conn->sconn.s_flags)) ||
|
if ((conn->dev == NULL && _SS_ISBOUND(conn->sconn.s_flags)) ||
|
||||||
conn->dev == dev)
|
conn->dev == dev)
|
||||||
{
|
{
|
||||||
|
#ifdef CONFIG_NET_CANPROTO_OPTIONS
|
||||||
|
if (can_recv_filter(conn, can_id) == 0)
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -219,6 +219,13 @@ static int can_in(FAR struct net_driver_s *dev)
|
|||||||
FAR struct can_conn_s *conn = can_active(dev, NULL);
|
FAR struct can_conn_s *conn = can_active(dev, NULL);
|
||||||
FAR struct can_conn_s *nextconn;
|
FAR struct can_conn_s *nextconn;
|
||||||
|
|
||||||
|
if (conn == NULL)
|
||||||
|
{
|
||||||
|
/* There is no listener on the dev. Just drop the packet. */
|
||||||
|
|
||||||
|
return OK;
|
||||||
|
}
|
||||||
|
|
||||||
/* Do we have second connection that can hold this packet? */
|
/* Do we have second connection that can hold this packet? */
|
||||||
|
|
||||||
while ((nextconn = can_active(dev, conn)) != NULL)
|
while ((nextconn = can_active(dev, conn)) != NULL)
|
||||||
|
|||||||
+2
-73
@@ -75,10 +75,6 @@ struct can_recvfrom_s
|
|||||||
* Private Functions
|
* Private Functions
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
|
|
||||||
#ifdef CONFIG_NET_CANPROTO_OPTIONS
|
|
||||||
static int can_recv_filter(FAR struct can_conn_s *conn, canid_t id);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
* Name: can_add_recvlen
|
* Name: can_add_recvlen
|
||||||
*
|
*
|
||||||
@@ -248,21 +244,6 @@ static inline int can_readahead(struct can_recvfrom_s *pstate)
|
|||||||
{
|
{
|
||||||
DEBUGASSERT(iob->io_pktlen > 0);
|
DEBUGASSERT(iob->io_pktlen > 0);
|
||||||
|
|
||||||
#ifdef CONFIG_NET_CANPROTO_OPTIONS
|
|
||||||
/* Check receive filters */
|
|
||||||
|
|
||||||
canid_t can_id;
|
|
||||||
iob_copyout((uint8_t *)&can_id, iob, sizeof(canid_t), 0);
|
|
||||||
|
|
||||||
if (can_recv_filter(conn, can_id) == 0)
|
|
||||||
{
|
|
||||||
/* Free the I/O buffer chain */
|
|
||||||
|
|
||||||
iob_free_chain(iob);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef CONFIG_NET_TIMESTAMP
|
#ifdef CONFIG_NET_TIMESTAMP
|
||||||
if (_SO_GETOPT(conn->sconn.s_options, SO_TIMESTAMP) &&
|
if (_SO_GETOPT(conn->sconn.s_options, SO_TIMESTAMP) &&
|
||||||
pstate->pr_msglen == sizeof(struct timeval))
|
pstate->pr_msglen == sizeof(struct timeval))
|
||||||
@@ -306,45 +287,6 @@ static inline int can_readahead(struct can_recvfrom_s *pstate)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef CONFIG_NET_CANPROTO_OPTIONS
|
|
||||||
static int can_recv_filter(FAR struct can_conn_s *conn, canid_t id)
|
|
||||||
{
|
|
||||||
uint32_t i;
|
|
||||||
|
|
||||||
#ifdef CONFIG_NET_CAN_ERRORS
|
|
||||||
/* error message frame */
|
|
||||||
|
|
||||||
if ((id & CAN_ERR_FLAG) != 0)
|
|
||||||
{
|
|
||||||
return id & conn->err_mask ? 1 : 0;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
for (i = 0; i < conn->filter_count; i++)
|
|
||||||
{
|
|
||||||
if (conn->filters[i].can_id & CAN_INV_FILTER)
|
|
||||||
{
|
|
||||||
if ((id & conn->filters[i].can_mask) !=
|
|
||||||
((conn->filters[i].can_id & ~CAN_INV_FILTER) &
|
|
||||||
conn->filters[i].can_mask))
|
|
||||||
{
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if ((id & conn->filters[i].can_mask) ==
|
|
||||||
(conn->filters[i].can_id & conn->filters[i].can_mask))
|
|
||||||
{
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
static uint16_t can_recvfrom_eventhandler(FAR struct net_driver_s *dev,
|
static uint16_t can_recvfrom_eventhandler(FAR struct net_driver_s *dev,
|
||||||
FAR void *pvpriv, uint16_t flags)
|
FAR void *pvpriv, uint16_t flags)
|
||||||
{
|
{
|
||||||
@@ -354,26 +296,13 @@ static uint16_t can_recvfrom_eventhandler(FAR struct net_driver_s *dev,
|
|||||||
|
|
||||||
if (pstate)
|
if (pstate)
|
||||||
{
|
{
|
||||||
#if defined(CONFIG_NET_CANPROTO_OPTIONS) || defined(CONFIG_NET_TIMESTAMP)
|
#if (defined(CONFIG_NET_CANPROTO_OPTIONS) && defined(CONFIG_NET_CAN_CANFD)) \
|
||||||
|
|| defined(CONFIG_NET_TIMESTAMP)
|
||||||
struct can_conn_s *conn = pstate->pr_conn;
|
struct can_conn_s *conn = pstate->pr_conn;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if ((flags & CAN_NEWDATA) != 0)
|
if ((flags & CAN_NEWDATA) != 0)
|
||||||
{
|
{
|
||||||
/* If a new packet is available, check receive filters
|
|
||||||
* when is valid then complete the read action.
|
|
||||||
*/
|
|
||||||
#ifdef CONFIG_NET_CANPROTO_OPTIONS
|
|
||||||
canid_t can_id;
|
|
||||||
memcpy(&can_id, dev->d_appdata, sizeof(canid_t));
|
|
||||||
|
|
||||||
if (can_recv_filter(conn, can_id) == 0)
|
|
||||||
{
|
|
||||||
flags &= ~CAN_NEWDATA;
|
|
||||||
return flags;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* do not pass frames with DLC > 8 to a legacy socket */
|
/* do not pass frames with DLC > 8 to a legacy socket */
|
||||||
#if defined(CONFIG_NET_CANPROTO_OPTIONS) && defined(CONFIG_NET_CAN_CANFD)
|
#if defined(CONFIG_NET_CANPROTO_OPTIONS) && defined(CONFIG_NET_CAN_CANFD)
|
||||||
if (!_SO_GETOPT(conn->sconn.s_options, CAN_RAW_FD_FRAMES))
|
if (!_SO_GETOPT(conn->sconn.s_options, CAN_RAW_FD_FRAMES))
|
||||||
|
|||||||
Reference in New Issue
Block a user