We've just found the cause of an intermittent CAN problem. It may be
instructive to others.
Our CAN code looks something like:
1) int skt = socket( PF_CAN, SOCK_RAW | SOCK_NONBLOCK, CAN_RAW );
...
2) int rc=ioctl(skt, SIOCGIFINDEX, &ifr); /* ifr.ifr_ifindex filled ... */
...
3) rc = bind(skt, (struct sockaddr*)&addr, sizeof(addr));
...
4) rc = setsockopt(skt, SOL_CAN_RAW, CAN_RAW_FILTER, &rfilter,
sizeof(rfilter));
...
5) rc = recv(skt, &frame, sizeof(frame), MSG_DONTWAIT);
The Receive path assumes the Filter that was applied to the socket is working.
That was a rookie mistake. It isn't.
We're receiving all sorts of garbage on the first few reads of the socket.
Messages that are being misinterpreted to make very bright warning lights
flash in all sorts of worrying and unexpected ways.
This is because the thread performing the above can get suspended between when
the socket is bound at (3), and when the filter is applied at (4).
And during this time it is WIDE OPEN and will receive every message on the CAN
bus, every ID, Standard and Extended.
So lots of "random" messages are being interpreted as if they were a specific
CAN ID.
Since we're using VCAN and not a physical CAN bus there's no limit on the
number of messages that might be.
The two possible solutions are to filter all received packets in software, not
trusting the hardware filters, or (more simply) flush the socket after the
filter registration.
Happy Holidays!
Tom Evans