Search code examples
linux-kernelsocketsmac-address

SocketCAN read socket call is blocking


I am trying to do a socket read from CAN socket. My read call is getting blocked and never returns control outside.

Steps in my code flow:

  1. open a socket
  2. assign interface name
  3. assign CAN ID
  4. Assign CAN mask
  5. bind
  6. read/receive call to socket

Here is the code:

mSock = socket(PF_CAN,SOCK_RAW,CAN_RAW);
if(mSock < 0)  {
    std::cout << "failed to open socket\n" << std::endl;
}
else  {
    std::cout << "mSock = \n" << mSock << std::endl;
}
strcpy(ifr.ifr_name,"can0");
iotlRetVal = ioctl(mSock,SIOCGIFINDEX, &ifr);

if(iotlRetVal < 0)  {
    std::cout << "failed to open socket\n" << std::endl;
}
else  {
    std::cout << "ifr.ifr_ifindex = \n" << ifr.ifr_ifindex << std::endl;
}

cfilter.can_id = 0xabcdef0;
cfilter.can_mask = CAN_EFF_MASK;

addr.can_family = AF_CAN;
addr.can_ifindex = ifr.ifr_ifindex;

bindRetVal = bind(mSock, (struct sockaddr *) &addr, sizeof(addr));
if(bindRetVal < 0)  {
    std::cout << "failed to bind socket\n" << std::endl;
}
else  {
    std::cout << "bindRetVal = \n" << bindRetVal << std::endl;
}
char buff[200];
int len;
int test;

test = recvfrom(mSock, &buff, sizeof(buff), 0,
         (struct sockaddr *) &addr, (socklen_t *)&len);
printf("test:%d \t len:%d\n",test,len);

What I am observing is that this call is not returning at all, and is simply getting blocked.

If I do ifconfig -a in my Linux PC, I see the following:

can0      Link encap:UNSPEC  HWaddr 00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00  
          UP RUNNING NOARP  MTU:16  Metric:1
          RX packets:0 errors:0 dropped:0 overruns:0 frame:0
          TX packets:0 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:10 
          RX bytes:0 (0.0 B)  TX bytes:0 (0.0 B)
          Interrupt:83 

Is it related to the 00s in the Hwaddr: 00-00-00 ..... Does this happen when there is problem on my Can interface hardware?

Or if it is a software issue, under what scenario would my read call get blocked?


Solution

  • It's the normal behaviour and happens when there is no message in the buffer. As soon as there is a message in the bus it will return with the contents of the message.
    If you don't want to wait, then use O_NONBLOCK flag.

    For global setting use fcntl(mSock, F_SETFL, O_NONBLOCK) on the open file description.

    If you intend to use it only per-call option with recvfrom(...), then use MSG_DONTWAIT on the other hand.