Skip to content

Commit

Permalink
logfile: add new extra info field
Browse files Browse the repository at this point in the history
This patch adds a fourth string field in the can logfile format.
This new field contains the rx/tx direction information R/T as the
first entry (only one character separated from the CAN frame by space).

To generate the logfile format with this extra field candump has to be
called with the '-x' option for extra message infos,
e.g. 'candump -x -l can0' or 'candump -x -L can0'

log2asc and asc2log are extended to support the direction information
but still support the previous format without direction information.

The format extension does not affect legacy tools, e.g. the existing
canplayer ignores this extra information and does not need to be changed.

Therefore the existing logfiles remain valid and usable.

The extra message infos will be colon separated when there's need for
additional content beyond the rx/tx direction information, e.g. R:xx:yyy

Suggested-by: Pallavi Revanna https://github.com/brpallu
Signed-off-by: Oliver Hartkopp <[email protected]>
  • Loading branch information
hartkopp committed Aug 18, 2020
1 parent a4905ed commit 7cb3e76
Show file tree
Hide file tree
Showing 3 changed files with 89 additions and 35 deletions.
60 changes: 40 additions & 20 deletions asc2log.c
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@ void print_usage(char *prg)
fprintf(stderr, "\t-O <outfile>\t(default stdout)\n");
}

void prframe(FILE *file, struct timeval *tv, int dev, struct canfd_frame *cf, unsigned int max_dlen) {
void prframe(FILE *file, struct timeval *tv, int dev, struct canfd_frame *cf, unsigned int max_dlen, char *extra_info) {

fprintf(file, "(%lu.%06lu) ", tv->tv_sec, tv->tv_usec);

Expand All @@ -79,7 +79,7 @@ void prframe(FILE *file, struct timeval *tv, int dev, struct canfd_frame *cf, un
else
fprintf(file, "canX ");

fprint_canframe(file, cf, "\n", 0, max_dlen);
fprint_canframe(file, cf, extra_info, 0, max_dlen);
}

void get_can_id(struct canfd_frame *cf, char *idstring, int base) {
Expand Down Expand Up @@ -135,6 +135,8 @@ void eval_can(char* buf, struct timeval *date_tvp, char timestamps, char base, i
int dlc = 0;
int data[8];
char tmp1[BUFLEN];
char dir[3]; /* 'Rx' or 'Tx' plus terminating zero */
char *extra_info;
int i, items, found;

/* 0.002367 1 390x Rx d 8 17 00 14 00 C0 00 08 00 */
Expand All @@ -143,30 +145,30 @@ void eval_can(char* buf, struct timeval *date_tvp, char timestamps, char base, i

if (base == 'h') { /* check for CAN frames with hexadecimal values */

items = sscanf(buf, "%lu.%lu %d %s %*s %c %d %x %x %x %x %x %x %x %x",
items = sscanf(buf, "%lu.%lu %d %s %2s %c %d %x %x %x %x %x %x %x %x",
&read_tv.tv_sec, &read_tv.tv_usec, &interface,
tmp1, &rtr, &dlc,
tmp1, dir, &rtr, &dlc,
&data[0], &data[1], &data[2], &data[3],
&data[4], &data[5], &data[6], &data[7]);

if ((items == dlc + 6 ) || /* data frame */
((items == 5) && (rtr == 'r')) || /* RTR without DLC */
((items == 6) && (rtr == 'r'))) { /* RTR with DLC */
if ((items == dlc + 7 ) || /* data frame */
((items == 6) && (rtr == 'r')) || /* RTR without DLC */
((items == 7) && (rtr == 'r'))) { /* RTR with DLC */
found = 1;
get_can_id(&cf, tmp1, 16);
}

} else { /* check for CAN frames with decimal values */

items = sscanf(buf, "%lu.%lu %d %s %*s %c %d %d %d %d %d %d %d %d %d",
items = sscanf(buf, "%lu.%lu %d %s %2s %c %d %d %d %d %d %d %d %d %d",
&read_tv.tv_sec, &read_tv.tv_usec, &interface,
tmp1, &rtr, &dlc,
tmp1, dir, &rtr, &dlc,
&data[0], &data[1], &data[2], &data[3],
&data[4], &data[5], &data[6], &data[7]);

if ((items == dlc + 6 ) || /* data frame */
((items == 5) && (rtr == 'r')) || /* RTR without DLC */
((items == 6) && (rtr == 'r'))) { /* RTR with DLC */
if ((items == dlc + 7 ) || /* data frame */
((items == 6) && (rtr == 'r')) || /* RTR without DLC */
((items == 7) && (rtr == 'r'))) { /* RTR with DLC */
found = 1;
get_can_id(&cf, tmp1, 10);
}
Expand All @@ -177,6 +179,14 @@ void eval_can(char* buf, struct timeval *date_tvp, char timestamps, char base, i
if (dlc > CAN_MAX_DLC)
return;

if (strlen(dir) != 2) /* "Rx" or "Tx" */
return;

if (dir[0] == 'R')
extra_info = " R\n";
else
extra_info = " T\n";

cf.len = dlc;
if (rtr == 'r')
cf.can_id |= CAN_RTR_FLAG;
Expand All @@ -185,7 +195,7 @@ void eval_can(char* buf, struct timeval *date_tvp, char timestamps, char base, i
cf.data[i] = data[i] & 0xFFU;

calc_tv(&tv, &read_tv, date_tvp, timestamps, dplace);
prframe(outfile, &tv, interface, &cf, CAN_MAX_DLEN);
prframe(outfile, &tv, interface, &cf, CAN_MAX_DLEN, extra_info);
fflush(outfile);
return;
}
Expand All @@ -203,7 +213,7 @@ void eval_can(char* buf, struct timeval *date_tvp, char timestamps, char base, i
cf.len = CAN_ERR_DLC;

calc_tv(&tv, &read_tv, date_tvp, timestamps, dplace);
prframe(outfile, &tv, interface, &cf, CAN_MAX_DLEN);
prframe(outfile, &tv, interface, &cf, CAN_MAX_DLEN, "\n");
fflush(outfile);
}
}
Expand All @@ -219,6 +229,8 @@ void eval_canfd(char* buf, struct timeval *date_tvp, char timestamps, int dplace
unsigned int flags;
int dlc, dlen = 0;
char tmp1[BUFLEN];
char dir[3]; /* 'Rx' or 'Tx' plus terminating zero */
char *extra_info;
char *ptr;
int i;

Expand All @@ -232,14 +244,14 @@ void eval_canfd(char* buf, struct timeval *date_tvp, char timestamps, int dplace
memset(&cf, 0, sizeof(cf));

/* check for valid line without symbolic name */
if (sscanf(buf, "%lu.%lu %*s %d %*s %s %hhx %hhx %x %d ",
if (sscanf(buf, "%lu.%lu %*s %d %2s %s %hhx %hhx %x %d ",
&read_tv.tv_sec, &read_tv.tv_usec, &interface,
tmp1, &brs, &esi, &dlc, &dlen) != 8) {
dir, tmp1, &brs, &esi, &dlc, &dlen) != 9) {

/* check for valid line with a symbolic name */
if (sscanf(buf, "%lu.%lu %*s %d %*s %s %*s %hhx %hhx %x %d ",
&read_tv.tv_sec, &read_tv.tv_usec, &interface,
tmp1, &brs, &esi, &dlc, &dlen) != 8) {
if (sscanf(buf, "%lu.%lu %*s %d %2s %s %*s %hhx %hhx %x %d ",
&read_tv.tv_sec, &read_tv.tv_usec, &interface,
dir, tmp1, &brs, &esi, &dlc, &dlen) != 9) {

/* no valid CANFD format pattern */
return;
Expand All @@ -251,6 +263,14 @@ void eval_canfd(char* buf, struct timeval *date_tvp, char timestamps, int dplace
(brs > 1) || (esi > 1))
return;

if (strlen(dir) != 2) /* "Rx" or "Tx" */
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_dlc2len(can_len2dlc(dlen)))
return;
Expand Down Expand Up @@ -313,7 +333,7 @@ void eval_canfd(char* buf, struct timeval *date_tvp, char timestamps, int dplace
}

calc_tv(&tv, &read_tv, date_tvp, timestamps, dplace);
prframe(outfile, &tv, interface, &cf, dlen);
prframe(outfile, &tv, interface, &cf, dlen, extra_info);
fflush(outfile);
return;

Expand Down
18 changes: 14 additions & 4 deletions candump.c
Original file line number Diff line number Diff line change
Expand Up @@ -628,6 +628,7 @@ int main(int argc, char **argv)
if (FD_ISSET(s[i], &rdfs)) {

int idx;
char *extra_info = "";

/* these settings may be modified by recvmsg() */
iov.iov_len = sizeof(frame);
Expand Down Expand Up @@ -701,24 +702,33 @@ int main(int argc, char **argv)
if (frame.can_id & CAN_EFF_FLAG)
view |= CANLIB_VIEW_INDENT_SFF;

if (extra_msg_info) {
if (msg.msg_flags & MSG_DONTROUTE)
extra_info = " T";
else
extra_info = " R";
}

if (log) {
char buf[CL_CFSZ]; /* max length */

/* log CAN frame with absolute timestamp & device */
sprint_canframe(buf, &frame, 0, maxdlen);
fprintf(logfile, "(%010lu.%06lu) %*s %s\n",
fprintf(logfile, "(%010lu.%06lu) %*s %s%s\n",
tv.tv_sec, tv.tv_usec,
max_devname_len, devname[idx], buf);
max_devname_len, devname[idx], buf,
extra_info);
}

if ((logfrmt) && (silent == SILENT_OFF)){
char buf[CL_CFSZ]; /* max length */

/* print CAN frame in log file style to stdout */
sprint_canframe(buf, &frame, 0, maxdlen);
printf("(%010lu.%06lu) %*s %s\n",
printf("(%010lu.%06lu) %*s %s%s\n",
tv.tv_sec, tv.tv_usec,
max_devname_len, devname[idx], buf);
max_devname_len, devname[idx], buf,
extra_info);
goto out_fflush; /* no other output to stdout */
}

Expand Down
46 changes: 35 additions & 11 deletions log2asc.c
Original file line number Diff line number Diff line change
Expand Up @@ -71,10 +71,11 @@ void print_usage(char *prg)
fprintf(stderr, " -r (supress dlc for RTR frames - pre v8.5 tools)\n");
}

void can_asc(struct canfd_frame *cf, int devno, int nortrdlc, FILE *outfile)
void can_asc(struct canfd_frame *cf, int devno, int nortrdlc, char *extra_info, FILE *outfile)
{
int i;
char id[10];
char *dir = "Rx";

fprintf(outfile, "%-2d ", devno); /* channel number left aligned */

Expand All @@ -83,7 +84,15 @@ void can_asc(struct canfd_frame *cf, int devno, int nortrdlc, FILE *outfile)
else {
sprintf(id, "%X%c", cf->can_id & CAN_EFF_MASK,
(cf->can_id & CAN_EFF_FLAG)?'x':' ');
fprintf(outfile, "%-15s Rx ", id);

/* check for extra info */
if (strlen(extra_info) > 0) {
/* only the first char is defined so far */
if (extra_info[0] == 'T')
dir = "Tx";
}

fprintf(outfile, "%-15s %s ", id, dir);

if (cf->can_id & CAN_RTR_FLAG) {
if (nortrdlc)
Expand All @@ -100,10 +109,11 @@ void can_asc(struct canfd_frame *cf, int devno, int nortrdlc, FILE *outfile)
}
}

void canfd_asc(struct canfd_frame *cf, int devno, int mtu, FILE *outfile)
void canfd_asc(struct canfd_frame *cf, int devno, int mtu, char *extra_info, FILE *outfile)
{
int i;
char id[10];
char *dir = "Rx";
unsigned int flags = 0;
unsigned int dlen = cf->len;

Expand All @@ -113,7 +123,14 @@ void canfd_asc(struct canfd_frame *cf, int devno, int mtu, FILE *outfile)
#define ASC_F_BRS 0x00002000
#define ASC_F_ESI 0x00004000

fprintf(outfile, "CANFD %3d Rx ", devno); /* 3 column channel number right aligned */
/* check for extra info */
if (strlen(extra_info) > 0) {
/* only the first char is defined so far */
if (extra_info[0] == 'T')
dir = "Tx";
}

fprintf(outfile, "CANFD %3d %s ", 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':' ');
Expand Down Expand Up @@ -147,7 +164,7 @@ void canfd_asc(struct canfd_frame *cf, int devno, int mtu, FILE *outfile)

int main(int argc, char **argv)
{
static char buf[BUFSZ], device[BUFSZ], ascframe[BUFSZ];
static char buf[BUFSZ], device[BUFSZ], ascframe[BUFSZ], extra_info[BUFSZ];

struct canfd_frame cf;
static struct timeval tv, start_tv;
Expand Down Expand Up @@ -223,10 +240,17 @@ int main(int argc, char **argv)
if (buf[0] != '(')
continue;

if (sscanf(buf, "(%lu.%lu) %s %s", &tv.tv_sec, &tv.tv_usec,
device, ascframe) != 4) {
fprintf(stderr, "incorrect line format in logfile\n");
return 1;
if (sscanf(buf, "(%lu.%lu) %s %s %s", &tv.tv_sec, &tv.tv_usec,
device, ascframe, extra_info) != 5) {

/* do not evaluate the extra info */
extra_info[0] = 0;

if (sscanf(buf, "(%lu.%lu) %s %s", &tv.tv_sec, &tv.tv_usec,
device, ascframe) != 4) {
fprintf(stderr, "incorrect line format in logfile\n");
return 1;
}
}

if (!start_tv.tv_sec) { /* print banner */
Expand Down Expand Up @@ -267,9 +291,9 @@ int main(int argc, char **argv)
fprintf(outfile, "%4lu.%06lu ", tv.tv_sec, tv.tv_usec);

if ((mtu == CAN_MTU) && (fdfmt == 0))
can_asc(&cf, devno, nortrdlc, outfile);
can_asc(&cf, devno, nortrdlc, extra_info, outfile);
else
canfd_asc(&cf, devno, mtu, outfile);
canfd_asc(&cf, devno, mtu, extra_info, outfile);

if (crlf)
fprintf(outfile, "\r");
Expand Down

0 comments on commit 7cb3e76

Please sign in to comment.