Review at  https://gerrit.osmocom.org/6949

test: osmo-pcap-test: Fix clock drift while replaying pcap file

In the previous implementation, the processing time was not being taken
into account, which was implicitly added for each new packet to be sent,
which caused a steady incremental drift in the clock clearly visible
when analysing a RTP stream.

As it uses timespecsub, it depends on libosmocore Change-Id
I45fc993b9bb0a343763238bf463c8640f47b00f1.

Change-Id: I11cb9a63e16e829ccd4af1096b9f473c802d822f
---
M tests/osmo-pcap-test/osmo_pcap.h
M tests/osmo-pcap-test/pcap.c
2 files changed, 26 insertions(+), 7 deletions(-)


  git pull ssh://gerrit.osmocom.org:29418/libosmo-netif refs/changes/49/6949/1

diff --git a/tests/osmo-pcap-test/osmo_pcap.h b/tests/osmo-pcap-test/osmo_pcap.h
index 171360d..d10a7f7 100644
--- a/tests/osmo-pcap-test/osmo_pcap.h
+++ b/tests/osmo-pcap-test/osmo_pcap.h
@@ -3,6 +3,7 @@
 
 #include <pcap.h>
 #include <osmocom/core/timer.h>
+#include <time.h>
 
 struct msgb;
 
@@ -11,7 +12,8 @@
 struct osmo_pcap {
        pcap_t                  *h;
        struct osmo_timer_list  timer;
-       struct timeval          last;
+       struct timespec         start_sys;
+       struct timeval          start_pcap;
        struct msgb             *deliver_msg;
 };
 
diff --git a/tests/osmo-pcap-test/pcap.c b/tests/osmo-pcap-test/pcap.c
index f9304b9..a67b121 100644
--- a/tests/osmo-pcap-test/pcap.c
+++ b/tests/osmo-pcap-test/pcap.c
@@ -18,6 +18,7 @@
 #include <string.h>
 #include <dlfcn.h>
 #include <unistd.h>
+#include <sys/time.h>
 
 #include <linux/if_ether.h>
 
@@ -26,6 +27,7 @@
 
 #include <osmocom/core/msgb.h>
 #include <osmocom/core/timer.h>
+#include <osmocom/core/timer_compat.h>
 #include <osmocom/core/select.h>
 
 #include <osmocom/netif/osmux.h>
@@ -108,7 +110,8 @@
        struct osmo_pcap_proto_l4 *l4h;
        struct pcap_pkthdr pcaph;
        const u_char *l2pkt, *l3pkt;
-       struct timeval res;
+       struct timespec now_ts, elapsed_sys_ts;
+       struct timeval res, elapsed_pcap, elapsed_sys;
        uint8_t l4protonum;
 
        if (p->deliver_msg) {
@@ -152,20 +155,34 @@
        }
 
        /* first packet that is going to be processed */
-       if (osmo_pcap_test_stats.processed == 0)
-               memcpy(&p->last, &pcaph.ts, sizeof(struct timeval));
+       if (osmo_pcap_test_stats.processed == 0) {
+               if (clock_gettime(CLOCK_MONOTONIC, &p->start_sys) < 0)
+                       return -1;
+               memcpy(&p->start_pcap, &pcaph.ts, sizeof(struct timeval));
+       }
 
        /* retry with next packet if this has been skipped. */
        if (osmo_pcap_process_packet(&p->deliver_msg, l2pkt, pcaph.caplen, l2h, 
l3h, l4h, cb) < 0)
                goto retry;
 
        /* calculate waiting time */
-       timersub(&pcaph.ts, &p->last, &res);
+       timersub(&pcaph.ts, &p->start_pcap, &elapsed_pcap);
+       if (clock_gettime(CLOCK_MONOTONIC, &now_ts) < 0)
+               return -1;
+       timespecsub(&now_ts, &p->start_sys, &elapsed_sys_ts);
+       elapsed_sys.tv_sec = elapsed_sys_ts.tv_sec;
+       elapsed_sys.tv_usec = elapsed_sys_ts.tv_nsec / 1000;
+
+       if (timercmp(&elapsed_sys, &elapsed_pcap, >)) {
+               printf("We are late!\n");
+               res.tv_sec = 0;
+               res.tv_usec = 0;
+       } else {
+               timersub(&elapsed_pcap, &elapsed_sys, &res);
+       }
        printf("next packet comes in %lu.%.6lu seconds\n",
                res.tv_sec, res.tv_usec);
        osmo_timer_schedule(&p->timer, res.tv_sec, res.tv_usec);
-
-       memcpy(&p->last, &pcaph.ts, sizeof(struct timeval));
 
        return 0;
 }

-- 
To view, visit https://gerrit.osmocom.org/6949
To unsubscribe, visit https://gerrit.osmocom.org/settings

Gerrit-MessageType: newchange
Gerrit-Change-Id: I11cb9a63e16e829ccd4af1096b9f473c802d822f
Gerrit-PatchSet: 1
Gerrit-Project: libosmo-netif
Gerrit-Branch: master
Gerrit-Owner: Pau Espin Pedrol <pes...@sysmocom.de>

Reply via email to