首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >SocketCAN:对具有特定CAN ID的帧进行过滤

SocketCAN:对具有特定CAN ID的帧进行过滤
EN

Stack Overflow用户
提问于 2019-05-29 08:09:44
回答 2查看 6.5K关注 0票数 5

我正在尝试使用特定ID过滤CAN帧,如下所述:https://landlock.io/linux-doc/landlock-v8/networking/can.html#raw-protocol-sockets-with-can-filters-sock-raw

我的代码之一是:

代码语言:javascript
运行
复制
struct can_filter rfilter[4];

if ((s = socket(PF_CAN, SOCK_RAW, CAN_RAW)) < 0) {
    fprintf(stderr, "Error while opening socket.\n");
    exit(EXIT_FAILURE);
}
rfilter[0].can_id   = 0x0D6 | CAN_INV_FILTER;
rfilter[0].can_mask = CAN_SFF_MASK;
rfilter[1].can_id   = 0x0D8 | CAN_INV_FILTER;
rfilter[1].can_mask = CAN_SFF_MASK;
rfilter[2].can_id   = 0x0E4 | CAN_INV_FILTER;
rfilter[2].can_mask = CAN_SFF_MASK;
rfilter[3].can_id   = 0x77F | CAN_INV_FILTER;
rfilter[3].can_mask = CAN_SFF_MASK;
setsockopt(s, SOL_CAN_RAW, CAN_RAW_FILTER, &rfilter, sizeof(rfilter));

如果我只使用我的四个过滤器中的一个,并注释掉另外三个,它就会像预期的那样工作。如果我把所有四个过滤器都用上,它根本就不起作用了。在这种情况下,我仍然在接收CANbus接口上的所有内容。

所以,我的猜测是,不知怎么我的过滤器正在中和对方?!需要更改哪些内容来筛选CAN ID 0x0D6、0x0D8、0x0E4和0x77F?

EN

回答 2

Stack Overflow用户

发布于 2019-05-29 09:57:21

像使用CAN_INV_FILTER一样使用ID_x时,可以指定“除ID_x外,一切都经过”。

当使用CAN_RAW_FILTER时,它将检查是否有允许接收到的ID传递的规则。在你的情况下,你的规则是相互矛盾的,这就是为什么没有过滤。

来自文档

4.1.6原始套接字选项CAN_RAW_JOIN_FILTERS CAN_RAW套接字可以设置多个can标识符特定过滤器,从而导致af_can.c筛选器处理中的多个过滤器。这些过滤器彼此独立,这导致应用逻辑或编辑过滤器(见4.1.1)。 这个套接字选项以只有帧才能传递给匹配所有给定CAN过滤器的用户空间的方式激活给定的CAN过滤器。因此,将应用过滤器的语义更改为逻辑和。 这非常有用,特别是当过滤器集是设置CAN_INV_FILTER标志的过滤器组合时,以便对单个CAN ID或CAN与传入通信量进行排序时。

若要具有预期的行为,应替换:

代码语言:javascript
运行
复制
setsockopt(s, SOL_CAN_RAW, CAN_RAW_FILTER, &rfilter, sizeof(rfilter));

出自:

代码语言:javascript
运行
复制
setsockopt(s, SOL_CAN_RAW, CAN_RAW_JOIN_FILTERS, &rfilter, sizeof(rfilter));

注意:您的Linux内核可能不支持CAN_RAW_JOIN_FILTERS选项

票数 5
EN

Stack Overflow用户

发布于 2019-08-27 18:38:10

您首先需要提供CAN文件:

代码语言:javascript
运行
复制
setsockopt(s, SOL_CAN_RAW, CAN_RAW_FILTER, &rfilter, sizeof(rfilter));

另外,是一个整数值,用于通过setsockopt()启用CAN_RAW_JOIN_FILTERS。

代码语言:javascript
运行
复制
int join_filter = 1;
setsockopt(s, SOL_CAN_RAW, CAN_RAW_JOIN_FILTERS, &join_filter, sizeof(join_filter));

顺便说一句。如果向CAN_RAW_JOIN_FILTERS提供CAN过滤器以setsockopt(),这是一个意外的长度,应该生成-EINVAL作为返回代码。

参见烛光代码:https://github.com/linux-can/can-utils/commit/1a2467ed29302149d4d1253888ac1f1dfcc11d3f

是的,Linux4.4支持CAN_RAW_JOIN_FILTERS :-)

票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/56355857

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档