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 <socketcan@hartkopp.net>
pull/504/head
Oliver Hartkopp 2024-02-27 20:03:07 +01:00
parent 04312e5a10
commit 3644a54d5b
6 changed files with 68 additions and 31 deletions

View File

@ -868,7 +868,7 @@ int main(int argc, char **argv)
} }
alen += sprintf(abuf + alen, "%s ", (color == 1) ? col_off : ""); 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)) { if ((view & CANLIB_VIEW_ERROR) && (cu.fd.can_id & CAN_ERR_FLAG)) {
alen += sprintf(abuf + alen, "\n\t"); alen += sprintf(abuf + alen, "\n\t");

View File

@ -833,7 +833,7 @@ int main(int argc, char **argv)
printf(" %s ", argv[optind]); printf(" %s ", argv[optind]);
if (verbose > 1) 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 else
sprint_canframe(abuf, (cu_t *)&frame, 1); sprint_canframe(abuf, (cu_t *)&frame, 1);

View File

@ -488,7 +488,7 @@ int main(int argc, char **argv)
static char abuf[10000]; /* ASCII buf FIXME - use calculated value */ static char abuf[10000]; /* ASCII buf FIXME - use calculated value */
printf("%s (%s) ", get_txname(device), device); 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); printf("%s\n", abuf);
} }

89
lib.c
View File

@ -361,35 +361,73 @@ int sprint_canframe(char *buf, cu_t *cu, int sep)
return offset; 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 */ /* documentation see lib.h */
unsigned char is_canfd = cf->flags; unsigned char is_canfd = cu->fd.flags;
int i, j, dlen, offset; int i, j, dlen, offset;
int len; 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 */ /* initialize space for CAN-ID and length information */
memset(buf, ' ', 15); memset(buf, ' ', 15);
if (cf->can_id & CAN_ERR_FLAG) { /* handle CAN XL frames */
put_eff_id(buf, cf->can_id & (CAN_ERR_MASK | CAN_ERR_FLAG)); 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; offset = 10;
} else if (cf->can_id & CAN_EFF_FLAG) { } else if (cu->fd.can_id & CAN_EFF_FLAG) {
put_eff_id(buf, cf->can_id & CAN_EFF_MASK); put_eff_id(buf, cu->fd.can_id & CAN_EFF_MASK);
offset = 10; offset = 10;
} else { } else {
if (view & CANLIB_VIEW_INDENT_SFF) { 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; offset = 10;
} else { } else {
put_sff_id(buf, cf->can_id & CAN_SFF_MASK); put_sff_id(buf, cu->fd.can_id & CAN_SFF_MASK);
offset = 5; 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) */ /* The len value is sanitized (see above) */
if (!(is_canfd)) { if (!(is_canfd)) {
if (view & CANLIB_VIEW_LEN8_DLC) { if (view & CANLIB_VIEW_LEN8_DLC) {
struct can_frame *ccf = (struct can_frame *)cf; unsigned char dlc = cu->cc.len8_dlc;
unsigned char dlc = ccf->len8_dlc;
/* fall back to len if we don't have a valid DLC > 8 */ /* fall back to len if we don't have a valid DLC > 8 */
if (!((len == CAN_MAX_DLEN) && (dlc > CAN_MAX_DLEN) && 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 */ /* 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"); offset += sprintf(buf + offset + 5, " remote request");
return offset + 5; 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--) { for (i = len - 1; i >= 0; i--) {
buf[offset++] = (i == len - 1) ? ' ' : SWAP_DELIMITER; buf[offset++] = (i == len - 1) ? ' ' : SWAP_DELIMITER;
for (j = 7; j >= 0; j--) 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 { } else {
for (i = 0; i < len; i++) { for (i = 0; i < len; i++) {
buf[offset++] = ' '; buf[offset++] = ' ';
for (j = 7; j >= 0; j--) 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 { } else {
@ -451,13 +488,13 @@ int sprint_long_canframe(char *buf, struct canfd_frame *cf, int view)
else else
buf[offset++] = SWAP_DELIMITER; buf[offset++] = SWAP_DELIMITER;
put_hex_byte(buf + offset, cf->data[i]); put_hex_byte(buf + offset, cu->fd.data[i]);
offset += 2; offset += 2;
} }
} else { } else {
for (i = 0; i < len; i++) { for (i = 0; i < len; i++) {
buf[offset++] = ' '; buf[offset++] = ' ';
put_hex_byte(buf + offset, cf->data[i]); put_hex_byte(buf + offset, cu->fd.data[i]);
offset += 2; offset += 2;
} }
} }
@ -473,7 +510,7 @@ int sprint_long_canframe(char *buf, struct canfd_frame *cf, int view)
if (len > CAN_MAX_DLEN) if (len > CAN_MAX_DLEN)
return offset; 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"); offset += sprintf(buf + offset, "%*s", dlen * (8 - len) + 13, "ERRORFRAME");
else if (view & CANLIB_VIEW_ASCII) { else if (view & CANLIB_VIEW_ASCII) {
j = dlen * (8 - len) + 4; 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, "`"); sprintf(buf + offset, "%*s", j, "`");
offset += j; offset += j;
for (i = len - 1; i >= 0; i--) for (i = len - 1; i >= 0; i--)
if ((cf->data[i] > 0x1F) && (cf->data[i] < 0x7F)) if ((cu->fd.data[i] > 0x1F) && (cu->fd.data[i] < 0x7F))
buf[offset++] = cf->data[i]; buf[offset++] = cu->fd.data[i];
else else
buf[offset++] = '.'; buf[offset++] = '.';
@ -491,8 +528,8 @@ int sprint_long_canframe(char *buf, struct canfd_frame *cf, int view)
sprintf(buf + offset, "%*s", j, "'"); sprintf(buf + offset, "%*s", j, "'");
offset += j; offset += j;
for (i = 0; i < len; i++) for (i = 0; i < len; i++)
if ((cf->data[i] > 0x1F) && (cf->data[i] < 0x7F)) if ((cu->fd.data[i] > 0x1F) && (cu->fd.data[i] < 0x7F))
buf[offset++] = cf->data[i]; buf[offset++] = cu->fd.data[i];
else else
buf[offset++] = '.'; buf[offset++] = '.';

2
lib.h
View File

@ -198,7 +198,7 @@ int sprint_canframe(char *buf , cu_t *cu, int sep);
#define SWAP_DELIMITER '`' #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. * Creates a CAN frame hexadecimal output in user readable format.
* *

View File

@ -75,7 +75,7 @@ int main(void)
} }
/* with ASCII output */ /* with ASCII output */
sprint_long_canframe(ascframe, &cf, sprint_long_canframe(ascframe, (cu_t *)&cf,
(CANLIB_VIEW_INDENT_SFF | CANLIB_VIEW_ASCII)); (CANLIB_VIEW_INDENT_SFF | CANLIB_VIEW_ASCII));
printf("%s %s %s\n", timestamp, device, ascframe); printf("%s %s %s\n", timestamp, device, ascframe);