From 0be95b53185239fdad8488d28524c65a50547b0e Mon Sep 17 00:00:00 2001 From: Marc Kleine-Budde Date: Wed, 20 Dec 2023 13:24:53 +0100 Subject: [PATCH 1/9] canfdtest: fix filter for extended CAN frames Fixes: 8e66a0bae343 ("canfdtest: Add extended frame format support") Cc: RICCIARDI-Adrien --- canfdtest.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/canfdtest.c b/canfdtest.c index 12bad177..c532fa5a 100644 --- a/canfdtest.c +++ b/canfdtest.c @@ -553,11 +553,11 @@ int main(int argc, char *argv[]) const struct can_filter filters[] = { { .can_id = can_id_ping, - .can_mask = CAN_EFF_FLAG | CAN_RTR_FLAG | CAN_SFF_MASK, + .can_mask = CAN_EFF_FLAG | CAN_RTR_FLAG | CAN_EFF_MASK, }, { .can_id = can_id_pong, - .can_mask = CAN_EFF_FLAG | CAN_RTR_FLAG | CAN_SFF_MASK, + .can_mask = CAN_EFF_FLAG | CAN_RTR_FLAG | CAN_EFF_MASK, }, }; From 146fd949c90939bf37850bd4d503926ef9c39255 Mon Sep 17 00:00:00 2001 From: Marc Kleine-Budde Date: Tue, 19 Dec 2023 11:19:54 +0100 Subject: [PATCH 2/9] canfdtest: don't initialize global variables to 0 --- canfdtest.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/canfdtest.c b/canfdtest.c index c532fa5a..28efca63 100644 --- a/canfdtest.c +++ b/canfdtest.c @@ -54,11 +54,11 @@ static int exit_sig; static int inflight_count = CAN_MSG_COUNT; static canid_t can_id_ping = CAN_MSG_ID_PING; static canid_t can_id_pong = CAN_MSG_ID_PONG; -static int has_pong_id = 0; -static int is_can_fd = 0; -static int bit_rate_switch = 0; +static int has_pong_id; +static int is_can_fd; +static int bit_rate_switch; static int msg_len = CAN_MSG_LEN; -static int is_extended_frame_format = 0; +static int is_extended_frame_format; static void print_usage(char *prg) { From 104072f0386eb7bed126a4b9b782544f8e62ed6a Mon Sep 17 00:00:00 2001 From: Marc Kleine-Budde Date: Tue, 19 Dec 2023 14:37:30 +0100 Subject: [PATCH 3/9] canfdtest: make use of bool --- canfdtest.c | 27 ++++++++++++++------------- 1 file changed, 14 insertions(+), 13 deletions(-) diff --git a/canfdtest.c b/canfdtest.c index 28efca63..1b5fcdb3 100644 --- a/canfdtest.c +++ b/canfdtest.c @@ -24,6 +24,7 @@ #include #include #include +#include #include #include #include @@ -54,11 +55,11 @@ static int exit_sig; static int inflight_count = CAN_MSG_COUNT; static canid_t can_id_ping = CAN_MSG_ID_PING; static canid_t can_id_pong = CAN_MSG_ID_PONG; -static int has_pong_id; -static int is_can_fd; -static int bit_rate_switch; +static bool has_pong_id; +static bool is_can_fd; +static bool bit_rate_switch; static int msg_len = CAN_MSG_LEN; -static int is_extended_frame_format; +static bool is_extended_frame_format; static void print_usage(char *prg) { @@ -312,7 +313,7 @@ static int can_echo_dut(void) static int can_echo_gen(void) { struct canfd_frame *tx_frames; - int *recv_tx; + bool *recv_tx; struct canfd_frame rx_frame; unsigned char counter = 0; int send_pos = 0, recv_rx_pos = 0, recv_tx_pos = 0, unprocessed = 0, loops = 0; @@ -334,7 +335,7 @@ static int can_echo_gen(void) /* still send messages */ tx_frames[send_pos].len = msg_len; tx_frames[send_pos].can_id = can_id_ping; - recv_tx[send_pos] = 0; + recv_tx[send_pos] = false; for (i = 0; i < msg_len; i++) tx_frames[send_pos].data[i] = counter + i; @@ -367,7 +368,7 @@ static int can_echo_gen(void) /* own frame */ if (rx_frame.can_id == can_id_ping) { err = compare_frame(&tx_frames[recv_tx_pos], &rx_frame, 0); - recv_tx[recv_tx_pos] = 1; + recv_tx[recv_tx_pos] = true; recv_tx_pos++; if (recv_tx_pos == inflight_count) recv_tx_pos = 0; @@ -411,7 +412,7 @@ int main(int argc, char *argv[]) int echo_gen = 0; int opt, err; int enable_socket_option = 1; - int filter = 0; + bool filter = false; signal(SIGTERM, signal_handler); signal(SIGHUP, signal_handler); @@ -420,15 +421,15 @@ int main(int argc, char *argv[]) while ((opt = getopt(argc, argv, "bdef:gi:l:o:s:vx?")) != -1) { switch (opt) { case 'b': - bit_rate_switch = 1; + bit_rate_switch = true; break; case 'd': - is_can_fd = 1; + is_can_fd = true; break; case 'e': - is_extended_frame_format = 1; + is_extended_frame_format = true; break; case 'f': @@ -449,7 +450,7 @@ int main(int argc, char *argv[]) case 'o': can_id_pong = strtoul(optarg, NULL, 16); - has_pong_id = 1; + has_pong_id = true; break; case 's': @@ -461,7 +462,7 @@ int main(int argc, char *argv[]) break; case 'x': - filter = 1; + filter = true; break; case '?': From 874b0d9faee4e569a530017c27fec6eced0901d4 Mon Sep 17 00:00:00 2001 From: Marc Kleine-Budde Date: Tue, 19 Dec 2023 15:02:28 +0100 Subject: [PATCH 4/9] canfdtest: can_echo_gen(): decrease scope of struct canfd_frame rx_frame --- canfdtest.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/canfdtest.c b/canfdtest.c index 1b5fcdb3..c81bf01b 100644 --- a/canfdtest.c +++ b/canfdtest.c @@ -314,7 +314,6 @@ static int can_echo_gen(void) { struct canfd_frame *tx_frames; bool *recv_tx; - struct canfd_frame rx_frame; unsigned char counter = 0; int send_pos = 0, recv_rx_pos = 0, recv_tx_pos = 0, unprocessed = 0, loops = 0; int err = 0; @@ -357,6 +356,8 @@ static int can_echo_gen(void) else millisleep(1); } else { + struct canfd_frame rx_frame; + if (recv_frame(&rx_frame)) { err = -1; goto out_free; From 7bb00837d0b1a7cc66de279f5cdf5a971441cef4 Mon Sep 17 00:00:00 2001 From: Marc Kleine-Budde Date: Tue, 19 Dec 2023 15:02:54 +0100 Subject: [PATCH 5/9] canfdtest: can_echo_gen(): introduce struct canfd_frame *tx_frame; --- canfdtest.c | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/canfdtest.c b/canfdtest.c index c81bf01b..763e0e33 100644 --- a/canfdtest.c +++ b/canfdtest.c @@ -332,13 +332,15 @@ static int can_echo_gen(void) while (running) { if (unprocessed < inflight_count) { /* still send messages */ - tx_frames[send_pos].len = msg_len; - tx_frames[send_pos].can_id = can_id_ping; + struct canfd_frame *tx_frame = &tx_frames[send_pos]; + + tx_frame->len = msg_len; + tx_frame->can_id = can_id_ping; recv_tx[send_pos] = false; for (i = 0; i < msg_len; i++) - tx_frames[send_pos].data[i] = counter + i; - if (send_frame(&tx_frames[send_pos])) { + tx_frame->data[i] = counter + i; + if (send_frame(tx_frame)) { err = -1; goto out_free; } From f110bf4cdef64c0d2dffd0d2409e4158893ee14d Mon Sep 17 00:00:00 2001 From: Marc Kleine-Budde Date: Tue, 19 Dec 2023 15:02:02 +0100 Subject: [PATCH 6/9] canfdtest: can_echo_gen(): use modulo instead of if to handle wrap arounds --- canfdtest.c | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/canfdtest.c b/canfdtest.c index 763e0e33..89b51f37 100644 --- a/canfdtest.c +++ b/canfdtest.c @@ -346,8 +346,8 @@ static int can_echo_gen(void) } send_pos++; - if (send_pos == inflight_count) - send_pos = 0; + send_pos %= inflight_count; + unprocessed++; if (verbose == 1) echo_progress(counter); @@ -373,8 +373,7 @@ static int can_echo_gen(void) err = compare_frame(&tx_frames[recv_tx_pos], &rx_frame, 0); recv_tx[recv_tx_pos] = true; recv_tx_pos++; - if (recv_tx_pos == inflight_count) - recv_tx_pos = 0; + recv_tx_pos %= inflight_count; continue; } @@ -386,8 +385,7 @@ static int can_echo_gen(void) /* compare with expected */ err = compare_frame(&tx_frames[recv_rx_pos], &rx_frame, 1); recv_rx_pos++; - if (recv_rx_pos == inflight_count) - recv_rx_pos = 0; + recv_rx_pos %= inflight_count; loops++; if (test_loops && loops >= test_loops) From c35ed80b3d250d1c6c70918a75362446e53ce497 Mon Sep 17 00:00:00 2001 From: Marc Kleine-Budde Date: Tue, 19 Dec 2023 14:49:57 +0100 Subject: [PATCH 7/9] canfdtest: use struct msghdr::msg_flags to detect own frames ...instead of relying on the can_id_ping. --- canfdtest.c | 38 +++++++++++++++++++++++--------------- 1 file changed, 23 insertions(+), 15 deletions(-) diff --git a/canfdtest.c b/canfdtest.c index 89b51f37..d9005223 100644 --- a/canfdtest.c +++ b/canfdtest.c @@ -186,23 +186,30 @@ static void signal_handler(int signo) exit_sig = signo; } -static int recv_frame(struct canfd_frame *frame) +static int recv_frame(struct canfd_frame *frame, int *flags) { - ssize_t ret, len; - - if (is_can_fd) - len = sizeof(struct canfd_frame); - else - len = sizeof(struct can_frame); - - ret = recv(sockfd, frame, len, 0); - if (ret != len) { + struct iovec iov = { + .iov_base = frame, + .iov_len = is_can_fd ? sizeof(struct canfd_frame) : sizeof(struct can_frame), + }; + struct msghdr msg = { + .msg_iov = &iov, + .msg_iovlen = 1, + }; + ssize_t ret; + + ret = recvmsg(sockfd, &msg, 0); + if (ret != iov.iov_len) { if (ret < 0) - perror("recv failed"); + perror("recvmsg() failed"); else - fprintf(stderr, "recv returned %zd", ret); + fprintf(stderr, "recvmsg() returned %zd", ret); return -1; } + + if (flags) + *flags = msg.msg_flags; + return 0; } @@ -283,7 +290,7 @@ static int can_echo_dut(void) int err = 0; while (running) { - if (recv_frame(&frame)) + if (recv_frame(&frame, NULL)) return -1; frame_count++; if (verbose == 1) { @@ -359,8 +366,9 @@ static int can_echo_gen(void) millisleep(1); } else { struct canfd_frame rx_frame; + int flags; - if (recv_frame(&rx_frame)) { + if (recv_frame(&rx_frame, &flags)) { err = -1; goto out_free; } @@ -369,7 +377,7 @@ static int can_echo_gen(void) print_frame(rx_frame.can_id, rx_frame.data, rx_frame.len, 0); /* own frame */ - if (rx_frame.can_id == can_id_ping) { + if (flags & MSG_DONTROUTE) { err = compare_frame(&tx_frames[recv_tx_pos], &rx_frame, 0); recv_tx[recv_tx_pos] = true; recv_tx_pos++; From 2b07d1526466316e5a38cb0d0da7dfd7aea0cdb1 Mon Sep 17 00:00:00 2001 From: Marc Kleine-Budde Date: Tue, 19 Dec 2023 15:19:59 +0100 Subject: [PATCH 8/9] canfdtest: normalize_canid(): introduce and make use of it --- canfdtest.c | 25 +++++++++++++++---------- 1 file changed, 15 insertions(+), 10 deletions(-) diff --git a/canfdtest.c b/canfdtest.c index d9005223..a5cfbf23 100644 --- a/canfdtest.c +++ b/canfdtest.c @@ -121,6 +121,18 @@ static void print_compare(canid_t exp_id, const uint8_t *exp_data, uint8_t exp_d print_frame(rec_id, rec_data, rec_dlc, 0); } +static canid_t normalize_canid(canid_t id) +{ + if (is_extended_frame_format) { + id &= CAN_EFF_MASK; + id |= CAN_EFF_FLAG; + } else { + id &= CAN_SFF_MASK; + } + + return id; +} + static int compare_frame(const struct canfd_frame *exp, const struct canfd_frame *rec, int inc) { int i, err = 0; @@ -277,7 +289,7 @@ static void inc_frame(struct canfd_frame *frame) if (has_pong_id) frame->can_id = can_id_pong; else - frame->can_id++; + frame->can_id = normalize_canid(frame->can_id + 1); for (i = 0; i < frame->len; i++) frame->data[i]++; @@ -504,15 +516,8 @@ int main(int argc, char *argv[]) } } - if (is_extended_frame_format) { - can_id_ping &= CAN_EFF_MASK; - can_id_ping |= CAN_EFF_FLAG; - can_id_pong &= CAN_EFF_MASK; - can_id_pong |= CAN_EFF_FLAG; - } else { - can_id_ping &= CAN_SFF_MASK; - can_id_pong &= CAN_SFF_MASK; - } + can_id_ping = normalize_canid(can_id_ping); + can_id_pong = normalize_canid(can_id_pong); if ((argc - optind) != 1) print_usage(basename(argv[0])); From 046b9d3b8f469deb8e4927a219ef2f26eeddd47b Mon Sep 17 00:00:00 2001 From: Marc Kleine-Budde Date: Tue, 19 Dec 2023 14:25:33 +0100 Subject: [PATCH 9/9] canfdtest: use can0 per default --- canfdtest.c | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/canfdtest.c b/canfdtest.c index a5cfbf23..37c7ea47 100644 --- a/canfdtest.c +++ b/canfdtest.c @@ -65,7 +65,7 @@ static void print_usage(char *prg) { fprintf(stderr, "%s - Full-duplex test program (DUT and host part).\n" - "Usage: %s [options] \n" + "Usage: %s [options] []\n" "\n" "Options:\n" " -b (enable CAN FD Bit Rate Switch)\n" @@ -86,6 +86,8 @@ static void print_usage(char *prg) " are sent back incrementing the CAN id and\n" "all data bytes. The program can be aborted with ^C.\n" "\n" + "Using 'can0' as default CAN-interface.\n" + "\n" "Examples:\n" "\ton DUT:\n" "%s -v can0\n" @@ -428,7 +430,7 @@ static int can_echo_gen(void) int main(int argc, char *argv[]) { struct sockaddr_can addr; - char *intf_name; + char *intf_name = "can0"; int family = PF_CAN, type = SOCK_RAW, proto = CAN_RAW; int echo_gen = 0; int opt, err; @@ -519,9 +521,10 @@ int main(int argc, char *argv[]) can_id_ping = normalize_canid(can_id_ping); can_id_pong = normalize_canid(can_id_pong); - if ((argc - optind) != 1) + if ((argc - optind) == 1) + intf_name = argv[optind]; + else if ((argc - optind)) print_usage(basename(argv[0])); - intf_name = argv[optind]; printf("interface = %s, family = %d, type = %d, proto = %d\n", intf_name, family, type, proto);