diff options
Diffstat (limited to 'tests/mgcp/mgcp_test.c')
-rw-r--r-- | tests/mgcp/mgcp_test.c | 235 |
1 files changed, 194 insertions, 41 deletions
diff --git a/tests/mgcp/mgcp_test.c b/tests/mgcp/mgcp_test.c index f6c421a..56d0cee 100644 --- a/tests/mgcp/mgcp_test.c +++ b/tests/mgcp/mgcp_test.c @@ -26,6 +26,8 @@ #include <osmocom/mgcp/mgcp_stat.h> #include <osmocom/mgcp/mgcp_msg.h> #include <osmocom/mgcp/mgcp_endp.h> +#include <osmocom/mgcp/mgcp_sdp.h> +#include <osmocom/mgcp/mgcp_codec.h> #include <osmocom/core/application.h> #include <osmocom/core/talloc.h> @@ -156,8 +158,8 @@ static void test_strline(void) "s=-\r\n" \ "c=IN IP4 0.0.0.0\r\n" \ "t=0 0\r\n" \ - "m=audio 16002 RTP/AVP 96\r\n" \ - "a=rtpmap:96 AMR\r\n" \ + "m=audio 16002 RTP/AVP 112\r\n" \ + "a=rtpmap:112 AMR\r\n" \ "a=ptime:40\r\n" #define MDCX4_PT1 \ @@ -404,7 +406,7 @@ static void test_strline(void) "v=0\r\n" \ "o=- 1439038275 1439038275 IN IP4 192.168.181.247\r\n" \ "s=-\r\nc=IN IP4 192.168.181.247\r\n" \ - "t=0 0\r\nm=audio 29084 RTP/AVP 255 0 8 3 18 4 96 97 101\r\n" \ + "t=0 0\r\nm=audio 29084 RTP/AVP 0 8 3 18 4 96 97 101\r\n" \ "a=rtpmap:0 PCMU/8000\r\n" \ "a=rtpmap:8 PCMA/8000\r\n" \ "a=rtpmap:3 gsm/8000\r\n" \ @@ -425,7 +427,24 @@ static void test_strline(void) "I: %s\r\n" \ "\r\n" \ "c=IN IP4 8.8.8.8\r\n" \ - "m=audio 16434 RTP/AVP 255\r\n" + "m=audio 16434 RTP/AVP 3\r\n" + +#define CRCX_NO_LCO_NO_SDP \ + "CRCX 2 6@mgw MGCP 1.0\r\n" \ + "M: recvonly\r\n" \ + "C: 2\r\n" + +#define CRCX_NO_LCO_NO_SDP_RET \ + "200 2 OK\r\n" \ + "I: %s\r\n" \ + "\r\n" \ + "v=0\r\n" \ + "o=- %s 23 IN IP4 0.0.0.0\r\n" \ + "s=-\r\n" \ + "c=IN IP4 0.0.0.0\r\n" \ + "t=0 0\r\n" \ + "m=audio 16008 RTP/AVP 0\r\n" \ + "a=ptime:20\r\n" struct mgcp_test { const char *name; @@ -462,6 +481,7 @@ static const struct mgcp_test tests[] = { {"MDCX3", MDCX3, MDCX3_FMTP_RET, PTYPE_NONE,.extra_fmtp = "a=fmtp:126 0/1/2"}, {"DLCX", DLCX, DLCX_RET, PTYPE_IGNORE,.extra_fmtp = "a=fmtp:126 0/1/2"}, + {"CRCX", CRCX_NO_LCO_NO_SDP, CRCX_NO_LCO_NO_SDP_RET, 97}, }; static const struct mgcp_test retransmit[] = { @@ -764,14 +784,14 @@ static void test_messages(void) fprintf(stderr, "endpoint %d: " "payload type %d (expected %d)\n", last_endpoint, - conn->end.codec.payload_type, t->ptype); + conn->end.codec->payload_type, t->ptype); if (t->ptype != PTYPE_IGNORE) - OSMO_ASSERT(conn->end.codec.payload_type == + OSMO_ASSERT(conn->end.codec->payload_type == t->ptype); /* Reset them again for next test */ - conn->end.codec.payload_type = PTYPE_NONE; + conn->end.codec->payload_type = PTYPE_NONE; } } @@ -917,23 +937,43 @@ static const struct pl_test pl_test_dat[] = { static void test_packet_loss_calc(void) { int i; + struct mgcp_endpoint endp; + struct mgcp_trunk_config trunk; + printf("Testing packet loss calculation.\n"); + memset(&endp, 0, sizeof(endp)); + memset(&trunk, 0, sizeof(trunk)); + + endp.type = &ep_typeset.rtp; + trunk.vty_number_endpoints = 1; + trunk.endpoints = &endp; + endp.tcfg = &trunk; + INIT_LLIST_HEAD(&endp.conns); + 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.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; + struct mgcp_conn_rtp *conn = NULL; + struct mgcp_conn *_conn = NULL; + struct mgcp_rtp_state *state; + struct rate_ctr *packets_rx; - rtp.stats.packets_rx = pl_test_dat[i].packets; - calc_loss(&state, &rtp, &expected, &loss); + _conn = + mgcp_conn_alloc(NULL, &endp, MGCP_CONN_TYPE_RTP, + "test-connection"); + conn = mgcp_conn_get_rtp(&endp, _conn->id); + state = &conn->state; + packets_rx = &conn->rate_ctr_group->ctr[RTP_PACKETS_RX_CTR]; + + 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; + + packets_rx->current = pl_test_dat[i].packets; + calc_loss(conn, &expected, &loss); if (loss != pl_test_dat[i].loss || expected != pl_test_dat[i].expected) { @@ -942,7 +982,10 @@ static void test_packet_loss_calc(void) i, loss, pl_test_dat[i].loss, expected, pl_test_dat[i].expected); } + + mgcp_conn_free_all(&endp); } + } int mgcp_parse_stats(struct msgb *msg, uint32_t *ps, uint32_t *os, @@ -1129,10 +1172,12 @@ static void test_packet_error_detection(int patch_ssrc, int patch_ts) uint32_t last_ssrc = 0; uint32_t last_timestamp = 0; uint32_t last_seqno = 0; - int last_in_ts_err_cnt = 0; - int last_out_ts_err_cnt = 0; + uint64_t last_in_ts_err_cnt = 0; + uint64_t last_out_ts_err_cnt = 0; struct mgcp_conn_rtp *conn = NULL; struct mgcp_conn *_conn = NULL; + struct rate_ctr test_ctr_in; + struct rate_ctr test_ctr_out; printf("Testing packet error detection%s%s.\n", patch_ssrc ? ", patch SSRC" : "", @@ -1142,6 +1187,11 @@ static void test_packet_error_detection(int patch_ssrc, int patch_ts) memset(&endp, 0, sizeof(endp)); memset(&state, 0, sizeof(state)); + memset(&test_ctr_in, 0, sizeof(test_ctr_in)); + memset(&test_ctr_out, 0, sizeof(test_ctr_out)); + state.in_stream.err_ts_ctr = &test_ctr_in; + state.out_stream.err_ts_ctr = &test_ctr_out; + endp.type = &ep_typeset.rtp; trunk.vty_number_endpoints = 1; @@ -1160,7 +1210,8 @@ static void test_packet_error_detection(int patch_ssrc, int patch_ts) rtp = &conn->end; - rtp->codec.payload_type = 98; + OSMO_ASSERT(mgcp_codec_add(conn, PTYPE_UNDEFINED, "AMR/8000/1") == 0); + rtp->codec = &rtp->codecs[0]; for (i = 0; i < ARRAY_SIZE(test_rtp_packets1); ++i) { struct rtp_packet_info *info = test_rtp_packets1 + i; @@ -1186,18 +1237,18 @@ static void test_packet_error_detection(int patch_ssrc, int patch_ts) state.in_stream.last_tsdelta, state.in_stream.last_seq); printf("Out TS change: %d, dTS: %d, Seq change: %d, " - "TS Err change: in %+d, out %+d\n", + "TS Err change: in +%u, out +%u\n", state.out_stream.last_timestamp - last_timestamp, state.out_stream.last_tsdelta, state.out_stream.last_seq - last_seqno, - state.in_stream.err_ts_counter - last_in_ts_err_cnt, - state.out_stream.err_ts_counter - last_out_ts_err_cnt); + (unsigned int) (state.in_stream.err_ts_ctr->current - last_in_ts_err_cnt), + (unsigned int) (state.out_stream.err_ts_ctr->current - last_out_ts_err_cnt)); printf("Stats: Jitter = %u, Transit = %d\n", 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; + last_in_ts_err_cnt = state.in_stream.err_ts_ctr->current; + last_out_ts_err_cnt = state.out_stream.err_ts_ctr->current; last_timestamp = state.out_stream.last_timestamp; last_seqno = state.out_stream.last_seq; } @@ -1236,8 +1287,7 @@ static void test_multilple_codec(void) endp = &cfg->trunk.endpoints[last_endpoint]; conn = mgcp_conn_get_rtp(endp, conn_id); OSMO_ASSERT(conn); - OSMO_ASSERT(conn->end.codec.payload_type == 18); - OSMO_ASSERT(conn->end.alt_codec.payload_type == 97); + OSMO_ASSERT(conn->end.codec->payload_type == 18); /* Allocate 2@mgw with three codecs, last one ignored */ last_endpoint = -1; @@ -1252,10 +1302,14 @@ static void test_multilple_codec(void) endp = &cfg->trunk.endpoints[last_endpoint]; conn = mgcp_conn_get_rtp(endp, conn_id); OSMO_ASSERT(conn); - OSMO_ASSERT(conn->end.codec.payload_type == 18); - OSMO_ASSERT(conn->end.alt_codec.payload_type == 97); - - /* Allocate 3@mgw with no codecs, check for PT == -1 */ + OSMO_ASSERT(conn->end.codec->payload_type == 18); + + /* Allocate 3@mgw with no codecs, check for PT == 0 */ + /* Note: It usually makes no sense to leave the payload type list + * out. However RFC 2327 does not clearly forbid this case and + * it makes and since we already decided in OS#2658 that a missing + * LCO should pick a sane default codec, it makes sense to expect + * the same behaviour if SDP lacks proper payload type information */ last_endpoint = -1; inp = create_msg(CRCX_MULT_3, NULL); resp = mgcp_handle_message(cfg, inp); @@ -1268,8 +1322,7 @@ static void test_multilple_codec(void) endp = &cfg->trunk.endpoints[last_endpoint]; conn = mgcp_conn_get_rtp(endp, conn_id); OSMO_ASSERT(conn); - OSMO_ASSERT(conn->end.codec.payload_type == -1); - OSMO_ASSERT(conn->end.alt_codec.payload_type == -1); + OSMO_ASSERT(conn->end.codec->payload_type == 0); /* Allocate 4@mgw with a single codec */ last_endpoint = -1; @@ -1284,8 +1337,7 @@ static void test_multilple_codec(void) endp = &cfg->trunk.endpoints[last_endpoint]; conn = mgcp_conn_get_rtp(endp, conn_id); OSMO_ASSERT(conn); - OSMO_ASSERT(conn->end.codec.payload_type == 18); - OSMO_ASSERT(conn->end.alt_codec.payload_type == -1); + OSMO_ASSERT(conn->end.codec->payload_type == 18); /* Allocate 5@mgw at select GSM.. */ last_endpoint = -1; @@ -1303,8 +1355,7 @@ static void test_multilple_codec(void) endp = &cfg->trunk.endpoints[last_endpoint]; conn = mgcp_conn_get_rtp(endp, conn_id); OSMO_ASSERT(conn); - OSMO_ASSERT(conn->end.codec.payload_type == 3); - OSMO_ASSERT(conn->end.alt_codec.payload_type == -1); + OSMO_ASSERT(conn->end.codec->payload_type == 3); inp = create_msg(MDCX_NAT_DUMMY, conn_id); last_endpoint = -1; @@ -1315,8 +1366,7 @@ static void test_multilple_codec(void) endp = &cfg->trunk.endpoints[last_endpoint]; conn = mgcp_conn_get_rtp(endp, conn_id); OSMO_ASSERT(conn); - OSMO_ASSERT(conn->end.codec.payload_type == 3); - OSMO_ASSERT(conn->end.alt_codec.payload_type == -1); + OSMO_ASSERT(conn->end.codec->payload_type == 3); OSMO_ASSERT(conn->end.rtp_port == htons(16434)); memset(&addr, 0, sizeof(addr)); inet_aton("8.8.8.8", &addr); @@ -1346,8 +1396,7 @@ static void test_multilple_codec(void) endp = &cfg->trunk.endpoints[last_endpoint]; conn = mgcp_conn_get_rtp(endp, conn_id); OSMO_ASSERT(conn); - OSMO_ASSERT(conn->end.codec.payload_type == 255); - OSMO_ASSERT(conn->end.alt_codec.payload_type == 0); + OSMO_ASSERT(conn->end.codec->payload_type == 0); talloc_free(cfg); } @@ -1465,6 +1514,108 @@ const struct log_info log_info = { .num_cat = ARRAY_SIZE(log_categories), }; +static void test_get_lco_identifier(void) +{ + char *test; + printf("Testing get_lco_identifier()\n"); + + /* Normal case at the beginning */ + test = "p:10, a:PCMU"; + printf("%s -> %s\n", test, get_lco_identifier(test)); + + test = "p:10, a:PCMU"; + printf("%s -> %s\n", test, get_lco_identifier(test)); + + /* Begin parsing in the middle of the value part of + * the previous LCO option value */ + test = "XXXX, p:10, a:PCMU"; + printf("'%s' -> '%s'\n", test, get_lco_identifier(test)); + + test = "XXXX,p:10,a:PCMU"; + printf("'%s' -> '%s'\n", test, get_lco_identifier(test)); + + test = "10,a:PCMU"; + printf("'%s' -> '%s'\n", test, get_lco_identifier(test)); + + test = "10, a:PCMU"; + printf("'%s' -> '%s'\n", test, get_lco_identifier(test)); + + test = "10,a: PCMU"; + printf("'%s' -> '%s'\n", test, get_lco_identifier(test)); + + test = "10 ,a: PCMU"; + printf("'%s' -> '%s'\n", test, get_lco_identifier(test)); + + /* Begin parsing right at the end of the previous LCO + * option value */ + test = ", a:PCMU"; + printf("'%s' -> '%s'\n", test, get_lco_identifier(test)); + + test = " a:PCMU"; + printf("'%s' -> '%s'\n", test, get_lco_identifier(test)); + + /* Empty string, result should be (null) */ + test = ""; + printf("'%s' -> '%s'\n", test, get_lco_identifier(test)); + + /* Missing colons, result should be (null) */ + test = "p10, aPCMU"; + printf("%s -> %s\n", test, get_lco_identifier(test)); + + /* Colon separated from the identifier, result should be (null) */ + test = "10,a :PCMU"; + printf("'%s' -> '%s'\n", test, get_lco_identifier(test)); +} + +static void test_check_local_cx_options(void *ctx) +{ + /* Legal cases */ + OSMO_ASSERT(check_local_cx_options(ctx, "p:10, a:PCMU") == 0); + OSMO_ASSERT(check_local_cx_options(ctx, "a:PCMU") == 0); + OSMO_ASSERT(check_local_cx_options(ctx, "a:PCMU, p:10, IN:10") == 0); + OSMO_ASSERT(check_local_cx_options(ctx, "one:AAA, two:BB, tree:C") == + 0); + OSMO_ASSERT(check_local_cx_options(ctx, "p:10, a:PCMU") == 0); + OSMO_ASSERT(check_local_cx_options(ctx, "p:10, a:G726-32") == 0); + OSMO_ASSERT(check_local_cx_options(ctx, "p:10-20, b:64") == 0); + OSMO_ASSERT(check_local_cx_options(ctx, "b:32-64, e:off") == 0); + OSMO_ASSERT(check_local_cx_options(ctx, "p:10, a:PCMU;G726-32") == 0); + + /* Illegal spaces before and after colon */ + OSMO_ASSERT(check_local_cx_options(ctx, "a:PCMU, p :10") == -1); + OSMO_ASSERT(check_local_cx_options(ctx, "a :PCMU, p:10") == -1); + OSMO_ASSERT(check_local_cx_options(ctx, "p: 10, a:PCMU") == -1); + + /* Check if multiple appearances of LCOs are rejected */ + OSMO_ASSERT(check_local_cx_options(ctx, "p:10, a:PCMU, p:10") == -1); + OSMO_ASSERT(check_local_cx_options(ctx, "p:10, a:PCMU, a:PCMU, p:10") == + -1); + OSMO_ASSERT(check_local_cx_options(ctx, "p:10, p:10") == -1); + + /* Check if empty LCO are rejected */ + OSMO_ASSERT(check_local_cx_options(ctx, "p: , a:PCMU") == -1); + OSMO_ASSERT(check_local_cx_options(ctx, "p: , a: PCMU") == -1); + OSMO_ASSERT(check_local_cx_options(ctx, "p:10, a: PCMU") == -1); + OSMO_ASSERT(check_local_cx_options(ctx, "p:, a:PCMU") == -1); + OSMO_ASSERT(check_local_cx_options(ctx, "p:10, a:") == -1); + + /* Garbeled beginning and ends */ + OSMO_ASSERT(check_local_cx_options(ctx, ":10, a:10") == -1); + OSMO_ASSERT(check_local_cx_options(ctx, "10, a:PCMU") == -1); + OSMO_ASSERT(check_local_cx_options(ctx, ", a:PCMU") == -1); + OSMO_ASSERT(check_local_cx_options(ctx, " a:PCMU") == -1); + OSMO_ASSERT(check_local_cx_options(ctx, "a:PCMU,") == -1); + OSMO_ASSERT(check_local_cx_options(ctx, "a:PCMU, ") == -1); + + /* Illegal strings */ + OSMO_ASSERT(check_local_cx_options(ctx, " ") == -1); + OSMO_ASSERT(check_local_cx_options(ctx, "") == -1); + OSMO_ASSERT(check_local_cx_options(ctx, "AAA") == -1); + OSMO_ASSERT(check_local_cx_options(ctx, ":,") == -1); + OSMO_ASSERT(check_local_cx_options(ctx, ",:") == -1); + OSMO_ASSERT(check_local_cx_options(ctx, ",,,") == -1); +} + int main(int argc, char **argv) { void *ctx = talloc_named_const(NULL, 0, "mgcp_test"); @@ -1486,6 +1637,8 @@ int main(int argc, char **argv) test_no_cycle(); test_no_name(); test_osmux_cid(); + test_get_lco_identifier(); + test_check_local_cx_options(ctx); OSMO_ASSERT(talloc_total_size(msgb_ctx) == 0); OSMO_ASSERT(talloc_total_blocks(msgb_ctx) == 1); |