From fcc9a89c6eb6683b7b18e5a903a0b3608c5440d4 Mon Sep 17 00:00:00 2001 From: Oliver Hartkopp Date: Sun, 1 Nov 2020 20:48:24 +0100 Subject: [PATCH] candump/lib: support len8_dlc for standard candump output The display of Classical CAN raw DLC values is an expert feature which is not enabled by default to not break toolchains that use the candump standard output for further processing. (N.B. using the log file format and the functions from lib.h/lib.c provide convenient CAN frame conversions) After enabling the raw DLC for Classical CAN with the '-8' option the raw DLC value is printed in 'unusual' curly braces {}. Signed-off-by: Oliver Hartkopp --- candump.c | 9 +++++++-- lib.c | 20 +++++++++++++++++--- lib.h | 8 +++++--- 3 files changed, 29 insertions(+), 8 deletions(-) diff --git a/candump.c b/candump.c index 41f680c..ca7d067 100644 --- a/candump.c +++ b/candump.c @@ -134,6 +134,7 @@ void print_usage(char *prg) fprintf(stderr, " -D (Don't exit if a \"detected\" can device goes down.\n"); fprintf(stderr, " -d (monitor dropped CAN frames)\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, " -x (print extra message infos, rx/tx brs esi)\n"); fprintf(stderr, " -T (terminate after without any reception)\n"); fprintf(stderr, "\n"); @@ -255,7 +256,7 @@ int main(int argc, char **argv) last_tv.tv_sec = 0; last_tv.tv_usec = 0; - while ((opt = getopt(argc, argv, "t:HciaSs:lDdxLn:r:heT:?")) != -1) { + while ((opt = getopt(argc, argv, "t:HciaSs:lDdxLn:r:he8T:?")) != -1) { switch (opt) { case 't': timestamp = optarg[0]; @@ -291,6 +292,10 @@ int main(int argc, char **argv) view |= CANLIB_VIEW_ERROR; break; + case '8': + view |= CANLIB_VIEW_LEN8_DLC; + break; + case 's': silent = atoi(optarg); if (silent > SILENT_ON) { @@ -359,7 +364,7 @@ int main(int argc, char **argv) } if (logfrmt && view) { - fprintf(stderr, "Log file format selected: Please disable ASCII/BINARY/SWAP options!\n"); + fprintf(stderr, "Log file format selected: Please disable ASCII/BINARY/SWAP/RAWDLC options!\n"); exit(0); } diff --git a/lib.c b/lib.c index 0642071..aed3734 100644 --- a/lib.c +++ b/lib.c @@ -381,9 +381,23 @@ void sprint_long_canframe(char *buf , struct canfd_frame *cf, int view, int maxd /* The len value is sanitized by maxdlen (see above) */ if (maxdlen == CAN_MAX_DLEN) { - buf[offset + 1] = '['; - buf[offset + 2] = len + '0'; - buf[offset + 3] = ']'; + if (view & CANLIB_VIEW_LEN8_DLC) { + struct can_frame *ccf = (struct can_frame *)cf; + unsigned char dlc = ccf->len8_dlc; + + /* fall back to len if we don't have a valid DLC > 8 */ + if (!((len == CAN_MAX_DLEN) && (dlc > CAN_MAX_DLEN) && + (dlc <= CAN_MAX_RAW_DLC))) + dlc = len; + + buf[offset + 1] = '{'; + buf[offset + 2] = hex_asc_upper[dlc]; + buf[offset + 3] = '}'; + } else { + buf[offset + 1] = '['; + buf[offset + 2] = len + '0'; + buf[offset + 3] = ']'; + } /* standard CAN frames may have RTR enabled */ if (cf->can_id & CAN_RTR_FLAG) { diff --git a/lib.h b/lib.h index 94760d4..e0a0e1c 100644 --- a/lib.h +++ b/lib.h @@ -182,6 +182,7 @@ void sprint_canframe(char *buf , struct canfd_frame *cf, int sep, int maxdlen); #define CANLIB_VIEW_SWAP 0x4 #define CANLIB_VIEW_ERROR 0x8 #define CANLIB_VIEW_INDENT_SFF 0x10 +#define CANLIB_VIEW_LEN8_DLC 0x20 #define SWAP_DELIMITER '`' @@ -194,11 +195,12 @@ void sprint_long_canframe(char *buf , struct canfd_frame *cf, int view, int maxd * maxdlen = 8 -> CAN2.0 frame (aka Classical CAN) * maxdlen = 64 -> CAN FD frame * - * 12345678 [3] 11 22 33 -> extended CAN-Id = 0x12345678, dlc = 3, data + * 12345678 [3] 11 22 33 -> extended CAN-Id = 0x12345678, len = 3, data * 12345678 [0] remote request -> extended CAN-Id = 0x12345678, RTR * 14B0DC51 [8] 4A 94 E8 2A EC 58 55 62 'J..*.XUb' -> (with ASCII output) + * 321 {B} 11 22 33 44 55 66 77 88 -> Classical CAN with raw '{DLC}' value B * 20001111 [7] C6 23 7B 32 69 98 3C ERRORFRAME -> (CAN_ERR_FLAG set) - * 12345678 [03] 11 22 33 -> CAN FD with extended CAN-Id = 0x12345678, dlc = 3 + * 12345678 [03] 11 22 33 -> CAN FD with extended CAN-Id = 0x12345678, len = 3 * * 123 [3] 11 22 33 -> CANLIB_VIEW_INDENT_SFF == 0 * 123 [3] 11 22 33 -> CANLIB_VIEW_INDENT_SFF == set @@ -208,7 +210,7 @@ void sprint_long_canframe(char *buf , struct canfd_frame *cf, int view, int maxd * // CAN FD frame with eol to STDOUT * fprint_long_canframe(stdout, &frame, "\n", 0, CANFD_MAX_DLEN); * - * // CAN 2.0 frame without eol to STDERR + * // Classical CAN 2.0 frame without eol to STDERR * fprint_long_canframe(stderr, &frame, NULL, 0, CAN_MAX_DLEN); * */