Merged revisions 294243 via svnmerge from
authorMatthew Nicholson <mnicholson@digium.com>
Mon, 8 Nov 2010 21:04:01 +0000 (21:04 +0000)
committerMatthew Nicholson <mnicholson@digium.com>
Mon, 8 Nov 2010 21:04:01 +0000 (21:04 +0000)
https://origsvn.digium.com/svn/asterisk/branches/1.8

................
  r294243 | mnicholson | 2010-11-08 14:56:30 -0600 (Mon, 08 Nov 2010) | 15 lines

  Merged revisions 294242 via svnmerge from
  https://origsvn.digium.com/svn/asterisk/branches/1.6.2

  ........
    r294242 | mnicholson | 2010-11-08 14:50:21 -0600 (Mon, 08 Nov 2010) | 8 lines

    Go off hold when we get an empty reinvite telling us to.

    (closes issue 0014448)
    Reported by: frawd

    (closes issue #17878)
    Reported by: frawd
  ........
................

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

channels/chan_sip.c

index 42a734f..3753a43 100644 (file)
@@ -8108,6 +8108,35 @@ static int find_sdp(struct sip_request *req)
        return FALSE;
 }
 
+/*! \brief Change hold state for a call */
+static void change_hold_state(struct sip_pvt *dialog, struct sip_request *req, int holdstate, int sendonly)
+{
+       if (sip_cfg.notifyhold && (!holdstate || !ast_test_flag(&dialog->flags[1], SIP_PAGE2_CALL_ONHOLD)))
+               sip_peer_hold(dialog, holdstate);
+       if (sip_cfg.callevents)
+               manager_event(EVENT_FLAG_CALL, "Hold",
+                             "Status: %s\r\n"
+                             "Channel: %s\r\n"
+                             "Uniqueid: %s\r\n",
+                             holdstate ? "On" : "Off",
+                             dialog->owner->name,
+                             dialog->owner->uniqueid);
+       append_history(dialog, holdstate ? "Hold" : "Unhold", "%s", req->data->str);
+       if (!holdstate) {       /* Put off remote hold */
+               ast_clear_flag(&dialog->flags[1], SIP_PAGE2_CALL_ONHOLD);       /* Clear both flags */
+               return;
+       }
+       /* No address for RTP, we're on hold */
+
+       if (sendonly == 1)      /* One directional hold (sendonly/recvonly) */
+               ast_set_flag(&dialog->flags[1], SIP_PAGE2_CALL_ONHOLD_ONEDIR);
+       else if (sendonly == 2) /* Inactive stream */
+               ast_set_flag(&dialog->flags[1], SIP_PAGE2_CALL_ONHOLD_INACTIVE);
+       else
+               ast_set_flag(&dialog->flags[1], SIP_PAGE2_CALL_ONHOLD_ACTIVE);
+       return;
+}
+
 
 static int get_ip_and_port_from_sdp(struct sip_request *req, const enum media_type media, struct ast_sockaddr *addr)
 {
@@ -8745,20 +8774,8 @@ static int process_sdp(struct sip_pvt *p, struct sip_request *req, int t38action
                ast_queue_control(p->owner, AST_CONTROL_UNHOLD);
                /* Activate a re-invite */
                ast_queue_frame(p->owner, &ast_null_frame);
-               /* Queue Manager Unhold event */
-               append_history(p, "Unhold", "%s", req->data->str);
-               if (sip_cfg.callevents)
-                       ast_manager_event(p->owner, EVENT_FLAG_CALL, "Hold",
-                                     "Status: Off\r\n"
-                                     "Channel: %s\r\n"
-                                     "Uniqueid: %s\r\n",
-                                     p->owner->name,
-                                     p->owner->uniqueid);
-               if (sip_cfg.notifyhold)
-                       sip_peer_hold(p, FALSE);
-               ast_clear_flag(&p->flags[1], SIP_PAGE2_CALL_ONHOLD); /* Clear both flags */
+               change_hold_state(p, req, FALSE, sendonly);
        } else if ((ast_sockaddr_isnull(sa) && ast_sockaddr_isnull(vsa) && ast_sockaddr_isnull(tsa) && ast_sockaddr_isnull(isa)) || (sendonly && sendonly != -1)) {
-               int already_on_hold = ast_test_flag(&p->flags[1], SIP_PAGE2_CALL_ONHOLD);
                ast_queue_control_data(p->owner, AST_CONTROL_HOLD,
                                       S_OR(p->mohsuggest, NULL),
                                       !ast_strlen_zero(p->mohsuggest) ? strlen(p->mohsuggest) + 1 : 0);
@@ -8767,24 +8784,7 @@ static int process_sdp(struct sip_pvt *p, struct sip_request *req, int t38action
                /* RTCP needs to go ahead, even if we're on hold!!! */
                /* Activate a re-invite */
                ast_queue_frame(p->owner, &ast_null_frame);
-               /* Queue Manager Hold event */
-               append_history(p, "Hold", "%s", req->data->str);
-               if (sip_cfg.callevents && !ast_test_flag(&p->flags[1], SIP_PAGE2_CALL_ONHOLD)) {
-                       ast_manager_event(p->owner, EVENT_FLAG_CALL, "Hold",
-                                     "Status: On\r\n"
-                                     "Channel: %s\r\n"
-                                     "Uniqueid: %s\r\n",
-                                     p->owner->name,
-                                     p->owner->uniqueid);
-               }
-               if (sendonly == 1)      /* One directional hold (sendonly/recvonly) */
-                       ast_set_flag(&p->flags[1], SIP_PAGE2_CALL_ONHOLD_ONEDIR);
-               else if (sendonly == 2) /* Inactive stream */
-                       ast_set_flag(&p->flags[1], SIP_PAGE2_CALL_ONHOLD_INACTIVE);
-               else
-                       ast_set_flag(&p->flags[1], SIP_PAGE2_CALL_ONHOLD_ACTIVE);
-               if (sip_cfg.notifyhold && !already_on_hold)
-                       sip_peer_hold(p, TRUE);
+               change_hold_state(p, req, TRUE, sendonly);
        }
        
        return 0;
@@ -21364,6 +21364,15 @@ static int handle_request_invite(struct sip_pvt *p, struct sip_request *req, int
                        } else {
                                p->jointcapability = p->capability;
                                ast_debug(1, "Hm....  No sdp for the moment\n");
+                               /* Some devices signal they want to be put off hold by sending a re-invite
+                                  *without* an SDP, which is supposed to mean "Go back to your state"
+                                  and since they put os on remote hold, we go back to off hold */
+                               if (ast_test_flag(&p->flags[1], SIP_PAGE2_CALL_ONHOLD)) {
+                                       ast_queue_control(p->owner, AST_CONTROL_UNHOLD);
+                                       /* Activate a re-invite */
+                                       ast_queue_frame(p->owner, &ast_null_frame);
+                                       change_hold_state(p, req, FALSE, 0);
+                               }
                        }
                        if (p->do_history) /* This is a response, note what it was for */
                                append_history(p, "ReInv", "Re-invite received");