Setting filter masks

classic Classic list List threaded Threaded
4 messages Options
Reply | Threaded
Open this post in threaded view
|

Setting filter masks

Jorge Fernandez Monteagudo

Hi,

 

I would like to know how to set the filter masks in order to receive can frames.

In my current code I'm using only standard frames with 11 bits. The three possible

situations for me are:

 

- Read frames from only an identifier: Then I set :

  can_id = 0x1A4

  can_mask = 0x00

 

- Read all the frames from a service. For instance, to receive all frames from NMT

  I set:

  can_id = 0x700

  can_mask = 0x7F

 

  then I get 11 bit address like this : 111 0xxx xxxx

 

- Read all the frames from a node. The I set:

  can_id = 0x24

  can_mask = 0x780

 

  then I get 11 bit address like this : xxx x010 0100

 

How can I recreate this situation using the socketcan filters?

 

Regards,

Jorge

 



Este mensaje se dirige exclusivamente a su destinatario y puede contener información privilegiada o CONFIDENCIAL. Si no es vd. el destinatario indicado, queda notificado de que la utilización, divulgación y/o copia sin autorización está prohibida en virtud de la legislación vigente. Si ha recibido este mensaje por error, le rogamos que nos lo comunique inmediatamente por esta misma vía y proceda a su destrucción.

This message is intended exclusively for its addressee and may contain information that is CONFIDENTIAL and protected by professional privilege.
If you are not the intended recipient you are hereby notified that any dissemination, copy or disclosure of this communication is strictly prohibited by law. If this message has been received in error, please immediately notify us via e-mail and delete it.

_______________________________________________
Socketcan-users mailing list
[hidden email]
https://lists.berlios.de/mailman/listinfo/socketcan-users
Reply | Threaded
Open this post in threaded view
|

Re: Setting filter masks

Hartkopp, Oliver (K-EFFI/P)
On 21.03.2011 08:25, Jorge Fernandez Monteagudo wrote:

> I would like to know how to set the filter masks in order to receive can
> frames.

Hello Jorge,

please read

<a href="http://lxr.linux.no/#linux+v2.6.38/Documentation/networking/can.txt#L378">http://lxr.linux.no/#linux+v2.6.38/Documentation/networking/can.txt#L378

It tells that ...

A filter matches, when

    <received_can_id> & mask == can_id & mask

which is analogous to known CAN controllers hardware filter semantics.


>
> In my current code I'm using only standard frames with 11 bits. The
> three possible
>
> situations for me are:
>
> - Read frames from only an identifier: Then I set :
>
> can_id = 0x1A4
>
> can_mask = 0x00
>

No.

Setting the can_mask to '0' means that no bits are relevant for the
filter and therefore you'll receive *anything* with this filter.

If you would like to filter only for 0x1A4 the filter mask must be 0x7FF
and as you would like to have no RTR nor EFF frames the higher bits must
be set:

can_mask = 0xC00007FF

which is the #defines (CAN_EFF_FLAG | CAN_RTR_FLAG | CAN_SFF_MASK) in can.h

Your other examples are flipped in the can_mask bits also.

Regards,
Oliver
_______________________________________________
Socketcan-users mailing list
[hidden email]
https://lists.berlios.de/mailman/listinfo/socketcan-users
Reply | Threaded
Open this post in threaded view
|

Re: Setting filter masks

Wolfgang Grandegger
In reply to this post by Jorge Fernandez Monteagudo
On 03/21/2011 08:25 AM, Jorge Fernandez Monteagudo wrote:

> Hi,
>
> I would like to know how to set the filter masks in order to receive can frames.
> In my current code I'm using only standard frames with 11 bits. The three possible
> situations for me are:
>
> - Read frames from only an identifier: Then I set :
>   can_id = 0x1A4
>   can_mask = 0x00
>
> - Read all the frames from a service. For instance, to receive all frames from NMT
>   I set:
>   can_id = 0x700
>   can_mask = 0x7F
>
>   then I get 11 bit address like this : 111 0xxx xxxx
>
> - Read all the frames from a node. The I set:
>   can_id = 0x24
>   can_mask = 0x780
>
>   then I get 11 bit address like this : xxx x010 0100
>
> How can I recreate this situation using the socketcan filters?

The following doc should make clear how SocketCAN filtering works:

<a href="http://lxr.linux.no/#linux+v2.6.38/Documentation/networking/can.txt#L394">http://lxr.linux.no/#linux+v2.6.38/Documentation/networking/can.txt#L394

Wolfgang.
_______________________________________________
Socketcan-users mailing list
[hidden email]
https://lists.berlios.de/mailman/listinfo/socketcan-users
toz
Reply | Threaded
Open this post in threaded view
|

Re: Setting filter masks

toz
This post has NOT been accepted by the mailing list yet.
Hi Wolfgang,

It's not directly related to this issue, but I have a comment on the documentation of SocketCAN:

In the example code for setting filters, the address of filter-array is passed-on to setsockopt(), which is fine since it's an array (and since C/C++ compiler will still pass-on the address of the 1st array element (i.e., &rfilter[0]), although &rfilter is given as argument). However, when the array is dynamically allocated, passing-on the address does not work, as in that case, the address of the pointer to the array is actually passed on (i.e., &&rfilter[0]). This has been an issue that cost me some time to figure-out, so in order to avoid other people having the same problem, it might be worthwhile to consider changing this example in the documentation.

Here is the example code that I refer to (in section 4.1.1):

    struct can_filter rfilter[2];
    rfilter[0].can_id   = 0x123;
    rfilter[0].can_mask = CAN_SFF_MASK;
    rfilter[1].can_id   = 0x200;
    rfilter[1].can_mask = 0x700;

    setsockopt(s, SOL_CAN_RAW, CAN_RAW_FILTER, &rfilter, sizeof(rfilter));

Here is the dynamic/heap-allocation variant, which looks the same, but doesn't work:

    struct can_filter* rfilter = new can_filter[2];

    rfilter[0].can_id   = 0x123;
    rfilter[0].can_mask = CAN_SFF_MASK;
    rfilter[1].can_id   = 0x200;
    rfilter[1].can_mask = 0x700;

    setsockopt(s, SOL_CAN_RAW, CAN_RAW_FILTER, &rfilter, sizeof(struct can_filter) * 2);

The following code would  work in both cases:

    struct can_filter* rfilter = new can_filter[2];

    rfilter[0].can_id   = 0x123;
    rfilter[0].can_mask = CAN_SFF_MASK;
    rfilter[1].can_id   = 0x200;
    rfilter[1].can_mask = 0x700;

    setsockopt(s, SOL_CAN_RAW, CAN_RAW_FILTER, rfilter, sizeof(struct can_filter) * 2);