mgcp: Do not detect the initial package as a wrap around

The Annex A code has a probation period but we don't have it. When
starting with seq_no==0 do not assume that the sequence numbers
have wrapped. Do it by moving the entire checking code into the
else.
This commit is contained in:
Holger Hans Peter Freyther 2014-10-06 21:01:26 +02:00
parent a5a59c9a05
commit 05d481a42c
4 changed files with 66 additions and 19 deletions

View File

@ -248,6 +248,11 @@ void mgcp_get_net_downlink_format_default(struct mgcp_endpoint *endp,
const char**subtype_name, const char**subtype_name,
const char**fmtp_extra); const char**fmtp_extra);
/* internal RTP Annex A counting */
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);
enum { enum {
MGCP_DEST_NET = 0, MGCP_DEST_NET = 0,
MGCP_DEST_BTS, MGCP_DEST_BTS,

View File

@ -336,7 +336,6 @@ void mgcp_rtp_annex_count(struct mgcp_endpoint *endp, struct mgcp_rtp_state *sta
const uint16_t seq, const int32_t transit, const uint16_t seq, const int32_t transit,
const uint32_t ssrc) const uint32_t ssrc)
{ {
uint16_t udelta;
int32_t d; int32_t d;
/* initialize or re-initialize */ /* initialize or re-initialize */
@ -348,25 +347,27 @@ void mgcp_rtp_annex_count(struct mgcp_endpoint *endp, struct mgcp_rtp_state *sta
state->stats_jitter = 0; state->stats_jitter = 0;
state->stats_transit = transit; state->stats_transit = transit;
state->stats_cycles = 0; state->stats_cycles = 0;
} } else {
uint16_t udelta;
/* /*
* The below takes the shape of the validation of * The below takes the shape of the validation of
* Appendix A. Check if there is something weird with * Appendix A. Check if there is something weird with
* the sequence number, otherwise check for a wrap * the sequence number, otherwise check for a wrap
* around in the sequence number. * around in the sequence number.
* It can't wrap during the initialization so let's * It can't wrap during the initialization so let's
* skip it here. The Appendix A probably doesn't have * skip it here. The Appendix A probably doesn't have
* this issue because of the probation. * this issue because of the probation.
*/ */
udelta = seq - state->stats_max_seq; udelta = seq - state->stats_max_seq;
if (udelta < RTP_MAX_DROPOUT) { if (udelta < RTP_MAX_DROPOUT) {
if (seq < state->stats_max_seq) if (seq < state->stats_max_seq)
state->stats_cycles += RTP_SEQ_MOD; state->stats_cycles += RTP_SEQ_MOD;
} else if (udelta <= RTP_SEQ_MOD - RTP_MAX_MISORDER) { } else if (udelta <= RTP_SEQ_MOD - RTP_MAX_MISORDER) {
LOGP(DMGCP, LOGL_NOTICE, LOGP(DMGCP, LOGL_NOTICE,
"RTP seqno made a very large jump on 0x%x delta: %u\n", "RTP seqno made a very large jump on 0x%x delta: %u\n",
ENDPOINT_NUMBER(endp), udelta); ENDPOINT_NUMBER(endp), udelta);
}
} }
/* /*

View File

@ -998,6 +998,45 @@ static void test_multilple_codec(void)
talloc_free(cfg); talloc_free(cfg);
} }
static void test_no_cycle(void)
{
struct mgcp_config *cfg;
struct mgcp_endpoint *endp;
printf("Testing no sequence flow on initial packet\n");
cfg = mgcp_config_alloc();
cfg->trunk.number_endpoints = 64;
mgcp_endpoints_allocate(&cfg->trunk);
endp = &cfg->trunk.endpoints[1];
OSMO_ASSERT(endp->net_state.stats_initialized == 0);
mgcp_rtp_annex_count(endp, &endp->net_state, 0, 0, 2342);
OSMO_ASSERT(endp->net_state.stats_initialized == 1);
OSMO_ASSERT(endp->net_state.stats_cycles == 0);
OSMO_ASSERT(endp->net_state.stats_max_seq == 0);
mgcp_rtp_annex_count(endp, &endp->net_state, 1, 0, 2342);
OSMO_ASSERT(endp->net_state.stats_initialized == 1);
OSMO_ASSERT(endp->net_state.stats_cycles == 0);
OSMO_ASSERT(endp->net_state.stats_max_seq == 1);
/* now jump.. */
mgcp_rtp_annex_count(endp, &endp->net_state, UINT16_MAX, 0, 2342);
OSMO_ASSERT(endp->net_state.stats_initialized == 1);
OSMO_ASSERT(endp->net_state.stats_cycles == 0);
OSMO_ASSERT(endp->net_state.stats_max_seq == UINT16_MAX);
/* and wrap */
mgcp_rtp_annex_count(endp, &endp->net_state, 0, 0, 2342);
OSMO_ASSERT(endp->net_state.stats_initialized == 1);
OSMO_ASSERT(endp->net_state.stats_cycles == UINT16_MAX + 1);
OSMO_ASSERT(endp->net_state.stats_max_seq == 0);
talloc_free(cfg);
}
int main(int argc, char **argv) int main(int argc, char **argv)
{ {
osmo_init_logging(&log_info); osmo_init_logging(&log_info);
@ -1014,6 +1053,7 @@ int main(int argc, char **argv)
test_packet_error_detection(0, 1); test_packet_error_detection(0, 1);
test_packet_error_detection(1, 1); test_packet_error_detection(1, 1);
test_multilple_codec(); test_multilple_codec();
test_no_cycle();
printf("Done\n"); printf("Done\n");
return EXIT_SUCCESS; return EXIT_SUCCESS;

View File

@ -475,4 +475,5 @@ In TS: 160320, dTS: 160, Seq: 1002
Out TS change: 160, dTS: 160, Seq change: 1, TS Err change: in +0, out +0 Out TS change: 160, dTS: 160, Seq change: 1, TS Err change: in +0, out +0
Stats: Jitter = 6810, Transit = -144000 Stats: Jitter = 6810, Transit = -144000
Testing multiple payload types Testing multiple payload types
Testing no sequence flow on initial packet
Done Done