#include #include #include #include #include #include #include #include #include #include #include #include #define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0])) static int open_can_sock(void) { struct can_filter rfilter; can_err_mask_t err_mask = CAN_ERR_TX_TIMEOUT | CAN_ERR_BUSOFF; struct ifreq ifr; int s; s = socket(PF_CAN, SOCK_RAW, CAN_RAW); if (s == -1) { perror("socket\n"); exit(EXIT_FAILURE); } strcpy(ifr.ifr_name, "can0"); if (ioctl(s, SIOCGIFINDEX, &ifr) == -1) { perror("ioctl\n"); exit(EXIT_FAILURE); } /* receive all frames */ rfilter.can_id = 0x000; rfilter.can_mask = 0x000; setsockopt(s, SOL_CAN_RAW, CAN_RAW_FILTER, &rfilter, sizeof(rfilter)); setsockopt(s, SOL_CAN_RAW, CAN_RAW_ERR_FILTER, &err_mask, sizeof(err_mask)); return s; } int main(void) { struct pollfd pfd[1]; int ret; int s; s = open_can_sock(); pfd[0].fd = s; for (;;) { int want_tx = 0; int timeout = 1; /* miliseconds */ pfd[0].events = POLLIN; if (want_tx) pfd[0].events |= POLLOUT; ret = poll(pfd, ARRAY_SIZE(pfd), timeout); if (ret < 0) { if (errno == EINTR) continue; perror("poll"); exit(EXIT_FAILURE); } else if (ret == 0) { /* timeout */ fprintf(stderr, "timeout"); continue; } if (pfd[0].revents & (POLLERR | POLLHUP | POLLNVAL)) { fprintf(stderr, "file descriptor error\n"); exit(EXIT_FAILURE); } if (pfd[0].revents & POLLIN) { struct can_frame frame; int ret; ret = read(s, &frame, sizeof(frame)); if (ret < 0) { if (errno != -EINTR && errno != -EAGAIN) { perror("read error"); exit(EXIT_FAILURE); } } else if (ret < sizeof(frame)) { fprintf(stderr, "read: incomplete CAN frame\n"); exit(EXIT_FAILURE); } else { fprintf(stderr, "received frame\n"); } } if (want_tx && (pfd[0].revents & POLLOUT)) { struct can_frame frame; int ret; memset(&frame, 0, sizeof(frame)); ret = write(s, &frame, sizeof(frame)); if (ret < 0) { if (errno != -EINTR && errno != -EAGAIN) { perror("write error"); exit(EXIT_FAILURE); } } } } }