Skip to content

Commit bfbf0c8

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 ed7822c commit bfbf0c8

File tree

1 file changed

+63
-47
lines changed

1 file changed

+63
-47
lines changed

cangen.c

Lines changed: 63 additions & 47 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,9 @@ int main(int argc, char **argv)
455455
unsigned char extended = 0;
456456
unsigned char canfd = 0;
457457
unsigned char canxl = 0;
458+
unsigned char mixcc = 1; /* mix default */
459+
unsigned char mixfd = 1; /* mix default */
460+
unsigned char mixxl = 1; /* mix default */
458461
unsigned char brs = 0;
459462
unsigned char esi = 0;
460463
unsigned char mix = 0;
@@ -574,7 +577,6 @@ int main(int argc, char **argv)
574577

575578
case 'm':
576579
mix = 1;
577-
canfd = 1; /* to switch the socket into CAN FD mode */
578580
view |= CANLIB_VIEW_INDENT_SFF;
579581
break;
580582

@@ -777,57 +779,66 @@ int main(int argc, char **argv)
777779
&loopback, sizeof(loopback));
778780
}
779781

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

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

797+
/* check CAN FD support */
798+
if (ifr.ifr_mtu < (int)CANFD_MTU) {
799+
mixfd = 0;
788800
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;
801+
printf("CAN interface not CAN FD capable - sorry.\n");
802+
return 1;
795803
}
804+
}
796805

797-
if (canxl && (ifr.ifr_mtu < (int)CANXL_MIN_MTU)) {
798-
printf("CAN interface not CAN XL capable - sorry.\n");
806+
/* enable CAN FD on the socket */
807+
if (mixfd) {
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");
799812
return 1;
800813
}
814+
}
801815

802-
if (canfd && (ifr.ifr_mtu < (int)CANFD_MTU)) {
803-
printf("CAN interface not CAN FD capable - sorry.\n");
816+
/* enable CAN XL on the socket */
817+
if (mixxl) {
818+
/* interface is ok - try to switch the socket into CAN XL mode */
819+
if (setsockopt(s, SOL_CAN_RAW, CAN_RAW_XL_FRAMES,
820+
&enable_canfx, sizeof(enable_canfx))){
821+
printf("error when enabling CAN XL support\n");
804822
return 1;
805823
}
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-
}
824+
/* try to enable the CAN XL VCID pass through mode */
825+
if (setsockopt(s, SOL_CAN_RAW, CAN_RAW_XL_VCID_OPTS,
826+
&vcid_opts, sizeof(vcid_opts))) {
827+
printf("error when enabling CAN XL VCID pass through\n");
828+
return 1;
814829
}
830+
}
815831

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-
}
832+
/* sanitize given values */
833+
if (canfd || canxl) {
834+
if (canfd) {
835+
/* ensure discrete CAN FD length values 0..8, 12, 16, 20, 24, 32, 64 */
836+
cu.fd.len = can_fd_dlc2len(can_fd_len2dlc(cu.fd.len));
837+
} else {
838+
/* limit fixed CAN XL data length to 64 */
839+
if (cu.fd.len > CANFD_MAX_DLEN)
840+
cu.fd.len = CANFD_MAX_DLEN;
829841
}
830-
831842
} else {
832843
/* sanitize Classical CAN 2.0 frame length */
833844
if (len8_dlc) {
@@ -1084,16 +1095,21 @@ int main(int argc, char **argv)
10841095
if (mix) {
10851096
i = random();
10861097
extended = i & 1;
1087-
canfd = i & 2;
1088-
if (canfd) {
1089-
brs = i & 4;
1090-
esi = i & 8;
1098+
if (mixfd) {
1099+
canfd = i & 2;
1100+
if (canfd) {
1101+
brs = i & 4;
1102+
esi = i & 8;
1103+
}
10911104
}
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-
1096-
rtr_frame = ((i & 24) == 24); /* reduce RTR frames to 1/4 */
1105+
if (mixxl) {
1106+
if (mixfd)
1107+
canxl = ((i & 96) == 96); /* 1/4 */
1108+
else
1109+
canxl = ((i & 32) == 32); /* 1/2 */
1110+
}
1111+
if (mixcc)
1112+
rtr_frame = ((i & 24) == 24); /* reduce RTR to 1/4 */
10971113
}
10981114
}
10991115

0 commit comments

Comments
 (0)