Task
I wanted to write my own smaller version of candump. The aim being that it's similar in nature but with the only feature being that I would like to show only the incoming message from one CAN ID.
Code
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.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>
int
main(void) {
int s;
int nbytes;
struct sockaddr_can addr;
struct can_frame frame;
struct ifreq ifr;
// struct can_filter *rfilter; // how do work?
const char *ifname = "vcan0";
if((s = socket(PF_CAN, SOCK_RAW, CAN_RAW)) < 0) {
perror("Error while opening socket");
return -1;
}
strcpy(ifr.ifr_name, ifname);
ioctl(s, SIOCGIFINDEX, &ifr);
addr.can_family = AF_CAN;
addr.can_ifindex = ifr.ifr_ifindex;
if(bind(s, (struct sockaddr *)&addr, sizeof(addr)) < 0) {
perror("Error in socket bind");
return -2;
}
nbytes = read(s, &frame, sizeof(struct can_frame));
if(nbytes < 0) {
perror("Error reading from socket.\n");
return 1;
}
while(1) {
if(read(s, &frame, sizeof(struct can_frame)) > 0) {
//printf("Message...\n");
printf("%X - [len] - %X %X %X %X %X %X %X %X\n", frame.can_id,
frame.data[0], frame.data[1], frame.data[2], frame.data[3],
frame.data[4], frame.data[5], frame.data[6], frame.data[7]);
}
}
close(s);
return 0;
}
Problem
I've been using cansend with the command cansend vcan0 18DA40F1#1234
. When running my code the response I get back is almost there apart from the first character in the CAN ID being a value 8+ bigger. Response 98DA40F1 - [len] - 12 34 0 0 0 0 0 0
I get back running my code.
Looking at the source code of previously mentioned candump I think it's something to do with rfilter
but I'm not 100% sure and checking the SocketCAN documentation it doesn't feel much clearer. Is it something to do with masking? An example of how to solve my problem would be appreciated. Feel free to ask questions if there's anything you feel I've not mentioned.