diff options
Diffstat (limited to 'openbsc/src/libmgcp/mgcp_protocol.c')
-rw-r--r-- | openbsc/src/libmgcp/mgcp_protocol.c | 41 |
1 files changed, 38 insertions, 3 deletions
diff --git a/openbsc/src/libmgcp/mgcp_protocol.c b/openbsc/src/libmgcp/mgcp_protocol.c index 21b9ff0f8..f0457d1aa 100644 --- a/openbsc/src/libmgcp/mgcp_protocol.c +++ b/openbsc/src/libmgcp/mgcp_protocol.c @@ -80,6 +80,8 @@ char *strline_r(char *str, char **saveptr) #define DEFAULT_RTP_AUDIO_DEFAULT_RATE 8000 #define DEFAULT_RTP_AUDIO_DEFAULT_CHANNELS 1 +#define PTYPE_UNDEFINED (-1) + static void mgcp_rtp_end_reset(struct mgcp_rtp_end *end); struct mgcp_parse_data { @@ -598,7 +600,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 != PTYPE_UNDEFINED) + rtp->payload_type = payload_type; if (!audio_name) { switch (payload_type) { @@ -614,7 +617,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; @@ -630,6 +633,20 @@ static int set_audio_info(void *ctx, struct mgcp_rtp_end *rtp, rtp->frame_duration_den = DEFAULT_RTP_AUDIO_FRAME_DUR_DEN; } + 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); @@ -801,9 +818,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 : ""); @@ -811,6 +831,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, @@ -955,6 +979,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, + PTYPE_UNDEFINED, endp->local_options.codec); if (p->cfg->bts_force_ptime) { endp->bts_end.packet_duration_ms = p->cfg->bts_force_ptime; @@ -1012,6 +1039,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, osmux = 0; + int have_sdp = 0; char *line; const char *local_options = NULL; @@ -1058,6 +1086,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. @@ -1088,6 +1117,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, + PTYPE_UNDEFINED, endp->local_options.codec); + setup_rtp_processing(endp); /* policy CB */ @@ -1462,6 +1495,8 @@ void mgcp_free_endp(struct mgcp_endpoint *endp) talloc_free(endp->local_options.string); endp->local_options.string = NULL; + talloc_free(endp->local_options.codec); + endp->local_options.codec = NULL; mgcp_rtp_end_reset(&endp->bts_end); mgcp_rtp_end_reset(&endp->net_end); |