From 0e692bf42e4600b897c45ff34db22107b8e4a9a4 Mon Sep 17 00:00:00 2001 From: Oliver Hartkopp Date: Fri, 24 Jan 2025 14:05:27 +0100 Subject: [PATCH 01/11] asc2log: unify multi-line comments Signed-off-by: Oliver Hartkopp --- asc2log.c | 36 +++++++++++++++++++++++------------- 1 file changed, 23 insertions(+), 13 deletions(-) diff --git a/asc2log.c b/asc2log.c index 2860f9d8..7d7291a8 100644 --- a/asc2log.c +++ b/asc2log.c @@ -258,12 +258,16 @@ static void eval_canfd(char* buf, struct timeval *date_tvp, char timestamps, int i; unsigned long long sec, usec; - /* The CANFD format is mainly in hex representation but - and probably some content we skip anyway. Don't trust the docs! */ + /* + * The CANFD format is mainly in hex representation but + * and probably some content we skip anyway. Don't trust the docs! + */ - /* 21.671796 CANFD 1 Tx 11 msgCanFdFr1 1 0 a 16 \ - 00 00 00 00 00 00 00 00 00 00 00 00 00 00 59 c0 \ - 100000 214 223040 80000000 46500250 460a0250 20011736 20010205 */ + /* + * 21.671796 CANFD 1 Tx 11 msgCanFdFr1 1 0 a 16 \ + * 00 00 00 00 00 00 00 00 00 00 00 00 00 00 59 c0 \ + * 100000 214 223040 80000000 46500250 460a0250 20011736 20010205 + */ /* check for valid line without symbolic name */ if (sscanf(buf, "%llu.%llu %*s %d %2s %s %hhx %hhx %x %d ", @@ -393,9 +397,11 @@ static int get_date(struct timeval *tv, char *date) } if (!strptime(date, "%B %d %I:%M:%S %p %Y", &tms)) { - /* The string might contain a milliseconds value which strptime() - does not support. So we read the ms value into the year variable - before parsing the real year value (hack) */ + /* + * The string might contain a milliseconds value which strptime() + * does not support. So we read the ms value into the year variable + * before parsing the real year value (hack) + */ if (!strptime(date, "%B %d %I:%M:%S.%Y %p %Y", &tms)) return 1; sscanf(date, "%*s %*d %*d:%*d:%*d.%3u ", &msecs); @@ -410,9 +416,11 @@ static int get_date(struct timeval *tv, char *date) } if (!strptime(date, "%B %d %H:%M:%S %Y", &tms)) { - /* The string might contain a milliseconds value which strptime() - does not support. So we read the ms value into the year variable - before parsing the real year value (hack) */ + /* + * The string might contain a milliseconds value which strptime() + * does not support. So we read the ms value into the year variable + * before parsing the real year value (hack) + */ if (!strptime(date, "%B %d %H:%M:%S.%Y %Y", &tms)) return 1; sscanf(date, "%*s %*d %*d:%*d:%*d.%3u ", &msecs); @@ -537,8 +545,10 @@ int main(int argc, char **argv) } } - /* the representation of a valid CAN frame is known here */ - /* so try to get CAN frames and ErrorFrames and convert them */ + /* + * The representation of a valid CAN frame is known here. + * So try to get CAN frames and ErrorFrames and convert them. + */ /* check classic CAN format or the CANFD tag which can take both types */ if (sscanf(buf, "%llu.%llu %s ", &sec, &usec, tmp1) == 3){ From cb5ab07f34662e5a99ae65a14988c04a4491172c Mon Sep 17 00:00:00 2001 From: Oliver Hartkopp Date: Fri, 24 Jan 2025 14:11:53 +0100 Subject: [PATCH 02/11] asc2log: handle and skip TxRq messages TxRq messages are internal measurement messages that document the time of a transmission request (to the CAN driver) to be checked against the real transmission time, when the CAN message has been sent. There is no such feature in the SocketCAN log format, so we detect this tag but skip TxRq messages in the ASC log files. Signed-off-by: Oliver Hartkopp --- asc2log.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/asc2log.c b/asc2log.c index 7d7291a8..aef29294 100644 --- a/asc2log.c +++ b/asc2log.c @@ -143,7 +143,7 @@ static void eval_can(char* buf, struct timeval *date_tvp, char timestamps, int len = 0; int data[8]; char tmp1[BUFLEN]; - char dir[3]; /* 'Rx' or 'Tx' plus terminating zero */ + char dir[5]; /* 'Rx'/'Tx'/'TxRq' plus terminating zero */ char *extra_info; int i, items; unsigned long long sec, usec; @@ -172,13 +172,13 @@ static void eval_can(char* buf, struct timeval *date_tvp, char timestamps, /* check for CAN frames with (hexa)decimal values */ if (base == 'h') - items = sscanf(buf, "%llu.%llu %d %s %2s %c %x %x %x %x %x %x %x %x %x", + items = sscanf(buf, "%llu.%llu %d %s %4s %c %x %x %x %x %x %x %x %x %x", &sec, &usec, &interface, tmp1, dir, &rtr, &dlc, &data[0], &data[1], &data[2], &data[3], &data[4], &data[5], &data[6], &data[7]); else - items = sscanf(buf, "%llu.%llu %d %s %2s %c %x %d %d %d %d %d %d %d %d", + items = sscanf(buf, "%llu.%llu %d %s %4s %c %x %d %d %d %d %d %d %d %d", &sec, &usec, &interface, tmp1, dir, &rtr, &dlc, &data[0], &data[1], &data[2], &data[3], @@ -252,7 +252,7 @@ static void eval_canfd(char* buf, struct timeval *date_tvp, char timestamps, unsigned int flags; int dlc, dlen = 0; char tmp1[BUFLEN]; - char dir[3]; /* 'Rx' or 'Tx' plus terminating zero */ + char dir[5]; /* 'Rx'/'Tx'/'TxRq' plus terminating zero */ char *extra_info; char *ptr; int i; @@ -270,12 +270,12 @@ static void eval_canfd(char* buf, struct timeval *date_tvp, char timestamps, */ /* check for valid line without symbolic name */ - if (sscanf(buf, "%llu.%llu %*s %d %2s %s %hhx %hhx %x %d ", + if (sscanf(buf, "%llu.%llu %*s %d %4s %s %hhx %hhx %x %d ", &sec, &usec, &interface, dir, tmp1, &brs, &esi, &dlc, &dlen) != 9) { /* check for valid line with a symbolic name */ - if (sscanf(buf, "%llu.%llu %*s %d %2s %s %*s %hhx %hhx %x %d ", + if (sscanf(buf, "%llu.%llu %*s %d %4s %s %*s %hhx %hhx %x %d ", &sec, &usec, &interface, dir, tmp1, &brs, &esi, &dlc, &dlen) != 9) { From df8e08fa705907cdc031a82d5b30d1b4d07b2b2c Mon Sep 17 00:00:00 2001 From: Oliver Hartkopp Date: Tue, 10 Dec 2024 17:25:29 +0100 Subject: [PATCH 03/11] asc2log: prepare helper functions for CAN XL frame handling Signed-off-by: Oliver Hartkopp --- asc2log.c | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/asc2log.c b/asc2log.c index aef29294..535629ec 100644 --- a/asc2log.c +++ b/asc2log.c @@ -72,7 +72,7 @@ static void print_usage(char *prg) } static void prframe(FILE *file, struct timeval *tv, int dev, - struct canfd_frame *cf, char *extra_info) + cu_t *cf, char *extra_info) { static char abuf[BUFLEN]; @@ -83,19 +83,19 @@ static void prframe(FILE *file, struct timeval *tv, int dev, else fprintf(file, "canX "); - snprintf_canframe(abuf, sizeof(abuf), (cu_t *)cf, 0); + snprintf_canframe(abuf, sizeof(abuf), cf, 0); fprintf(file, "%s%s", abuf, extra_info); } -static void get_can_id(struct canfd_frame *cf, char *idstring, int base) +static void get_can_id(canid_t *can_id, char *idstring, int base) { if (idstring[strlen(idstring)-1] == 'x') { - cf->can_id = CAN_EFF_FLAG; + *can_id = CAN_EFF_FLAG; idstring[strlen(idstring)-1] = 0; } else - cf->can_id = 0; + *can_id = 0; - cf->can_id |= strtoul(idstring, NULL, base); + *can_id |= strtoul(idstring, NULL, base); } static void calc_tv(struct timeval *tv, struct timeval *read_tv, @@ -162,7 +162,7 @@ static void eval_can(char* buf, struct timeval *date_tvp, char timestamps, cf.len = CAN_ERR_DLC; calc_tv(&tv, &read_tv, date_tvp, timestamps, dplace); - prframe(outfile, &tv, interface, &cf, "\n"); + prframe(outfile, &tv, interface, (cu_t *)&cf, "\n"); fflush(outfile); return; } @@ -205,9 +205,9 @@ static void eval_can(char* buf, struct timeval *date_tvp, char timestamps, /* check for CAN ID with (hexa)decimal value */ if (base == 'h') - get_can_id(&cf, tmp1, 16); + get_can_id(&cf.can_id, tmp1, 16); else - get_can_id(&cf, tmp1, 10); + get_can_id(&cf.can_id, tmp1, 10); /* dlc > 8 => len == CAN_MAX_DLEN => fill len8_dlc value */ if (dlc > CAN_MAX_DLC) @@ -236,7 +236,7 @@ static void eval_can(char* buf, struct timeval *date_tvp, char timestamps, cf.data[i] = data[i] & 0xFFU; calc_tv(&tv, &read_tv, date_tvp, timestamps, dplace); - prframe(outfile, &tv, interface, &cf, extra_info); + prframe(outfile, &tv, interface, (cu_t *)&cf, extra_info); fflush(outfile); } } @@ -311,7 +311,7 @@ static void eval_canfd(char* buf, struct timeval *date_tvp, char timestamps, if (dlen != can_fd_dlc2len(can_fd_len2dlc(dlen))) return; - get_can_id(&cf, tmp1, 16); + get_can_id(&cf.can_id, tmp1, 16); /* now search for the beginning of the data[] content */ sprintf(tmp1, " %x %x %x %2d ", brs, esi, dlc, dlen); @@ -377,7 +377,7 @@ static void eval_canfd(char* buf, struct timeval *date_tvp, char timestamps, } calc_tv(&tv, &read_tv, date_tvp, timestamps, dplace); - prframe(outfile, &tv, interface, &cf, extra_info); + prframe(outfile, &tv, interface, (cu_t *)&cf, extra_info); fflush(outfile); /* No support for really strange CANFD ErrorFrames format m( */ From 99c5c1479054ac9579940d2942fd10e9cf7ada04 Mon Sep 17 00:00:00 2001 From: Oliver Hartkopp Date: Tue, 10 Dec 2024 18:49:49 +0100 Subject: [PATCH 04/11] can.h: canxl: support Remote Request Substitution bit access The Remote Request Substitution bit is a dominant bit ("0") in the CAN XL frame. As some CAN XL controllers support to access this bit a new CANXL_RRS value has been defined for the canxl_frame.flags element. Signed-off-by: Oliver Hartkopp --- include/linux/can.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/include/linux/can.h b/include/linux/can.h index 2b7d511c..b3e2999d 100644 --- a/include/linux/can.h +++ b/include/linux/can.h @@ -182,7 +182,7 @@ struct canfd_frame { /* * defined bits for canxl_frame.flags * - * The canxl_frame.flags element contains two bits CANXL_XLF and CANXL_SEC + * The canxl_frame.flags element contains three bits CANXL_[XLF|SEC|RRS] * and shares the relative position of the struct can[fd]_frame.len element. * The CANXL_XLF bit ALWAYS needs to be set to indicate a valid CAN XL frame. * As a side effect setting this bit intentionally breaks the length checks @@ -192,6 +192,7 @@ struct canfd_frame { */ #define CANXL_XLF 0x80 /* mandatory CAN XL frame flag (must always be set!) */ #define CANXL_SEC 0x01 /* Simple Extended Content (security/segmentation) */ +#define CANXL_RRS 0x02 /* Remote Request Substitution */ /* the 8-bit VCID is optionally placed in the canxl_frame.prio element */ #define CANXL_VCID_OFFSET 16 /* bit offset of VCID in prio element */ From 0e9c53f6d3ce362b2a99b0f14a3ee7d33a081ad0 Mon Sep 17 00:00:00 2001 From: Oliver Hartkopp Date: Fri, 24 Jan 2025 14:33:59 +0100 Subject: [PATCH 05/11] asc2log: add CAN XL support for CAN XL message events Signed-off-by: Oliver Hartkopp --- asc2log.c | 220 +++++++++++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 211 insertions(+), 9 deletions(-) diff --git a/asc2log.c b/asc2log.c index 535629ec..060c4d30 100644 --- a/asc2log.c +++ b/asc2log.c @@ -58,7 +58,16 @@ #include "lib.h" -#define BUFLEN 400 /* CAN FD mode lines can be pretty long */ +#define BUFLEN 6500 /* CAN XL mode lines can be pretty long */ + +/* relevant flags in Flags field */ +#define ASC_F_RTR 0x00000010 +#define ASC_F_FDF 0x00001000 +#define ASC_F_BRS 0x00002000 +#define ASC_F_ESI 0x00004000 +#define ASC_F_XLF 0x00400000 +#define ASC_F_RES 0x00800000 +#define ASC_F_SEC 0x01000000 extern int optind, opterr, optopt; @@ -345,12 +354,6 @@ static void eval_canfd(char* buf, struct timeval *date_tvp, char timestamps, if (sscanf(ptr, " %*x %*x %x ", &flags) != 1) return; - /* relevant flags in Flags field */ -#define ASC_F_RTR 0x00000010 -#define ASC_F_FDF 0x00001000 -#define ASC_F_BRS 0x00002000 -#define ASC_F_ESI 0x00004000 - if (flags & ASC_F_FDF) { cf.flags = CANFD_FDF; if (flags & ASC_F_BRS) @@ -383,6 +386,203 @@ static void eval_canfd(char* buf, struct timeval *date_tvp, char timestamps, /* No support for really strange CANFD ErrorFrames format m( */ } +static void eval_canxl_cc(char* buf, struct timeval *date_tvp, char timestamps, + int dplace, FILE *outfile) +{} + +static void eval_canxl_fd(char* buf, struct timeval *date_tvp, char timestamps, + int dplace, FILE *outfile) +{} + +static void eval_canxl_xl(char* buf, struct timeval *date_tvp, char timestamps, + int dplace, FILE *outfile) +{ + int interface; + static struct timeval tv; /* current frame timestamp */ + static struct timeval read_tv; /* frame timestamp from ASC file */ + struct canxl_frame cf = { 0 }; + unsigned char sdt, vcid, secbit, ctmp; + unsigned int af, sbc, pcrc, flags; + int dlc, dlen = 0; + char tmp1[BUFLEN]; + char dir[5]; /* 'Rx'/'Tx'/'TxRq' plus terminating zero */ + char *extra_info; + char *ptr; + int i; + unsigned long long sec, usec; + + /* + * 59.171614 CANXL 2 Rx XLFF 984438 4656 432 msgCanXlTest1 \ + * e0 0 1fe 511 1 1f96 00 00000000 e1 89 e8 c2 b9 6d 5a f1 c5 97 ( .. ) \ + * ( .. ) c7 e3 4e f6 bf 12cfbd62 02503000 00000000 000000050005000e \ + * 0000000000a00010 0000000a000a001d 0000000000a00002 000000100010000f \ + * 000000000a00001 + */ + + /* check for valid line without symbolic name */ + if (sscanf(buf, + "%llu.%llu %*s %d %4s " /* time, CANXL, channel, direction */ + "%*s %*s %*s %s " /* frame format, msg dur, bit count, ID */ + "%hhx %hhx %x %d " /* SDT, SEC, DLC, Datalen */ + "%x %x %hhx %x ", /* stuff bit count, crc, VCID, AF */ + &sec, &usec, &interface, dir, + tmp1, + &sdt, &secbit, &dlc, &dlen, + &sbc, &pcrc, &vcid, &af) != 13) { + /* check for valid line with a symbolic name */ + if (sscanf(buf, + "%llu.%llu %*s %d %4s " /* time, CANXL, channel, direction */ + "%*s %*s %*s %s " /* frame format, msg dur, bit count, ID */ + "%*s %hhx %hhx %x %d " /* sym name, SDT, SEC, DLC, Datalen */ + "%x %x %hhx %x ", /* stuff bit count, crc, VCID, AF */ + &sec, &usec, &interface, dir, + tmp1, + &sdt, &secbit, &dlc, &dlen, + &sbc, &pcrc, &vcid, &af) != 13) { + + /* no valid CANXL format pattern */ + return; + } + } + + read_tv.tv_sec = sec; + read_tv.tv_usec = usec; + + /* check for allowed (unsigned) value ranges */ + if ((dlen > CANXL_MAX_DLEN) || (dlc > CANXL_MAX_DLC) || + (sbc > 7) || (secbit > 1)) + return; + + cf.sdt = sdt; + cf.af = af; + + if (strlen(dir) != 2) /* "Rx" or "Tx" */ + return; + + /* check for signed integer overflow */ + if (dplace == 4 && read_tv.tv_usec >= INT_MAX / 100) + return; + + /* check for signed integer overflow */ + if (dplace == 5 && read_tv.tv_usec >= INT_MAX / 10) + return; + + if (dir[0] == 'R') + extra_info = " R\n"; + else + extra_info = " T\n"; + + /* don't trust ASCII content - sanitize data length */ + if (dlen != dlc + 1) + return; + + get_can_id(&cf.prio, tmp1, 16); + + if ((cf.prio & CANXL_PRIO_MASK) != cf.prio) + return; + + if (vcid) + cf.prio |= (vcid << CANXL_VCID_OFFSET); + + /* now search for the beginning of the data[] content */ + sprintf(tmp1, " %x %04x %02x %08x ", sbc, pcrc, vcid, af); + + /* search for the pattern generated by real data */ + ptr = strcasestr(buf, tmp1); + if (ptr == NULL) + return; + + ptr += strlen(tmp1); /* start of ASCII hex frame data */ + + cf.len = dlen; + + for (i = 0; i < dlen; i++) { + ctmp = asc2nibble(ptr[0]); + if (ctmp > 0x0F) + return; + + cf.data[i] = (ctmp << 4); + + ctmp = asc2nibble(ptr[1]); + if (ctmp > 0x0F) + return; + + cf.data[i] |= ctmp; + + ptr += 3; /* start of next ASCII hex byte */ + } + + /* skip FCRC to get Flags value */ + if (sscanf(ptr, "%*x %x ", &flags) != 1) + return; + + /* mandatory for CAN XL frames */ + if (!(flags & ASC_F_XLF)) + return; + + /* mark as CAN XL */ + cf.flags = CANXL_XLF; + + if (flags & ASC_F_SEC) + cf.flags |= CANXL_SEC; + + if (flags & ASC_F_RES) + cf.flags |= CANXL_RRS; + + calc_tv(&tv, &read_tv, date_tvp, timestamps, dplace); + prframe(outfile, &tv, interface, (cu_t *)&cf, extra_info); + fflush(outfile); + + /* No support for CAN XL ErrorFrames */ +} + +static void eval_canxl(char* buf, struct timeval *date_tvp, char timestamps, + int dplace, FILE *outfile) +{ + int interface; + char dir[5]; /* 'Rx'/'Tx'/'TxRq' plus terminating zero */ + char frfo[5]; /* frame format 'CBFF'/'CEFF'/'FBFF'/'FEFF'/'XLFF' plus terminating zero */ + unsigned long long sec, usec; + + /* + * The CANXL format is mainly in hex representation but + * and probably some content we skip anyway. Check out the new spec: + * CAN, Log & Trigger ASC Logging Format Spec V 1.4.17 of 2024-05-21 + */ + + /* + * This is a CAN XL ("XLFF") example for the CANXL Message Event: + * + * 59.171614 CANXL 2 Rx XLFF 984438 4656 432 msgCanXlTest1 \ + * e0 0 1fe 511 1 1f96 00 00000000 e1 89 e8 c2 b9 6d 5a f1 c5 97 ( .. ) \ + * ( .. ) c7 e3 4e f6 bf 12cfbd62 02503000 00000000 000000050005000e \ + * 0000000000a00010 0000000a000a001d 0000000000a00002 000000100010000f \ + * 000000000a00001 + */ + + /* check for valid line until frame format tag */ + if (sscanf(buf, "%llu.%llu %*s %d %4s %4s ", + &sec, &usec, &interface, dir, frfo) != 5) + return; /* no valid CANXL format pattern */ + + if (strlen(dir) != 2) /* "Rx" or "Tx" */ + return; + + if (strlen(frfo) != 4) /* 'CBFF'/'CEFF'/'FBFF'/'FEFF'/'XLFF' */ + return; + + if (!strncmp(frfo, "XLFF", 4)) + eval_canxl_xl(buf, date_tvp, timestamps, dplace, outfile); + else if (!strncmp(frfo, "FBFF", 4)) + eval_canxl_fd(buf, date_tvp, timestamps, dplace, outfile); + else if (!strncmp(frfo, "FEFF", 4)) + eval_canxl_fd(buf, date_tvp, timestamps, dplace, outfile); + else if (!strncmp(frfo, "CBFF", 4)) + eval_canxl_cc(buf, date_tvp, timestamps, dplace, outfile); + else if (!strncmp(frfo, "CEFF", 4)) + eval_canxl_cc(buf, date_tvp, timestamps, dplace, outfile); +} + static int get_date(struct timeval *tv, char *date) { struct tm tms; @@ -550,9 +750,11 @@ int main(int argc, char **argv) * So try to get CAN frames and ErrorFrames and convert them. */ - /* check classic CAN format or the CANFD tag which can take both types */ + /* check classic CAN format or the CANFD/CANXL tag which can take different types */ if (sscanf(buf, "%llu.%llu %s ", &sec, &usec, tmp1) == 3){ - if (!strncmp(tmp1, "CANFD", 5)) + if (!strncmp(tmp1, "CANXL", 5)) + eval_canxl(buf, &date_tv, timestamps, dplace, outfile); + else if (!strncmp(tmp1, "CANFD", 5)) eval_canfd(buf, &date_tv, timestamps, dplace, outfile); else eval_can(buf, &date_tv, timestamps, base, dplace, outfile); From 4d8b24725888d07eb918c3562badbd32ab1d98a3 Mon Sep 17 00:00:00 2001 From: Oliver Hartkopp Date: Fri, 24 Jan 2025 14:48:32 +0100 Subject: [PATCH 06/11] asc2log: make use of sscanf consumed characters feature Signed-off-by: Oliver Hartkopp --- asc2log.c | 43 ++++++++++++++----------------------------- 1 file changed, 14 insertions(+), 29 deletions(-) diff --git a/asc2log.c b/asc2log.c index 060c4d30..fe695982 100644 --- a/asc2log.c +++ b/asc2log.c @@ -265,6 +265,7 @@ static void eval_canfd(char* buf, struct timeval *date_tvp, char timestamps, char *extra_info; char *ptr; int i; + int n = 0; /* sscanf consumed characters */ unsigned long long sec, usec; /* @@ -279,14 +280,14 @@ static void eval_canfd(char* buf, struct timeval *date_tvp, char timestamps, */ /* check for valid line without symbolic name */ - if (sscanf(buf, "%llu.%llu %*s %d %4s %s %hhx %hhx %x %d ", + if (sscanf(buf, "%llu.%llu %*s %d %4s %s %hhx %hhx %x %d %n", &sec, &usec, &interface, - dir, tmp1, &brs, &esi, &dlc, &dlen) != 9) { + dir, tmp1, &brs, &esi, &dlc, &dlen, &n) != 9) { /* check for valid line with a symbolic name */ - if (sscanf(buf, "%llu.%llu %*s %d %4s %s %*s %hhx %hhx %x %d ", + if (sscanf(buf, "%llu.%llu %*s %d %4s %s %*s %hhx %hhx %x %d %n", &sec, &usec, &interface, - dir, tmp1, &brs, &esi, &dlc, &dlen) != 9) { + dir, tmp1, &brs, &esi, &dlc, &dlen, &n) != 9) { /* no valid CANFD format pattern */ return; @@ -322,15 +323,7 @@ static void eval_canfd(char* buf, struct timeval *date_tvp, char timestamps, get_can_id(&cf.can_id, tmp1, 16); - /* now search for the beginning of the data[] content */ - sprintf(tmp1, " %x %x %x %2d ", brs, esi, dlc, dlen); - - /* search for the pattern generated by real data */ - ptr = strcasestr(buf, tmp1); - if (ptr == NULL) - return; - - ptr += strlen(tmp1); /* start of ASCII hex frame data */ + ptr = buf + n; /* start of ASCII hex frame data */ cf.len = dlen; @@ -402,13 +395,14 @@ static void eval_canxl_xl(char* buf, struct timeval *date_tvp, char timestamps, static struct timeval read_tv; /* frame timestamp from ASC file */ struct canxl_frame cf = { 0 }; unsigned char sdt, vcid, secbit, ctmp; - unsigned int af, sbc, pcrc, flags; + unsigned int af, flags; int dlc, dlen = 0; char tmp1[BUFLEN]; char dir[5]; /* 'Rx'/'Tx'/'TxRq' plus terminating zero */ char *extra_info; char *ptr; int i; + int n = 0; /* sscanf consumed characters */ unsigned long long sec, usec; /* @@ -424,21 +418,21 @@ static void eval_canxl_xl(char* buf, struct timeval *date_tvp, char timestamps, "%llu.%llu %*s %d %4s " /* time, CANXL, channel, direction */ "%*s %*s %*s %s " /* frame format, msg dur, bit count, ID */ "%hhx %hhx %x %d " /* SDT, SEC, DLC, Datalen */ - "%x %x %hhx %x ", /* stuff bit count, crc, VCID, AF */ + "%*s %*s %hhx %x %n", /* stuff bit count, crc, VCID, AF */ &sec, &usec, &interface, dir, tmp1, &sdt, &secbit, &dlc, &dlen, - &sbc, &pcrc, &vcid, &af) != 13) { + &vcid, &af, &n) != 11) { /* check for valid line with a symbolic name */ if (sscanf(buf, "%llu.%llu %*s %d %4s " /* time, CANXL, channel, direction */ "%*s %*s %*s %s " /* frame format, msg dur, bit count, ID */ "%*s %hhx %hhx %x %d " /* sym name, SDT, SEC, DLC, Datalen */ - "%x %x %hhx %x ", /* stuff bit count, crc, VCID, AF */ + "%*s %*s %hhx %x %n", /* stuff bit count, crc, VCID, AF */ &sec, &usec, &interface, dir, tmp1, &sdt, &secbit, &dlc, &dlen, - &sbc, &pcrc, &vcid, &af) != 13) { + &vcid, &af, &n) != 11) { /* no valid CANXL format pattern */ return; @@ -449,8 +443,7 @@ static void eval_canxl_xl(char* buf, struct timeval *date_tvp, char timestamps, read_tv.tv_usec = usec; /* check for allowed (unsigned) value ranges */ - if ((dlen > CANXL_MAX_DLEN) || (dlc > CANXL_MAX_DLC) || - (sbc > 7) || (secbit > 1)) + if ((dlen > CANXL_MAX_DLEN) || (dlc > CANXL_MAX_DLC) || (secbit > 1)) return; cf.sdt = sdt; @@ -484,15 +477,7 @@ static void eval_canxl_xl(char* buf, struct timeval *date_tvp, char timestamps, if (vcid) cf.prio |= (vcid << CANXL_VCID_OFFSET); - /* now search for the beginning of the data[] content */ - sprintf(tmp1, " %x %04x %02x %08x ", sbc, pcrc, vcid, af); - - /* search for the pattern generated by real data */ - ptr = strcasestr(buf, tmp1); - if (ptr == NULL) - return; - - ptr += strlen(tmp1); /* start of ASCII hex frame data */ + ptr = buf + n; /* start of ASCII hex frame data */ cf.len = dlen; From 6d69bef837596cfcbdf291ba3a77703f53f08b04 Mon Sep 17 00:00:00 2001 From: Oliver Hartkopp Date: Tue, 10 Dec 2024 22:02:09 +0100 Subject: [PATCH 07/11] asc2log: add CAN CC and CAN FD support for CAN XL message events Signed-off-by: Oliver Hartkopp --- asc2log.c | 220 +++++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 218 insertions(+), 2 deletions(-) diff --git a/asc2log.c b/asc2log.c index fe695982..7d180f7c 100644 --- a/asc2log.c +++ b/asc2log.c @@ -381,11 +381,227 @@ static void eval_canfd(char* buf, struct timeval *date_tvp, char timestamps, static void eval_canxl_cc(char* buf, struct timeval *date_tvp, char timestamps, int dplace, FILE *outfile) -{} +{ + int interface; + static struct timeval tv; /* current frame timestamp */ + static struct timeval read_tv; /* frame timestamp from ASC file */ + struct can_frame cf = { 0 }; + unsigned char ctmp; + unsigned int flags; + int dlc, dlen = 0; + char tmp1[BUFLEN]; + char dir[5]; /* 'Rx'/'Tx'/'TxRq' plus terminating zero */ + char *extra_info; + char *ptr; + int i; + int n = 0; /* sscanf consumed characters */ + unsigned long long sec, usec; + + /* + * 59.171614 CANXL 2 Rx CBFF 243215 176 432 msgCanCCTest1 \ + * f 8 e1 89 e8 c2 b9 6d 5a f1 174 00000000 00000000 \ + * 000000050005000e 0000000000a00010 0000000a000a001d \ + * 0000000000a00002 000000100010000f 000000000a00001 + */ + + /* check for valid line without symbolic name */ + if (sscanf(buf, + "%llu.%llu %*s %d %4s " /* time, CANXL, channel, direction */ + "%*s %*s %*s %s " /* frame format, msg dur, bit count, ID */ + "%x %d %n", /* DLC, Datalen */ + &sec, &usec, &interface, dir, + tmp1, + &dlc, &dlen, &n) != 7) { + /* check for valid line with a symbolic name */ + if (sscanf(buf, + "%llu.%llu %*s %d %4s " /* time, CANXL, channel, direction */ + "%*s %*s %*s %s " /* frame format, msg dur, bit count, ID */ + "%*s %x %d %n", /* sym name, DLC, Datalen */ + &sec, &usec, &interface, dir, + tmp1, + &dlc, &dlen, &n) != 7) { + /* no valid CAN CC format pattern */ + return; + } + } + + read_tv.tv_sec = sec; + read_tv.tv_usec = usec; + + /* check for allowed (unsigned) value ranges */ + if ((dlen > CAN_MAX_DLEN) || (dlc > CAN_MAX_RAW_DLC)) + return; + + if (strlen(dir) != 2) /* "Rx" or "Tx" */ + return; + + /* check for signed integer overflow */ + if (dplace == 4 && read_tv.tv_usec >= INT_MAX / 100) + return; + + /* check for signed integer overflow */ + if (dplace == 5 && read_tv.tv_usec >= INT_MAX / 10) + return; + + if (dir[0] == 'R') + extra_info = " R\n"; + else + extra_info = " T\n"; + + get_can_id(&cf.can_id, tmp1, 16); + + ptr = buf + n; /* start of ASCII hex frame data */ + + cf.len = dlen; + + for (i = 0; i < dlen; i++) { + ctmp = asc2nibble(ptr[0]); + if (ctmp > 0x0F) + return; + + cf.data[i] = (ctmp << 4); + + ctmp = asc2nibble(ptr[1]); + if (ctmp > 0x0F) + return; + + cf.data[i] |= ctmp; + + ptr += 3; /* start of next ASCII hex byte */ + } + + /* skip FCRC to get Flags value */ + if (sscanf(ptr, "%*x %x ", &flags) != 1) + return; + + if (flags & ASC_F_RTR) { + cf.can_id |= CAN_RTR_FLAG; + /* dlen is always 0 for classic CAN RTR frames + but the DLC value is valid in RTR cases */ + cf.len = dlc; + /* sanitize payload length value */ + if (dlc > CAN_MAX_DLEN) + cf.len = CAN_MAX_DLEN; + } + + /* check for extra DLC when having a Classic CAN with 8 bytes payload */ + if ((cf.len == CAN_MAX_DLEN) && (dlc > CAN_MAX_DLEN) && (dlc <= CAN_MAX_RAW_DLC)) + cf.len8_dlc = dlc; + + calc_tv(&tv, &read_tv, date_tvp, timestamps, dplace); + prframe(outfile, &tv, interface, (cu_t *)&cf, extra_info); + fflush(outfile); +} static void eval_canxl_fd(char* buf, struct timeval *date_tvp, char timestamps, int dplace, FILE *outfile) -{} +{ + int interface; + static struct timeval tv; /* current frame timestamp */ + static struct timeval read_tv; /* frame timestamp from ASC file */ + struct canfd_frame cf = { 0 }; + unsigned char ctmp; + unsigned int flags; + int dlc, dlen = 0; + char tmp1[BUFLEN]; + char dir[5]; /* 'Rx'/'Tx'/'TxRq' plus terminating zero */ + char *extra_info; + char *ptr; + int i; + int n = 0; /* sscanf consumed characters */ + unsigned long long sec, usec; + + /* + * 59.171614 CANXL 2 Rx FBFF 243215 176 432 msgCanFDTest2 \ + * 9 12 e1 89 e8 c2 b9 6d 5a f1 11 22 33 44 a 12345 00001240 00000000 \ + * 000000050005000e 0000000000a00010 0000000a000a001d \ + * 0000000000a00002 000000100010000f 000000000a00001 + */ + + /* check for valid line without symbolic name */ + if (sscanf(buf, + "%llu.%llu %*s %d %4s " /* time, CANXL, channel, direction */ + "%*s %*s %*s %s " /* frame format, msg dur, bit count, ID */ + "%x %d %n", /* DLC, Datalen */ + &sec, &usec, &interface, dir, + tmp1, + &dlc, &dlen, &n) != 7) { + /* check for valid line with a symbolic name */ + if (sscanf(buf, + "%llu.%llu %*s %d %4s " /* time, CANXL, channel, direction */ + "%*s %*s %*s %s " /* frame format, msg dur, bit count, ID */ + "%*s %x %d %n", /* sym name, DLC, Datalen */ + &sec, &usec, &interface, dir, + tmp1, + &dlc, &dlen, &n) != 7) { + /* no valid CAN CC format pattern */ + return; + } + } + + read_tv.tv_sec = sec; + read_tv.tv_usec = usec; + + /* check for allowed (unsigned) value ranges */ + if ((dlen > CANFD_MAX_DLEN) || (dlc > CANFD_MAX_DLC)) + return; + + if (strlen(dir) != 2) /* "Rx" or "Tx" */ + return; + + /* check for signed integer overflow */ + if (dplace == 4 && read_tv.tv_usec >= INT_MAX / 100) + return; + + /* check for signed integer overflow */ + if (dplace == 5 && read_tv.tv_usec >= INT_MAX / 10) + return; + + if (dir[0] == 'R') + extra_info = " R\n"; + else + extra_info = " T\n"; + + get_can_id(&cf.can_id, tmp1, 16); + + ptr = buf + n; /* start of ASCII hex frame data */ + + cf.len = dlen; + + for (i = 0; i < dlen; i++) { + ctmp = asc2nibble(ptr[0]); + if (ctmp > 0x0F) + return; + + cf.data[i] = (ctmp << 4); + + ctmp = asc2nibble(ptr[1]); + if (ctmp > 0x0F) + return; + + cf.data[i] |= ctmp; + + ptr += 3; /* start of next ASCII hex byte */ + } + + /* skip stuff field and FCRC to get Flags value */ + if (sscanf(ptr, "%*s %*s %x ", &flags) != 1) + return; + + if (!(flags & ASC_F_FDF)) + return; + + cf.flags = CANFD_FDF; + + if (flags & ASC_F_BRS) + cf.flags |= CANFD_BRS; + if (flags & ASC_F_ESI) + cf.flags |= CANFD_ESI; + + calc_tv(&tv, &read_tv, date_tvp, timestamps, dplace); + prframe(outfile, &tv, interface, (cu_t *)&cf, extra_info); + fflush(outfile); +} static void eval_canxl_xl(char* buf, struct timeval *date_tvp, char timestamps, int dplace, FILE *outfile) From e6e32539728b6003d9c69df7fee5d6fe65d3572f Mon Sep 17 00:00:00 2001 From: Oliver Hartkopp Date: Fri, 24 Jan 2025 14:56:16 +0100 Subject: [PATCH 08/11] asc2log: shrink string buffer for CAN identifier Since using the %n feature the tmp1 buffer is only used for the handling of the CAN identifier. So this buffer can be shrinked for that use case. Signed-off-by: Oliver Hartkopp --- asc2log.c | 68 +++++++++++++++++++++++++++---------------------------- 1 file changed, 34 insertions(+), 34 deletions(-) diff --git a/asc2log.c b/asc2log.c index 7d180f7c..e76d0e53 100644 --- a/asc2log.c +++ b/asc2log.c @@ -151,20 +151,20 @@ static void eval_can(char* buf, struct timeval *date_tvp, char timestamps, int dlc = 0; int len = 0; int data[8]; - char tmp1[BUFLEN]; + char idstr[21]; char dir[5]; /* 'Rx'/'Tx'/'TxRq' plus terminating zero */ char *extra_info; int i, items; unsigned long long sec, usec; /* check for ErrorFrames */ - if (sscanf(buf, "%llu.%llu %d %s", + if (sscanf(buf, "%llu.%llu %d %20s", &sec, &usec, - &interface, tmp1) == 4) { + &interface, idstr) == 4) { read_tv.tv_sec = sec; read_tv.tv_usec = usec; - if (!strncmp(tmp1, "ErrorFrame", strlen("ErrorFrame"))) { + if (!strncmp(idstr, "ErrorFrame", strlen("ErrorFrame"))) { /* do not know more than 'Error' */ cf.can_id = (CAN_ERR_FLAG | CAN_ERR_BUSERROR); @@ -181,15 +181,15 @@ static void eval_can(char* buf, struct timeval *date_tvp, char timestamps, /* check for CAN frames with (hexa)decimal values */ if (base == 'h') - items = sscanf(buf, "%llu.%llu %d %s %4s %c %x %x %x %x %x %x %x %x %x", + items = sscanf(buf, "%llu.%llu %d %20s %4s %c %x %x %x %x %x %x %x %x %x", &sec, &usec, &interface, - tmp1, dir, &rtr, &dlc, + idstr, dir, &rtr, &dlc, &data[0], &data[1], &data[2], &data[3], &data[4], &data[5], &data[6], &data[7]); else - items = sscanf(buf, "%llu.%llu %d %s %4s %c %x %d %d %d %d %d %d %d %d", + items = sscanf(buf, "%llu.%llu %d %20s %4s %c %x %d %d %d %d %d %d %d %d", &sec, &usec, &interface, - tmp1, dir, &rtr, &dlc, + idstr, dir, &rtr, &dlc, &data[0], &data[1], &data[2], &data[3], &data[4], &data[5], &data[6], &data[7]); @@ -214,9 +214,9 @@ static void eval_can(char* buf, struct timeval *date_tvp, char timestamps, /* check for CAN ID with (hexa)decimal value */ if (base == 'h') - get_can_id(&cf.can_id, tmp1, 16); + get_can_id(&cf.can_id, idstr, 16); else - get_can_id(&cf.can_id, tmp1, 10); + get_can_id(&cf.can_id, idstr, 10); /* dlc > 8 => len == CAN_MAX_DLEN => fill len8_dlc value */ if (dlc > CAN_MAX_DLC) @@ -260,7 +260,7 @@ static void eval_canfd(char* buf, struct timeval *date_tvp, char timestamps, unsigned char brs, esi, ctmp; unsigned int flags; int dlc, dlen = 0; - char tmp1[BUFLEN]; + char idstr[21]; char dir[5]; /* 'Rx'/'Tx'/'TxRq' plus terminating zero */ char *extra_info; char *ptr; @@ -280,14 +280,14 @@ static void eval_canfd(char* buf, struct timeval *date_tvp, char timestamps, */ /* check for valid line without symbolic name */ - if (sscanf(buf, "%llu.%llu %*s %d %4s %s %hhx %hhx %x %d %n", + if (sscanf(buf, "%llu.%llu %*s %d %4s %20s %hhx %hhx %x %d %n", &sec, &usec, &interface, - dir, tmp1, &brs, &esi, &dlc, &dlen, &n) != 9) { + dir, idstr, &brs, &esi, &dlc, &dlen, &n) != 9) { /* check for valid line with a symbolic name */ - if (sscanf(buf, "%llu.%llu %*s %d %4s %s %*s %hhx %hhx %x %d %n", + if (sscanf(buf, "%llu.%llu %*s %d %4s %20s %*s %hhx %hhx %x %d %n", &sec, &usec, &interface, - dir, tmp1, &brs, &esi, &dlc, &dlen, &n) != 9) { + dir, idstr, &brs, &esi, &dlc, &dlen, &n) != 9) { /* no valid CANFD format pattern */ return; @@ -321,7 +321,7 @@ static void eval_canfd(char* buf, struct timeval *date_tvp, char timestamps, if (dlen != can_fd_dlc2len(can_fd_len2dlc(dlen))) return; - get_can_id(&cf.can_id, tmp1, 16); + get_can_id(&cf.can_id, idstr, 16); ptr = buf + n; /* start of ASCII hex frame data */ @@ -389,7 +389,7 @@ static void eval_canxl_cc(char* buf, struct timeval *date_tvp, char timestamps, unsigned char ctmp; unsigned int flags; int dlc, dlen = 0; - char tmp1[BUFLEN]; + char idstr[21]; char dir[5]; /* 'Rx'/'Tx'/'TxRq' plus terminating zero */ char *extra_info; char *ptr; @@ -407,18 +407,18 @@ static void eval_canxl_cc(char* buf, struct timeval *date_tvp, char timestamps, /* check for valid line without symbolic name */ if (sscanf(buf, "%llu.%llu %*s %d %4s " /* time, CANXL, channel, direction */ - "%*s %*s %*s %s " /* frame format, msg dur, bit count, ID */ + "%*s %*s %*s %20s " /* frame format, msg dur, bit count, ID */ "%x %d %n", /* DLC, Datalen */ &sec, &usec, &interface, dir, - tmp1, + idstr, &dlc, &dlen, &n) != 7) { /* check for valid line with a symbolic name */ if (sscanf(buf, "%llu.%llu %*s %d %4s " /* time, CANXL, channel, direction */ - "%*s %*s %*s %s " /* frame format, msg dur, bit count, ID */ + "%*s %*s %*s %20s " /* frame format, msg dur, bit count, ID */ "%*s %x %d %n", /* sym name, DLC, Datalen */ &sec, &usec, &interface, dir, - tmp1, + idstr, &dlc, &dlen, &n) != 7) { /* no valid CAN CC format pattern */ return; @@ -448,7 +448,7 @@ static void eval_canxl_cc(char* buf, struct timeval *date_tvp, char timestamps, else extra_info = " T\n"; - get_can_id(&cf.can_id, tmp1, 16); + get_can_id(&cf.can_id, idstr, 16); ptr = buf + n; /* start of ASCII hex frame data */ @@ -503,7 +503,7 @@ static void eval_canxl_fd(char* buf, struct timeval *date_tvp, char timestamps, unsigned char ctmp; unsigned int flags; int dlc, dlen = 0; - char tmp1[BUFLEN]; + char idstr[21]; char dir[5]; /* 'Rx'/'Tx'/'TxRq' plus terminating zero */ char *extra_info; char *ptr; @@ -521,18 +521,18 @@ static void eval_canxl_fd(char* buf, struct timeval *date_tvp, char timestamps, /* check for valid line without symbolic name */ if (sscanf(buf, "%llu.%llu %*s %d %4s " /* time, CANXL, channel, direction */ - "%*s %*s %*s %s " /* frame format, msg dur, bit count, ID */ + "%*s %*s %*s %20s " /* frame format, msg dur, bit count, ID */ "%x %d %n", /* DLC, Datalen */ &sec, &usec, &interface, dir, - tmp1, + idstr, &dlc, &dlen, &n) != 7) { /* check for valid line with a symbolic name */ if (sscanf(buf, "%llu.%llu %*s %d %4s " /* time, CANXL, channel, direction */ - "%*s %*s %*s %s " /* frame format, msg dur, bit count, ID */ + "%*s %*s %*s %20s " /* frame format, msg dur, bit count, ID */ "%*s %x %d %n", /* sym name, DLC, Datalen */ &sec, &usec, &interface, dir, - tmp1, + idstr, &dlc, &dlen, &n) != 7) { /* no valid CAN CC format pattern */ return; @@ -562,7 +562,7 @@ static void eval_canxl_fd(char* buf, struct timeval *date_tvp, char timestamps, else extra_info = " T\n"; - get_can_id(&cf.can_id, tmp1, 16); + get_can_id(&cf.can_id, idstr, 16); ptr = buf + n; /* start of ASCII hex frame data */ @@ -613,7 +613,7 @@ static void eval_canxl_xl(char* buf, struct timeval *date_tvp, char timestamps, unsigned char sdt, vcid, secbit, ctmp; unsigned int af, flags; int dlc, dlen = 0; - char tmp1[BUFLEN]; + char idstr[21]; char dir[5]; /* 'Rx'/'Tx'/'TxRq' plus terminating zero */ char *extra_info; char *ptr; @@ -632,21 +632,21 @@ static void eval_canxl_xl(char* buf, struct timeval *date_tvp, char timestamps, /* check for valid line without symbolic name */ if (sscanf(buf, "%llu.%llu %*s %d %4s " /* time, CANXL, channel, direction */ - "%*s %*s %*s %s " /* frame format, msg dur, bit count, ID */ + "%*s %*s %*s %20s " /* frame format, msg dur, bit count, ID */ "%hhx %hhx %x %d " /* SDT, SEC, DLC, Datalen */ "%*s %*s %hhx %x %n", /* stuff bit count, crc, VCID, AF */ &sec, &usec, &interface, dir, - tmp1, + idstr, &sdt, &secbit, &dlc, &dlen, &vcid, &af, &n) != 11) { /* check for valid line with a symbolic name */ if (sscanf(buf, "%llu.%llu %*s %d %4s " /* time, CANXL, channel, direction */ - "%*s %*s %*s %s " /* frame format, msg dur, bit count, ID */ + "%*s %*s %*s %20s " /* frame format, msg dur, bit count, ID */ "%*s %hhx %hhx %x %d " /* sym name, SDT, SEC, DLC, Datalen */ "%*s %*s %hhx %x %n", /* stuff bit count, crc, VCID, AF */ &sec, &usec, &interface, dir, - tmp1, + idstr, &sdt, &secbit, &dlc, &dlen, &vcid, &af, &n) != 11) { @@ -685,7 +685,7 @@ static void eval_canxl_xl(char* buf, struct timeval *date_tvp, char timestamps, if (dlen != dlc + 1) return; - get_can_id(&cf.prio, tmp1, 16); + get_can_id(&cf.prio, idstr, 16); if ((cf.prio & CANXL_PRIO_MASK) != cf.prio) return; From 4b66e8c56f4bba2f274eb7c2e1cd395dd193b21b Mon Sep 17 00:00:00 2001 From: Oliver Hartkopp Date: Fri, 24 Jan 2025 14:59:57 +0100 Subject: [PATCH 09/11] asc2log: shrink string buffer for header analysis Signed-off-by: Oliver Hartkopp --- asc2log.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/asc2log.c b/asc2log.c index e76d0e53..31c0a827 100644 --- a/asc2log.c +++ b/asc2log.c @@ -843,7 +843,7 @@ static int get_date(struct timeval *tv, char *date) int main(int argc, char **argv) { - char buf[BUFLEN], tmp1[BUFLEN], tmp2[BUFLEN]; + char buf[BUFLEN], tmp1[10], tmp2[10]; FILE *infile = stdin; FILE *outfile = stdout; @@ -897,7 +897,7 @@ int main(int argc, char **argv) /* check for base and timestamp entries in the header */ if ((!base) && - (sscanf(buf, "base %s timestamps %s", tmp1, tmp2) == 2)) { + (sscanf(buf, "base %9s timestamps %9s", tmp1, tmp2) == 2)) { base = tmp1[0]; timestamps = tmp2[0]; if (verbose) @@ -931,7 +931,7 @@ int main(int argc, char **argv) } /* check for decimal places length in valid CAN frames */ - if (sscanf(buf, "%llu.%s %s ", &sec, tmp2, + if (sscanf(buf, "%llu.%9s %9s ", &sec, tmp2, tmp1) != 3) continue; /* dplace remains zero until first found CAN frame */ @@ -952,7 +952,7 @@ int main(int argc, char **argv) */ /* check classic CAN format or the CANFD/CANXL tag which can take different types */ - if (sscanf(buf, "%llu.%llu %s ", &sec, &usec, tmp1) == 3){ + if (sscanf(buf, "%llu.%llu %9s ", &sec, &usec, tmp1) == 3) { if (!strncmp(tmp1, "CANXL", 5)) eval_canxl(buf, &date_tv, timestamps, dplace, outfile); else if (!strncmp(tmp1, "CANFD", 5)) From 66e7c08bebba9ccee36650e4af5f3f635ede0ab6 Mon Sep 17 00:00:00 2001 From: Oliver Hartkopp Date: Thu, 12 Dec 2024 14:02:12 +0100 Subject: [PATCH 10/11] log2asc: add CAN XL support Signed-off-by: Oliver Hartkopp --- log2asc.c | 172 +++++++++++++++++++++++++++++++++++++++++++++--------- 1 file changed, 144 insertions(+), 28 deletions(-) diff --git a/log2asc.c b/log2asc.c index a0a325f4..09e5abed 100644 --- a/log2asc.c +++ b/log2asc.c @@ -54,6 +54,15 @@ #include "lib.h" +/* relevant flags in Flags field */ +#define ASC_F_RTR 0x00000010 +#define ASC_F_FDF 0x00001000 +#define ASC_F_BRS 0x00002000 +#define ASC_F_ESI 0x00004000 +#define ASC_F_XLF 0x00400000 +#define ASC_F_RES 0x00800000 +#define ASC_F_SEC 0x01000000 + extern int optind, opterr, optopt; static void print_usage(char *prg) @@ -65,18 +74,17 @@ static void print_usage(char *prg) fprintf(stderr, " -O (default stdout)\n"); fprintf(stderr, " -4 (reduce decimal place to 4 digits)\n"); fprintf(stderr, " -n (set newline to cr/lf - default lf)\n"); - fprintf(stderr, " -f (use CANFD format also for Classic CAN)\n"); + fprintf(stderr, " -f (use CANFD format also for CAN CC)\n"); + fprintf(stderr, " -x (use CANXL format also for CAN CC/FD)\n"); fprintf(stderr, " -r (suppress dlc for RTR frames - pre v8.5 tools)\n"); } -static void can_asc(struct canfd_frame *cfd, int devno, int nortrdlc, +static void can_asc(struct can_frame *cf, int devno, int nortrdlc, char *extra_info, FILE *outfile) { - int i; + unsigned int i, dlc; char id[10]; char *dir = "Rx"; - int dlc; - struct can_frame *cf = (struct can_frame *)cfd; /* for len8_dlc */ fprintf(outfile, "%-2d ", devno); /* channel number left aligned */ @@ -93,7 +101,7 @@ static void can_asc(struct canfd_frame *cfd, int devno, int nortrdlc, dir = "Tx"; } - fprintf(outfile, "%-15s %s ", id, dir); + fprintf(outfile, "%-15s %-4s ", id, dir); if (cf->len == CAN_MAX_DLC && cf->len8_dlc > CAN_MAX_DLC && @@ -120,19 +128,13 @@ static void can_asc(struct canfd_frame *cfd, int devno, int nortrdlc, static void canfd_asc(struct canfd_frame *cf, int devno, int mtu, char *extra_info, FILE *outfile) { - int i; + unsigned int i; char id[10]; char *dir = "Rx"; unsigned int flags = 0; unsigned int dlen = cf->len; unsigned int dlc = can_fd_len2dlc(dlen); - /* relevant flags in Flags field */ -#define ASC_F_RTR 0x00000010 -#define ASC_F_FDF 0x00001000 -#define ASC_F_BRS 0x00002000 -#define ASC_F_ESI 0x00004000 - /* check for extra info */ if (strlen(extra_info) > 0) { /* only the first char is defined so far */ @@ -140,7 +142,7 @@ static void canfd_asc(struct canfd_frame *cf, int devno, int mtu, dir = "Tx"; } - fprintf(outfile, "CANFD %3d %s ", devno, dir); /* 3 column channel number right aligned */ + fprintf(outfile, "CANFD %3d %-4s ", devno, dir); /* 3 column channel number right aligned */ sprintf(id, "%X%c", cf->can_id & CAN_EFF_MASK, (cf->can_id & CAN_EFF_FLAG)?'x':' '); @@ -174,13 +176,124 @@ static void canfd_asc(struct canfd_frame *cf, int devno, int mtu, fprintf(outfile, "%2d", dlen); - for (i = 0; i < (int)dlen; i++) { + for (i = 0; i < dlen; i++) { fprintf(outfile, " %02X", cf->data[i]); } fprintf(outfile, " %8d %4d %8X 0 0 0 0 0", 130000, 130, flags); } +static void canxl_asc(cu_t *cu, int devno, int mtu, + char *extra_info, FILE *outfile) +{ + char id[10]; + char *dir = "Rx"; + char *frametype; + unsigned char *dataptr; + unsigned int i, dlen, dlc, flags = 0; + + /* check for extra info */ + if (strlen(extra_info) > 0) { + /* only the first char is defined so far */ + if (extra_info[0] == 'T') + dir = "Tx"; + } + + switch (mtu) { + case CANXL_MTU: + sprintf(id, "%X", cu->xl.prio & CANXL_PRIO_MASK); + frametype = "XLFF"; + + dataptr = &cu->xl.data[0]; + dlen = cu->xl.len; + dlc = dlen - 1; + flags = (ASC_F_XLF | ASC_F_FDF | ASC_F_BRS); + + if (cu->xl.flags & CANXL_SEC) + flags |= ASC_F_SEC; + if (cu->xl.flags & CANXL_RRS) + flags |= ASC_F_RES; + break; + + case CANFD_MTU: + if (cu->fd.can_id & CAN_EFF_FLAG) { + sprintf(id, "%Xx", cu->fd.can_id & CAN_EFF_MASK); + frametype = "FEFF"; + } else { + sprintf(id, "%X", cu->fd.can_id & CAN_SFF_MASK); + frametype = "FBFF"; + } + + dataptr = &cu->fd.data[0]; + dlen = cu->fd.len; + dlc = can_fd_len2dlc(dlen); + flags = ASC_F_FDF; + if (cu->fd.flags & CANFD_BRS) + flags |= ASC_F_BRS; + if (cu->fd.flags & CANFD_ESI) + flags |= ASC_F_ESI; + break; + + case CAN_MTU: + if (cu->cc.can_id & CAN_EFF_FLAG) { + sprintf(id, "%Xx", cu->cc.can_id & CAN_EFF_MASK); + frametype = "CEFF"; + } else { + sprintf(id, "%X", cu->cc.can_id & CAN_SFF_MASK); + frametype = "CBFF"; + } + + dataptr = &cu->cc.data[0]; + dlen = cu->cc.len; + dlc = dlen ; + + /* check for extra DLC when having a Classic CAN with 8 bytes payload */ + if ((dlen == CAN_MAX_DLEN) && (cu->cc.len8_dlc > CAN_MAX_DLEN) && + (cu->cc.len8_dlc <= CAN_MAX_RAW_DLC)) + dlc = cu->cc.len8_dlc; + + if (cu->cc.can_id & CAN_RTR_FLAG) { + /* no data length but dlc for RTR frames */ + dlen = 0; + flags = ASC_F_RTR; + } + break; + + default: + return; + } + + fprintf(outfile, "CANXL %3d %-4s ", devno, dir); /* 3 column channel number and direction */ + + fprintf(outfile, "%s 984438 4656 ", frametype); /* frame type / msg duration / bit count */ + + fprintf(outfile, "%9s ", id); /* ID / symbolic name (empty) */ + + if (mtu == CANXL_MTU) /* SDT, SEC bit for CAN XL only */ + fprintf(outfile, "%02x %d ", cu->xl.sdt, (cu->xl.flags & CANXL_SEC)?1:0); + + fprintf(outfile, "%x %d", dlc, dlen); /* DLC and data length */ + + if (mtu == CANXL_MTU) /* SBC / PCRC / VCID / AF */ + fprintf(outfile, " 1 1f96 %02x %08x", + (unsigned char)((cu->xl.prio >> CANXL_VCID_OFFSET) & CANXL_VCID_VAL_MASK), + cu->xl.af); + + for (i = 0; i < dlen; i++) { + fprintf(outfile, " %02x", dataptr[i]); + } + + if (mtu == CANFD_MTU) /* stuff field */ + fprintf(outfile, " 8"); + + fprintf(outfile, " 123123 %08x %08x", flags, 0); /* fcsc, msg flags, msg flags ext */ + + fprintf(outfile, /* bitrate settings for CC/FD/XL */ + " 000000050005000e 0000000000a00010" + " 0000000a000a001d 0000000000a00002" + " 000000100010000f 0000000000a00001"); +} + #define DEVSZ 22 #define EXTRASZ 20 #define TIMESZ sizeof("(1345212884.318850) ") @@ -205,11 +318,11 @@ int main(int argc, char **argv) static struct timeval tv, start_tv; FILE *infile = stdin; FILE *outfile = stdout; - static int maxdev, devno, i, crlf, fdfmt, nortrdlc, d4, opt, mtu; + static int maxdev, devno, i, crlf, fdfmt, xlfmt, nortrdlc, d4, opt, mtu; int print_banner = 1; unsigned long long sec, usec; - while ((opt = getopt(argc, argv, "I:O:4nfr?")) != -1) { + while ((opt = getopt(argc, argv, "I:O:4nfxr?")) != -1) { switch (opt) { case 'I': infile = fopen(optarg, "r"); @@ -235,6 +348,10 @@ int main(int argc, char **argv) fdfmt = 1; break; + case 'x': + xlfmt = 1; + break; + case 'r': nortrdlc = 1; break; @@ -300,6 +417,9 @@ int main(int argc, char **argv) (crlf)?"\r\n":"\n"); fprintf(outfile, "no internal events logged%s", (crlf)?"\r\n":"\n"); + fprintf(outfile, "// version 18.2.0%s", (crlf)?"\r\n":"\n"); + fprintf(outfile, "// Measurement UUID: cc9c7b54-68ae-" + "46d2-a43a-6aa87df7dd74%s", (crlf)?"\r\n":"\n"); } for (i = 0, devno = 0; i < maxdev; i++) { @@ -313,14 +433,8 @@ int main(int argc, char **argv) mtu = parse_canframe(afrbuf, &cu); - /* convert only CAN CC and CAN FD frames */ - if ((mtu != CAN_MTU) && (mtu != CANFD_MTU)) { - printf("no valid CAN CC/FD frame\n"); - return 1; - } - - /* we don't support error message frames in CAN FD */ - if ((mtu == CANFD_MTU) && (cu.cc.can_id & CAN_ERR_FLAG)) + /* no error message frames in non CAN CC frames */ + if ((mtu != CAN_MTU) && (cu.cc.can_id & CAN_ERR_FLAG)) continue; tv.tv_sec = tv.tv_sec - start_tv.tv_sec; @@ -335,10 +449,12 @@ int main(int argc, char **argv) else fprintf(outfile, "%4llu.%06llu ", (unsigned long long)tv.tv_sec, (unsigned long long)tv.tv_usec); - if ((mtu == CAN_MTU) && (fdfmt == 0)) - can_asc(&cu.fd, devno, nortrdlc, extra_info, outfile); - else + if ((mtu == CAN_MTU) && (fdfmt == 0) && (xlfmt == 0)) + can_asc(&cu.cc, devno, nortrdlc, extra_info, outfile); + else if ((mtu != CANXL_MTU) && (xlfmt == 0)) canfd_asc(&cu.fd, devno, mtu, extra_info, outfile); + else + canxl_asc(&cu, devno, mtu, extra_info, outfile); if (crlf) fprintf(outfile, "\r"); From 008f9f8e227d116b7bf2be7d8e6082b8a08c5203 Mon Sep 17 00:00:00 2001 From: Oliver Hartkopp Date: Fri, 24 Jan 2025 15:08:46 +0100 Subject: [PATCH 11/11] asc2log: add option to disable direction info The ASC file provides an information whether the CAN frame is sent (Tx) or received (Rx) on the local CAN node. With the new '-d' option the generation of this information is disabled for the log file generation to simplify the comparision of log files. E.g. log1 -> asc -> log2 always created the T/R information in the log2 file which is then hard to compare to the log1 file which might not have the T/R information at all. Signed-off-by: Oliver Hartkopp --- asc2log.c | 104 ++++++++++++++++++++++++++---------------------------- 1 file changed, 50 insertions(+), 54 deletions(-) diff --git a/asc2log.c b/asc2log.c index 31c0a827..3d21f5f5 100644 --- a/asc2log.c +++ b/asc2log.c @@ -59,6 +59,7 @@ #include "lib.h" #define BUFLEN 6500 /* CAN XL mode lines can be pretty long */ +#define NO_DIR '.' /* relevant flags in Flags field */ #define ASC_F_RTR 0x00000010 @@ -78,10 +79,12 @@ static void print_usage(char *prg) fprintf(stderr, "Options:\n"); fprintf(stderr, "\t-I \t(default stdin)\n"); fprintf(stderr, "\t-O \t(default stdout)\n"); + fprintf(stderr, "\t-d (disable direction information R/T)\n"); + fprintf(stderr, "\t-v (verbose)\n"); } static void prframe(FILE *file, struct timeval *tv, int dev, - cu_t *cf, char *extra_info) + cu_t *cf, char dir) { static char abuf[BUFLEN]; @@ -93,7 +96,11 @@ static void prframe(FILE *file, struct timeval *tv, int dev, fprintf(file, "canX "); snprintf_canframe(abuf, sizeof(abuf), cf, 0); - fprintf(file, "%s%s", abuf, extra_info); + + if (dir == NO_DIR) + fprintf(file, "%s\n", abuf); + else + fprintf(file, "%s %c\n", abuf, dir); } static void get_can_id(canid_t *can_id, char *idstring, int base) @@ -140,7 +147,7 @@ static void calc_tv(struct timeval *tv, struct timeval *read_tv, } static void eval_can(char* buf, struct timeval *date_tvp, char timestamps, - char base, int dplace, FILE *outfile) + char base, int dplace, int disable_dir, FILE *outfile) { int interface; static struct timeval tv; /* current frame timestamp */ @@ -153,7 +160,6 @@ static void eval_can(char* buf, struct timeval *date_tvp, char timestamps, int data[8]; char idstr[21]; char dir[5]; /* 'Rx'/'Tx'/'TxRq' plus terminating zero */ - char *extra_info; int i, items; unsigned long long sec, usec; @@ -171,7 +177,7 @@ static void eval_can(char* buf, struct timeval *date_tvp, char timestamps, cf.len = CAN_ERR_DLC; calc_tv(&tv, &read_tv, date_tvp, timestamps, dplace); - prframe(outfile, &tv, interface, (cu_t *)&cf, "\n"); + prframe(outfile, &tv, interface, (cu_t *)&cf, NO_DIR); fflush(outfile); return; } @@ -225,6 +231,9 @@ static void eval_can(char* buf, struct timeval *date_tvp, char timestamps, if (strlen(dir) != 2) /* "Rx" or "Tx" */ return; + if (disable_dir) + dir[0] = NO_DIR; + /* check for signed integer overflow */ if (dplace == 4 && read_tv.tv_usec >= INT_MAX / 100) return; @@ -232,11 +241,6 @@ static void eval_can(char* buf, struct timeval *date_tvp, char timestamps, if (dplace == 5 && read_tv.tv_usec >= INT_MAX / 10) return; - if (dir[0] == 'R') - extra_info = " R\n"; - else - extra_info = " T\n"; - cf.len = len; if (rtr == 'r') cf.can_id |= CAN_RTR_FLAG; @@ -245,13 +249,13 @@ static void eval_can(char* buf, struct timeval *date_tvp, char timestamps, cf.data[i] = data[i] & 0xFFU; calc_tv(&tv, &read_tv, date_tvp, timestamps, dplace); - prframe(outfile, &tv, interface, (cu_t *)&cf, extra_info); + prframe(outfile, &tv, interface, (cu_t *)&cf, dir[0]); fflush(outfile); } } static void eval_canfd(char* buf, struct timeval *date_tvp, char timestamps, - int dplace, FILE *outfile) + int dplace, int disable_dir, FILE *outfile) { int interface; static struct timeval tv; /* current frame timestamp */ @@ -262,7 +266,6 @@ static void eval_canfd(char* buf, struct timeval *date_tvp, char timestamps, int dlc, dlen = 0; char idstr[21]; char dir[5]; /* 'Rx'/'Tx'/'TxRq' plus terminating zero */ - char *extra_info; char *ptr; int i; int n = 0; /* sscanf consumed characters */ @@ -304,6 +307,9 @@ static void eval_canfd(char* buf, struct timeval *date_tvp, char timestamps, if (strlen(dir) != 2) /* "Rx" or "Tx" */ return; + if (disable_dir) + dir[0] = NO_DIR; + /* check for signed integer overflow */ if (dplace == 4 && read_tv.tv_usec >= INT_MAX / 100) return; @@ -312,11 +318,6 @@ static void eval_canfd(char* buf, struct timeval *date_tvp, char timestamps, if (dplace == 5 && read_tv.tv_usec >= INT_MAX / 10) return; - if (dir[0] == 'R') - extra_info = " R\n"; - else - extra_info = " T\n"; - /* don't trust ASCII content - sanitize data length */ if (dlen != can_fd_dlc2len(can_fd_len2dlc(dlen))) return; @@ -373,14 +374,14 @@ static void eval_canfd(char* buf, struct timeval *date_tvp, char timestamps, } calc_tv(&tv, &read_tv, date_tvp, timestamps, dplace); - prframe(outfile, &tv, interface, (cu_t *)&cf, extra_info); + prframe(outfile, &tv, interface, (cu_t *)&cf, dir[0]); fflush(outfile); /* No support for really strange CANFD ErrorFrames format m( */ } static void eval_canxl_cc(char* buf, struct timeval *date_tvp, char timestamps, - int dplace, FILE *outfile) + int dplace, int disable_dir, FILE *outfile) { int interface; static struct timeval tv; /* current frame timestamp */ @@ -391,7 +392,6 @@ static void eval_canxl_cc(char* buf, struct timeval *date_tvp, char timestamps, int dlc, dlen = 0; char idstr[21]; char dir[5]; /* 'Rx'/'Tx'/'TxRq' plus terminating zero */ - char *extra_info; char *ptr; int i; int n = 0; /* sscanf consumed characters */ @@ -435,6 +435,9 @@ static void eval_canxl_cc(char* buf, struct timeval *date_tvp, char timestamps, if (strlen(dir) != 2) /* "Rx" or "Tx" */ return; + if (disable_dir) + dir[0] = NO_DIR; + /* check for signed integer overflow */ if (dplace == 4 && read_tv.tv_usec >= INT_MAX / 100) return; @@ -443,11 +446,6 @@ static void eval_canxl_cc(char* buf, struct timeval *date_tvp, char timestamps, if (dplace == 5 && read_tv.tv_usec >= INT_MAX / 10) return; - if (dir[0] == 'R') - extra_info = " R\n"; - else - extra_info = " T\n"; - get_can_id(&cf.can_id, idstr, 16); ptr = buf + n; /* start of ASCII hex frame data */ @@ -489,12 +487,12 @@ static void eval_canxl_cc(char* buf, struct timeval *date_tvp, char timestamps, cf.len8_dlc = dlc; calc_tv(&tv, &read_tv, date_tvp, timestamps, dplace); - prframe(outfile, &tv, interface, (cu_t *)&cf, extra_info); + prframe(outfile, &tv, interface, (cu_t *)&cf, dir[0]); fflush(outfile); } static void eval_canxl_fd(char* buf, struct timeval *date_tvp, char timestamps, - int dplace, FILE *outfile) + int dplace, int disable_dir, FILE *outfile) { int interface; static struct timeval tv; /* current frame timestamp */ @@ -505,7 +503,6 @@ static void eval_canxl_fd(char* buf, struct timeval *date_tvp, char timestamps, int dlc, dlen = 0; char idstr[21]; char dir[5]; /* 'Rx'/'Tx'/'TxRq' plus terminating zero */ - char *extra_info; char *ptr; int i; int n = 0; /* sscanf consumed characters */ @@ -549,6 +546,9 @@ static void eval_canxl_fd(char* buf, struct timeval *date_tvp, char timestamps, if (strlen(dir) != 2) /* "Rx" or "Tx" */ return; + if (disable_dir) + dir[0] = NO_DIR; + /* check for signed integer overflow */ if (dplace == 4 && read_tv.tv_usec >= INT_MAX / 100) return; @@ -557,11 +557,6 @@ static void eval_canxl_fd(char* buf, struct timeval *date_tvp, char timestamps, if (dplace == 5 && read_tv.tv_usec >= INT_MAX / 10) return; - if (dir[0] == 'R') - extra_info = " R\n"; - else - extra_info = " T\n"; - get_can_id(&cf.can_id, idstr, 16); ptr = buf + n; /* start of ASCII hex frame data */ @@ -599,12 +594,12 @@ static void eval_canxl_fd(char* buf, struct timeval *date_tvp, char timestamps, cf.flags |= CANFD_ESI; calc_tv(&tv, &read_tv, date_tvp, timestamps, dplace); - prframe(outfile, &tv, interface, (cu_t *)&cf, extra_info); + prframe(outfile, &tv, interface, (cu_t *)&cf, dir[0]); fflush(outfile); } static void eval_canxl_xl(char* buf, struct timeval *date_tvp, char timestamps, - int dplace, FILE *outfile) + int dplace, int disable_dir, FILE *outfile) { int interface; static struct timeval tv; /* current frame timestamp */ @@ -615,7 +610,6 @@ static void eval_canxl_xl(char* buf, struct timeval *date_tvp, char timestamps, int dlc, dlen = 0; char idstr[21]; char dir[5]; /* 'Rx'/'Tx'/'TxRq' plus terminating zero */ - char *extra_info; char *ptr; int i; int n = 0; /* sscanf consumed characters */ @@ -668,6 +662,9 @@ static void eval_canxl_xl(char* buf, struct timeval *date_tvp, char timestamps, if (strlen(dir) != 2) /* "Rx" or "Tx" */ return; + if (disable_dir) + dir[0] = NO_DIR; + /* check for signed integer overflow */ if (dplace == 4 && read_tv.tv_usec >= INT_MAX / 100) return; @@ -676,11 +673,6 @@ static void eval_canxl_xl(char* buf, struct timeval *date_tvp, char timestamps, if (dplace == 5 && read_tv.tv_usec >= INT_MAX / 10) return; - if (dir[0] == 'R') - extra_info = " R\n"; - else - extra_info = " T\n"; - /* don't trust ASCII content - sanitize data length */ if (dlen != dlc + 1) return; @@ -731,14 +723,14 @@ static void eval_canxl_xl(char* buf, struct timeval *date_tvp, char timestamps, cf.flags |= CANXL_RRS; calc_tv(&tv, &read_tv, date_tvp, timestamps, dplace); - prframe(outfile, &tv, interface, (cu_t *)&cf, extra_info); + prframe(outfile, &tv, interface, (cu_t *)&cf, dir[0]); fflush(outfile); /* No support for CAN XL ErrorFrames */ } static void eval_canxl(char* buf, struct timeval *date_tvp, char timestamps, - int dplace, FILE *outfile) + int dplace, int disable_dir, FILE *outfile) { int interface; char dir[5]; /* 'Rx'/'Tx'/'TxRq' plus terminating zero */ @@ -773,15 +765,15 @@ static void eval_canxl(char* buf, struct timeval *date_tvp, char timestamps, return; if (!strncmp(frfo, "XLFF", 4)) - eval_canxl_xl(buf, date_tvp, timestamps, dplace, outfile); + eval_canxl_xl(buf, date_tvp, timestamps, dplace, disable_dir, outfile); else if (!strncmp(frfo, "FBFF", 4)) - eval_canxl_fd(buf, date_tvp, timestamps, dplace, outfile); + eval_canxl_fd(buf, date_tvp, timestamps, dplace, disable_dir, outfile); else if (!strncmp(frfo, "FEFF", 4)) - eval_canxl_fd(buf, date_tvp, timestamps, dplace, outfile); + eval_canxl_fd(buf, date_tvp, timestamps, dplace, disable_dir, outfile); else if (!strncmp(frfo, "CBFF", 4)) - eval_canxl_cc(buf, date_tvp, timestamps, dplace, outfile); + eval_canxl_cc(buf, date_tvp, timestamps, dplace, disable_dir, outfile); else if (!strncmp(frfo, "CEFF", 4)) - eval_canxl_cc(buf, date_tvp, timestamps, dplace, outfile); + eval_canxl_cc(buf, date_tvp, timestamps, dplace, disable_dir, outfile); } static int get_date(struct timeval *tv, char *date) @@ -847,7 +839,7 @@ int main(int argc, char **argv) FILE *infile = stdin; FILE *outfile = stdout; - static int verbose; + static int verbose, disable_dir; static struct timeval date_tv; /* date of the ASC file */ static int dplace; /* decimal place 4, 5 or 6 or uninitialized */ static char base; /* 'd'ec or 'h'ex */ @@ -855,7 +847,7 @@ int main(int argc, char **argv) int opt; unsigned long long sec, usec; - while ((opt = getopt(argc, argv, "I:O:v?")) != -1) { + while ((opt = getopt(argc, argv, "I:O:dv?")) != -1) { switch (opt) { case 'I': infile = fopen(optarg, "r"); @@ -873,6 +865,10 @@ int main(int argc, char **argv) } break; + case 'd': + disable_dir = 1; + break; + case 'v': verbose = 1; break; @@ -954,11 +950,11 @@ int main(int argc, char **argv) /* check classic CAN format or the CANFD/CANXL tag which can take different types */ if (sscanf(buf, "%llu.%llu %9s ", &sec, &usec, tmp1) == 3) { if (!strncmp(tmp1, "CANXL", 5)) - eval_canxl(buf, &date_tv, timestamps, dplace, outfile); + eval_canxl(buf, &date_tv, timestamps, dplace, disable_dir, outfile); else if (!strncmp(tmp1, "CANFD", 5)) - eval_canfd(buf, &date_tv, timestamps, dplace, outfile); + eval_canfd(buf, &date_tv, timestamps, dplace, disable_dir, outfile); else - eval_can(buf, &date_tv, timestamps, base, dplace, outfile); + eval_can(buf, &date_tv, timestamps, base, dplace, disable_dir, outfile); } } fclose(outfile);