Currently the SDP 'ptime' media attribute is never set in generated
MGCP responses.

This patch optionally includes the 'ptime' attribute if
packet_duration_ms is != 0. This behaviour can be enabled/disabled
by using the VTY command "sdp audio-payload send-ptime" (enabled by
default).

Sponsored-by: On-Waves ehf
---
 openbsc/include/openbsc/mgcp.h      |    1 +
 openbsc/src/libmgcp/mgcp_protocol.c |   23 +++++++++++++++-
 openbsc/src/libmgcp/mgcp_vty.c      |   50 +++++++++++++++++++++++++++++++++++
 openbsc/tests/mgcp/mgcp_test.c      |   20 +++++++++++---
 4 files changed, 89 insertions(+), 5 deletions(-)

diff --git a/openbsc/include/openbsc/mgcp.h b/openbsc/include/openbsc/mgcp.h
index 8ab52ce..0d64590 100644
--- a/openbsc/include/openbsc/mgcp.h
+++ b/openbsc/include/openbsc/mgcp.h
@@ -114,6 +114,7 @@ struct mgcp_trunk_config {
        char *audio_fmtp_extra;
        char *audio_name;
        int audio_payload;
+       int audio_send_ptime;
        int audio_loop;
 
        int omit_rtcp;
diff --git a/openbsc/src/libmgcp/mgcp_protocol.c 
b/openbsc/src/libmgcp/mgcp_protocol.c
index b9e1382..f632149 100644
--- a/openbsc/src/libmgcp/mgcp_protocol.c
+++ b/openbsc/src/libmgcp/mgcp_protocol.c
@@ -230,11 +230,12 @@ 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;
        char sdp_record[4096];
+       int len;
 
        if (!addr)
                addr = endp->cfg->source_addr;
 
-       snprintf(sdp_record, sizeof(sdp_record) - 1,
+       len = snprintf(sdp_record, sizeof(sdp_record) - 1,
                        "I: %u\n\n"
                        "v=0\r\n"
                        "o=- %u 23 IN IP4 %s\r\n"
@@ -247,7 +248,25 @@ static struct msgb *create_response_with_sdp(struct 
mgcp_endpoint *endp,
                        endp->net_end.local_port, endp->bts_end.payload_type,
                        endp->bts_end.payload_type, endp->tcfg->audio_name,
                        fmtp_extra ? fmtp_extra : "", fmtp_extra ? "\r\n" : "");
+
+       if (len < 0 || len >= sizeof(sdp_record))
+               goto buffer_too_small;
+
+       if (endp->bts_end.packet_duration_ms > 0 && 
endp->tcfg->audio_send_ptime) {
+               int nchars = snprintf(sdp_record + len, sizeof(sdp_record) - 
len,
+                                     "a=ptime:%d\r\n",
+                                     endp->bts_end.packet_duration_ms);
+               if (nchars < 0 || nchars >= sizeof(sdp_record) - len)
+                       goto buffer_too_small;
+
+               len += nchars;
+       }
        return create_resp(endp, 200, " OK", msg, trans_id, NULL, sdp_record);
+
+buffer_too_small:
+       LOGP(DMGCP, LOGL_ERROR, "SDP buffer too small: %d (needed %d)\n",
+            sizeof(sdp_record), len);
+       return NULL;
 }
 
 /*
@@ -1113,6 +1132,7 @@ struct mgcp_config *mgcp_config_alloc(void)
        cfg->trunk.trunk_type = MGCP_TRUNK_VIRTUAL;
        cfg->trunk.audio_name = talloc_strdup(cfg, "AMR/8000");
        cfg->trunk.audio_payload = 126;
+       cfg->trunk.audio_send_ptime = 1;
        cfg->trunk.omit_rtcp = 0;
 
        INIT_LLIST_HEAD(&cfg->trunks);
@@ -1135,6 +1155,7 @@ struct mgcp_trunk_config *mgcp_trunk_alloc(struct 
mgcp_config *cfg, int nr)
        trunk->trunk_nr = nr;
        trunk->audio_name = talloc_strdup(cfg, "AMR/8000");
        trunk->audio_payload = 126;
+       trunk->audio_send_ptime = 1;
        trunk->number_endpoints = 33;
        trunk->omit_rtcp = 0;
        llist_add_tail(&trunk->entry, &cfg->trunks);
diff --git a/openbsc/src/libmgcp/mgcp_vty.c b/openbsc/src/libmgcp/mgcp_vty.c
index e48b050..235b8bd 100644
--- a/openbsc/src/libmgcp/mgcp_vty.c
+++ b/openbsc/src/libmgcp/mgcp_vty.c
@@ -105,6 +105,8 @@ static int config_write_mgcp(struct vty *vty)
        if (g_cfg->trunk.audio_fmtp_extra)
                vty_out(vty, "  sdp audio fmtp-extra %s%s",
                        g_cfg->trunk.audio_fmtp_extra, VTY_NEWLINE);
+       vty_out(vty, "  %ssdp audio-payload send-ptime%s",
+               g_cfg->trunk.audio_send_ptime ? "" : "no ", VTY_NEWLINE);
        vty_out(vty, "  loop %u%s", !!g_cfg->trunk.audio_loop, VTY_NEWLINE);
        vty_out(vty, "  number endpoints %u%s", g_cfg->trunk.number_endpoints - 
1, VTY_NEWLINE);
        if (g_cfg->call_agent_addr)
@@ -391,6 +393,26 @@ ALIAS_DEPRECATED(cfg_mgcp_sdp_payload_name, 
cfg_mgcp_sdp_payload_name_cmd_old,
       "sdp audio payload name NAME",
       SDP_STR AUDIO_STR AUDIO_STR "Name\n" "Payload name\n")
 
+DEFUN(cfg_mgcp_sdp_payload_send_ptime,
+      cfg_mgcp_sdp_payload_send_ptime_cmd,
+      "sdp audio-payload send-ptime",
+      SDP_STR AUDIO_STR
+      "Send SDP ptime (packet duration) attribute\n")
+{
+       g_cfg->trunk.audio_send_ptime = 1;
+       return CMD_SUCCESS;
+}
+
+DEFUN(cfg_mgcp_no_sdp_payload_send_ptime,
+      cfg_mgcp_no_sdp_payload_send_ptime_cmd,
+      "no sdp audio-payload send-ptime",
+      NO_STR SDP_STR AUDIO_STR
+      "Send SDP ptime (packet duration) attribute\n")
+{
+       g_cfg->trunk.audio_send_ptime = 0;
+       return CMD_SUCCESS;
+}
+
 DEFUN(cfg_mgcp_loop,
       cfg_mgcp_loop_cmd,
       "loop (0|1)",
@@ -568,6 +590,8 @@ static int config_write_trunk(struct vty *vty)
                        trunk->audio_payload, VTY_NEWLINE);
                vty_out(vty, "  sdp audio-payload name %s%s",
                        trunk->audio_name, VTY_NEWLINE);
+               vty_out(vty, "  %ssdp audio-payload send-ptime%s",
+                       trunk->audio_send_ptime ? "" : "no ", VTY_NEWLINE);
                vty_out(vty, "  loop %d%s",
                        trunk->audio_loop, VTY_NEWLINE);
                if (trunk->omit_rtcp)
@@ -649,6 +673,28 @@ DEFUN(cfg_trunk_loop,
        return CMD_SUCCESS;
 }
 
+DEFUN(cfg_trunk_sdp_payload_send_ptime,
+      cfg_trunk_sdp_payload_send_ptime_cmd,
+      "sdp audio-payload send-ptime",
+      SDP_STR AUDIO_STR
+      "Send SDP ptime (packet duration) attribute\n")
+{
+       struct mgcp_trunk_config *trunk = vty->index;
+       trunk->audio_send_ptime = 1;
+       return CMD_SUCCESS;
+}
+
+DEFUN(cfg_trunk_no_sdp_payload_send_ptime,
+      cfg_trunk_no_sdp_payload_send_ptime_cmd,
+      "no sdp audio-payload send-ptime",
+      NO_STR SDP_STR AUDIO_STR
+      "Send SDP ptime (packet duration) attribute\n")
+{
+       struct mgcp_trunk_config *trunk = vty->index;
+       trunk->audio_send_ptime = 0;
+       return CMD_SUCCESS;
+}
+
 DEFUN(cfg_trunk_omit_rtcp,
       cfg_trunk_omit_rtcp_cmd,
       "rtcp-omit",
@@ -966,6 +1012,8 @@ int mgcp_vty_init(void)
        install_element(MGCP_NODE, &cfg_mgcp_no_patch_rtp_ts_cmd);
        install_element(MGCP_NODE, &cfg_mgcp_no_patch_rtp_cmd);
        install_element(MGCP_NODE, &cfg_mgcp_sdp_fmtp_extra_cmd);
+       install_element(MGCP_NODE, &cfg_mgcp_sdp_payload_send_ptime_cmd);
+       install_element(MGCP_NODE, &cfg_mgcp_no_sdp_payload_send_ptime_cmd);
 
        install_element(MGCP_NODE, &cfg_mgcp_trunk_cmd);
        install_node(&trunk_node, config_write_trunk);
@@ -983,6 +1031,8 @@ int mgcp_vty_init(void)
        install_element(TRUNK_NODE, &cfg_trunk_no_patch_rtp_ts_cmd);
        install_element(TRUNK_NODE, &cfg_trunk_no_patch_rtp_cmd);
        install_element(TRUNK_NODE, &cfg_trunk_sdp_fmtp_extra_cmd);
+       install_element(TRUNK_NODE, &cfg_trunk_sdp_payload_send_ptime_cmd);
+       install_element(TRUNK_NODE, &cfg_trunk_no_sdp_payload_send_ptime_cmd);
 
        return 0;
 }
diff --git a/openbsc/tests/mgcp/mgcp_test.c b/openbsc/tests/mgcp/mgcp_test.c
index 8768426..2e2dfe7 100644
--- a/openbsc/tests/mgcp/mgcp_test.c
+++ b/openbsc/tests/mgcp/mgcp_test.c
@@ -81,7 +81,8 @@ static void test_strline(void)
                 "c=IN IP4 0.0.0.0\r\n"         \
                 "t=0 0\r\n"                    \
                 "m=audio 0 RTP/AVP 126\r\n"    \
-                "a=rtpmap:126 AMR/8000\r\n"
+                "a=rtpmap:126 AMR/8000\r\n"    \
+                "a=ptime:20\r\n"
 #define MDCX4 "MDCX 18983216 1@mgw MGCP 1.0\r\n" \
                 "C: 2\r\n"          \
                 "I: 1\r\n"                    \
@@ -102,7 +103,8 @@ static void test_strline(void)
                 "c=IN IP4 0.0.0.0\r\n"         \
                 "t=0 0\r\n"                    \
                 "m=audio 0 RTP/AVP 126\r\n"    \
-                "a=rtpmap:126 AMR/8000\r\n"
+                "a=rtpmap:126 AMR/8000\r\n"    \
+                "a=ptime:20\r\n"
 
 #define MDCX4_PT1 "MDCX 18983217 1@mgw MGCP 1.0\r\n" \
                 "C: 2\r\n"          \
@@ -168,7 +170,8 @@ static void test_strline(void)
                 "c=IN IP4 0.0.0.0\r\n"         \
                 "t=0 0\r\n"                    \
                 "m=audio 0 RTP/AVP 126\r\n"    \
-                "a=rtpmap:126 AMR/8000\r\n"
+                "a=rtpmap:126 AMR/8000\r\n"    \
+                "a=ptime:20\r\n"
 
 #define CRCX_ZYN "CRCX 2 1@mgw MGCP 1.0\r"     \
                 "M: sendrecv\r"                \
@@ -186,7 +189,8 @@ static void test_strline(void)
                 "c=IN IP4 0.0.0.0\r\n"         \
                 "t=0 0\r\n"                    \
                 "m=audio 0 RTP/AVP 126\r\n"    \
-                "a=rtpmap:126 AMR/8000\r\n"
+                "a=rtpmap:126 AMR/8000\r\n"    \
+                "a=ptime:20\r\n"
 
 #define DLCX    "DLCX 7 1@mgw MGCP 1.0\r\n"    \
                 "C: 2\r\n"
@@ -290,6 +294,7 @@ static void test_messages(void)
                endp = &cfg->trunk.endpoints[i];
                endp->net_end.payload_type = PTYPE_NONE;
                endp->net_end.packet_duration_ms = -1;
+               endp->bts_end.packet_duration_ms = 20;
        }
 
        for (i = 0; i < ARRAY_SIZE(tests); i++) {
@@ -371,6 +376,13 @@ static void test_retransmission(void)
 
        mgcp_endpoints_allocate(mgcp_trunk_alloc(cfg, 1));
 
+       /* reset endpoints */
+       for (i = 0; i < cfg->trunk.number_endpoints; i++) {
+               struct mgcp_endpoint *endp;
+               endp = &cfg->trunk.endpoints[i];
+               endp->bts_end.packet_duration_ms = 20;
+       }
+
        for (i = 0; i < ARRAY_SIZE(retransmit); i++) {
                const struct mgcp_test *t = &retransmit[i];
                struct msgb *inp;
-- 
1.7.9.5


Reply via email to