我正在尝试使用特定ID过滤CAN帧,如下所述:https://landlock.io/linux-doc/landlock-v8/networking/can.html#raw-protocol-sockets-with-can-filters-sock-raw
我的代码之一是:
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?
发布于 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与传入通信量进行排序时。
若要具有预期的行为,应替换:
setsockopt(s, SOL_CAN_RAW, CAN_RAW_FILTER, &rfilter, sizeof(rfilter));
出自:
setsockopt(s, SOL_CAN_RAW, CAN_RAW_JOIN_FILTERS, &rfilter, sizeof(rfilter));
注意:您的Linux内核可能不支持CAN_RAW_JOIN_FILTERS选项
发布于 2019-08-27 18:38:10
您首先需要提供CAN文件:
setsockopt(s, SOL_CAN_RAW, CAN_RAW_FILTER, &rfilter, sizeof(rfilter));
另外,是一个整数值,用于通过setsockopt()启用CAN_RAW_JOIN_FILTERS。
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 :-)
https://stackoverflow.com/questions/56355857
复制相似问题