CANbus errors bring down multiple sockets.

classic Classic list List threaded Threaded
1 message Options
Reply | Threaded
Open this post in threaded view

CANbus errors bring down multiple sockets.

Nathan Ehrenholz
When a CAN interface is disconnected from the bus by unplugging the hardware from the bus, and the socket connected to the unplugged CAN interface is continually sent data for transmission, all other sockets (including UDP) will be unable to receive/send data. The properly plugged in sockets will continue to operate for a certain amount of time, which seems to be proportional to the amount of data sent to the unplugged socket. This has been replicated with the peak_usb, sja1000, and kvaser_usb drivers, on Debian 8, 9 and Ubuntu.

The CAN Tx/Rx, and UDP Rx are continually looped to retry when errNo is EINTR, similar to:
{ n = read( fd, buf, CAN_FRAME_SIZE );
    if ( errNo == EINTR )
    { retry = TRUE; // Retry for an interrupted call. }
} while ( retry );

UDP Rx is similar however uses recvfrom() in the loop. The CAN socket is setup as follows:

// ---- Create a socket ----
fd = socket( PF_CAN, sockType, protocol );

// ---- Get the CAN interface index ----
strncpy( ifr.ifr_name, if, CAN_NAME_SIZE );
ioctl( fd, SIOCGIFINDEX, &ifr );
addr.can_family = AF_CAN;
addr.can_ifindex = ifr.ifr_ifindex;
bind( fd, (RawSocketAddr *) &addr, sizeof( addr ) );

Error frames seen on the bus are CAN_ERR_CTRL_TX_PASSIVE for every controller in this situation. And either many CAN_ERR_LOSTARB errors for the sja1000 driver, or many CAN_ERR_PROT_STUFF & CAN_ERR_PROT_FORM errors for the *_usb drivers.