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
parent
e5de3cbeeb
commit
592c916948
54
canplayer.c
54
canplayer.c
|
|
@ -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))
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue