aboutsummaryrefslogtreecommitdiffstats
path: root/openbsc/src/libmgcp/mgcp_protocol.c
diff options
context:
space:
mode:
authorJacob Erlbeck <jerlbeck@sysmocom.de>2013-12-10 13:09:37 +0100
committerHolger Hans Peter Freyther <holger@moiji-mobile.com>2013-12-13 13:49:32 +0100
commit24754f0490b0f77fca4110402bbff08603a29360 (patch)
treee56020ed200cd99993d581c56b1ee2d668e58c1a /openbsc/src/libmgcp/mgcp_protocol.c
parent2c2ca4df382110c4bebdb91d7410838fbf20d493 (diff)
mgcp: Parse SDP to get rate and packet duration
This patch parses the 'ptime' and 'maxptime' SDP attributes, and the SDP rate information and sets up packet_duration_ms accordingly. If the packet duration is unknown or allows for different values (e.g. because 'ptime' uses a range or 'maxptime' allows for more than one frame) the duration is set to 0. Sponsored-by: On-Waves ehf
Diffstat (limited to 'openbsc/src/libmgcp/mgcp_protocol.c')
-rw-r--r--openbsc/src/libmgcp/mgcp_protocol.c53
1 files changed, 47 insertions, 6 deletions
diff --git a/openbsc/src/libmgcp/mgcp_protocol.c b/openbsc/src/libmgcp/mgcp_protocol.c
index c4ff757c3..b8d192043 100644
--- a/openbsc/src/libmgcp/mgcp_protocol.c
+++ b/openbsc/src/libmgcp/mgcp_protocol.c
@@ -562,25 +562,64 @@ static int parse_sdp_data(struct mgcp_rtp_end *rtp, struct mgcp_parse_data *p)
{
char *line;
int found_media = 0;
+ int audio_payload = -1;
for_each_line(line, p->save) {
switch (line[0]) {
- case 'a':
case 'o':
case 's':
case 't':
case 'v':
/* skip these SDP attributes */
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",
+ &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));
+ } else if (sscanf(line, "a=ptime:%d-%d",
+ &ptime, &ptime2) >= 1) {
+ if (ptime2 > 0 && ptime2 != ptime)
+ rtp->packet_duration_ms = 0;
+ else
+ rtp->packet_duration_ms = ptime;
+ } else if (sscanf(line, "a=maxptime:%d", &ptime2) == 1) {
+ if (ptime2 * rtp->frame_duration_den >
+ rtp->frame_duration_num * 1500)
+ /* more than 1 frame */
+ rtp->packet_duration_ms = 0;
+ }
+ break;
+ }
case 'm': {
int port;
- int payload;
+ audio_payload = -1;
if (sscanf(line, "m=audio %d RTP/AVP %d",
- &port, &payload) == 2) {
+ &port, &audio_payload) == 2) {
rtp->rtp_port = htons(port);
rtp->rtcp_port = htons(port + 1);
- rtp->payload_type = payload;
+ rtp->payload_type = audio_payload;
found_media = 1;
}
break;
@@ -608,8 +647,10 @@ static int parse_sdp_data(struct mgcp_rtp_end *rtp, struct mgcp_parse_data *p)
if (found_media)
LOGP(DMGCP, LOGL_NOTICE,
- "Got media info via SDP: port %d, payload %d, addr %s\n",
- ntohs(rtp->rtp_port), rtp->payload_type, inet_ntoa(rtp->addr));
+ "Got media info via SDP: port %d, payload %d, "
+ "duration %d, addr %s\n",
+ ntohs(rtp->rtp_port), rtp->payload_type,
+ rtp->packet_duration_ms, inet_ntoa(rtp->addr));
return found_media;
}