aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorHolger Hans Peter Freyther <zecke@selfish.org>2012-10-22 18:09:35 +0200
committerHolger Hans Peter Freyther <zecke@selfish.org>2012-11-12 10:44:58 +0100
commit38e02c51250d61bb78912a4f8e67a650691c5149 (patch)
tree6b623114d6083c1d672e4ce72e793bc1af76c9ca
parent769912c9e95e9247831c51e6f7592b07712709d3 (diff)
mgcp: Calculate the packet loss as of Appendix A of RFC 3550
Calculate the expected packages and packet loss as of RFC 3550. The values should be clamped but our packet loss counter is 32 bits and not 24 and we should clamp at other values but I am waiting for some issues first before dealing with that.
-rw-r--r--openbsc/include/openbsc/mgcp_internal.h7
-rw-r--r--openbsc/src/libmgcp/mgcp_network.c32
-rw-r--r--openbsc/src/libmgcp/mgcp_protocol.c10
-rw-r--r--openbsc/tests/mgcp/mgcp_test.c60
-rw-r--r--openbsc/tests/mgcp/mgcp_test.ok1
5 files changed, 101 insertions, 9 deletions
diff --git a/openbsc/include/openbsc/mgcp_internal.h b/openbsc/include/openbsc/mgcp_internal.h
index f5e3cfce2..6e2072fdb 100644
--- a/openbsc/include/openbsc/mgcp_internal.h
+++ b/openbsc/include/openbsc/mgcp_internal.h
@@ -1,8 +1,8 @@
/* MGCP Private Data */
/*
- * (C) 2009-2011 by Holger Hans Peter Freyther <zecke@selfish.org>
- * (C) 2009-2011 by On-Waves
+ * (C) 2009-2012 by Holger Hans Peter Freyther <zecke@selfish.org>
+ * (C) 2009-2012 by On-Waves
* All Rights Reserved
*
* This program is free software; you can redistribute it and/or modify
@@ -151,5 +151,8 @@ static inline int endp_back_channel(int endpoint)
struct mgcp_trunk_config *mgcp_trunk_alloc(struct mgcp_config *cfg, int index);
struct mgcp_trunk_config *mgcp_trunk_num(struct mgcp_config *cfg, int index);
+void mgcp_state_calc_loss(struct mgcp_rtp_state *s, struct mgcp_rtp_end *,
+ uint32_t *expected, int *loss);
+
#endif
diff --git a/openbsc/src/libmgcp/mgcp_network.c b/openbsc/src/libmgcp/mgcp_network.c
index 233418b87..fe72b7b49 100644
--- a/openbsc/src/libmgcp/mgcp_network.c
+++ b/openbsc/src/libmgcp/mgcp_network.c
@@ -2,8 +2,8 @@
/* The protocol implementation */
/*
- * (C) 2009-2011 by Holger Hans Peter Freyther <zecke@selfish.org>
- * (C) 2009-2011 by On-Waves
+ * (C) 2009-2012 by Holger Hans Peter Freyther <zecke@selfish.org>
+ * (C) 2009-2012 by On-Waves
* All Rights Reserved
*
* This program is free software; you can redistribute it and/or modify
@@ -607,3 +607,31 @@ int mgcp_free_rtp_port(struct mgcp_rtp_end *end)
return 0;
}
+
+
+void mgcp_state_calc_loss(struct mgcp_rtp_state *state,
+ struct mgcp_rtp_end *end, uint32_t *expected,
+ int *loss)
+{
+ *expected = state->cycles + state->max_seq;
+ *expected = *expected - state->base_seq + 1;
+
+ if (!state->initialized) {
+ *expected = 0;
+ *loss = 0;
+ return;
+ }
+
+ /*
+ * Make sure the sign is correct and use the biggest
+ * positive/negative number that fits.
+ */
+ *loss = *expected - end->packets;
+ if (*expected < end->packets) {
+ if (*loss > 0)
+ *loss = INT_MIN;
+ } else {
+ if (*loss < 0)
+ *loss = INT_MAX;
+ }
+}
diff --git a/openbsc/src/libmgcp/mgcp_protocol.c b/openbsc/src/libmgcp/mgcp_protocol.c
index d57ad0024..0d8e9ea55 100644
--- a/openbsc/src/libmgcp/mgcp_protocol.c
+++ b/openbsc/src/libmgcp/mgcp_protocol.c
@@ -1121,8 +1121,14 @@ int mgcp_reset_transcoder(struct mgcp_config *cfg)
void mgcp_format_stats(struct mgcp_endpoint *endp, char *msg, size_t size)
{
- snprintf(msg, size, "\r\nP: PS=%u, OS=%u, PR=%u, OR=%u",
+ uint32_t expected;
+ int ploss;
+ mgcp_state_calc_loss(&endp->net_state, &endp->net_end,
+ &expected, &ploss);
+
+ snprintf(msg, size, "\r\nP: PS=%u, OS=%u, PR=%u, OR=%u, PL=%d",
endp->bts_end.packets, endp->bts_end.octets,
- endp->net_end.packets, endp->net_end.octets);
+ endp->net_end.packets, endp->net_end.octets,
+ ploss);
msg[size - 1] = '\0';
}
diff --git a/openbsc/tests/mgcp/mgcp_test.c b/openbsc/tests/mgcp/mgcp_test.c
index 41a51dea0..02bcddb2e 100644
--- a/openbsc/tests/mgcp/mgcp_test.c
+++ b/openbsc/tests/mgcp/mgcp_test.c
@@ -1,6 +1,6 @@
/*
- * (C) 2011 by Holger Hans Peter Freyther <zecke@selfish.org>
- * (C) 2011 by On-Waves
+ * (C) 2011-2012 by Holger Hans Peter Freyther <zecke@selfish.org>
+ * (C) 2011-2012 by On-Waves
* All Rights Reserved
*
* This program is free software; you can redistribute it and/or modify
@@ -23,6 +23,7 @@
#include <osmocom/core/application.h>
#include <osmocom/core/talloc.h>
#include <string.h>
+#include <limits.h>
#define AUEP1 "AUEP 158663169 ds/e1-1/2@172.16.6.66 MGCP 1.0\r\n"
#define AUEP1_RET "200 158663169 OK\r\n"
@@ -71,7 +72,7 @@
"C: 2\r\n"
#define DLCX_RET "250 7 OK\r\n" \
- "P: PS=0, OS=0, PR=0, OR=0\r\n"
+ "P: PS=0, OS=0, PR=0, OR=0, PL=0\r\n"
struct mgcp_test {
@@ -136,11 +137,64 @@ static void test_messages(void)
talloc_free(cfg);
}
+struct pl_test {
+ int cycles;
+ uint16_t base_seq;
+ uint16_t max_seq;
+ uint32_t packets;
+
+ uint32_t expected;
+ int loss;
+};
+
+static const struct pl_test pl_test_dat[] = {
+ /* basic.. just one package */
+ { .cycles = 0, .base_seq = 0, .max_seq = 0, .packets = 1, .expected = 1, .loss = 0},
+ /* some packages and a bit of loss */
+ { .cycles = 0, .base_seq = 0, .max_seq = 100, .packets = 100, .expected = 101, .loss = 1},
+ /* wrap around */
+ { .cycles = 1<<16, .base_seq = 0xffff, .max_seq = 2, .packets = 4, .expected = 4, .loss = 0},
+ /* min loss */
+ { .cycles = 0, .base_seq = 0, .max_seq = 0, .packets = UINT_MAX, .expected = 1, .loss = INT_MIN },
+ /* max loss, with wrap around on expected max */
+ { .cycles = INT_MAX, .base_seq = 0, .max_seq = UINT16_MAX, .packets = 0, .expected = ((uint32_t)(INT_MAX) + UINT16_MAX + 1), .loss = INT_MAX },
+};
+
+static void test_packet_loss_calc(void)
+{
+ int i;
+ printf("Testing packet loss calculation.\n");
+
+ for (i = 0; i < ARRAY_SIZE(pl_test_dat); ++i) {
+ uint32_t expected;
+ int loss;
+ struct mgcp_rtp_state state;
+ struct mgcp_rtp_end rtp;
+ memset(&state, 0, sizeof(state));
+ memset(&rtp, 0, sizeof(rtp));
+
+ state.initialized = 1;
+ state.base_seq = pl_test_dat[i].base_seq;
+ state.max_seq = pl_test_dat[i].max_seq;
+ state.cycles = pl_test_dat[i].cycles;
+
+ rtp.packets = pl_test_dat[i].packets;
+ mgcp_state_calc_loss(&state, &rtp, &expected, &loss);
+
+ if (loss != pl_test_dat[i].loss || expected != pl_test_dat[i].expected) {
+ printf("FAIL: Wrong exp/loss at idx(%d) Loss(%d vs. %d) Exp(%u vs. %u)\n",
+ i, loss, pl_test_dat[i].loss,
+ expected, pl_test_dat[i].expected);
+ }
+ }
+}
+
int main(int argc, char **argv)
{
osmo_init_logging(&log_info);
test_messages();
+ test_packet_loss_calc();
printf("Done\n");
return EXIT_SUCCESS;
diff --git a/openbsc/tests/mgcp/mgcp_test.ok b/openbsc/tests/mgcp/mgcp_test.ok
index 5e0e47cab..e61c0bc15 100644
--- a/openbsc/tests/mgcp/mgcp_test.ok
+++ b/openbsc/tests/mgcp/mgcp_test.ok
@@ -8,4 +8,5 @@ Testing SHORT2
Testing SHORT3
Testing SHORT4
Testing DLCX
+Testing packet loss calculation.
Done