summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorHolger Hans Peter Freyther <holger@moiji-mobile.com>2015-09-15 19:30:40 +0200
committerHolger Hans Peter Freyther <holger@moiji-mobile.com>2015-09-15 19:32:35 +0200
commit3a912d3f6ec53b907fe7f8f1b1f494807f2b468d (patch)
treecff189f864e7c7871b7ed43162f3e9258df97885
parentfb51539951c3e2e49497ad35c5032647dd924fd6 (diff)
mgcp: Align the code closer to Annex A and introduce bad_seqzecke/fixes/mgcp-rtp-stats
Introduce the bad_seq handling that is dealing with a very long sequence number jump. The only missing part is the probation handling that is of not that much interest right now. Change the initialization sequence, in case of a new SSRC re-set the jitter and transit time calculation to an initial value. The sender might be a different system that takes a different path so the average jitter does not make that munch sense.
-rw-r--r--openbsc/include/openbsc/mgcp_internal.h2
-rw-r--r--openbsc/src/libmgcp/mgcp_network.c71
2 files changed, 43 insertions, 30 deletions
diff --git a/openbsc/include/openbsc/mgcp_internal.h b/openbsc/include/openbsc/mgcp_internal.h
index 4582630..e442167 100644
--- a/openbsc/include/openbsc/mgcp_internal.h
+++ b/openbsc/include/openbsc/mgcp_internal.h
@@ -71,7 +71,7 @@ struct mgcp_rtp_state {
uint16_t stats_max_seq;
uint32_t stats_cycles;
uint32_t stats_base_seq;
- /* uint32_t stats_bad_seq; no probation */
+ uint32_t stats_bad_seq;
/* uint32_t probation */
uint32_t stats_received;
/* uint32_t expected_prior no SenderReport */
diff --git a/openbsc/src/libmgcp/mgcp_network.c b/openbsc/src/libmgcp/mgcp_network.c
index 3b84142..1804aaf 100644
--- a/openbsc/src/libmgcp/mgcp_network.c
+++ b/openbsc/src/libmgcp/mgcp_network.c
@@ -334,47 +334,62 @@ void mgcp_get_net_downlink_format_default(struct mgcp_endpoint *endp,
*fmtp_extra = endp->bts_end.fmtp_extra;
}
+static void init_seq(struct mgcp_rtp_state *state, const uint16_t seq)
+{
+ state->stats_initialized = 1;
+ state->stats_base_seq = seq;
+ state->stats_max_seq = seq;
+ state->stats_base_seq = RTP_SEQ_MOD + 1;
+ state->stats_jitter = 0;
+ state->stats_cycles = 0;
+ state->stats_received = 0;
+}
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)
{
int32_t d;
+ uint16_t udelta;
/* 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;
+ init_seq(state, seq);
state->stats_ssrc = ssrc;
- state->stats_jitter = 0;
+ state->stats_received += 1;
state->stats_transit = transit;
- state->stats_cycles = 0;
- state->stats_received = 0;
- } else {
- uint16_t udelta;
-
- /*
- * 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);
- }
+ state->stats_jitter = 0;
+ return;
+ }
+
+ /*
+ * 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;
state->stats_max_seq = seq;
+ } 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);
+ if (seq == state->stats_bad_seq)
+ init_seq(state, seq);
+ else {
+ state->stats_bad_seq = (seq + 1) & (RTP_SEQ_MOD - 1);
+ return;
+ }
}
+ state->stats_received += 1;
+
/*
* Calculate the jitter between the two packages. The TS should be
* taken closer to the read function. This was taken from the
@@ -706,7 +721,6 @@ static int rtp_data_net(struct osmo_fd *fd, unsigned int what)
}
proto = fd == &endp->net_end.rtp ? MGCP_PROTO_RTP : MGCP_PROTO_RTCP;
- endp->net_state.stats_received += 1;
endp->net_end.packets += 1;
endp->net_end.octets += rc;
@@ -799,7 +813,6 @@ static int rtp_data_bts(struct osmo_fd *fd, unsigned int what)
}
/* do this before the loop handling */
- endp->bts_state.stats_received += 1;
endp->bts_end.packets += 1;
endp->bts_end.octets += rc;