#include <linux/can.h>
#include <linux/can/raw.h>
#include <sys/socket.h>
#include <net/if.h>
int can_init(const char *ifname)
{
int s = socket(PF_CAN, SOCK_RAW, CAN_RAW);
struct ifreq ifr;
strcpy(ifr.ifr_name, ifname);
ioctl(s, SIOCGIFINDEX, &ifr);
struct sockaddr_can addr;
memset(&addr, 0, sizeof(addr));
addr.can_family = AF_CAN;
addr.can_ifindex = ifr.ifr_ifindex;
bind(s, (struct sockaddr *)&addr, sizeof(addr));
return s;
}
// 发送CAN帧
int can_send(int s, uint32_t id, uint8_t *data, uint8_t len)
{
struct can_frame frame;
frame.can_id = id;
frame.can_dlc = len;
memcpy(frame.data, data, len);
return write(s, &frame, sizeof(frame));
}
// 发送扩展帧
int can_send_extended(int s, uint32_t id, uint8_t *data, uint8_t len)
{
struct can_frame frame;
frame.can_id = id | CAN_EFF_FLAG;
frame.can_dlc = len;
memcpy(frame.data, data, len);
return write(s, &frame, sizeof(frame));
}
// 接收CAN帧
int can_recv(int s, uint32_t *id, uint8_t *data, uint8_t *len)
{
struct can_frame frame;
int nbytes = read(s, &frame, sizeof(frame));
if (nbytes < 0) return -1;
*id = frame.can_id & CAN_EFF_MASK;
*len = frame.can_dlc;
memcpy(data, frame.data, *len);
return 0;
}
// 设置过滤器
void can_set_filter(int s, uint32_t id, uint32_t mask)
{
struct can_filter filter;
filter.can_id = id;
filter.can_mask = mask;
setsockopt(s, SOL_CAN_RAW, CAN_RAW_FILTER, &filter, sizeof(filter));
}