I implemented a CAN bus communication for writing and read operations with linux. I am using socketCan library. Write function works correctly. I have problems with my reading function:
int can_receive(void)
{
struct can_frame frameRead;
//struct sockaddr_can addr;
//struct ifreq ifr;
//struct timeval tv;
//socklen_t len = sizeof(addr);
int8_t nbytesReceive;
//nbytesReceive = 16;
LE_INFO("while");
/*
while(nbytesReceive != -1)
{
if((nbytesReceive = recvfrom(sdr, &frameRead, sizeof(struct can_frame), 0, (struct sockaddr *)&addr, &len)) != sizeof(struct can_frame))
{
LE_INFO("Socket reading error, nbytesReceive = %d", nbytesReceive);
return SOCK_READING_ERROR;
}
else
{
ifr.ifr_ifindex = addr.can_ifindex;
ioctl(sdr, SIOCGIFNAME, &ifr);
ioctl(sdr, SIOCGSTAMP, &tv);
LE_INFO( " Receive message %02X %02X %02X %02X %02X %02X %02X %02X %02X", frameRead.can_id, frameRead.data[0], frameRead.data[1], frameRead.data[2], frameRead.data[3]
, frameRead.data[4], frameRead.data[5], frameRead.data[6], frameRead.data[7] );
}
}*/
LE_INFO("SDR is: %d ", sdr);
nbytesReceive = read(sdr, &frameRead, sizeof(frameRead));
LE_INFO("nbytes is: %d ", nbytesReceive);
while(nbytesReceive != 0)
{
if ((nbytesReceive = read(sdr, &frameRead, sizeof(frameRead))) != sizeof(frameRead))
{
LE_INFO("Socket reading error, nbytesReceive = %d", nbytesReceive);
return SOCK_READING_ERROR;
}
else
{
LE_INFO("Receive message %X %X %X %X %X %X %X %X %X", frameRead.can_id, frameRead.data[0], frameRead.data[1], frameRead.data[2], frameRead.data[3]
, frameRead.data[4], frameRead.data[5], frameRead.data[6], frameRead.data[7]);
}
}
return 0;
}
I implemented while in two ways in order to understand what happens (one is a comment). I obtain always socket error, so the first condition of while loop. I inizialized CAN_socket in this way:
// SOCKET FOR READING
sdr = socket(PF_CAN, SOCK_RAW, CAN_RAW);
LE_INFO("sdr è: %d", sdr);
if ((sdr = socket(PF_CAN, SOCK_RAW, CAN_RAW)) < 0)
{
LE_INFO("sdr errato");
return SOCKET_ERROR;
}
addr.can_family = AF_CAN;
strcpy(ifr.ifr_name, name);
if (ioctl(sdr, SIOCGIFINDEX, &ifr) < 0)
{
return SOCK_IOCTL_ERROR;
}
addr.can_ifindex = ifr.ifr_ifindex;
if (bind(sdr, (struct sockaddr *)&addr, sizeof(addr)) < 0)
{
return SOCK_BINDING_ERROR;
}
// Filter
struct can_filter rfilter[7]; int i = 0;
rfilter[i].can_id = CHG_TX_STS;
rfilter[i].can_mask = CAN_SFF_MASK | CAN_EFF_FLAG | CAN_RTR_FLAG; i++;
rfilter[i].can_id = CHG_TX_ACT;
rfilter[i].can_mask = CAN_SFF_MASK | CAN_EFF_FLAG | CAN_RTR_FLAG; i++;
rfilter[i].can_id = BMS_CHRGR_CTL;
rfilter[i].can_mask = CAN_SFF_MASK | CAN_EFF_FLAG | CAN_RTR_FLAG; i++;
rfilter[i].can_id = BMS_SOC_DATA;
rfilter[i].can_mask = CAN_SFF_MASK | CAN_EFF_FLAG | CAN_RTR_FLAG; i++;
rfilter[i].can_id = BMS_BATTP_DATA;
rfilter[i].can_mask = CAN_SFF_MASK | CAN_EFF_FLAG | CAN_RTR_FLAG; i++;
rfilter[i].can_id = BMS_BATP_DATA;
rfilter[i].can_mask = CAN_SFF_MASK | CAN_EFF_FLAG | CAN_RTR_FLAG; i++;
rfilter[i].can_id = BMS_BATU_DATA;
rfilter[i].can_mask = CAN_SFF_MASK | CAN_EFF_FLAG | CAN_RTR_FLAG; i++;
setsockopt(sdr, SOL_CAN_RAW, CAN_RAW_FILTER, &rfilter, sizeof(rfilter));
// SET SOCKET BUFFER SIZE
setsockopt(sdr, SOL_CAN_RAW, SO_RCVBUF, (char *)&sock_buf_size, sizeof(sock_buf_size));
Can kindly someone help me to understand where am I wrong, since I cannot read anything? I want to clarify that on therminal by candump command I can read CAN signals correctly, so the problem is in the software. Any help is appreciated Regards.