This is merely a historical archive of years 2008-2021, before the migration to mailman3.
A maintained and still updated list archive can be found at https://lists.osmocom.org/hyperkitty/list/OpenBSC@lists.osmocom.org/.
Jacob Erlbeck jerlbeck at sysmocom.deThis patch adds the fields channels, subtype_name, and audio_name to the struct. The field audio_name contains the full string that has been used for the last part of a SDP a=rtpmap line. The others contain decoded parts of that string. If no a=rtpmap line has been given (e.g. because dynamic payload types are not used), values are assigned when the payload type matches one of the predefined ones (GSM, G729, PCMA). Sponsored-by: On-Waves ehf --- openbsc/include/openbsc/mgcp_internal.h | 3 ++ openbsc/src/libmgcp/mgcp_protocol.c | 82 +++++++++++++++++++++++-------- 2 files changed, 64 insertions(+), 21 deletions(-) diff --git a/openbsc/include/openbsc/mgcp_internal.h b/openbsc/include/openbsc/mgcp_internal.h index 56c280d..72ac8e9 100644 --- a/openbsc/include/openbsc/mgcp_internal.h +++ b/openbsc/include/openbsc/mgcp_internal.h @@ -81,11 +81,14 @@ struct mgcp_rtp_end { /* per endpoint data */ int payload_type; uint32_t rate; + int channels; uint32_t frame_duration_num; uint32_t frame_duration_den; int frames_per_packet; uint32_t packet_duration_ms; char *fmtp_extra; + char *audio_name; + char *subtype_name; int output_enabled; /* RTP patching */ diff --git a/openbsc/src/libmgcp/mgcp_protocol.c b/openbsc/src/libmgcp/mgcp_protocol.c index 0f8614c..761a35c 100644 --- a/openbsc/src/libmgcp/mgcp_protocol.c +++ b/openbsc/src/libmgcp/mgcp_protocol.c @@ -28,6 +28,7 @@ #include <time.h> #include <limits.h> #include <unistd.h> +#include <errno.h> #include <osmocom/core/msgb.h> #include <osmocom/core/talloc.h> @@ -77,6 +78,7 @@ char *strline_r(char *str, char **saveptr) #define DEFAULT_RTP_AUDIO_FRAME_DUR_DEN 1000 #define DEFAULT_RTP_AUDIO_PACKET_DURATION_MS 20 #define DEFAULT_RTP_AUDIO_DEFAULT_RATE 8000 +#define DEFAULT_RTP_AUDIO_DEFAULT_CHANNELS 1 static void mgcp_rtp_end_reset(struct mgcp_rtp_end *end); @@ -231,6 +233,8 @@ static struct msgb *create_response_with_sdp(struct mgcp_endpoint *endp, { const char *addr = endp->cfg->local_ip; const char *fmtp_extra = endp->bts_end.fmtp_extra; + const char *audio_name = endp->bts_end.audio_name; + int payload_type = endp->bts_end.payload_type; char sdp_record[4096]; int len; @@ -244,11 +248,12 @@ static struct msgb *create_response_with_sdp(struct mgcp_endpoint *endp, "c=IN IP4 %s\r\n" "t=0 0\r\n" "m=audio %d RTP/AVP %d\r\n" - "a=rtpmap:%d %s\r\n" + "a=rtpmap:%d%s%s\r\n" "%s%s", endp->ci, endp->ci, addr, addr, - endp->net_end.local_port, endp->bts_end.payload_type, - endp->bts_end.payload_type, endp->tcfg->audio_name, + endp->net_end.local_port, payload_type, + payload_type, + audio_name ? " " : "", audio_name ? audio_name : "", fmtp_extra ? fmtp_extra : "", fmtp_extra ? "\r\n" : ""); if (len < 0 || len >= sizeof(sdp_record)) @@ -514,6 +519,47 @@ static int parse_conn_mode(const char *msg, struct mgcp_endpoint *endp) return ret; } +static int set_audio_info(struct mgcp_rtp_end *rtp, + int payload_type, const char *audio_name) +{ + int rate = 8000; + int channels = 1; + char audio_codec[64]; + + talloc_free(rtp->subtype_name); + rtp->subtype_name = NULL; + talloc_free(rtp->audio_name); + rtp->audio_name = NULL; + + rtp->payload_type = payload_type; + + if (!audio_name) { + switch (payload_type) { + case 3: audio_name = "GSM/8000/1"; break; + case 8: audio_name = "PCMA/8000/1"; break; + case 18: audio_name = "G729/8000/1"; break; + default: + rtp->rate = 8000; + rtp->channels = 1; + return 0; + } + } + + if (sscanf(audio_name, "%63[^/]/%d/%d", + audio_codec, &rate, &channels) < 2) + return -EINVAL; + + rtp->rate = rate; + rtp->channels = channels; + rtp->subtype_name = talloc_strdup(NULL, audio_codec); + rtp->audio_name = talloc_strdup(NULL, audio_name); + if (channels != 1) + LOGP(DMGCP, LOGL_NOTICE, + "Channels != 1 in SDP: '%s'\n", audio_name); + + return 0; +} + static int allocate_port(struct mgcp_endpoint *endp, struct mgcp_rtp_end *end, struct mgcp_port_range *range, int (*alloc)(struct mgcp_endpoint *endp, int port)) @@ -600,29 +646,18 @@ static int parse_sdp_data(struct mgcp_rtp_end *rtp, struct mgcp_parse_data *p) break; case 'a': { int payload; - int rate; - int channels = 1; int ptime, ptime2 = 0; char audio_name[64]; - char audio_codec[64]; if (audio_payload == -1) break; - if (sscanf(line, "a=rtpmap:%d %64s", + if (sscanf(line, "a=rtpmap:%d %63s", &payload, audio_name) == 2) { if (payload != audio_payload) break; - if (sscanf(audio_name, "%[^/]/%d/%d", - audio_codec, &rate, &channels) < 2) - break; - - rtp->rate = rate; - if (channels != 1) - LOGP(DMGCP, LOGL_NOTICE, - "Channels != 1 in SDP: '%s' on 0x%x\n", - line, ENDPOINT_NUMBER(p->endp)); + set_audio_info(rtp, payload, audio_name); } else if (sscanf(line, "a=ptime:%d-%d", &ptime, &ptime2) >= 1) { if (ptime2 > 0 && ptime2 != ptime) @@ -645,8 +680,8 @@ static int parse_sdp_data(struct mgcp_rtp_end *rtp, struct mgcp_parse_data *p) &port, &audio_payload) == 2) { rtp->rtp_port = htons(port); rtp->rtcp_port = htons(port + 1); - rtp->payload_type = audio_payload; found_media = 1; + set_audio_info(rtp, audio_payload, NULL); } break; } @@ -826,7 +861,7 @@ mgcp_header_done: endp->allocated = 1; /* set up RTP media parameters */ - endp->bts_end.payload_type = tcfg->audio_payload; + set_audio_info(&endp->bts_end, tcfg->audio_payload, tcfg->audio_name); endp->bts_end.fmtp_extra = talloc_strdup(tcfg->endpoints, tcfg->audio_fmtp_extra); if (have_sdp) { @@ -1252,6 +1287,7 @@ static void mgcp_rtp_end_reset(struct mgcp_rtp_end *end) end->frames_per_packet = 0; /* unknown */ end->packet_duration_ms = DEFAULT_RTP_AUDIO_PACKET_DURATION_MS; end->rate = DEFAULT_RTP_AUDIO_DEFAULT_RATE; + end->channels = DEFAULT_RTP_AUDIO_DEFAULT_CHANNELS; end->output_enabled = 0; } @@ -1329,6 +1365,9 @@ static void send_msg(struct mgcp_endpoint *endp, int endpoint, int port, { char buf[2096]; int len; + const char *fmtp_extra = endp->bts_end.fmtp_extra; + const char *audio_name = endp->bts_end.audio_name; + int payload_type = endp->bts_end.payload_type; /* hardcoded to AMR right now, we do not know the real type at this point */ len = snprintf(buf, sizeof(buf), @@ -1338,10 +1377,11 @@ static void send_msg(struct mgcp_endpoint *endp, int endpoint, int port, "\r\n" "c=IN IP4 %s\r\n" "m=audio %d RTP/AVP %d\r\n" - "a=rtpmap:%d %s\r\n", + "a=rtpmap:%d%s%s\r\n", msg, endpoint, mode, endp->cfg->source_addr, - port, endp->tcfg->audio_payload, - endp->tcfg->audio_payload, endp->tcfg->audio_name); + port, payload_type, + payload_type, + audio_name ? " " : "", audio_name ? audio_name : ""); if (len < 0) return; -- 1.7.9.5