diff --git a/README.md b/README.md index 06178d8..3e8c22d 100644 --- a/README.md +++ b/README.md @@ -11,7 +11,7 @@ subsystem (aka SocketCAN): * candump : display, filter and log CAN data to files * canplayer : replay CAN logfiles -* cansend : send a single frame +* cansend : send single frames * cangen : generate (random) CAN traffic * cansniffer : display CAN data content differences (just 11bit CAN IDs) diff --git a/cansend.c b/cansend.c index a9f189f..5b9e2b7 100644 --- a/cansend.c +++ b/cansend.c @@ -60,14 +60,15 @@ int main(int argc, char **argv) int s; /* can raw socket */ int required_mtu; int mtu; - int enable_canfd = 1; + int enable_canfd = 0; + int framecnt; struct sockaddr_can addr; struct canfd_frame frame; struct ifreq ifr; /* check command line options */ - if (argc != 3) { - fprintf(stderr, "Usage: %s .\n", argv[0]); + if (argc < 3) { + fprintf(stderr, "Usage: %s ...\n", argv[0]); return 1; } @@ -100,52 +101,57 @@ int main(int argc, char **argv) return 1; } - /* parse CAN frame */ - required_mtu = parse_canframe(argv[2], &frame); - if (!required_mtu){ - fprintf(stderr, "\nWrong CAN-frame format! Try:\n\n"); - fprintf(stderr, " #{R|data} for CAN 2.0 frames\n"); - fprintf(stderr, " ##{data} for CAN FD frames\n\n"); - fprintf(stderr, " can have 3 (SFF) or 8 (EFF) hex chars\n"); - fprintf(stderr, "{data} has 0..8 (0..64 CAN FD) ASCII hex-values (optionally"); - fprintf(stderr, " separated by '.')\n"); - fprintf(stderr, " a single ASCII Hex value (0 .. F) which defines"); - fprintf(stderr, " canfd_frame.flags\n\n"); - fprintf(stderr, "e.g. 5A1#11.2233.44556677.88 / 123#DEADBEEF / 5AA# / "); - fprintf(stderr, "123##1 / 213##311\n 1F334455#1122334455667788 / 123#R "); - fprintf(stderr, "for remote transmission request.\n\n"); - return 1; - } - - if (required_mtu > CAN_MTU) { - - /* check if the frame fits into the CAN netdevice */ - if (ioctl(s, SIOCGIFMTU, &ifr) < 0) { - perror("SIOCGIFMTU"); - return 1; - } - mtu = ifr.ifr_mtu; - - if (mtu != CANFD_MTU) { - printf("CAN interface is not CAN FD capable - sorry.\n"); + for (framecnt = 2; framecnt < argc; framecnt++) { + /* parse CAN frame */ + required_mtu = parse_canframe(argv[framecnt], &frame); + if (!required_mtu){ + fprintf(stderr, "\nWrong CAN-frame format! Try:\n\n"); + fprintf(stderr, " #{R|data} for CAN 2.0 frames\n"); + fprintf(stderr, " ##{data} for CAN FD frames\n\n"); + fprintf(stderr, " can have 3 (SFF) or 8 (EFF) hex chars\n"); + fprintf(stderr, "{data} has 0..8 (0..64 CAN FD) ASCII hex-values (optionally"); + fprintf(stderr, " separated by '.')\n"); + fprintf(stderr, " a single ASCII Hex value (0 .. F) which defines"); + fprintf(stderr, " canfd_frame.flags\n\n"); + fprintf(stderr, "e.g. 5A1#11.2233.44556677.88 / 123#DEADBEEF / 5AA# / "); + fprintf(stderr, "123##1 / 213##311\n 1F334455#1122334455667788 / 123#R "); + fprintf(stderr, "for remote transmission request.\n\n"); return 1; } - /* interface is ok - try to switch the socket into CAN FD mode */ - if (setsockopt(s, SOL_CAN_RAW, CAN_RAW_FD_FRAMES, - &enable_canfd, sizeof(enable_canfd))){ - printf("error when enabling CAN FD support\n"); - return 1; + if (required_mtu > CAN_MTU) { + + if (enable_canfd == 0) { + /* check if the frame fits into the CAN netdevice */ + if (ioctl(s, SIOCGIFMTU, &ifr) < 0) { + perror("SIOCGIFMTU"); + return 1; + } + mtu = ifr.ifr_mtu; + + if (mtu != CANFD_MTU) { + printf("CAN interface is not CAN FD capable - sorry.\n"); + return 1; + } + + /* interface is ok - try to switch the socket into CAN FD mode */ + enable_canfd = 1; + if (setsockopt(s, SOL_CAN_RAW, CAN_RAW_FD_FRAMES, + &enable_canfd, sizeof(enable_canfd))){ + printf("error when enabling CAN FD support\n"); + return 1; + } + } + + /* ensure discrete CAN FD length values 0..8, 12, 16, 20, 24, 32, 64 */ + frame.len = can_dlc2len(can_len2dlc(frame.len)); } - /* ensure discrete CAN FD length values 0..8, 12, 16, 20, 24, 32, 64 */ - frame.len = can_dlc2len(can_len2dlc(frame.len)); - } - - /* send frame */ - if (write(s, &frame, required_mtu) != required_mtu) { - perror("write"); - return 1; + /* send frame */ + if (write(s, &frame, required_mtu) != required_mtu) { + perror("write"); + return 1; + } } close(s);