aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorHolger Hans Peter Freyther <holger@moiji-mobile.com>2014-10-06 20:04:42 +0200
committerHolger Hans Peter Freyther <holger@moiji-mobile.com>2014-10-09 17:22:33 +0200
commita5a59c9a05982efdcf2a87337d9dc763beb5c3bd (patch)
tree4f604c1c4ac397eaa4b7fc39d9e3f3424feda92f
parent2a7ab868e39760dc51321230d3a4fa2926bf21d7 (diff)
mgcp: Move Annex A counting out of patch/count method
mgcp_patch_and_count has grown due supporting linearizing timestamps, ssrc and other things for equipment like the ip.access nanoBTS. Fight back and move the Annex A code into a dedicated method. The result is updated as we now count after all the patching and for the Annex A code no change in SSRC can be detected.
-rw-r--r--openbsc/include/openbsc/mgcp_internal.h13
-rw-r--r--openbsc/src/libmgcp/mgcp_network.c104
-rw-r--r--openbsc/tests/mgcp/mgcp_test.c10
-rw-r--r--openbsc/tests/mgcp/mgcp_test.ok72
4 files changed, 113 insertions, 86 deletions
diff --git a/openbsc/include/openbsc/mgcp_internal.h b/openbsc/include/openbsc/mgcp_internal.h
index 3bccb39df..0ec18cd5b 100644
--- a/openbsc/include/openbsc/mgcp_internal.h
+++ b/openbsc/include/openbsc/mgcp_internal.h
@@ -54,17 +54,22 @@ struct mgcp_rtp_state {
uint32_t orig_ssrc;
- uint16_t base_seq;
int seq_offset;
- int cycles;
int32_t timestamp_offset;
uint32_t packet_duration;
- uint32_t jitter;
- int32_t transit;
struct mgcp_rtp_stream_state in_stream;
struct mgcp_rtp_stream_state out_stream;
+
+ /* jitter and packet loss calculation */
+ int stats_initialized;
+ uint16_t stats_base_seq;
+ uint16_t stats_max_seq;
+ uint32_t stats_ssrc;
+ uint32_t stats_jitter;
+ int32_t stats_transit;
+ int stats_cycles;
};
struct mgcp_rtp_codec {
diff --git a/openbsc/src/libmgcp/mgcp_network.c b/openbsc/src/libmgcp/mgcp_network.c
index be8ba1bf0..888ec6eb7 100644
--- a/openbsc/src/libmgcp/mgcp_network.c
+++ b/openbsc/src/libmgcp/mgcp_network.c
@@ -331,6 +331,60 @@ void mgcp_get_net_downlink_format_default(struct mgcp_endpoint *endp,
*fmtp_extra = endp->bts_end.fmtp_extra;
}
+
+void mgcp_rtp_annex_count(struct mgcp_endpoint *endp, struct mgcp_rtp_state *state,
+ const uint16_t seq, const int32_t transit,
+ const uint32_t ssrc)
+{
+ uint16_t udelta;
+ int32_t d;
+
+ /* initialize or re-initialize */
+ if (!state->stats_initialized || state->stats_ssrc != ssrc) {
+ state->stats_initialized = 1;
+ state->stats_base_seq = seq;
+ state->stats_max_seq = seq - 1;
+ state->stats_ssrc = ssrc;
+ state->stats_jitter = 0;
+ state->stats_transit = transit;
+ state->stats_cycles = 0;
+ }
+
+ /*
+ * The below takes the shape of the validation of
+ * Appendix A. Check if there is something weird with
+ * the sequence number, otherwise check for a wrap
+ * around in the sequence number.
+ * It can't wrap during the initialization so let's
+ * skip it here. The Appendix A probably doesn't have
+ * this issue because of the probation.
+ */
+ udelta = seq - state->stats_max_seq;
+ if (udelta < RTP_MAX_DROPOUT) {
+ if (seq < state->stats_max_seq)
+ state->stats_cycles += RTP_SEQ_MOD;
+ } else if (udelta <= RTP_SEQ_MOD - RTP_MAX_MISORDER) {
+ LOGP(DMGCP, LOGL_NOTICE,
+ "RTP seqno made a very large jump on 0x%x delta: %u\n",
+ 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. Timestamp and arrival_time have a 1/rate
+ * resolution.
+ */
+ d = transit - state->stats_transit;
+ state->stats_transit = transit;
+ if (d < 0)
+ d = -d;
+ state->stats_jitter += d - ((state->stats_jitter + 8) >> 4);
+ state->stats_max_seq = seq;
+}
+
+
+
/**
* The RFC 3550 Appendix A assumes there are multiple sources but
* some of the supported endpoints (e.g. the nanoBTS) can only handle
@@ -344,8 +398,8 @@ void mgcp_patch_and_count(struct mgcp_endpoint *endp, struct mgcp_rtp_state *sta
char *data, int len)
{
uint32_t arrival_time;
- int32_t transit, d;
- uint16_t seq, udelta;
+ int32_t transit;
+ uint16_t seq;
uint32_t timestamp, ssrc;
struct rtp_hdr *rtp_hdr;
int payload = rtp_end->codec.payload_type;
@@ -361,13 +415,10 @@ void mgcp_patch_and_count(struct mgcp_endpoint *endp, struct mgcp_rtp_state *sta
transit = arrival_time - timestamp;
if (!state->initialized) {
+ state->initialized = 1;
state->in_stream.last_seq = seq - 1;
state->in_stream.ssrc = state->orig_ssrc = ssrc;
state->in_stream.last_tsdelta = 0;
- state->base_seq = seq;
- state->initialized = 1;
- state->jitter = 0;
- state->transit = transit;
state->packet_duration = mgcp_rtp_packet_duration(endp, rtp_end);
state->out_stream = state->in_stream;
state->out_stream.last_timestamp = timestamp;
@@ -398,8 +449,6 @@ void mgcp_patch_and_count(struct mgcp_endpoint *endp, struct mgcp_rtp_state *sta
endp->conn_mode);
state->in_stream.ssrc = ssrc;
- state->jitter = 0;
- state->transit = transit;
if (rtp_end->force_constant_ssrc) {
int16_t delta_seq;
@@ -470,34 +519,7 @@ void mgcp_patch_and_count(struct mgcp_endpoint *endp, struct mgcp_rtp_state *sta
addr, seq, timestamp, "output",
&state->out_stream.last_tsdelta);
- /*
- * The below takes the shape of the validation from Appendix A. Check
- * if there is something weird with the sequence number, otherwise check
- * for a wrap around in the sequence number.
- *
- * Note that last_seq is used where the appendix mentions max_seq.
- */
- udelta = seq - state->out_stream.last_seq;
- if (udelta < RTP_MAX_DROPOUT) {
- if (seq < state->out_stream.last_seq)
- state->cycles += RTP_SEQ_MOD;
- } else if (udelta <= RTP_SEQ_MOD - RTP_MAX_MISORDER) {
- LOGP(DMGCP, LOGL_NOTICE,
- "RTP seqno made a very large jump on 0x%x delta: %u\n",
- 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. Timestamp and arrival_time have a 1/rate
- * resolution.
- */
- d = transit - state->transit;
- state->transit = transit;
- if (d < 0)
- d = -d;
- state->jitter += d - ((state->jitter + 8) >> 4);
+ mgcp_rtp_annex_count(endp, state, seq, transit, ssrc);
/* Save output values */
state->out_stream.last_seq = seq;
@@ -998,10 +1020,10 @@ void mgcp_state_calc_loss(struct mgcp_rtp_state *state,
struct mgcp_rtp_end *end, uint32_t *expected,
int *loss)
{
- *expected = state->cycles + state->out_stream.last_seq;
- *expected = *expected - state->base_seq + 1;
+ *expected = state->stats_cycles + state->stats_max_seq;
+ *expected = *expected - state->stats_base_seq + 1;
- if (!state->initialized) {
+ if (!state->stats_initialized) {
*expected = 0;
*loss = 0;
return;
@@ -1023,7 +1045,7 @@ void mgcp_state_calc_loss(struct mgcp_rtp_state *state,
uint32_t mgcp_state_calc_jitter(struct mgcp_rtp_state *state)
{
- if (!state->initialized)
+ if (!state->stats_initialized)
return 0;
- return state->jitter >> 4;
+ return state->stats_jitter >> 4;
}
diff --git a/openbsc/tests/mgcp/mgcp_test.c b/openbsc/tests/mgcp/mgcp_test.c
index a0575032c..e145c6ab9 100644
--- a/openbsc/tests/mgcp/mgcp_test.c
+++ b/openbsc/tests/mgcp/mgcp_test.c
@@ -699,10 +699,10 @@ static void test_packet_loss_calc(void)
memset(&state, 0, sizeof(state));
memset(&rtp, 0, sizeof(rtp));
- state.initialized = 1;
- state.base_seq = pl_test_dat[i].base_seq;
- state.out_stream.last_seq = pl_test_dat[i].max_seq;
- state.cycles = pl_test_dat[i].cycles;
+ state.stats_initialized = 1;
+ state.stats_base_seq = pl_test_dat[i].base_seq;
+ state.stats_max_seq = pl_test_dat[i].max_seq;
+ state.stats_cycles = pl_test_dat[i].cycles;
rtp.packets = pl_test_dat[i].packets;
mgcp_state_calc_loss(&state, &rtp, &expected, &loss);
@@ -921,7 +921,7 @@ static void test_packet_error_detection(int patch_ssrc, int patch_ts)
state.out_stream.err_ts_counter - last_out_ts_err_cnt);
printf("Stats: Jitter = %u, Transit = %d\n",
- mgcp_state_calc_jitter(&state), state.transit);
+ mgcp_state_calc_jitter(&state), state.stats_transit);
last_in_ts_err_cnt = state.in_stream.err_ts_counter;
last_out_ts_err_cnt = state.out_stream.err_ts_counter;
diff --git a/openbsc/tests/mgcp/mgcp_test.ok b/openbsc/tests/mgcp/mgcp_test.ok
index a56a3fd1b..a25bed4d3 100644
--- a/openbsc/tests/mgcp/mgcp_test.ok
+++ b/openbsc/tests/mgcp/mgcp_test.ok
@@ -142,58 +142,58 @@ Out TS change: 160, dTS: 160, Seq change: 1, TS Err change: in +0, out +0
Stats: Jitter = 15, Transit = 40
In TS: 34688, dTS: 0, Seq: 12
Out TS change: 160, dTS: 160, Seq change: 1, TS Err change: in +0, out +0
-Stats: Jitter = 0, Transit = -32768
+Stats: Jitter = 2065, Transit = -32768
In TS: 34848, dTS: 160, Seq: 13
Out TS change: 160, dTS: 160, Seq change: 1, TS Err change: in +0, out +0
-Stats: Jitter = 0, Transit = -32768
+Stats: Jitter = 1935, Transit = -32768
In TS: 35008, dTS: 160, Seq: 14
Out TS change: 160, dTS: 160, Seq change: 1, TS Err change: in +0, out +0
-Stats: Jitter = 0, Transit = -32768
+Stats: Jitter = 1814, Transit = -32768
In TS: 35128, dTS: 120, Seq: 15
Out TS change: 120, dTS: 120, Seq change: 1, TS Err change: in +1, out +1
-Stats: Jitter = 2, Transit = -32728
+Stats: Jitter = 1704, Transit = -32728
In TS: 35288, dTS: 160, Seq: 16
Out TS change: 160, dTS: 160, Seq change: 1, TS Err change: in +0, out +0
-Stats: Jitter = 2, Transit = -32728
+Stats: Jitter = 1597, Transit = -32728
In TS: 35448, dTS: 160, Seq: 17
Out TS change: 160, dTS: 160, Seq change: 1, TS Err change: in +0, out +0
-Stats: Jitter = 2, Transit = -32728
+Stats: Jitter = 1497, Transit = -32728
In TS: 35768, dTS: 160, Seq: 19
Out TS change: 320, dTS: 160, Seq change: 2, TS Err change: in +0, out +0
-Stats: Jitter = 12, Transit = -32888
+Stats: Jitter = 1414, Transit = -32888
In TS: 35928, dTS: 160, Seq: 20
Out TS change: 160, dTS: 160, Seq change: 1, TS Err change: in +0, out +0
-Stats: Jitter = 11, Transit = -32888
+Stats: Jitter = 1325, Transit = -32888
In TS: 36088, dTS: 160, Seq: 21
Out TS change: 160, dTS: 160, Seq change: 1, TS Err change: in +0, out +0
-Stats: Jitter = 20, Transit = -33048
+Stats: Jitter = 1252, Transit = -33048
In TS: 36088, dTS: 160, Seq: 21
Out TS change: 0, dTS: 160, Seq change: 0, TS Err change: in +0, out +0
-Stats: Jitter = 29, Transit = -32888
+Stats: Jitter = 1184, Transit = -32888
In TS: 36248, dTS: 160, Seq: 22
Out TS change: 160, dTS: 160, Seq change: 1, TS Err change: in +0, out +0
-Stats: Jitter = 27, Transit = -32888
+Stats: Jitter = 1110, Transit = -32888
In TS: 36408, dTS: 160, Seq: 23
Out TS change: 160, dTS: 160, Seq change: 1, TS Err change: in +0, out +0
-Stats: Jitter = 25, Transit = -32888
+Stats: Jitter = 1041, Transit = -32888
In TS: 36568, dTS: 160, Seq: 23
Out TS change: 160, dTS: 160, Seq change: 0, TS Err change: in +1, out +1
-Stats: Jitter = 24, Transit = -32888
+Stats: Jitter = 976, Transit = -32888
In TS: 36728, dTS: 160, Seq: 24
Out TS change: 160, dTS: 160, Seq change: 1, TS Err change: in +0, out +0
-Stats: Jitter = 22, Transit = -32888
+Stats: Jitter = 915, Transit = -32888
In TS: 36888, dTS: 160, Seq: 25
Out TS change: 160, dTS: 160, Seq change: 1, TS Err change: in +0, out +0
-Stats: Jitter = 21, Transit = -32888
+Stats: Jitter = 857, Transit = -32888
In TS: 160000, dTS: 0, Seq: 1000
Out TS change: 12000, dTS: 12000, Seq change: 1, TS Err change: in +0, out +0
-Stats: Jitter = 0, Transit = -144000
+Stats: Jitter = 7748, Transit = -144000
In TS: 160160, dTS: 160, Seq: 1001
Out TS change: 160, dTS: 160, Seq change: 1, TS Err change: in +0, out +0
-Stats: Jitter = 0, Transit = -144000
+Stats: Jitter = 7264, Transit = -144000
In TS: 160320, dTS: 160, Seq: 1002
Out TS change: 160, dTS: 160, Seq change: 1, TS Err change: in +0, out +0
-Stats: Jitter = 0, Transit = -144000
+Stats: Jitter = 6810, Transit = -144000
Testing packet error detection.
Output SSRC changed to 11223344
In TS: 0, dTS: 0, Seq: 0
@@ -422,57 +422,57 @@ Out TS change: 160, dTS: 160, Seq change: 1, TS Err change: in +0, out +0
Stats: Jitter = 15, Transit = 40
In TS: 34688, dTS: 0, Seq: 12
Out TS change: 160, dTS: 160, Seq change: 1, TS Err change: in +0, out +0
-Stats: Jitter = 0, Transit = -32768
+Stats: Jitter = 2065, Transit = -32768
In TS: 34848, dTS: 160, Seq: 13
Out TS change: 160, dTS: 160, Seq change: 1, TS Err change: in +0, out +0
-Stats: Jitter = 0, Transit = -32768
+Stats: Jitter = 1935, Transit = -32768
In TS: 35008, dTS: 160, Seq: 14
Out TS change: 160, dTS: 160, Seq change: 1, TS Err change: in +0, out +0
-Stats: Jitter = 0, Transit = -32768
+Stats: Jitter = 1814, Transit = -32768
In TS: 35128, dTS: 120, Seq: 15
Out TS change: 160, dTS: 160, Seq change: 1, TS Err change: in +1, out +0
-Stats: Jitter = 2, Transit = -32728
+Stats: Jitter = 1704, Transit = -32728
In TS: 35288, dTS: 160, Seq: 16
Out TS change: 160, dTS: 160, Seq change: 1, TS Err change: in +0, out +0
-Stats: Jitter = 2, Transit = -32728
+Stats: Jitter = 1597, Transit = -32728
In TS: 35448, dTS: 160, Seq: 17
Out TS change: 160, dTS: 160, Seq change: 1, TS Err change: in +0, out +0
-Stats: Jitter = 2, Transit = -32728
+Stats: Jitter = 1497, Transit = -32728
In TS: 35768, dTS: 160, Seq: 19
Out TS change: 320, dTS: 160, Seq change: 2, TS Err change: in +0, out +0
-Stats: Jitter = 12, Transit = -32888
+Stats: Jitter = 1414, Transit = -32888
In TS: 35928, dTS: 160, Seq: 20
Out TS change: 160, dTS: 160, Seq change: 1, TS Err change: in +0, out +0
-Stats: Jitter = 11, Transit = -32888
+Stats: Jitter = 1325, Transit = -32888
In TS: 36088, dTS: 160, Seq: 21
Out TS change: 160, dTS: 160, Seq change: 1, TS Err change: in +0, out +0
-Stats: Jitter = 20, Transit = -33048
+Stats: Jitter = 1252, Transit = -33048
In TS: 36088, dTS: 160, Seq: 21
Out TS change: 0, dTS: 160, Seq change: 0, TS Err change: in +0, out +0
-Stats: Jitter = 29, Transit = -32888
+Stats: Jitter = 1184, Transit = -32888
In TS: 36248, dTS: 160, Seq: 22
Out TS change: 160, dTS: 160, Seq change: 1, TS Err change: in +0, out +0
-Stats: Jitter = 27, Transit = -32888
+Stats: Jitter = 1110, Transit = -32888
In TS: 36408, dTS: 160, Seq: 23
Out TS change: 160, dTS: 160, Seq change: 1, TS Err change: in +0, out +0
-Stats: Jitter = 25, Transit = -32888
+Stats: Jitter = 1041, Transit = -32888
In TS: 36568, dTS: 160, Seq: 23
Out TS change: 160, dTS: 160, Seq change: 0, TS Err change: in +1, out +1
-Stats: Jitter = 24, Transit = -32888
+Stats: Jitter = 976, Transit = -32888
In TS: 36728, dTS: 160, Seq: 24
Out TS change: 160, dTS: 160, Seq change: 1, TS Err change: in +0, out +0
-Stats: Jitter = 22, Transit = -32888
+Stats: Jitter = 915, Transit = -32888
In TS: 36888, dTS: 160, Seq: 25
Out TS change: 160, dTS: 160, Seq change: 1, TS Err change: in +0, out +0
-Stats: Jitter = 21, Transit = -32888
+Stats: Jitter = 857, Transit = -32888
In TS: 160000, dTS: 0, Seq: 1000
Out TS change: 12000, dTS: 12000, Seq change: 1, TS Err change: in +0, out +0
-Stats: Jitter = 0, Transit = -144000
+Stats: Jitter = 7748, Transit = -144000
In TS: 160160, dTS: 160, Seq: 1001
Out TS change: 160, dTS: 160, Seq change: 1, TS Err change: in +0, out +0
-Stats: Jitter = 0, Transit = -144000
+Stats: Jitter = 7264, Transit = -144000
In TS: 160320, dTS: 160, Seq: 1002
Out TS change: 160, dTS: 160, Seq change: 1, TS Err change: in +0, out +0
-Stats: Jitter = 0, Transit = -144000
+Stats: Jitter = 6810, Transit = -144000
Testing multiple payload types
Done