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 <socketcan@hartkopp.net>
pull/260/head
Oliver Hartkopp 2020-11-01 20:48:24 +01:00
parent a23eb24f95
commit fcc9a89c6e
3 changed files with 29 additions and 8 deletions

View File

@ -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 <msecs> (terminate after <msecs> 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);
}

20
lib.c
View File

@ -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) {

8
lib.h
View File

@ -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);
*
*/