Compare commits

..

1 Commits

Author SHA1 Message Date
Ben Gardiner fc53b4e8d2
Merge 63500f8dd0 into 8bf5f8873f 2025-10-07 10:30:58 -07:00
4 changed files with 65 additions and 133 deletions

View File

@ -113,8 +113,7 @@ static const int canfx_on = 1;
#define MAXANI 4 #define MAXANI 4
static const char anichar[MAXANI] = { '|', '/', '-', '\\' }; static const char anichar[MAXANI] = { '|', '/', '-', '\\' };
static const char extra_fd_info[4][4] = { "- -", "B -", "- E", "B E" }; static const char extra_m_info[4][4] = { "- -", "B -", "- E", "B E" };
static const char extra_xl_info[4][4] = { "- -", "S -", "- R", "S R" };
extern int optind, opterr, optopt; extern int optind, opterr, optopt;
@ -144,7 +143,7 @@ static void print_usage(void)
fprintf(stderr, " -d (monitor dropped CAN frames)\n"); fprintf(stderr, " -d (monitor dropped CAN frames)\n");
fprintf(stderr, " -e (dump CAN error frames in human-readable format)\n"); fprintf(stderr, " -e (dump CAN error frames in human-readable format)\n");
fprintf(stderr, " -8 (display raw DLC values in {} for Classical CAN)\n"); fprintf(stderr, " -8 (display raw DLC values in {} for Classical CAN)\n");
fprintf(stderr, " -x (print extra message infos, rx/tx [brs esi|sec rrs])\n"); fprintf(stderr, " -x (print extra message infos, rx/tx brs esi)\n");
fprintf(stderr, " -T <msecs> (terminate after <msecs> if no frames were received)\n"); fprintf(stderr, " -T <msecs> (terminate after <msecs> if no frames were received)\n");
fprintf(stderr, "\n"); fprintf(stderr, "\n");
fprintf(stderr, "Up to %d CAN interfaces with optional filter sets can be specified\n", MAXSOCK); fprintf(stderr, "Up to %d CAN interfaces with optional filter sets can be specified\n", MAXSOCK);
@ -893,16 +892,11 @@ int main(int argc, char **argv)
if (extra_msg_info) { if (extra_msg_info) {
if (msg.msg_flags & MSG_DONTROUTE) if (msg.msg_flags & MSG_DONTROUTE)
alen += sprintf(afrbuf + alen, " TX"); alen += sprintf(afrbuf + alen, " TX %s",
extra_m_info[cu.fd.flags & 3]);
else else
alen += sprintf(afrbuf + alen, " RX"); alen += sprintf(afrbuf + alen, " RX %s",
extra_m_info[cu.fd.flags & 3]);
if (cu.xl.flags & CANXL_XLF)
alen += sprintf(afrbuf + alen, " %s",
extra_xl_info[cu.xl.flags & 3]);
else
alen += sprintf(afrbuf + alen, " %s",
extra_fd_info[cu.fd.flags & 3]);
} }
alen += sprintf(afrbuf + alen, "%s ", (color == 1) ? col_off : ""); alen += sprintf(afrbuf + alen, "%s ", (color == 1) ? col_off : "");

170
cangen.c
View File

@ -180,7 +180,7 @@ static void print_usage(char *prg)
fprintf(stderr, " -X (generate CAN XL CAN frames)\n"); fprintf(stderr, " -X (generate CAN XL CAN frames)\n");
fprintf(stderr, " -R (generate RTR frames)\n"); fprintf(stderr, " -R (generate RTR frames)\n");
fprintf(stderr, " -8 (allow DLC values greater then 8 for Classic CAN frames)\n"); fprintf(stderr, " -8 (allow DLC values greater then 8 for Classic CAN frames)\n");
fprintf(stderr, " -m (mix CC [-e -R] FD [-f -b -E] XL [-X] on capable devices)\n"); fprintf(stderr, " -m (mix -e -f -b -E -R -X frames)\n");
fprintf(stderr, " -I <mode> (CAN ID generation mode - see below)\n"); fprintf(stderr, " -I <mode> (CAN ID generation mode - see below)\n");
fprintf(stderr, " -L <mode> (CAN data length code (dlc) generation mode - see below)\n"); fprintf(stderr, " -L <mode> (CAN data length code (dlc) generation mode - see below)\n");
fprintf(stderr, " -D <mode> (CAN data (payload) generation mode - see below)\n"); fprintf(stderr, " -D <mode> (CAN data (payload) generation mode - see below)\n");
@ -339,9 +339,10 @@ resend:
nbytes = sendmsg(fd, &msg, 0); nbytes = sendmsg(fd, &msg, 0);
if (nbytes < 0) { if (nbytes < 0) {
ret = -errno; ret = -errno;
if (ret != -ENOBUFS) if (ret != -ENOBUFS) {
perror("write");
return ret; return ret;
}
if (!ignore_enobufs && !timeout) { if (!ignore_enobufs && !timeout) {
perror("write"); perror("write");
return ret; return ret;
@ -454,9 +455,6 @@ int main(int argc, char **argv)
unsigned char extended = 0; unsigned char extended = 0;
unsigned char canfd = 0; unsigned char canfd = 0;
unsigned char canxl = 0; unsigned char canxl = 0;
unsigned char mixcc = 1; /* mix default */
unsigned char mixfd = 1; /* mix default */
unsigned char mixxl = 1; /* mix default */
unsigned char brs = 0; unsigned char brs = 0;
unsigned char esi = 0; unsigned char esi = 0;
unsigned char mix = 0; unsigned char mix = 0;
@ -576,6 +574,7 @@ int main(int argc, char **argv)
case 'm': case 'm':
mix = 1; mix = 1;
canfd = 1; /* to switch the socket into CAN FD mode */
view |= CANLIB_VIEW_INDENT_SFF; view |= CANLIB_VIEW_INDENT_SFF;
break; break;
@ -778,58 +777,14 @@ int main(int argc, char **argv)
&loopback, sizeof(loopback)); &loopback, sizeof(loopback));
} }
/* get CAN netdevice MTU for frame type capabilities */
if (ioctl(s, SIOCGIFMTU, &ifr) < 0) {
perror("SIOCGIFMTU");
return 1;
}
/* check CAN XL support */
if (ifr.ifr_mtu < (int)CANXL_MIN_MTU) {
mixxl = 0;
if (canxl) {
printf("CAN interface not CAN XL capable - sorry.\n");
return 1;
}
}
/* check CAN FD support */
if (ifr.ifr_mtu < (int)CANFD_MTU) {
mixfd = 0;
if (canfd) {
printf("CAN interface not CAN FD capable - sorry.\n");
return 1;
}
}
/* enable CAN FD on the socket */
if (mixfd) {
/* interface is ok - try to switch the socket into CAN FD mode */
if (setsockopt(s, SOL_CAN_RAW, CAN_RAW_FD_FRAMES,
&enable_canfx, sizeof(enable_canfx))){
printf("error when enabling CAN FD support\n");
return 1;
}
}
/* enable CAN XL on the socket */
if (mixxl) {
/* interface is ok - try to switch the socket into CAN XL mode */
if (setsockopt(s, SOL_CAN_RAW, CAN_RAW_XL_FRAMES,
&enable_canfx, sizeof(enable_canfx))){
printf("error when enabling CAN XL support\n");
return 1;
}
/* try to enable the CAN XL VCID pass through mode */
if (setsockopt(s, SOL_CAN_RAW, CAN_RAW_XL_VCID_OPTS,
&vcid_opts, sizeof(vcid_opts))) {
printf("error when enabling CAN XL VCID pass through\n");
return 1;
}
}
/* sanitize given values */
if (canfd || canxl) { if (canfd || canxl) {
/* check if the frame fits into the CAN netdevice */
if (ioctl(s, SIOCGIFMTU, &ifr) < 0) {
perror("SIOCGIFMTU");
return 1;
}
if (canfd) { if (canfd) {
/* ensure discrete CAN FD length values 0..8, 12, 16, 20, 24, 32, 64 */ /* ensure discrete CAN FD length values 0..8, 12, 16, 20, 24, 32, 64 */
cu.fd.len = can_fd_dlc2len(can_fd_len2dlc(cu.fd.len)); cu.fd.len = can_fd_dlc2len(can_fd_len2dlc(cu.fd.len));
@ -838,6 +793,41 @@ int main(int argc, char **argv)
if (cu.fd.len > CANFD_MAX_DLEN) if (cu.fd.len > CANFD_MAX_DLEN)
cu.fd.len = CANFD_MAX_DLEN; cu.fd.len = CANFD_MAX_DLEN;
} }
if (canxl && (ifr.ifr_mtu < (int)CANXL_MIN_MTU)) {
printf("CAN interface not CAN XL capable - sorry.\n");
return 1;
}
if (canfd && (ifr.ifr_mtu < (int)CANFD_MTU)) {
printf("CAN interface not CAN FD capable - sorry.\n");
return 1;
}
if (ifr.ifr_mtu == (int)CANFD_MTU) {
/* interface is ok - try to switch the socket into CAN FD mode */
if (setsockopt(s, SOL_CAN_RAW, CAN_RAW_FD_FRAMES,
&enable_canfx, sizeof(enable_canfx))){
printf("error when enabling CAN FD support\n");
return 1;
}
}
if (ifr.ifr_mtu >= (int)CANXL_MIN_MTU) {
/* interface is ok - try to switch the socket into CAN XL mode */
if (setsockopt(s, SOL_CAN_RAW, CAN_RAW_XL_FRAMES,
&enable_canfx, sizeof(enable_canfx))){
printf("error when enabling CAN XL support\n");
return 1;
}
/* try to enable the CAN XL VCID pass through mode */
if (setsockopt(s, SOL_CAN_RAW, CAN_RAW_XL_VCID_OPTS,
&vcid_opts, sizeof(vcid_opts))) {
printf("error when enabling CAN XL VCID pass through\n");
return 1;
}
}
} else { } else {
/* sanitize Classical CAN 2.0 frame length */ /* sanitize Classical CAN 2.0 frame length */
if (len8_dlc) { if (len8_dlc) {
@ -1050,31 +1040,8 @@ int main(int argc, char **argv)
} }
ret = do_send_one(s, &cu, mtu, polltimeout); ret = do_send_one(s, &cu, mtu, polltimeout);
if ((ret == -EINVAL) && mix) { if (ret)
/* mix mode: disable unsupported CAN frame type */
switch (mtu) {
case CAN_MTU:
mixcc = 0;
break;
case CANFD_MTU:
mixfd = 0;
break;
case CANXL_MTU:
mixxl = 0;
break;
default:
printf ("mix mode: unknown MTU");
return 1;
}
if (!mixcc && !mixfd && !mixxl) {
printf ("mix mode: no valid CAN frame types\n");
return 1;
}
} else if (ret) {
/* other error than -ENOBUFS and -EINVAL */
perror("write");
return 1; return 1;
}
if (burst_sent_count >= burst_count) if (burst_sent_count >= burst_count)
burst_sent_count = 0; burst_sent_count = 0;
@ -1115,41 +1082,18 @@ int main(int argc, char **argv)
} }
if (mix) { if (mix) {
canfd = 0;
canxl = 0;
i = random(); i = random();
extended = i & 1; extended = i & 1;
if (mixfd) { canfd = i & 2;
canfd = i & 2; if (canfd) {
if (canfd) { brs = i & 4;
brs = i & 4; esi = i & 8;
esi = i & 8;
}
}
if (mixxl) {
if (mixfd)
canxl = ((i & 96) == 96); /* 1/4 */
else
canxl = ((i & 32) == 32); /* 1/2 */
}
if (mixcc) {
rtr_frame = ((i & 24) == 24); /* reduce RTR to 1/4 */
} else {
/* no CC frames allowed - CAN XL-only mode? */
if (!canxl && !canfd) {
/* force XL or FD frames */
if (mixxl)
canxl = 1;
else if (mixfd) {
canfd = 1;
brs = i & 4;
esi = i & 8;
} else {
printf ("mix mode: no valid CAN frame types\n");
return 1;
}
}
} }
/* generate CAN XL traffic if the interface is capable */
if (ifr.ifr_mtu >= (int)CANXL_MIN_MTU)
canxl = ((i & 96) == 96);
rtr_frame = ((i & 24) == 24); /* reduce RTR frames to 1/4 */
} }
} }

View File

@ -80,10 +80,7 @@ static void print_usage(char *prg)
"_{dlc}:\n" "_{dlc}:\n"
" an optional 9..F data length code value when payload length is 8\n" " an optional 9..F data length code value when payload length is 8\n"
"<flags>:\n" "<flags>:\n"
" a single ASCII Hex value (0 .. F) which defines canfd_frame.flags:\n" " a single ASCII Hex value (0 .. F) which defines canfd_frame.flags\n"
" %x CANFD_BRS\n"
" %x CANFD_ESI\n"
" %x CANFD_FDF\n"
"\n" "\n"
"<vcid>:\n" "<vcid>:\n"
" 2 hex chars - virtual CAN network identifier (00 .. FF)\n" " 2 hex chars - virtual CAN network identifier (00 .. FF)\n"
@ -103,8 +100,7 @@ static void print_usage(char *prg)
" 1F334455#1122334455667788_B / 123#R / 00000123#R3 / 333#R8_E /\n" " 1F334455#1122334455667788_B / 123#R / 00000123#R3 / 333#R8_E /\n"
" 45123#81:00:12345678#11223344.556677 / 00242#81:07:40000123#112233\n" " 45123#81:00:12345678#11223344.556677 / 00242#81:07:40000123#112233\n"
"\n", "\n",
prg, prg, prg, prg);
CANFD_BRS, CANFD_ESI, CANFD_FDF);
} }
int main(int argc, char **argv) int main(int argc, char **argv)

2
lib.h
View File

@ -49,8 +49,6 @@
#include <stddef.h> #include <stddef.h>
#include <stdio.h> #include <stdio.h>
#include <linux/can.h>
#ifdef DEBUG #ifdef DEBUG
#define pr_debug(fmt, args...) printf(fmt, ##args) #define pr_debug(fmt, args...) printf(fmt, ##args)
#else #else