Merged revisions 340971 via svnmerge from
authorKinsey Moore <kmoore@digium.com>
Fri, 14 Oct 2011 20:51:19 +0000 (20:51 +0000)
committerKinsey Moore <kmoore@digium.com>
Fri, 14 Oct 2011 20:51:19 +0000 (20:51 +0000)
https://origsvn.digium.com/svn/asterisk/branches/10

................
  r340971 | kmoore | 2011-10-14 15:50:37 -0500 (Fri, 14 Oct 2011) | 15 lines

  Merged revisions 340970 via svnmerge from
  https://origsvn.digium.com/svn/asterisk/branches/1.8

  ........
    r340970 | kmoore | 2011-10-14 15:49:39 -0500 (Fri, 14 Oct 2011) | 8 lines

    Quiet RTCP Receiver Reports during fax transmission

    RTCP is now disabled for "inactive" RTP audio streams during SIP T.38 sessions.
    The ability to disable RTCP streams in res_rtp_asterisk was missing, so this
    code was added to support the bug fix.

    (closes issue ASTERISK-18400)
  ........
................

git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@340972 65c4cc65-6c06-0410-ace0-fbb531ad65f3

channels/chan_sip.c
res/res_rtp_asterisk.c

index 2d340f7..ff96898 100644 (file)
@@ -9127,6 +9127,9 @@ static int process_sdp(struct sip_pvt *p, struct sip_request *req, int t38action
                        }
 
                        ast_rtp_codecs_payloads_copy(&newaudiortp, ast_rtp_instance_get_codecs(p->rtp), p->rtp);
+                       /* Ensure RTCP is enabled since it may be inactive
+                          if we're coming back from a T.38 session */
+                       ast_rtp_instance_set_prop(p->rtp, AST_RTP_PROPERTY_RTCP, 1);
 
                        if (ast_test_flag(&p->flags[0], SIP_DTMF) == SIP_DTMF_AUTO) {
                                ast_clear_flag(&p->flags[0], SIP_DTMF);
@@ -9143,6 +9146,8 @@ static int process_sdp(struct sip_pvt *p, struct sip_request *req, int t38action
                } else if (udptlportno > 0) {
                        if (debug)
                                ast_verbose("Got T.38 Re-invite without audio. Keeping RTP active during T.38 session.\n");
+                       /* Silence RTCP while audio RTP is inactive */
+                       ast_rtp_instance_set_prop(p->rtp, AST_RTP_PROPERTY_RTCP, 0);
                } else {
                        ast_rtp_instance_stop(p->rtp);
                        if (debug)
index 4621d2c..aaa31c3 100644 (file)
@@ -2382,44 +2382,65 @@ static void ast_rtp_prop_set(struct ast_rtp_instance *instance, enum ast_rtp_pro
        struct ast_rtp *rtp = ast_rtp_instance_get_data(instance);
 
        if (property == AST_RTP_PROPERTY_RTCP) {
-               if (rtp->rtcp) {
-                       ast_debug(1, "Ignoring duplicate RTCP property on RTP instance '%p'\n", instance);
-                       return;
-               }
-               if (!(rtp->rtcp = ast_calloc(1, sizeof(*rtp->rtcp)))) {
-                       return;
-               }
+               if (value) {
+                       if (rtp->rtcp) {
+                               ast_debug(1, "Ignoring duplicate RTCP property on RTP instance '%p'\n", instance);
+                               return;
+                       }
+                       /* Setup RTCP to be activated on the next RTP write */
+                       if (!(rtp->rtcp = ast_calloc(1, sizeof(*rtp->rtcp)))) {
+                               return;
+                       }
 
-               /* Grab the IP address and port we are going to use */
-               ast_rtp_instance_get_local_address(instance, &rtp->rtcp->us);
-               ast_sockaddr_set_port(&rtp->rtcp->us,
-                                     ast_sockaddr_port(&rtp->rtcp->us) + 1);
-
-               if ((rtp->rtcp->s =
-                    create_new_socket("RTCP",
-                                      ast_sockaddr_is_ipv4(&rtp->rtcp->us) ?
-                                      AF_INET :
-                                      ast_sockaddr_is_ipv6(&rtp->rtcp->us) ?
-                                      AF_INET6 : -1)) < 0) {
-                       ast_debug(1, "Failed to create a new socket for RTCP on instance '%p'\n", instance);
-                       ast_free(rtp->rtcp);
-                       rtp->rtcp = NULL;
-                       return;
-               }
+                       /* Grab the IP address and port we are going to use */
+                       ast_rtp_instance_get_local_address(instance, &rtp->rtcp->us);
+                       ast_sockaddr_set_port(&rtp->rtcp->us,
+                                             ast_sockaddr_port(&rtp->rtcp->us) + 1);
+
+                       if ((rtp->rtcp->s =
+                            create_new_socket("RTCP",
+                                              ast_sockaddr_is_ipv4(&rtp->rtcp->us) ?
+                                              AF_INET :
+                                              ast_sockaddr_is_ipv6(&rtp->rtcp->us) ?
+                                              AF_INET6 : -1)) < 0) {
+                               ast_debug(1, "Failed to create a new socket for RTCP on instance '%p'\n", instance);
+                               ast_free(rtp->rtcp);
+                               rtp->rtcp = NULL;
+                               return;
+                       }
 
-               /* Try to actually bind to the IP address and port we are going to use for RTCP, if this fails we have to bail out */
-               if (ast_bind(rtp->rtcp->s, &rtp->rtcp->us)) {
-                       ast_debug(1, "Failed to setup RTCP on RTP instance '%p'\n", instance);
-                       close(rtp->rtcp->s);
-                       ast_free(rtp->rtcp);
-                       rtp->rtcp = NULL;
-                       return;
-               }
+                       /* Try to actually bind to the IP address and port we are going to use for RTCP, if this fails we have to bail out */
+                       if (ast_bind(rtp->rtcp->s, &rtp->rtcp->us)) {
+                               ast_debug(1, "Failed to setup RTCP on RTP instance '%p'\n", instance);
+                               close(rtp->rtcp->s);
+                               ast_free(rtp->rtcp);
+                               rtp->rtcp = NULL;
+                               return;
+                       }
 
-               ast_debug(1, "Setup RTCP on RTP instance '%p'\n", instance);
-               rtp->rtcp->schedid = -1;
+                       ast_debug(1, "Setup RTCP on RTP instance '%p'\n", instance);
+                       rtp->rtcp->schedid = -1;
 
-               return;
+                       return;
+               } else {
+                       if (rtp->rtcp) {
+                               if (rtp->rtcp->schedid > 0) {
+                                       if (!ast_sched_del(rtp->sched, rtp->rtcp->schedid)) {
+                                               /* Successfully cancelled scheduler entry. */
+                                               ao2_ref(instance, -1);
+                                       } else {
+                                               /* Unable to cancel scheduler entry */
+                                               ast_debug(1, "Failed to tear down RTCP on RTP instance '%p'\n", instance);
+                                               return;
+                                       }
+                                       rtp->rtcp->schedid = -1;
+                               }
+                               close(rtp->rtcp->s);
+                               ast_free(rtp->rtcp);
+                               rtp->rtcp = NULL;
+                       }
+                       return;
+               }
        }
 
        return;