Skip to content

Commit eb66451

Browse files
Richard Younghartkopp
authored andcommitted
candump: Enable zero relative timestamps to be used in log files
The logfile format which is generated with '-l' and '-L' consists of an absolute epoch timestamp. In some use cases (e.g. for documentation) a zero relative timestamp can be useful which was only configurable with the '-tz' option for the classic output. '-tz' and '-ta' are now valid options for the logfile format. Signed-off-by: Richard Young <[email protected]> Signed-off-by: Oliver Hartkopp <[email protected]>
1 parent 682e01a commit eb66451

File tree

1 file changed

+70
-49
lines changed

1 file changed

+70
-49
lines changed

candump.c

Lines changed: 70 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,7 @@
7676
#define SOF_TIMESTAMPING_SOFTWARE (1 << 4)
7777
#define SOF_TIMESTAMPING_RX_SOFTWARE (1 << 3)
7878
#define SOF_TIMESTAMPING_RAW_HARDWARE (1 << 6)
79+
#define TIMESTAMPSZ 50 /* string 'absolute with date' requires max 49 bytes */
7980

8081
#define MAXSOCK 16 /* max. number of CAN interfaces given on the cmdline */
8182
#define MAXIFNAMES 30 /* size of receive name index to omit ioctls */
@@ -221,6 +222,60 @@ static int idx2dindex(int ifidx, int socket)
221222
return i;
222223
}
223224

225+
static inline void sprint_timestamp(const char timestamp, const struct timeval *tv,
226+
struct timeval *const last_tv, char *ts_buffer)
227+
{
228+
switch (timestamp) {
229+
230+
case 'a': /* absolute with timestamp */
231+
sprintf(ts_buffer, "(%010lu.%06lu) ", tv->tv_sec, tv->tv_usec);
232+
break;
233+
234+
case 'A': /* absolute with date */
235+
{
236+
struct tm tm;
237+
char timestring[25];
238+
239+
tm = *localtime(&tv->tv_sec);
240+
strftime(timestring, 24, "%Y-%m-%d %H:%M:%S", &tm);
241+
sprintf(ts_buffer, "(%s.%06lu) ", timestring, tv->tv_usec);
242+
}
243+
break;
244+
245+
case 'd': /* delta */
246+
case 'z': /* starting with zero */
247+
{
248+
struct timeval diff;
249+
250+
if (last_tv->tv_sec == 0) /* first init */
251+
*last_tv = *tv;
252+
diff.tv_sec = tv->tv_sec - last_tv->tv_sec;
253+
diff.tv_usec = tv->tv_usec - last_tv->tv_usec;
254+
if (diff.tv_usec < 0)
255+
diff.tv_sec--, diff.tv_usec += 1000000;
256+
if (diff.tv_sec < 0)
257+
diff.tv_sec = diff.tv_usec = 0;
258+
sprintf(ts_buffer, "(%03lu.%06lu) ", diff.tv_sec, diff.tv_usec);
259+
260+
if (timestamp == 'd')
261+
*last_tv = *tv; /* update for delta calculation */
262+
}
263+
break;
264+
265+
default: /* no timestamp output */
266+
break;
267+
}
268+
}
269+
270+
static inline void print_timestamp(const char timestamp, const struct timeval *tv,
271+
struct timeval *const last_tv)
272+
{
273+
static char buffer[TIMESTAMPSZ];
274+
275+
sprint_timestamp(timestamp, tv, last_tv, buffer);
276+
printf("%s", buffer);
277+
}
278+
224279
int main(int argc, char **argv)
225280
{
226281
int fd_epoll;
@@ -229,6 +284,7 @@ int main(int argc, char **argv)
229284
.events = EPOLLIN, /* prepare the common part */
230285
};
231286
unsigned char timestamp = 0;
287+
unsigned char logtimestamp = 'a';
232288
unsigned char hwtimestamp = 0;
233289
unsigned char down_causes_exit = 1;
234290
unsigned char dropmonitor = 0;
@@ -270,12 +326,16 @@ int main(int argc, char **argv)
270326
switch (opt) {
271327
case 't':
272328
timestamp = optarg[0];
329+
logtimestamp = optarg[0];
273330
if ((timestamp != 'a') && (timestamp != 'A') &&
274331
(timestamp != 'd') && (timestamp != 'z')) {
275332
fprintf(stderr, "%s: unknown timestamp mode '%c' - ignored\n",
276333
basename(argv[0]), optarg[0]);
277334
timestamp = 0;
278335
}
336+
if ((logtimestamp != 'a') && (logtimestamp != 'z')) {
337+
logtimestamp = 'a';
338+
}
279339
break;
280340

281341
case 'H':
@@ -314,7 +374,6 @@ int main(int argc, char **argv)
314374
}
315375
break;
316376

317-
318377
case 'l':
319378
log = 1;
320379
break;
@@ -724,11 +783,13 @@ int main(int argc, char **argv)
724783

725784
if (log) {
726785
char buf[CL_CFSZ]; /* max length */
786+
char ts_buf[TIMESTAMPSZ];
787+
788+
sprint_timestamp(logtimestamp, &tv, &last_tv, ts_buf);
727789

728790
/* log CAN frame with absolute timestamp & device */
729791
sprint_canframe(buf, &frame, 0, maxdlen);
730-
fprintf(logfile, "(%010lu.%06lu) %*s %s%s\n",
731-
tv.tv_sec, tv.tv_usec,
792+
fprintf(logfile, "%s%*s %s%s\n", ts_buf,
732793
max_devname_len, devname[idx], buf,
733794
extra_info);
734795
}
@@ -738,10 +799,11 @@ int main(int argc, char **argv)
738799

739800
/* print CAN frame in log file style to stdout */
740801
sprint_canframe(buf, &frame, 0, maxdlen);
741-
printf("(%010lu.%06lu) %*s %s%s\n",
742-
tv.tv_sec, tv.tv_usec,
743-
max_devname_len, devname[idx], buf,
744-
extra_info);
802+
print_timestamp(logtimestamp, &tv, &last_tv);
803+
804+
printf("%*s %s%s\n",
805+
max_devname_len, devname[idx], buf,
806+
extra_info);
745807
goto out_fflush; /* no other output to stdout */
746808
}
747809

@@ -754,48 +816,7 @@ int main(int argc, char **argv)
754816
}
755817

756818
printf(" %s", (color > 2) ? col_on[idx % MAXCOL] : "");
757-
758-
switch (timestamp) {
759-
760-
case 'a': /* absolute with timestamp */
761-
printf("(%010lu.%06lu) ", tv.tv_sec, tv.tv_usec);
762-
break;
763-
764-
case 'A': /* absolute with date */
765-
{
766-
struct tm tm;
767-
char timestring[25];
768-
769-
tm = *localtime(&tv.tv_sec);
770-
strftime(timestring, 24, "%Y-%m-%d %H:%M:%S", &tm);
771-
printf("(%s.%06lu) ", timestring, tv.tv_usec);
772-
}
773-
break;
774-
775-
case 'd': /* delta */
776-
case 'z': /* starting with zero */
777-
{
778-
struct timeval diff;
779-
780-
if (last_tv.tv_sec == 0) /* first init */
781-
last_tv = tv;
782-
diff.tv_sec = tv.tv_sec - last_tv.tv_sec;
783-
diff.tv_usec = tv.tv_usec - last_tv.tv_usec;
784-
if (diff.tv_usec < 0)
785-
diff.tv_sec--, diff.tv_usec += 1000000;
786-
if (diff.tv_sec < 0)
787-
diff.tv_sec = diff.tv_usec = 0;
788-
printf("(%03lu.%06lu) ", diff.tv_sec, diff.tv_usec);
789-
790-
if (timestamp == 'd')
791-
last_tv = tv; /* update for delta calculation */
792-
}
793-
break;
794-
795-
default: /* no timestamp output */
796-
break;
797-
}
798-
819+
print_timestamp(timestamp, &tv, &last_tv);
799820
printf(" %s", (color && (color < 3)) ? col_on[idx % MAXCOL] : "");
800821
printf("%*s", max_devname_len, devname[idx]);
801822

0 commit comments

Comments
 (0)