0

I am trying to send 29bit EFF CAN messages over socket can, but for some reason it sends them with 11bit identifier cutting off 5 bytes from ID. Using loopback mode, through candump i can see that messages are received as 11bit.

I get no errors, nothing, thats why i am confused

I am using raspberry pi 3b+ if that makes any difference. And Can-utils library.

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <time.h>
#include <net/if.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/ioctl.h>

#include <linux/can.h>
#include <linux/can/raw.h>

#include </home/pi/can-utils/lib.h>

int main(int argc, char **argv)
{
int s,loop = 1;
int nbytes;
struct sockaddr_can addr;
struct can_frame frame;
struct ifreq ifr;

//can interface 

if((s=socket(PF_CAN, SOCK_RAW, CAN_RAW))<0){
    perror("socket");
    return 1;
    }


strcpy(ifr.ifr_name, "can0");
if(ioctl(s, SIOCGIFINDEX, &ifr) < 0){
    perror("SIOCGIFINDEX");
    return 1;
    }


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


if(bind(s,(struct sockaddr *)&addr, sizeof(addr)) < 0){
    perror("bind");
    return 1;
    }

//data send loop

while(loop){
    int g;

for (int e = 0; e < 1020; e++){
if(e < 10) {g = 0;}
    else if (e%100 == 0){ g = 1;}
        else if (e%50 == 0){ g = 2;}
            else if (e%20 == 0) {g = 3;}

if (g==0){  
switch(e){

    case 1:                 //TOTAL FUEL USED 5-8
frame.can_id = 0x0000FEE9;
    printf("value %X",frame.can_id);
frame.can_dlc = 8;
frame.data[0] = 0x00;
frame.data[1] = 0x00;
frame.data[2] = 0x00;
frame.data[3] = 0x00;
frame.data[4] = 0xF5;       //0.5L/BIT
frame.data[5] = 0x06;       //0.5L/BIT
frame.data[6] = 0x07;       //0.5L/BIT
frame.data[7] = 0x08;       //0.5L/BIT
break;

    case 2:                 //FUEL LEVEL 2
frame.can_id = 0x0000FEFC;
frame.can_dlc = 8;
frame.data[0] = 0x00;
frame.data[1] = 0x88;       //0.4%/BIT
frame.data[2] = 0x00;
frame.data[3] = 0x00;
frame.data[4] = 0x00;
frame.data[5] = 0x00;
frame.data[6] = 0x00;
frame.data[7] = 0x00;
break;

    case 3:                 //TOTAL ENGINE HOURS 1-4
frame.can_id = 0x0000FEE5;  
frame.can_dlc = 8;
frame.data[0] = 0x11;       //0.05h/BIT
frame.data[1] = 0x22;       //0.05h/BIT
frame.data[2] = 0x33;       //0.05h/BIT
frame.data[3] = 0x44;       //0.05h/BIT
frame.data[4] = 0x00;
frame.data[5] = 0x00;
frame.data[6] = 0x00;
frame.data[7] = 0x00;
break;

    case 4:                 //MILLEAGE 1-4
frame.can_id = 0x0000FEC1;  
frame.can_dlc = 8;
frame.data[0] = 0x44;       //5M/BIT
frame.data[1] = 0x33;       //5M/BIT
frame.data[2] = 0x22;       //5M/BIT
frame.data[3] = 0x11;       //5M/BIT
frame.data[4] = 0x00;
frame.data[5] = 0x00;
frame.data[6] = 0x00;
frame.data[7] = 0x00;
break;

    case 5:
frame.can_id = 0x0000FEEE;  //ENGINE TEMPERATURE 1
frame.can_dlc = 8;
frame.data[0] = 0xCC;       //1C/BIT -40C OFFSET
frame.data[1] = 0x00;
frame.data[2] = 0x00;
frame.data[3] = 0x00;
frame.data[4] = 0x00;
frame.data[5] = 0x00;
frame.data[6] = 0x00;
frame.data[7] = 0x00;
break;

    case 6:
frame.can_id = 0x0000FEF5;  //AMBIENT TEMPERATURE 4-5
frame.can_dlc = 8;
frame.data[0] = 0x00;
frame.data[1] = 0x00;
frame.data[2] = 0x00;
frame.data[3] = 0xE4;       //0.03125C/BIT -273C OFFSET
frame.data[4] = 0xF2;       //0.03125C/BIT -273C OFFSET
frame.data[5] = 0x00;
frame.data[6] = 0x00;
frame.data[7] = 0x00;
break;

    case 7:                 //HIGH RES FUEL 5-8
frame.can_id = 0x0000FD09;  
frame.can_dlc = 8;
frame.data[0] = 0x00;       
frame.data[1] = 0x00;
frame.data[2] = 0x00;
frame.data[3] = 0x00;
frame.data[4] = 0x01;       //0.001L/BIT
frame.data[5] = 0x02;       //0.001L/BIT
frame.data[6] = 0x03;       //0.001L/BIT
frame.data[7] = 0x04;       //0.001L/BIT
break;

    case 8:             //VEHICLE WEIGHT 2-3
frame.can_id = 0x0000FEEA;  
frame.can_dlc = 8;
frame.data[0] = 0x00;
frame.data[1] = 0x05;       //0.5KG/BIT
frame.data[2] = 0xFF;       //0.5KG/BIT
frame.data[3] = 0x00;
frame.data[4] = 0x00;
frame.data[5] = 0x00;
frame.data[6] = 0x00;
frame.data[7] = 0x00;
break;

    case 9:             //DISTANCE BEFORE SERVICE 2-3
frame.can_id = 0x0000FEC0;  
frame.can_dlc = 8;
frame.data[0] = 0x00;
frame.data[1] = 0xEF;       //5KM/BIT -160 635 KM OFFSET
frame.data[2] = 0xCD;       //5KM/BIT -160 635 KM OFFSET
frame.data[3] = 0x00;
frame.data[4] = 0x00;
frame.data[5] = 0x00;
frame.data[6] = 0x00;
frame.data[7] = 0x00;
break;
    default:    
    break;
}

for(int i = 0; i <1; i++){
    if ((nbytes = write(s, &frame, sizeof(struct can_frame))) != sizeof(frame)){
        }
    }
}

if (g == 1){
    for(int l = 1; l < 5; l++){
        switch(l){
    case 1:                 //EEC 3-5
frame.can_id = 0x000CF004;
frame.can_dlc = 8;
frame.data[0] = 0x00;
frame.data[1] = 0x00;
frame.data[2] = 0xEE;       //TORQUE 1%/BIT -125% OFFSET
frame.data[3] = 0xEF;       //RPM 0.125/BIT
frame.data[4] = 0x12;       //RPM 0.125/BIT
frame.data[5] = 0x00;
frame.data[6] = 0x00;
frame.data[7] = 0x00;
break;

    case 2:                 //FUEL ECONOMY 1-4
frame.can_id = 0x0000FEF2;  
frame.can_dlc = 8;
frame.data[0] = 0xEC;       //FUEL RATE (0.05L/h)/BIT 
frame.data[1] = 0xFF;       //FUEL RATE (0.05L/h)/BIT 
frame.data[2] = 0x15;       //CURRENT FUEL (1/512KM/L)/BIT 
frame.data[3] = 0xE5;       //CURRENT FUEL (1/512KM/L)/BIT 
frame.data[4] = 0x00;
frame.data[5] = 0x00;
frame.data[6] = 0x00;
frame.data[7] = 0x00;
break;  

    case 3:                 //WHEEL SPEED 2-3
frame.can_id = 0x0000FEF1;  
frame.can_dlc = 8;
frame.data[0] = 0x00;       
frame.data[1] = 0x01;       //(1/256KM/h)/BIT
frame.data[2] = 0x99;       //(1/256KM/h)/BIT
frame.data[3] = 0x00;
frame.data[4] = 0x00;
frame.data[5] = 0x00;
frame.data[6] = 0x00;
frame.data[7] = 0x00;
break;

    case 4:             //EEC2 2-3
frame.can_id = 0x0000F003;
frame.can_dlc = 8;
frame.data[0] = 0x00;       
frame.data[1] = 0x03;       //0.4%/BIT CCELERATOR POSITION 
frame.data[2] = 0x55;       //1%/BIT ENGINE LOAD
frame.data[3] = 0x00;
frame.data[4] = 0x00;
frame.data[5] = 0x00;
frame.data[6] = 0x00;
frame.data[7] = 0x00;
break;  
}
        for(int i = 0; i <1; i++){
    if ((nbytes = write(s, &frame, sizeof(struct can_frame))) != sizeof(frame)){
        }
    }
    if(l<5) usleep(1000);
}

}
else if (g == 2){

frame.can_id = 0x0000F003;
frame.can_dlc = 8;
frame.data[0] = 0x00;       
frame.data[1] = 0x03;       //0.4%/BIT CCELERATOR POSITION 
frame.data[2] = 0x55;       //1%/BIT ENGINE LOAD
frame.data[3] = 0x00;
frame.data[4] = 0x00;
frame.data[5] = 0x00;
frame.data[6] = 0x00;
frame.data[7] = 0x00;

for(int i = 0; i <1; i++){
    if ((nbytes = write(s, &frame, sizeof(struct can_frame))) != sizeof(frame)){
        }
    }
    }
else if (g == 3){

frame.can_id = 0x0000F004;
frame.can_dlc = 8;
frame.data[0] = 0x00;
frame.data[1] = 0x00;
frame.data[2] = 0xEE;       //TORQUE 1%/BIT -125% OFFSET
frame.data[3] = 0xEF;       //RPM 0.125/BIT
frame.data[4] = 0x12;       //RPM 0.125/BIT
frame.data[5] = 0x00;
frame.data[6] = 0x00;
frame.data[7] = 0x00;

for(int i = 0; i <1; i++){
    if ((nbytes = write(s, &frame, sizeof(struct can_frame))) != sizeof(frame)){
        }
    }
    }
usleep(10000);
g = 5;
if(e==900) e = 0;
}
}                   

close(s);
return 0; 
}
  • It is important here to illuminate that whoever wrote this library uses very weird and incorrect terms. There is nothing called "EFF" in a CAN frame. If there was, it could only stand for End of Frame Field, a 7 bit recessive sequence sent at the end of each frame, which has absolutely nothing to do with extended and standard identifiers. So it the mask you are looking for should not be called EFF. The formal and correct name for the bit is IDE, identifier extension. This terms are all 100% formally standardized, make sure to use the correct ones. – Lundin Apr 04 '19 at 06:48
  • @Lundin SocketCAN _is_ the standard when it comes to dealing with CAN in Linux and SocketCAN calls it Extended Frame Format, hence `EFF_`, – Andreas Magnusson Feb 02 '21 at 18:50
  • @AndreasMagnusson Oh it got standardized? The CAN standard is called ISO 11898-2. What ISO number has "SocketCAN" gotten? – Lundin Feb 03 '21 at 08:10
  • @Lundin Ok, so de-facto standard if you're feeling nit-picky today :) – Andreas Magnusson Feb 03 '21 at 12:23
  • @AndreasMagnusson The point here is that when using something that's already properly standardized since several decades back, you stick to the standardized terms instead of inventing your own 3 letter abbreviations out of the blue. – Lundin Feb 04 '21 at 14:37
  • @Lundin While that _is_ a valid point, none of the people involved in this question on SO has had any influence whatsoever on the design of SocketCAN, so it's useless to make in this context. This question was tagged with `socketcan` so it doesn't matter what we would _like_ things to be called but what they are _actually_ called in SocketCAN. – Andreas Magnusson Feb 05 '21 at 08:46
  • @Lundin Funnily enough I had a work related reason to read ISO11898-1, the Data link layer part of the CAN standard. As it turns out, the CAN standard calls 29 bit IDs for _Extended Format_ IDs, so it seems SocketCAN isn't that far off after all. – Andreas Magnusson Feb 16 '21 at 10:33
  • @AndreasMagnusson Yes it is called the extended format or extended identifier. I think the argument here was about inventing new TLA that nobody understands. The individual bits of the arbitration field apart from the identifier are named SOF, RTR/SRR and IDE in the standard. – Lundin Feb 16 '21 at 10:51

1 Answers1

5

You need to add correct flag after setting can_id:

frame.can_id |= CAN_EFF_FLAG;

Or for example: instead of

frame.can_id = 0x0000FEE9

use

frame.can_id = 0x0000FEE9U | CAN_EFF_FLAG ;

Here U signifies, that your integer literal is unsigned. Also see https://github.com/linux-can/can-utils/blob/master/include/linux/can.h

nulleight
  • 794
  • 1
  • 5
  • 12