Compare commits

...

6 Commits

Author SHA1 Message Date
Oliver Hartkopp d651820d93
Merge 7e3e497693 into e9ea9d1168 2025-11-21 22:11:15 +07:00
Marc Kleine-Budde e9ea9d1168
Merge pull request #607 from marckleinebudde/cansend-fix-typo
cansend: fix typo in CANFD_FDF flag name
2025-11-07 12:55:39 +01:00
Marc Kleine-Budde 2d793d38d2 cansend: fix typo in CANFD_FDF flag name
Closes: https://github.com/linux-can/can-utils/issues/606
Fixes: 3e0e6ae3a4 ("cansend: print canfd_frame.flags in help text")
2025-11-07 12:51:19 +01:00
Marc Kleine-Budde 340a3b8c92
Merge pull request #605 from marckleinebudde/lib_h-selfcontained
lib.h: include linux/can.h
2025-11-07 12:34:08 +01:00
Marc Kleine-Budde d6c57240ed lib.h: include linux/can.h
Make lib.h self contained, so that language servers can parse it without
errors.
2025-11-07 12:30:15 +01:00
Oliver Hartkopp 7e3e497693 cangen: auto enable FD/XL content in mixed mode
Automatically create FD/XL content in mixed mode when the CAN interface
is capable to deal with it.

Suggested-by: Vincent Mailhol <mailhol@kernel.org>
Signed-off-by: Oliver Hartkopp <socketcan@hartkopp.net>
2025-09-08 18:41:11 +02:00
3 changed files with 66 additions and 50 deletions

112
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, " -R (generate RTR frames)\n");
fprintf(stderr, " -8 (allow DLC values greater then 8 for Classic CAN frames)\n");
fprintf(stderr, " -m (mix -e -f -b -E -R -X frames)\n");
fprintf(stderr, " -m (mix CC [-e -R] FD [-f -b -E] XL [-X] on capable devices)\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, " -D <mode> (CAN data (payload) generation mode - see below)\n");
@ -455,6 +455,8 @@ int main(int argc, char **argv)
unsigned char extended = 0;
unsigned char canfd = 0;
unsigned char canxl = 0;
unsigned char canfd_en = 1; /* mix default */
unsigned char canxl_en = 1; /* mix default */
unsigned char brs = 0;
unsigned char esi = 0;
unsigned char mix = 0;
@ -574,7 +576,6 @@ int main(int argc, char **argv)
case 'm':
mix = 1;
canfd = 1; /* to switch the socket into CAN FD mode */
view |= CANLIB_VIEW_INDENT_SFF;
break;
@ -777,14 +778,58 @@ int main(int argc, char **argv)
&loopback, sizeof(loopback));
}
if (canfd || canxl) {
/* get CAN netdevice MTU for frame type capabilities */
if (ioctl(s, SIOCGIFMTU, &ifr) < 0) {
perror("SIOCGIFMTU");
return 1;
}
/* check if the frame fits into the CAN netdevice */
if (ioctl(s, SIOCGIFMTU, &ifr) < 0) {
perror("SIOCGIFMTU");
/* check CAN XL support */
if (ifr.ifr_mtu < (int)CANXL_MIN_MTU) {
canxl_en = 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) {
canfd_en = 0;
if (canfd) {
printf("CAN interface not CAN FD capable - sorry.\n");
return 1;
}
}
/* enable CAN FD on the socket */
if (canfd_en) {
/* 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 (canxl_en) {
/* 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) {
/* 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));
@ -793,41 +838,6 @@ int main(int argc, char **argv)
if (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 {
/* sanitize Classical CAN 2.0 frame length */
if (len8_dlc) {
@ -1084,15 +1094,19 @@ int main(int argc, char **argv)
if (mix) {
i = random();
extended = i & 1;
canfd = i & 2;
if (canfd) {
brs = i & 4;
esi = i & 8;
if (canfd_en) {
canfd = i & 2;
if (canfd) {
brs = i & 4;
esi = i & 8;
}
}
if (canxl_en) {
if (canfd_en)
canxl = ((i & 96) == 96); /* 1/4 */
else
canxl = ((i & 32) == 32); /* 1/2 */
}
/* 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

@ -83,7 +83,7 @@ static void print_usage(char *prg)
" a single ASCII Hex value (0 .. F) which defines canfd_frame.flags:\n"
" %x CANFD_BRS\n"
" %x CANFD_ESI\n"
" %x CANFD_FEF\n"
" %x CANFD_FDF\n"
"\n"
"<vcid>:\n"
" 2 hex chars - virtual CAN network identifier (00 .. FF)\n"

2
lib.h
View File

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