From patchwork Thu May 15 08:29:19 2014 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jacob Erlbeck X-Patchwork-Id: 349117 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from ganesha.gnumonks.org (ganesha.gnumonks.org [IPv6:2001:780:45:1d:225:90ff:fe52:c662]) (using TLSv1 with cipher AES256-SHA (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 7C287140084 for ; Thu, 15 May 2014 18:52:48 +1000 (EST) Received: from localhost ([127.0.0.1] helo=ganesha.gnumonks.org) by ganesha.gnumonks.org with esmtp (Exim 4.72) (envelope-from ) id 1WkrP3-0000o1-7l; Thu, 15 May 2014 10:52:38 +0200 Received: from mail.sysmocom.de ([144.76.43.93]) by ganesha.gnumonks.org with esmtp (Exim 4.72) (envelope-from ) id 1WkrDt-0007xf-U2 for openbsc@lists.osmocom.org; Thu, 15 May 2014 10:41:10 +0200 Received: from sysmocom-tmp.home (24-134-58-61-dynip.superkabel.de [24.134.58.61]) by mail.sysmocom.de (Postfix) with ESMTPSA id 3496258F24; Thu, 15 May 2014 08:40:55 +0000 (UTC) From: Jacob Erlbeck To: openbsc@lists.osmocom.org Subject: [PATCH 11/11] mgcp: Set net_end audio params in recvonly mode Date: Thu, 15 May 2014 10:29:19 +0200 Message-Id: <1400142559-26788-11-git-send-email-jerlbeck@sysmocom.de> X-Mailer: git-send-email 1.7.9.5 In-Reply-To: <1400142559-26788-1-git-send-email-jerlbeck@sysmocom.de> References: <1399891147-31419-1-git-send-email-jerlbeck@sysmocom.de> <1400142559-26788-1-git-send-email-jerlbeck@sysmocom.de> X-Spam-Score: 0.2 (/) X-Spam-Report: SpamASsassin versoin 3.3.1 on ganesha.gnumonks.org summary: Content analysis details: (0.2 points, 5.0 required) pts rule name description ---- ---------------------- -------------------------------------------------- 0.1 TW_CF BODY: Odd Letter Triples with CF 0.1 TW_MG BODY: Odd Letter Triples with MG 0.1 TW_GC BODY: Odd Letter Triples with GC Cc: Jacob Erlbeck X-BeenThere: openbsc@lists.osmocom.org X-Mailman-Version: 2.1.13 Precedence: list List-Id: Development of the OpenBSC GSM base station controller List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: openbsc-bounces@lists.osmocom.org Errors-To: openbsc-bounces@lists.osmocom.org Currently, if there is no SDP data in the MGCP message received from the net, the fields containing audio encoding information are not set in net_end. So in recvonly mode transcoding would not be set up correctly. This patch changes the implementation of the code handling CRCX and MDCX to use the codec signalled in the MGCP local connection options (field 'a:') if there isn't any SDP data. This is only halfway negotiation, because the codec is used blindly and not matched against the supported ones. Sponsored-by: On-Waves ehf --- openbsc/include/openbsc/mgcp_internal.h | 1 + openbsc/src/libmgcp/mgcp_protocol.c | 37 ++++++++++++++++++++++++++++--- openbsc/tests/mgcp/mgcp_test.c | 7 ++++++ openbsc/tests/mgcp/mgcp_test.ok | 5 +++++ 4 files changed, 47 insertions(+), 3 deletions(-) diff --git a/openbsc/include/openbsc/mgcp_internal.h b/openbsc/include/openbsc/mgcp_internal.h index c7bc2a8..e877026 100644 --- a/openbsc/include/openbsc/mgcp_internal.h +++ b/openbsc/include/openbsc/mgcp_internal.h @@ -124,6 +124,7 @@ struct mgcp_rtp_tap { struct mgcp_lco { char *string; + char *codec; int pkt_period_min; /* time in ms */ int pkt_period_max; /* time in ms */ }; diff --git a/openbsc/src/libmgcp/mgcp_protocol.c b/openbsc/src/libmgcp/mgcp_protocol.c index a903e3c..04f7750 100644 --- a/openbsc/src/libmgcp/mgcp_protocol.c +++ b/openbsc/src/libmgcp/mgcp_protocol.c @@ -582,7 +582,8 @@ static int set_audio_info(void *ctx, struct mgcp_rtp_end *rtp, talloc_free(rtp->audio_name); rtp->audio_name = NULL; - rtp->payload_type = payload_type; + if (payload_type >= 0) + rtp->payload_type = payload_type; if (!audio_name) { switch (payload_type) { @@ -597,7 +598,7 @@ static int set_audio_info(void *ctx, struct mgcp_rtp_end *rtp, } if (sscanf(audio_name, "%63[^/]/%d/%d", - audio_codec, &rate, &channels) < 2) + audio_codec, &rate, &channels) < 1) return -EINVAL; rtp->rate = rate; @@ -610,6 +611,20 @@ static int set_audio_info(void *ctx, struct mgcp_rtp_end *rtp, rtp->frame_duration_den = 1000; } + if (payload_type < 0) { + payload_type = 96; + if (rate == 8000 && channels == 1) { + if (!strcmp(audio_codec, "GSM")) + payload_type = 3; + else if (!strcmp(audio_codec, "PCMA")) + payload_type = 8; + else if (!strcmp(audio_codec, "G729")) + payload_type = 18; + } + + rtp->payload_type = payload_type; + } + if (channels != 1) LOGP(DMGCP, LOGL_NOTICE, "Channels != 1 in SDP: '%s'\n", audio_name); @@ -781,9 +796,12 @@ static int parse_sdp_data(struct mgcp_rtp_end *rtp, struct mgcp_parse_data *p) static void set_local_cx_options(void *ctx, struct mgcp_lco *lco, const char *options) { - char *p_opt; + char *p_opt, *a_opt; + char codec[9]; talloc_free(lco->string); + talloc_free(lco->codec); + lco->codec = NULL; lco->pkt_period_min = lco->pkt_period_max = 0; lco->string = talloc_strdup(ctx, options ? options : ""); @@ -791,6 +809,10 @@ static void set_local_cx_options(void *ctx, struct mgcp_lco *lco, if (p_opt && sscanf(p_opt, "p:%d-%d", &lco->pkt_period_min, &lco->pkt_period_max) == 1) lco->pkt_period_max = lco->pkt_period_min; + + a_opt = strstr(lco->string, "a:"); + if (a_opt && sscanf(a_opt, "a:%8[^,]", codec) == 1) + lco->codec = talloc_strdup(ctx, codec); } void mgcp_rtp_end_config(struct mgcp_endpoint *endp, int expect_ssrc_change, @@ -924,6 +946,9 @@ mgcp_header_done: tcfg->audio_fmtp_extra); if (have_sdp) parse_sdp_data(&endp->net_end, p); + else if (endp->local_options.codec) + set_audio_info(p->cfg, &endp->net_end, + -1, endp->local_options.codec); if (p->cfg->bts_force_ptime) { endp->bts_end.packet_duration_ms = p->cfg->bts_force_ptime; @@ -977,6 +1002,7 @@ static struct msgb *handle_modify_con(struct mgcp_parse_data *p) struct mgcp_endpoint *endp = p->endp; int error_code = 500; int silent = 0; + int have_sdp = 0; char *line; const char *local_options = NULL; @@ -1016,6 +1042,7 @@ static struct msgb *handle_modify_con(struct mgcp_parse_data *p) break; case '\0': /* SDP file begins */ + have_sdp = 1; parse_sdp_data(&endp->net_end, p); /* This will exhaust p->save, so the loop will * terminate next time. @@ -1031,6 +1058,10 @@ static struct msgb *handle_modify_con(struct mgcp_parse_data *p) set_local_cx_options(endp->tcfg->endpoints, &endp->local_options, local_options); + if (!have_sdp && endp->local_options.codec) + set_audio_info(p->cfg, &endp->net_end, + -1, endp->local_options.codec); + setup_rtp_processing(endp); /* policy CB */ diff --git a/openbsc/tests/mgcp/mgcp_test.c b/openbsc/tests/mgcp/mgcp_test.c index 498a1d8..0552c72 100644 --- a/openbsc/tests/mgcp/mgcp_test.c +++ b/openbsc/tests/mgcp/mgcp_test.c @@ -168,6 +168,12 @@ static void test_strline(void) "a=rtpmap:99 AMR/8000\r\n" \ "a=ptime:40\r\n" +#define MDCX4_RO "MDCX 18983221 1@mgw MGCP 1.0\r\n" \ + "M: recvonly\r" \ + "C: 2\r\n" \ + "I: 1\r\n" \ + "L: p:20, a:AMR, nt:IN\r\n" + #define SHORT2 "CRCX 1" #define SHORT2_RET "510 000000 FAIL\r\n" #define SHORT3 "CRCX 1 1@mgw" @@ -257,6 +263,7 @@ static const struct mgcp_test tests[] = { { "MDCX4_PT2", MDCX4_PT2, MDCX4_RET("18983218"), 99, 126 }, { "MDCX4_PT3", MDCX4_PT3, MDCX4_RET("18983219"), 99, 126 }, { "MDCX4_SO", MDCX4_SO, MDCX4_RET("18983220"), 99, 126 }, + { "MDCX4_RO", MDCX4_RO, MDCX4_RET("18983221"), PTYPE_IGNORE, 126 }, { "DLCX", DLCX, DLCX_RET, -1, -1 }, { "CRCX_ZYN", CRCX_ZYN, CRCX_ZYN_RET, 97, 126 }, { "EMPTY", EMPTY, EMPTY_RET }, diff --git a/openbsc/tests/mgcp/mgcp_test.ok b/openbsc/tests/mgcp/mgcp_test.ok index 3901cfb..7301a81 100644 --- a/openbsc/tests/mgcp/mgcp_test.ok +++ b/openbsc/tests/mgcp/mgcp_test.ok @@ -49,6 +49,11 @@ Testing MDCX4_SO Detected packet duration: 40 Requested packetetization period: 20-20 Connection mode: 2: SEND +Testing MDCX4_RO +Dummy packets: 1 +Packet duration not set +Requested packetetization period: 20-20 +Connection mode: 1: RECV Testing DLCX Detected packet duration: 20 Requested packetization period not set