From 3644a54d5b78854719b045dac9a5955d73630495 Mon Sep 17 00:00:00 2001 From: Oliver Hartkopp Date: Tue, 27 Feb 2024 20:03:07 +0100 Subject: [PATCH] candump/lib: make sprint_long_canframe CAN XL aware The 'long' CAN frame representation does not really fit for CAN XL content. Therefore just a cropped output is provided to be able to see the CAN XL header information and up to 64 byte of data (without binary or swap formating options). To get the full qualified CAN XL content use the log file format. Signed-off-by: Oliver Hartkopp --- candump.c | 2 +- cangen.c | 2 +- canplayer.c | 2 +- lib.c | 89 +++++++++++++++++++++++++++++++++++++---------------- lib.h | 2 +- log2long.c | 2 +- 6 files changed, 68 insertions(+), 31 deletions(-) diff --git a/candump.c b/candump.c index c5500ad..d1bc975 100644 --- a/candump.c +++ b/candump.c @@ -868,7 +868,7 @@ int main(int argc, char **argv) } alen += sprintf(abuf + alen, "%s ", (color == 1) ? col_off : ""); - alen += sprint_long_canframe(abuf + alen, &cu.fd, view); + alen += sprint_long_canframe(abuf + alen, &cu, view); if ((view & CANLIB_VIEW_ERROR) && (cu.fd.can_id & CAN_ERR_FLAG)) { alen += sprintf(abuf + alen, "\n\t"); diff --git a/cangen.c b/cangen.c index ad93ea8..11b156f 100644 --- a/cangen.c +++ b/cangen.c @@ -833,7 +833,7 @@ int main(int argc, char **argv) printf(" %s ", argv[optind]); if (verbose > 1) - sprint_long_canframe(abuf, &frame, (verbose > 2) ? CANLIB_VIEW_ASCII : 0); + sprint_long_canframe(abuf, (cu_t *)&frame, (verbose > 2) ? CANLIB_VIEW_ASCII : 0); else sprint_canframe(abuf, (cu_t *)&frame, 1); diff --git a/canplayer.c b/canplayer.c index bd93740..cefc78d 100644 --- a/canplayer.c +++ b/canplayer.c @@ -488,7 +488,7 @@ int main(int argc, char **argv) static char abuf[10000]; /* ASCII buf FIXME - use calculated value */ printf("%s (%s) ", get_txname(device), device); - sprint_long_canframe(abuf, &frame, CANLIB_VIEW_INDENT_SFF); + sprint_long_canframe(abuf, (cu_t *)&frame, CANLIB_VIEW_INDENT_SFF); printf("%s\n", abuf); } diff --git a/lib.c b/lib.c index 53defb6..fec71ac 100644 --- a/lib.c +++ b/lib.c @@ -361,35 +361,73 @@ int sprint_canframe(char *buf, cu_t *cu, int sep) return offset; } -int sprint_long_canframe(char *buf, struct canfd_frame *cf, int view) +int sprint_long_canframe(char *buf, cu_t *cu, int view) { /* documentation see lib.h */ - unsigned char is_canfd = cf->flags; + unsigned char is_canfd = cu->fd.flags; int i, j, dlen, offset; int len; - /* ensure max length values */ - if (is_canfd) - len = (cf->len > CANFD_MAX_DLEN) ? CANFD_MAX_DLEN : cf->len; - else - len = (cf->len > CAN_MAX_DLEN) ? CAN_MAX_DLEN : cf->len; - /* initialize space for CAN-ID and length information */ memset(buf, ' ', 15); - if (cf->can_id & CAN_ERR_FLAG) { - put_eff_id(buf, cf->can_id & (CAN_ERR_MASK | CAN_ERR_FLAG)); + /* handle CAN XL frames */ + if (cu->xl.flags & CANXL_XLF) { + len = cu->xl.len; + + if (view & CANLIB_VIEW_INDENT_SFF) { + put_sff_id(buf + 5, cu->xl.prio & CANXL_PRIO_MASK); + offset = 9; + } else { + put_sff_id(buf, cu->xl.prio & CANXL_PRIO_MASK); + offset = 4; + } + + /* print prio and CAN XL header content */ + offset += sprintf(buf + offset, "[%04d] (%02X|%02X:%02X:%08X) ", + len, + (canid_t)(cu->xl.prio & CANXL_VCID_MASK) >> CANXL_VCID_OFFSET, + cu->xl.flags, cu->xl.sdt, cu->xl.af); + + /* data - crop to CANFD_MAX_DLEN */ + if (len > CANFD_MAX_DLEN) + len = CANFD_MAX_DLEN; + + for (i = 0; i < len; i++) { + put_hex_byte(buf + offset, cu->xl.data[i]); + offset += 2; + if (i + 1 < len) + buf[offset++] = ' '; + } + + /* indicate cropped output */ + if (cu->xl.len > len) + offset += sprintf(buf + offset, " ..."); + + buf[offset] = 0; + + return offset; + } + + /* ensure max length values */ + if (is_canfd) + len = (cu->fd.len > CANFD_MAX_DLEN) ? CANFD_MAX_DLEN : cu->fd.len; + else + len = (cu->fd.len > CAN_MAX_DLEN) ? CAN_MAX_DLEN : cu->fd.len; + + if (cu->cc.can_id & CAN_ERR_FLAG) { + put_eff_id(buf, cu->cc.can_id & (CAN_ERR_MASK | CAN_ERR_FLAG)); offset = 10; - } else if (cf->can_id & CAN_EFF_FLAG) { - put_eff_id(buf, cf->can_id & CAN_EFF_MASK); + } else if (cu->fd.can_id & CAN_EFF_FLAG) { + put_eff_id(buf, cu->fd.can_id & CAN_EFF_MASK); offset = 10; } else { if (view & CANLIB_VIEW_INDENT_SFF) { - put_sff_id(buf + 5, cf->can_id & CAN_SFF_MASK); + put_sff_id(buf + 5, cu->fd.can_id & CAN_SFF_MASK); offset = 10; } else { - put_sff_id(buf, cf->can_id & CAN_SFF_MASK); + put_sff_id(buf, cu->fd.can_id & CAN_SFF_MASK); offset = 5; } } @@ -397,8 +435,7 @@ int sprint_long_canframe(char *buf, struct canfd_frame *cf, int view) /* The len value is sanitized (see above) */ if (!(is_canfd)) { if (view & CANLIB_VIEW_LEN8_DLC) { - struct can_frame *ccf = (struct can_frame *)cf; - unsigned char dlc = ccf->len8_dlc; + unsigned char dlc = cu->cc.len8_dlc; /* fall back to len if we don't have a valid DLC > 8 */ if (!((len == CAN_MAX_DLEN) && (dlc > CAN_MAX_DLEN) && @@ -415,7 +452,7 @@ int sprint_long_canframe(char *buf, struct canfd_frame *cf, int view) } /* standard CAN frames may have RTR enabled */ - if (cf->can_id & CAN_RTR_FLAG) { + if (cu->fd.can_id & CAN_RTR_FLAG) { offset += sprintf(buf + offset + 5, " remote request"); return offset + 5; } @@ -433,13 +470,13 @@ int sprint_long_canframe(char *buf, struct canfd_frame *cf, int view) for (i = len - 1; i >= 0; i--) { buf[offset++] = (i == len - 1) ? ' ' : SWAP_DELIMITER; for (j = 7; j >= 0; j--) - buf[offset++] = (1 << j & cf->data[i]) ? '1' : '0'; + buf[offset++] = (1 << j & cu->fd.data[i]) ? '1' : '0'; } } else { for (i = 0; i < len; i++) { buf[offset++] = ' '; for (j = 7; j >= 0; j--) - buf[offset++] = (1 << j & cf->data[i]) ? '1' : '0'; + buf[offset++] = (1 << j & cu->fd.data[i]) ? '1' : '0'; } } } else { @@ -451,13 +488,13 @@ int sprint_long_canframe(char *buf, struct canfd_frame *cf, int view) else buf[offset++] = SWAP_DELIMITER; - put_hex_byte(buf + offset, cf->data[i]); + put_hex_byte(buf + offset, cu->fd.data[i]); offset += 2; } } else { for (i = 0; i < len; i++) { buf[offset++] = ' '; - put_hex_byte(buf + offset, cf->data[i]); + put_hex_byte(buf + offset, cu->fd.data[i]); offset += 2; } } @@ -473,7 +510,7 @@ int sprint_long_canframe(char *buf, struct canfd_frame *cf, int view) if (len > CAN_MAX_DLEN) return offset; - if (cf->can_id & CAN_ERR_FLAG) + if (cu->fd.can_id & CAN_ERR_FLAG) offset += sprintf(buf + offset, "%*s", dlen * (8 - len) + 13, "ERRORFRAME"); else if (view & CANLIB_VIEW_ASCII) { j = dlen * (8 - len) + 4; @@ -481,8 +518,8 @@ int sprint_long_canframe(char *buf, struct canfd_frame *cf, int view) sprintf(buf + offset, "%*s", j, "`"); offset += j; for (i = len - 1; i >= 0; i--) - if ((cf->data[i] > 0x1F) && (cf->data[i] < 0x7F)) - buf[offset++] = cf->data[i]; + if ((cu->fd.data[i] > 0x1F) && (cu->fd.data[i] < 0x7F)) + buf[offset++] = cu->fd.data[i]; else buf[offset++] = '.'; @@ -491,8 +528,8 @@ int sprint_long_canframe(char *buf, struct canfd_frame *cf, int view) sprintf(buf + offset, "%*s", j, "'"); offset += j; for (i = 0; i < len; i++) - if ((cf->data[i] > 0x1F) && (cf->data[i] < 0x7F)) - buf[offset++] = cf->data[i]; + if ((cu->fd.data[i] > 0x1F) && (cu->fd.data[i] < 0x7F)) + buf[offset++] = cu->fd.data[i]; else buf[offset++] = '.'; diff --git a/lib.h b/lib.h index fc8e17b..67902fc 100644 --- a/lib.h +++ b/lib.h @@ -198,7 +198,7 @@ int sprint_canframe(char *buf , cu_t *cu, int sep); #define SWAP_DELIMITER '`' -int sprint_long_canframe(char *buf , struct canfd_frame *cf, int view); +int sprint_long_canframe(char *buf , cu_t *cu, int view); /* * Creates a CAN frame hexadecimal output in user readable format. * diff --git a/log2long.c b/log2long.c index 61208a3..97e25ab 100644 --- a/log2long.c +++ b/log2long.c @@ -75,7 +75,7 @@ int main(void) } /* with ASCII output */ - sprint_long_canframe(ascframe, &cf, + sprint_long_canframe(ascframe, (cu_t *)&cf, (CANLIB_VIEW_INDENT_SFF | CANLIB_VIEW_ASCII)); printf("%s %s %s\n", timestamp, device, ascframe);