Skip to content

Commit bddef73

Browse files
committed
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 <[email protected]> Signed-off-by: Oliver Hartkopp <[email protected]>
1 parent 8bf5f88 commit bddef73

File tree

1 file changed

+60
-46
lines changed

1 file changed

+60
-46
lines changed

cangen.c

Lines changed: 60 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -180,7 +180,7 @@ static void print_usage(char *prg)
180180
fprintf(stderr, " -X (generate CAN XL CAN frames)\n");
181181
fprintf(stderr, " -R (generate RTR frames)\n");
182182
fprintf(stderr, " -8 (allow DLC values greater then 8 for Classic CAN frames)\n");
183-
fprintf(stderr, " -m (mix -e -f -b -E -R -X frames)\n");
183+
fprintf(stderr, " -m (mix CC [-e -R] FD [-f -b -E] XL [-X] on capable devices)\n");
184184
fprintf(stderr, " -I <mode> (CAN ID generation mode - see below)\n");
185185
fprintf(stderr, " -L <mode> (CAN data length code (dlc) generation mode - see below)\n");
186186
fprintf(stderr, " -D <mode> (CAN data (payload) generation mode - see below)\n");
@@ -455,6 +455,8 @@ int main(int argc, char **argv)
455455
unsigned char extended = 0;
456456
unsigned char canfd = 0;
457457
unsigned char canxl = 0;
458+
unsigned char canfd_en = 1; /* mix default */
459+
unsigned char canxl_en = 1; /* mix default */
458460
unsigned char brs = 0;
459461
unsigned char esi = 0;
460462
unsigned char mix = 0;
@@ -574,7 +576,6 @@ int main(int argc, char **argv)
574576

575577
case 'm':
576578
mix = 1;
577-
canfd = 1; /* to switch the socket into CAN FD mode */
578579
view |= CANLIB_VIEW_INDENT_SFF;
579580
break;
580581

@@ -777,57 +778,66 @@ int main(int argc, char **argv)
777778
&loopback, sizeof(loopback));
778779
}
779780

780-
if (canfd || canxl) {
781+
/* get CAN netdevice MTU for frame type capabilities */
782+
if (ioctl(s, SIOCGIFMTU, &ifr) < 0) {
783+
perror("SIOCGIFMTU");
784+
return 1;
785+
}
781786

782-
/* check if the frame fits into the CAN netdevice */
783-
if (ioctl(s, SIOCGIFMTU, &ifr) < 0) {
784-
perror("SIOCGIFMTU");
787+
/* check CAN XL support */
788+
if (ifr.ifr_mtu < (int)CANXL_MIN_MTU) {
789+
canxl_en = 0;
790+
if (canxl) {
791+
printf("CAN interface not CAN XL capable - sorry.\n");
785792
return 1;
786793
}
794+
}
787795

796+
/* check CAN FD support */
797+
if (ifr.ifr_mtu < (int)CANFD_MTU) {
798+
canfd_en = 0;
788799
if (canfd) {
789-
/* ensure discrete CAN FD length values 0..8, 12, 16, 20, 24, 32, 64 */
790-
cu.fd.len = can_fd_dlc2len(can_fd_len2dlc(cu.fd.len));
791-
} else {
792-
/* limit fixed CAN XL data length to 64 */
793-
if (cu.fd.len > CANFD_MAX_DLEN)
794-
cu.fd.len = CANFD_MAX_DLEN;
800+
printf("CAN interface not CAN FD capable - sorry.\n");
801+
return 1;
795802
}
803+
}
796804

797-
if (canxl && (ifr.ifr_mtu < (int)CANXL_MIN_MTU)) {
798-
printf("CAN interface not CAN XL capable - sorry.\n");
805+
/* enable CAN FD on the socket */
806+
if (canfd_en) {
807+
/* interface is ok - try to switch the socket into CAN FD mode */
808+
if (setsockopt(s, SOL_CAN_RAW, CAN_RAW_FD_FRAMES,
809+
&enable_canfx, sizeof(enable_canfx))){
810+
printf("error when enabling CAN FD support\n");
799811
return 1;
800812
}
813+
}
801814

802-
if (canfd && (ifr.ifr_mtu < (int)CANFD_MTU)) {
803-
printf("CAN interface not CAN FD capable - sorry.\n");
815+
/* enable CAN XL on the socket */
816+
if (canxl_en) {
817+
/* interface is ok - try to switch the socket into CAN XL mode */
818+
if (setsockopt(s, SOL_CAN_RAW, CAN_RAW_XL_FRAMES,
819+
&enable_canfx, sizeof(enable_canfx))){
820+
printf("error when enabling CAN XL support\n");
804821
return 1;
805822
}
806-
807-
if (ifr.ifr_mtu == (int)CANFD_MTU) {
808-
/* interface is ok - try to switch the socket into CAN FD mode */
809-
if (setsockopt(s, SOL_CAN_RAW, CAN_RAW_FD_FRAMES,
810-
&enable_canfx, sizeof(enable_canfx))){
811-
printf("error when enabling CAN FD support\n");
812-
return 1;
813-
}
823+
/* try to enable the CAN XL VCID pass through mode */
824+
if (setsockopt(s, SOL_CAN_RAW, CAN_RAW_XL_VCID_OPTS,
825+
&vcid_opts, sizeof(vcid_opts))) {
826+
printf("error when enabling CAN XL VCID pass through\n");
827+
return 1;
814828
}
829+
}
815830

816-
if (ifr.ifr_mtu >= (int)CANXL_MIN_MTU) {
817-
/* interface is ok - try to switch the socket into CAN XL mode */
818-
if (setsockopt(s, SOL_CAN_RAW, CAN_RAW_XL_FRAMES,
819-
&enable_canfx, sizeof(enable_canfx))){
820-
printf("error when enabling CAN XL support\n");
821-
return 1;
822-
}
823-
/* try to enable the CAN XL VCID pass through mode */
824-
if (setsockopt(s, SOL_CAN_RAW, CAN_RAW_XL_VCID_OPTS,
825-
&vcid_opts, sizeof(vcid_opts))) {
826-
printf("error when enabling CAN XL VCID pass through\n");
827-
return 1;
828-
}
831+
/* sanitize given values */
832+
if (canfd || canxl) {
833+
if (canfd) {
834+
/* ensure discrete CAN FD length values 0..8, 12, 16, 20, 24, 32, 64 */
835+
cu.fd.len = can_fd_dlc2len(can_fd_len2dlc(cu.fd.len));
836+
} else {
837+
/* limit fixed CAN XL data length to 64 */
838+
if (cu.fd.len > CANFD_MAX_DLEN)
839+
cu.fd.len = CANFD_MAX_DLEN;
829840
}
830-
831841
} else {
832842
/* sanitize Classical CAN 2.0 frame length */
833843
if (len8_dlc) {
@@ -1084,15 +1094,19 @@ int main(int argc, char **argv)
10841094
if (mix) {
10851095
i = random();
10861096
extended = i & 1;
1087-
canfd = i & 2;
1088-
if (canfd) {
1089-
brs = i & 4;
1090-
esi = i & 8;
1097+
if (canfd_en) {
1098+
canfd = i & 2;
1099+
if (canfd) {
1100+
brs = i & 4;
1101+
esi = i & 8;
1102+
}
1103+
}
1104+
if (canxl_en) {
1105+
if (canfd_en)
1106+
canxl = ((i & 96) == 96); /* 1/4 */
1107+
else
1108+
canxl = ((i & 32) == 32); /* 1/2 */
10911109
}
1092-
/* generate CAN XL traffic if the interface is capable */
1093-
if (ifr.ifr_mtu >= (int)CANXL_MIN_MTU)
1094-
canxl = ((i & 96) == 96);
1095-
10961110
rtr_frame = ((i & 24) == 24); /* reduce RTR frames to 1/4 */
10971111
}
10981112
}

0 commit comments

Comments
 (0)