Updated the canplayer to accept logfile timestamps in the future (which

is very nice when you don't have a RTC and your systemtime is somewhere 
in the 1970's :)
Added a new commandline option to skip timestamp jumps greater than x 
seconds to allow to concatenate different logfiles that replay 
constantly and not waiting for the absolute timestamp offsets.
pull/7/head
Oliver Hartkopp 2007-09-07 11:15:22 +00:00
parent e5de3cbeeb
commit 592c916948
1 changed files with 38 additions and 16 deletions

View File

@ -87,6 +87,8 @@ void print_usage(char *prg)
"send frames immediately)\n"); "send frames immediately)\n");
fprintf(stderr, " -g <ms> (gap in milli " fprintf(stderr, " -g <ms> (gap in milli "
"seconds - default: %d ms)\n", DEFAULT_GAP); "seconds - default: %d ms)\n", DEFAULT_GAP);
fprintf(stderr, " -s <s> (skip gaps in "
"timestamps > 's' seconds)\n");
fprintf(stderr, " -x (disable local " fprintf(stderr, " -x (disable local "
"loopback of sent CAN frames)\n"); "loopback of sent CAN frames)\n");
fprintf(stderr, " -v (verbose: print " fprintf(stderr, " -v (verbose: print "
@ -113,6 +115,14 @@ static inline int timeval_compare(struct timeval *lhs, struct timeval *rhs)
return lhs->tv_usec - rhs->tv_usec; return lhs->tv_usec - rhs->tv_usec;
} }
static inline void create_diff_tv(struct timeval *today, struct timeval *diff,
struct timeval *log) {
/* create diff_tv so that log_tv + diff_tv = today_tv */
diff->tv_sec = today->tv_sec - log->tv_sec;
diff->tv_usec = today->tv_usec - log->tv_usec;
}
static inline int frames_to_send(struct timeval *today, struct timeval *diff, static inline int frames_to_send(struct timeval *today, struct timeval *diff,
struct timeval *log) struct timeval *log)
{ {
@ -128,6 +138,11 @@ static inline int frames_to_send(struct timeval *today, struct timeval *diff,
cmp.tv_sec++; cmp.tv_sec++;
} }
if (cmp.tv_usec < 0) {
cmp.tv_usec += 1000000;
cmp.tv_sec--;
}
return timeval_compare(&cmp, today); return timeval_compare(&cmp, today);
} }
@ -214,13 +229,13 @@ int main(int argc, char **argv)
static char buf[BUFSZ], device[BUFSZ], ascframe[BUFSZ]; static char buf[BUFSZ], device[BUFSZ], ascframe[BUFSZ];
struct sockaddr_can addr; struct sockaddr_can addr;
static struct can_frame frame; static struct can_frame frame;
static struct timeval today_tv, log_tv, diff_tv; static struct timeval today_tv, log_tv, last_log_tv, diff_tv;
struct timespec sleep_ts; struct timespec sleep_ts;
int s; /* CAN_RAW socket */ int s; /* CAN_RAW socket */
FILE *infile = stdin; FILE *infile = stdin;
unsigned long gap = DEFAULT_GAP; unsigned long gap = DEFAULT_GAP;
int use_timestamps = 1; int use_timestamps = 1;
static int verbose, opt, delay_loops; static int verbose, opt, delay_loops, skipgap;
static int loopback_disable = 0; static int loopback_disable = 0;
static int infinite_loops = 0; static int infinite_loops = 0;
static int loops = DEFAULT_LOOPS; static int loops = DEFAULT_LOOPS;
@ -228,7 +243,7 @@ int main(int argc, char **argv)
int txidx; /* sendto() interface index */ int txidx; /* sendto() interface index */
int eof, nbytes, i, j; int eof, nbytes, i, j;
while ((opt = getopt(argc, argv, "I:l:tg:xv")) != -1) { while ((opt = getopt(argc, argv, "I:l:tg:s:xv")) != -1) {
switch (opt) { switch (opt) {
case 'I': case 'I':
infile = fopen(optarg, "r"); infile = fopen(optarg, "r");
@ -256,6 +271,14 @@ int main(int argc, char **argv)
gap = strtoul(optarg, NULL, 10); gap = strtoul(optarg, NULL, 10);
break; break;
case 's':
skipgap = strtoul(optarg, NULL, 10);
if (skipgap < 1) {
fprintf(stderr, "Invalid argument for option -s !\n");
return 1;
}
break;
case 'x': case 'x':
loopback_disable = 1; loopback_disable = 1;
break; break;
@ -355,18 +378,8 @@ int main(int argc, char **argv)
if (use_timestamps) { /* throttle sending due to logfile timestamps */ if (use_timestamps) { /* throttle sending due to logfile timestamps */
gettimeofday(&today_tv, NULL); gettimeofday(&today_tv, NULL);
create_diff_tv(&today_tv, &diff_tv, &log_tv);
/* omit crazy comparations with negative diff_tv */ last_log_tv = log_tv;
if (timeval_compare(&today_tv, &log_tv) < 1) {
fprintf(stderr, "logfile timestamps newer than time of day!\n");
return 1;
}
/* create diff_tv so that log_tv + diff_tv = today_tv */
diff_tv.tv_sec = today_tv.tv_sec - log_tv.tv_sec;
diff_tv.tv_usec = today_tv.tv_usec - log_tv.tv_usec;
if (diff_tv.tv_usec < 0)
diff_tv.tv_sec--, diff_tv.tv_usec += 1000000;
} }
while (!eof) { while (!eof) {
@ -425,9 +438,18 @@ int main(int argc, char **argv)
device, ascframe) != 4) device, ascframe) != 4)
return 1; return 1;
if (use_timestamps) /* save a syscall if possible */ if (use_timestamps) {
gettimeofday(&today_tv, NULL); gettimeofday(&today_tv, NULL);
/* test for logfile timestamps jumping backwards OR */
/* if the user likes to skip long gaps in the timestamps */
if ((last_log_tv.tv_sec > log_tv.tv_sec) ||
(skipgap && abs(last_log_tv.tv_sec - log_tv.tv_sec) > skipgap))
create_diff_tv(&today_tv, &diff_tv, &log_tv);
last_log_tv = log_tv;
}
} /* while frames_to_send ... */ } /* while frames_to_send ... */
if (nanosleep(&sleep_ts, NULL)) if (nanosleep(&sleep_ts, NULL))