aboutsummaryrefslogtreecommitdiffstats
path: root/openbsc/src/libmgcp/mgcp_network.c
diff options
context:
space:
mode:
authorHolger Hans Peter Freyther <zecke@selfish.org>2012-10-24 20:31:25 +0200
committerHolger Hans Peter Freyther <zecke@selfish.org>2012-11-12 10:45:03 +0100
commit30690adbc81a1fe15eb5e48b3201772486d79ed0 (patch)
tree0efb8f0cb11025304234cfe718076b9b55df615e /openbsc/src/libmgcp/mgcp_network.c
parent38e02c51250d61bb78912a4f8e67a650691c5149 (diff)
mgcp: Calculate the jitter with the formula/code from the appendix
Use a usec timestamp for the local time. The seconds to usec will swap over to the lower bits but this appears to be correct. The CLOCK_MONOTONIC is used to fulfill the RFC 3550 requirement even if it is a bit slower than the gettimeofday. Make sure to initialize transit in a way that the first transit time will be 0. Otherwise the jitter will contain the difference of the localtime and the remote time.
Diffstat (limited to 'openbsc/src/libmgcp/mgcp_network.c')
-rw-r--r--openbsc/src/libmgcp/mgcp_network.c42
1 files changed, 42 insertions, 0 deletions
diff --git a/openbsc/src/libmgcp/mgcp_network.c b/openbsc/src/libmgcp/mgcp_network.c
index fe72b7b..b28c5a1 100644
--- a/openbsc/src/libmgcp/mgcp_network.c
+++ b/openbsc/src/libmgcp/mgcp_network.c
@@ -40,6 +40,7 @@
/* attempt to determine byte order */
#include <sys/param.h>
#include <limits.h>
+#include <time.h>
#ifndef __BYTE_ORDER
# ifdef __APPLE__
@@ -91,6 +92,29 @@ enum {
#define DUMMY_LOAD 0x23
+/**
+ * This does not need to be a precision timestamp and
+ * is allowed to wrap quite fast. The returned value is
+ * milli seconds now.
+ */
+uint32_t get_current_ts(void)
+{
+ struct timespec tp;
+ uint64_t ret;
+
+ memset(&tp, 0, sizeof(tp));
+ if (clock_gettime(CLOCK_MONOTONIC, &tp) != 0)
+ LOGP(DMGCP, LOGL_NOTICE,
+ "Getting the clock failed.\n");
+
+ /* convert it to useconds */
+ ret = tp.tv_sec;
+ ret *= 1000;
+ ret += tp.tv_nsec / 1000 / 1000;
+
+ return ret;
+}
+
static int udp_send(int fd, struct in_addr *addr, int port, char *buf, int len)
{
struct sockaddr_in out;
@@ -120,6 +144,8 @@ int mgcp_send_dummy(struct mgcp_endpoint *endp)
static void patch_and_count(struct mgcp_endpoint *endp, struct mgcp_rtp_state *state,
int payload, struct sockaddr_in *addr, char *data, int len)
{
+ uint32_t arrival_time;
+ int32_t transit, d;
uint16_t seq, udelta;
uint32_t timestamp;
struct rtp_hdr *rtp_hdr;
@@ -130,6 +156,7 @@ static void patch_and_count(struct mgcp_endpoint *endp, struct mgcp_rtp_state *s
rtp_hdr = (struct rtp_hdr *) data;
seq = ntohs(rtp_hdr->sequence);
timestamp = ntohl(rtp_hdr->timestamp);
+ arrival_time = get_current_ts();
if (!state->initialized) {
state->base_seq = seq;
@@ -137,6 +164,8 @@ static void patch_and_count(struct mgcp_endpoint *endp, struct mgcp_rtp_state *s
state->ssrc = state->orig_ssrc = rtp_hdr->ssrc;
state->initialized = 1;
state->last_timestamp = timestamp;
+ state->jitter = 0;
+ state->transit = arrival_time - timestamp;
} else if (state->ssrc != rtp_hdr->ssrc) {
state->ssrc = rtp_hdr->ssrc;
state->seq_offset = (state->max_seq + 1) - seq;
@@ -173,6 +202,19 @@ static void patch_and_count(struct mgcp_endpoint *endp, struct mgcp_rtp_state *s
ENDPOINT_NUMBER(endp), udelta);
}
+ /*
+ * calculate the jitter between the two packages. The TS should be
+ * taken closer to the read function. This was taken from the
+ * Appendix A of RFC 3550. The local timestamp has a usec resolution.
+ */
+ transit = arrival_time - timestamp;
+ d = transit - state->transit;
+ state->transit = transit;
+ if (d < 0)
+ d = -d;
+ state->jitter += d - ((state->jitter + 8) >> 4);
+
+
state->max_seq = seq;
state->last_timestamp = timestamp;