unsigned overrun;
unsigned lost;
struct timespec tic, tac;
+ unsigned timeouts;
+ unsigned invalid_frame;
} stats;
int num_interfaces = 0;
}
}
-static inline struct msg_info *frame2info(struct can_frame *frame)
+static inline uint16_t frame_index(struct can_frame *frame)
{
uint16_t idx;
if (frame->can_dlc >= 2) {
error(1, 0, "%s error", __FUNCTION__);
}
- return &msg_infos[idx];
+ return idx;
+}
+
+static inline struct msg_info *frame2info(struct can_frame *frame)
+{
+ return &msg_infos[frame_index(frame)];
}
static inline char *tstamp_str(const void *ctx, struct timespec *tstamp)
talloc_free (local);
}
-int msg_info_store(FILE *f, struct msg_info *mi)
-{
- struct timespec diff;
- void *local = talloc_new (NULL);
- static long num = 0;
-
-#define S(ts) tstamp_str(local, &ts)
-#define DIFF(a, b) (timespec_subtract(&diff, &b, &a), S(diff))
-
- switch (num_interfaces) {
- case 2:
- fprintf(f, "%ld %d %d %s\n",
- num, mi->id, mi->length,
- DIFF(mi->ts_sent, mi->ts_rx_final_kern));
- break;
- case 3:
- fprintf(f, "%ld %d %d %s\n",
- num, mi->id, mi->length,
- DIFF(mi->ts_rx_onwire_kern, mi->ts_rx_final_kern));
- break;
- }
-#undef S
-#undef DIFF
- talloc_free (local);
-}
-
-
/* Subtract the `struct timespec' values X and Y, storing the result in
RESULT. Return 1 if the difference is negative, otherwise 0. */
{
struct timespec diff;
switch (num_interfaces) {
- case 2:
+ case 3:
if (opt.userhist)
timespec_subtract(&diff, &mi->ts_rx_final, &mi->ts_rx_onwire);
else
timespec_subtract(&diff, &mi->ts_rx_final_kern, &mi->ts_rx_onwire_kern);
break;
- case 3:
+ case 2:
if (opt.userhist)
timespec_subtract(&diff, &mi->ts_rx_final, &mi->ts_sent);
else
write(trace_fd, "0", 1);
}
-void msg_info_free(struct msg_info *mi)
+static inline void msg_info_free(struct msg_info *mi)
{
mi->id = -1;
}
+static inline bool msg_info_used(struct msg_info *mi)
+{
+ return mi->id != -1;
+}
+
int send_frame(int socket)
{
struct can_frame frame;
MEMSET_ZERO(frame);
i = curr_msg+1;
- while (msg_infos[i].id != -1 && i != curr_msg) {
+ while (msg_info_used(&msg_infos[i]) && i != curr_msg) {
i++;
if (i >= MAX_INFOS)
i = 0;
struct msg_info *mi;
receive(s, &frame, &ts_kern, &ts_user);
mi = frame2info(&frame);
- mi->ts_rx_onwire_kern = ts_kern;
- mi->ts_rx_onwire = ts_user;
+ if (msg_info_used(mi)) {
+ mi->ts_rx_onwire_kern = ts_kern;
+ mi->ts_rx_onwire = ts_user;
+ } else
+ stats.invalid_frame++;
}
struct timespec timeout;
struct sockaddr_can addr;
sigset_t set;
+ int consecutive_timeouts = 0;
MEMSET_ZERO(pfd);
SEND();
}
} else {
- error(1, 0, "poll timeout");
+ /* Lost message - send a new one */
+ stats.timeouts++;
+ consecutive_timeouts++;
+ if (consecutive_timeouts < 10)
+ SEND();
+ else /* Something is really broken */
+ finish_flag = 1;
}
break;
default: // Event
}
pfd[0].revents = 0;
- if (num_interfaces == 3 && pfd[1].revents != 0) {
+ if (num_interfaces == 3 && pfd[1].revents & POLLIN) {
process_on_wire_rx(pfd[1].fd);
pfd[1].revents = 0;
}
+ if (num_interfaces == 3 && pfd[1].revents & ~POLLIN)
+ error(1, 0, "Unexpected pfd[1].revents: 0x%04x\n", pfd[1].revents);
i = (num_interfaces == 2) ? 1 : 2;
- if (pfd[i].revents != 0) {
+ if (pfd[i].revents & POLLIN) {
+ consecutive_timeouts = 0;
process_final_rx(pfd[i].fd);
msg_in_progress--;
pfd[i].revents = 0;
SEND();
}
}
+ if (pfd[i].revents & ~POLLIN)
+ error(1, 0, "Unexpected pfd[%d].revents: 0x%04x\n", pfd[i].revents);
}
}
fprintf(opt.f_stat, "lost=%d\n", stats.lost);
if (stats.lost && !opt.quiet)
printf("lost=%d\n", stats.lost);
+ fprintf(opt.f_stat, "timeouts=%d\n", stats.timeouts);
+ if (stats.timeouts && !opt.quiet)
+ printf("timeouts=%d\n", stats.timeouts);
+ fprintf(opt.f_stat, "invalid_frame=%d\n", stats.timeouts);
+ if (stats.timeouts && !opt.quiet)
+ printf("invalid_frame=%d\n", stats.timeouts);
fclose(opt.f_stat);