cangen: disable generation of unsupported CAN frame types in mixed mode

The mixed mode is able to automatically detect the potential supported
CAN frame types CAN CC/FD/XL by checking the CAN device MTU at startup.

Usually the MTU shows which CAN frame types can be sent but in the case of
CAN XL in CANXL-only mode CC and FD frames can not be sent on the CAN_RAW
socket.

Since this patch [1] the CAN_RAW socket rejects unsupported CAN frames and
returns -EINVAL as error code. With this change in cangen the CC and FD
frame generation can be disabled in mixed mode at runtime.

[1] https://lore.kernel.org/linux-can/20251125123859.3924-17-socketcan@hartkopp.net/T/#u

Signed-off-by: Oliver Hartkopp <socketcan@hartkopp.net>
pull/17/merge
Oliver Hartkopp 2025-11-27 16:49:34 +01:00
parent bfbf0c851f
commit 374fecde09
1 changed files with 45 additions and 5 deletions

View File

@ -339,10 +339,9 @@ 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;
@ -1051,8 +1050,31 @@ int main(int argc, char **argv)
} }
ret = do_send_one(s, &cu, mtu, polltimeout); ret = do_send_one(s, &cu, mtu, polltimeout);
if (ret) if ((ret == -EINVAL) && mix) {
/* 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;
@ -1093,6 +1115,8 @@ 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) { if (mixfd) {
@ -1108,8 +1132,24 @@ int main(int argc, char **argv)
else else
canxl = ((i & 32) == 32); /* 1/2 */ canxl = ((i & 32) == 32); /* 1/2 */
} }
if (mixcc) if (mixcc) {
rtr_frame = ((i & 24) == 24); /* reduce RTR to 1/4 */ 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;
}
}
}
} }
} }