#include #include #include #include #include #include #include #include #include #include #include #include #include #include static void usage(int argc, char **argv, const char *message, ...) { if (message) { va_list args; va_start(args, message); vfprintf(stderr, message, args); va_end(args); } fprintf(stderr, "usage: %s canif [file.can]\n", argv[0]); exit(1); } static int capture_replay(hexagram_capture *capture, int sock) { ssize_t len; uint32_t timestamp[2], usec_last = 0; struct can_frame frame; while (1) { if ((len = hexagram_capture_read(capture, ×tamp[0], ×tamp[1], &frame)) < 0) { goto error_io; } else if (len == 0) { break; } if (usec_last) { usleep((useconds_t)(timestamp[1] - usec_last)); } if (write(sock, &frame, sizeof(struct can_frame)) < 0) { goto error_io; } usec_last = timestamp[1]; } return 0; error_io: return -1; } int main(int argc, char **argv) { struct sockaddr_can addr; struct ifreq ifr; int sock; hexagram_capture *capture; if (argc == 2) { if ((capture = hexagram_capture_open_fd(fileno(stdin), O_RDONLY)) == NULL) { goto error_capture_open; } } else if (argc == 3) { if ((capture = hexagram_capture_open_file(argv[2], O_RDONLY)) == NULL) { perror("hexagram_capture_open_file()"); goto error_capture_open; } } else { usage(argc, argv, NULL); exit(1); } if ((sock = socket(PF_CAN, SOCK_RAW, CAN_RAW)) < 0) { perror("socket()"); goto error_socket; } strcpy(ifr.ifr_name, argv[1]); ioctl(sock, SIOCGIFINDEX, &ifr); addr.can_family = AF_CAN; addr.can_ifindex = ifr.ifr_ifindex; if (bind(sock, (struct sockaddr *)&addr, sizeof(addr)) < 0) { perror("bind()"); goto error_bind; } if (capture_replay(capture, sock) < 0) { perror("capture_replay()"); goto error_capture_replay; } close(sock); if (argc == 3) { hexagram_capture_close(capture); } return 0; error_capture_replay: error_bind: close(sock); error_socket: if (argc == 3) { hexagram_capture_close(capture); } error_capture_open: return 1; }