@@ -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 */
};
@@ -582,7 +582,8 @@ static int set_audio_info(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(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(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,8 @@ 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(&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 +1001,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 +1041,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 +1057,9 @@ 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(&endp->net_end, -1, endp->local_options.codec);
+
setup_rtp_processing(endp);
/* policy CB */
@@ -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 },
@@ -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