diff options
author | Holger Hans Peter Freyther <holger@moiji-mobile.com> | 2014-09-01 10:50:22 +0200 |
---|---|---|
committer | Holger Hans Peter Freyther <holger@moiji-mobile.com> | 2014-09-02 09:22:19 +0200 |
commit | e46bc2714d3703ce11d71edcc3a0f060ff513ce3 (patch) | |
tree | e217c13f0327220d0f16e42caf050596ab732de8 | |
parent | fa80d07de0975fe3b00daeadd5d9f685abf62653 (diff) |
mgcp: Store one more codec/payload type if it is present
In case of some RTP proxy from time to time we are offered both
G729 and G711 but only one of them will work. I intend to adjust
the codec at runtime in case we receive the wrong codec.
-rw-r--r-- | openbsc/include/openbsc/mgcp_internal.h | 1 | ||||
-rw-r--r-- | openbsc/src/libmgcp/mgcp_protocol.c | 25 | ||||
-rw-r--r-- | openbsc/tests/mgcp/mgcp_test.c | 126 | ||||
-rw-r--r-- | openbsc/tests/mgcp/mgcp_test.ok | 1 |
4 files changed, 144 insertions, 9 deletions
diff --git a/openbsc/include/openbsc/mgcp_internal.h b/openbsc/include/openbsc/mgcp_internal.h index 245890994..34c3d973a 100644 --- a/openbsc/include/openbsc/mgcp_internal.h +++ b/openbsc/include/openbsc/mgcp_internal.h @@ -90,6 +90,7 @@ struct mgcp_rtp_end { /* audio codec information */ struct mgcp_rtp_codec codec; + struct mgcp_rtp_codec alt_codec; /* TODO/XXX: make it generic */ /* per endpoint data */ int frames_per_packet; diff --git a/openbsc/src/libmgcp/mgcp_protocol.c b/openbsc/src/libmgcp/mgcp_protocol.c index fff2ece5c..a728b67c4 100644 --- a/openbsc/src/libmgcp/mgcp_protocol.c +++ b/openbsc/src/libmgcp/mgcp_protocol.c @@ -738,7 +738,9 @@ static int parse_sdp_data(struct mgcp_rtp_end *rtp, struct mgcp_parse_data *p) { char *line; int found_media = 0; + /* TODO/XXX make it more generic */ int audio_payload = -1; + int audio_payload_alt = -1; for_each_line(line, p->save) { switch (line[0]) { @@ -758,10 +760,12 @@ static int parse_sdp_data(struct mgcp_rtp_end *rtp, struct mgcp_parse_data *p) if (sscanf(line, "a=rtpmap:%d %63s", &payload, audio_name) == 2) { - if (payload != audio_payload) - break; - - set_audio_info(p->cfg, &rtp->codec, payload, audio_name); + if (payload == audio_payload) + set_audio_info(p->cfg, &rtp->codec, + payload, audio_name); + else if (payload == audio_payload_alt) + set_audio_info(p->cfg, &rtp->alt_codec, + payload, audio_name); } else if (sscanf(line, "a=ptime:%d-%d", &ptime, &ptime2) >= 1) { if (ptime2 > 0 && ptime2 != ptime) @@ -769,6 +773,7 @@ static int parse_sdp_data(struct mgcp_rtp_end *rtp, struct mgcp_parse_data *p) else rtp->packet_duration_ms = ptime; } else if (sscanf(line, "a=maxptime:%d", &ptime2) == 1) { + /* TODO/XXX: Store this per codec and derive it on use */ if (ptime2 * rtp->codec.frame_duration_den > rtp->codec.frame_duration_num * 1500) /* more than 1 frame */ @@ -777,15 +782,20 @@ static int parse_sdp_data(struct mgcp_rtp_end *rtp, struct mgcp_parse_data *p) break; } case 'm': { - int port; + int port, rc; audio_payload = -1; + audio_payload_alt = -1; - if (sscanf(line, "m=audio %d RTP/AVP %d", - &port, &audio_payload) == 2) { + rc = sscanf(line, "m=audio %d RTP/AVP %d %d", + &port, &audio_payload, &audio_payload_alt); + if (rc >= 2) { rtp->rtp_port = htons(port); rtp->rtcp_port = htons(port + 1); found_media = 1; set_audio_info(p->cfg, &rtp->codec, audio_payload, NULL); + if (rc == 3) + set_audio_info(p->cfg, &rtp->alt_codec, + audio_payload_alt, NULL); } break; } @@ -1486,6 +1496,7 @@ static void mgcp_rtp_end_reset(struct mgcp_rtp_end *end) end->output_enabled = 0; mgcp_rtp_codec_reset(&end->codec); + mgcp_rtp_codec_reset(&end->alt_codec); } static void mgcp_rtp_end_init(struct mgcp_rtp_end *end) diff --git a/openbsc/tests/mgcp/mgcp_test.c b/openbsc/tests/mgcp/mgcp_test.c index 06981dd44..a0575032c 100644 --- a/openbsc/tests/mgcp/mgcp_test.c +++ b/openbsc/tests/mgcp/mgcp_test.c @@ -1,6 +1,6 @@ /* - * (C) 2011-2012 by Holger Hans Peter Freyther <zecke@selfish.org> - * (C) 2011-2012 by On-Waves + * (C) 2011-2012,2014 by Holger Hans Peter Freyther <zecke@selfish.org> + * (C) 2011-2012,2014 by On-Waves * All Rights Reserved * * This program is free software; you can redistribute it and/or modify @@ -268,6 +268,61 @@ static void test_strline(void) #define PTYPE_NONE 128 #define PTYPE_NYI PTYPE_NONE +#define CRCX_MULT_1 "CRCX 2 1@mgw MGCP 1.0\r\n" \ + "M: recvonly\r\n" \ + "C: 2\r\n" \ + "X\r\n" \ + "L: p:20\r\n" \ + "\r\n" \ + "v=0\r\n" \ + "c=IN IP4 123.12.12.123\r\n" \ + "m=audio 5904 RTP/AVP 18 97\r\n"\ + "a=rtpmap:18 G729/8000\r\n" \ + "a=rtpmap:97 GSM-EFR/8000\r\n" \ + "a=ptime:40\r\n" + +#define CRCX_MULT_2 "CRCX 2 2@mgw MGCP 1.0\r\n" \ + "M: recvonly\r\n" \ + "C: 2\r\n" \ + "X\r\n" \ + "L: p:20\r\n" \ + "\r\n" \ + "v=0\r\n" \ + "c=IN IP4 123.12.12.123\r\n" \ + "m=audio 5904 RTP/AVP 18 97 101\r\n"\ + "a=rtpmap:18 G729/8000\r\n" \ + "a=rtpmap:97 GSM-EFR/8000\r\n" \ + "a=rtpmap:101 FOO/8000\r\n" \ + "a=ptime:40\r\n" + +#define CRCX_MULT_3 "CRCX 2 3@mgw MGCP 1.0\r\n" \ + "M: recvonly\r\n" \ + "C: 2\r\n" \ + "X\r\n" \ + "L: p:20\r\n" \ + "\r\n" \ + "v=0\r\n" \ + "c=IN IP4 123.12.12.123\r\n" \ + "m=audio 5904 RTP/AVP\r\n" \ + "a=rtpmap:18 G729/8000\r\n" \ + "a=rtpmap:97 GSM-EFR/8000\r\n" \ + "a=rtpmap:101 FOO/8000\r\n" \ + "a=ptime:40\r\n" + +#define CRCX_MULT_4 "CRCX 2 4@mgw MGCP 1.0\r\n" \ + "M: recvonly\r\n" \ + "C: 2\r\n" \ + "X\r\n" \ + "L: p:20\r\n" \ + "\r\n" \ + "v=0\r\n" \ + "c=IN IP4 123.12.12.123\r\n" \ + "m=audio 5904 RTP/AVP 18\r\n" \ + "a=rtpmap:18 G729/8000\r\n" \ + "a=rtpmap:97 GSM-EFR/8000\r\n" \ + "a=rtpmap:101 FOO/8000\r\n" \ + "a=ptime:40\r\n" + struct mgcp_test { const char *name; const char *req; @@ -877,6 +932,72 @@ static void test_packet_error_detection(int patch_ssrc, int patch_ts) force_monotonic_time_us = -1; } +static void test_multilple_codec(void) +{ + struct mgcp_config *cfg; + struct mgcp_endpoint *endp; + struct msgb *inp, *resp; + + printf("Testing multiple payload types\n"); + + cfg = mgcp_config_alloc(); + cfg->trunk.number_endpoints = 64; + mgcp_endpoints_allocate(&cfg->trunk); + cfg->policy_cb = mgcp_test_policy_cb; + mgcp_endpoints_allocate(mgcp_trunk_alloc(cfg, 1)); + + /* Allocate endpoint 1@mgw with two codecs */ + last_endpoint = -1; + inp = create_msg(CRCX_MULT_1); + resp = mgcp_handle_message(cfg, inp); + msgb_free(inp); + msgb_free(resp); + + OSMO_ASSERT(last_endpoint == 1); + endp = &cfg->trunk.endpoints[last_endpoint]; + OSMO_ASSERT(endp->net_end.codec.payload_type == 18); + OSMO_ASSERT(endp->net_end.alt_codec.payload_type == 97); + + /* Allocate 2@mgw with three codecs, last one ignored */ + last_endpoint = -1; + inp = create_msg(CRCX_MULT_2); + resp = mgcp_handle_message(cfg, inp); + msgb_free(inp); + msgb_free(resp); + + OSMO_ASSERT(last_endpoint == 2); + endp = &cfg->trunk.endpoints[last_endpoint]; + OSMO_ASSERT(endp->net_end.codec.payload_type == 18); + OSMO_ASSERT(endp->net_end.alt_codec.payload_type == 97); + + /* Allocate 3@mgw with no codecs, check for PT == -1 */ + last_endpoint = -1; + inp = create_msg(CRCX_MULT_3); + resp = mgcp_handle_message(cfg, inp); + msgb_free(inp); + msgb_free(resp); + + OSMO_ASSERT(last_endpoint == 3); + endp = &cfg->trunk.endpoints[last_endpoint]; + OSMO_ASSERT(endp->net_end.codec.payload_type == -1); + OSMO_ASSERT(endp->net_end.alt_codec.payload_type == -1); + + /* Allocate 4@mgw with a single codec */ + last_endpoint = -1; + inp = create_msg(CRCX_MULT_4); + resp = mgcp_handle_message(cfg, inp); + msgb_free(inp); + msgb_free(resp); + + OSMO_ASSERT(last_endpoint == 4); + endp = &cfg->trunk.endpoints[last_endpoint]; + OSMO_ASSERT(endp->net_end.codec.payload_type == 18); + OSMO_ASSERT(endp->net_end.alt_codec.payload_type == -1); + + + talloc_free(cfg); +} + int main(int argc, char **argv) { osmo_init_logging(&log_info); @@ -892,6 +1013,7 @@ int main(int argc, char **argv) test_packet_error_detection(0, 0); test_packet_error_detection(0, 1); test_packet_error_detection(1, 1); + test_multilple_codec(); printf("Done\n"); return EXIT_SUCCESS; diff --git a/openbsc/tests/mgcp/mgcp_test.ok b/openbsc/tests/mgcp/mgcp_test.ok index 033f783f3..a56a3fd1b 100644 --- a/openbsc/tests/mgcp/mgcp_test.ok +++ b/openbsc/tests/mgcp/mgcp_test.ok @@ -474,4 +474,5 @@ Stats: Jitter = 0, 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 +Testing multiple payload types Done |