I am trying to open a SocketCAN J1939 and receive and send J1939 messages. I am very confused with type “sockaddr_can”. This structure has j1939.addr, j1939.pgn, j1939.name etc. When I receive a message with
recvfrom(s, &lCANFrame.data, sizeof(lCANFrame.data), 0x0, (struct sockaddr*)&j1939_addr, &recv_data_len)
where sockaddr_can j1939_addr;
, the address of the sender is in j1939_addr.can_addr.j1939.addr
and PGN of received message is in j1939_addr.can_addr.j1939.pgn
. However, I assigned the these values to be my SRC address and NAME as seen below when I am initializing the socket.
// J1939 CAN Socket
j1939_addr.can_family = AF_CAN;
j1939_addr.can_ifindex = ifr.ifr_ifindex;
j1939_addr.can_addr.j1939.name = J1939_NAME; //J1939 Name
j1939_addr.can_addr.j1939.addr = CAN_SRC_ADDR; //J1939: this is the SRC address of this device transmitting
//j1939_addr.can_addr.j1939.addr = J1939_IDLE_ADDR; //J1939: this is the SRC address of this device transmitting
j1939_addr.can_addr.j1939.pgn = J1939_NO_PGN; //This is a filter for receive function. This will only recieve PGN that is mentioned
So, when a message is received, ADDR and PGN are over written by the received message. If that is the case, how do I compare my NAME to received NAME and update my address if these is a conflict (for address claiming).
Does the Kernel take care of address claim?
Also, how do I send a message out. Below is not working. What am I doing wrong please?
send_response = sendto(s, &lCANFrame.data[1], 1, 0, (const struct sockaddr*)&j1939_addr, sizeof(j1939_addr)); //Send OUT CAN data to the interface //Send one byte CAN message OUT
I have tried send() and write() and I still can not send a message out. For CAN_RAW, everything works fine. Once I change the protocol to J1939, it does not work. Can you please give me a sample C code example. Here is my initialization:
s = socket(PF_CAN, SOCK_DGRAM, CAN_J1939); //Open J1939 socket
strcpy(ifr.ifr_name, can_int_name); //can_int_name is the can interface name "vcan0", can0 etc.
ioctl(s, SIOCGIFINDEX, &ifr); //Retreive the index to the CAN interface
// J1939 CAN Socket
j1939_addr.can_family = AF_CAN;
j1939_addr.can_ifindex = ifr.ifr_ifindex;
j1939_addr.can_addr.j1939.name = J1939_NAME; //J1939 Name
j1939_addr.can_addr.j1939.addr = CAN_SRC_ADDR; //J1939: this is the SRC address of this device transmitting
j1939_addr.can_addr.j1939.pgn = J1939_NO_PGN; //This is a filter for receive function. This will only recieve PGN that is mentioned
if(bind(s, (struct sockaddr*)&j1939_addr, sizeof(j1939_addr))) // Check to make sure Socket Binding is successful
{
perror("Error in Binding Socket");
}
Thank you
ha_purchase is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.