From 3a912d3f6ec53b907fe7f8f1b1f494807f2b468d Mon Sep 17 00:00:00 2001 From: Holger Hans Peter Freyther Date: Tue, 15 Sep 2015 19:30:40 +0200 Subject: mgcp: Align the code closer to Annex A and introduce bad_seq 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. --- openbsc/include/openbsc/mgcp_internal.h | 2 +- openbsc/src/libmgcp/mgcp_network.c | 71 +++++++++++++++++++-------------- 2 files changed, 43 insertions(+), 30 deletions(-) diff --git a/openbsc/include/openbsc/mgcp_internal.h b/openbsc/include/openbsc/mgcp_internal.h index 45826300e..e44216736 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 3b84142e1..1804aafe5 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; -- cgit v1.2.3