15 struct HW :
public CAN {
19 HW(
const char *ifname ) {
21 sock = socket(PF_CAN, SOCK_RAW, CAN_RAW);
23 int flags = fcntl(sock, F_GETFL, 0);
25 perror(
"cannot get CAN socket flags");
28 if (fcntl(sock, F_SETFL, flags | O_NONBLOCK) == -1) {
29 perror(
"cannot set O_NONBLOCK on CAN socket");
33 struct ifreq ifr = {};
34 strncpy(ifr.ifr_name, ifname, IF_NAMESIZE);
35 if (ioctl(sock, SIOCGIFINDEX, &ifr) == -1) {
36 perror(
"cannot find CAN interface index");
40 struct sockaddr_can addr {
42 .can_ifindex = ifr.ifr_ifindex,
45 if (bind(sock, (
struct sockaddr *)&addr,
sizeof(addr)) == -1) {
46 perror(
"cannot bind socket to CAN interface");
56 void push(Message &&msg)
override {
57 struct can_frame frame = frameFromMessage(std::move(msg));
64 auto frame = tx.
front();
65 int l = write(sock, &frame,
sizeof(frame));
67 if (errno != EAGAIN) {
68 perror(
"writing on CAN socket error");
71 }
else if ((
size_t)l <
sizeof(frame)) {
72 fprintf(stderr,
"write: incomplete CAN frame: %d\n", l);
81 Message
pop()
override {
85 struct can_frame frame;
86 int l = read(sock, &frame,
sizeof(frame));
88 if (errno != EAGAIN) {
89 perror(
"reading on CAN socket error");
92 }
else if ((
size_t)l <
sizeof(frame)) {
93 fprintf(stderr,
"read: incomplete CAN frame: %d\n", l);
96 Message msg = messageFromFrame(frame);
100 struct can_frame frameFromMessage(Message &&msg) {
101 struct can_frame f {};
103 if (msg.opts.rtr) f.can_id |= CAN_RTR_FLAG;
104 f.len = msg.opts.dlc;
105 for (
int i = 0; i < f.len; ++i) {
106 f.data[i] = ((uint8_t*)&msg.data)[i];
110 Message messageFromFrame(
struct can_frame frame) {
112 .id = frame.can_id & ((1<<30)-1),
114 .rtr = !!(frame.can_id & CAN_RTR_FLAG),
118 for (
int i = 0; i < frame.len; ++i) {
119 ((uint8_t*)&msg.data)[i] = frame.data[i];