]> git.ipfire.org Git - thirdparty/asterisk.git/commitdiff
Merge of several needed fixes for 1.8-digiumphones
authorMatthew Jordan <mjordan@digium.com>
Thu, 12 Apr 2012 18:47:16 +0000 (18:47 +0000)
committerMatthew Jordan <mjordan@digium.com>
Thu, 12 Apr 2012 18:47:16 +0000 (18:47 +0000)
This merges fixes for the following issues into the 1.8-digiumphones branch:
 * ASTERISK-19355 - Call transfer with consultation frequently fails in cross-
   linked Asterisk scenario (directmedia & sendrpid active)
 * ASTERISK 19365 - Remote SIP Call legs are frequently not released in a
   cross-linked Asterisk scenario (directmedia & sendrpid)
 * ASTERISK-19183 - Sporadically missing connectedline event to caller channel
   in directed pickup app

git-svn-id: https://origsvn.digium.com/svn/asterisk/branches/1.8-digiumphones@362042 65c4cc65-6c06-0410-ace0-fbb531ad65f3

channels/chan_sip.c
main/features.c

index 2c94c021ec71da5c34824277a90fbea064096270..09195fa05ffcd7125eea345fb2051813025da6dc 100644 (file)
@@ -12238,7 +12238,7 @@ static int transmit_invite(struct sip_pvt *p, int sipmethod, int sdp, int init,
                /* If init=1, we should not generate a new branch. If it's 0, we need a new branch. */
                reqprep(&req, p, sipmethod, 0, init ? 0 : 1);
        }
-               
+
        if (p->options && p->options->auth) {
                add_header(&req, p->options->authheader, p->options->auth);
        }
@@ -13060,7 +13060,7 @@ static void update_connectedline(struct sip_pvt *p, const void *data, size_t dat
        if (p->owner->_state == AST_STATE_UP || ast_test_flag(&p->flags[0], SIP_OUTGOING)) {
                struct sip_request req;
 
-               if (p->invitestate == INV_CONFIRMED || p->invitestate == INV_TERMINATED) {
+               if (!p->pendinginvite && (p->invitestate == INV_CONFIRMED || p->invitestate == INV_TERMINATED)) {
                        reqprep(&req, p, ast_test_flag(&p->flags[0], SIP_REINVITE_UPDATE) ? SIP_UPDATE : SIP_INVITE, 0, 1);
 
                        add_header(&req, "Allow", ALLOWED_METHODS);
@@ -20048,6 +20048,10 @@ static void check_pendings(struct sip_pvt *p)
                if (p->invitestate == INV_PROCEEDING || p->invitestate == INV_EARLY_MEDIA) {
                        p->invitestate = INV_CANCELLED;
                        transmit_request(p, SIP_CANCEL, p->lastinvite, XMIT_RELIABLE, FALSE);
+                       /* If the cancel occurred on an initial invite, cancel the pending BYE */
+                       if (!ast_test_flag(&p->flags[1], SIP_PAGE2_DIALOG_ESTABLISHED)) {
+                               ast_clear_flag(&p->flags[0], SIP_PENDINGBYE);
+                       }
                        /* Actually don't destroy us yet, wait for the 487 on our original
                           INVITE, but do set an autodestruct just in case we never get it. */
                } else {
@@ -20061,8 +20065,8 @@ static void check_pendings(struct sip_pvt *p)
                        }
                        /* Perhaps there is an SD change INVITE outstanding */
                        transmit_request_with_auth(p, SIP_BYE, 0, XMIT_RELIABLE, TRUE);
+                       ast_clear_flag(&p->flags[0], SIP_PENDINGBYE);
                }
-               ast_clear_flag(&p->flags[0], SIP_PENDINGBYE);   
                sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT);
        } else if (ast_test_flag(&p->flags[0], SIP_NEEDREINVITE)) {
                /* if we can't REINVITE, hold it for later */
@@ -20224,7 +20228,7 @@ static void handle_response_invite(struct sip_pvt *p, int resp, const char *rest
        int outgoing = ast_test_flag(&p->flags[0], SIP_OUTGOING);
        int res = 0;
        int xmitres = 0;
-       int reinvite = (p->owner && p->owner->_state == AST_STATE_UP);
+       int reinvite = ast_test_flag(&p->flags[1], SIP_PAGE2_DIALOG_ESTABLISHED);
        char *p_hdrval;
        int rtn;
        struct ast_party_connected_line connected;
@@ -20414,10 +20418,11 @@ static void handle_response_invite(struct sip_pvt *p, int resp, const char *rest
                p->authtries = 0;
                if (find_sdp(req)) {
                        if ((res = process_sdp(p, req, SDP_T38_ACCEPT)) && !req->ignore)
-                               if (!reinvite)
+                               if (!reinvite) {
                                        /* This 200 OK's SDP is not acceptable, so we need to ack, then hangup */
                                        /* For re-invites, we try to recover */
                                        ast_set_flag(&p->flags[0], SIP_PENDINGBYE);
+                               }
                        ast_rtp_instance_activate(p->rtp);
                }
 
@@ -20461,9 +20466,9 @@ static void handle_response_invite(struct sip_pvt *p, int resp, const char *rest
                        update_call_counter(p, DEC_CALL_RINGING);
                        parse_ok_contact(p, req);
                        /* Save Record-Route for any later requests we make on this dialogue */
-                       if (!reinvite)
+                       if (!reinvite) {
                                build_route(p, req, 1, resp);
-
+                       }
                        if(set_address_from_contact(p)) {
                                /* Bad contact - we don't know how to reach this device */
                                /* We need to ACK, but then send a bye */
@@ -20611,6 +20616,7 @@ static void handle_response_invite(struct sip_pvt *p, int resp, const char *rest
                        update_call_counter(p, DEC_CALL_LIMIT);
                        append_history(p, "Hangup", "Got 487 on CANCEL request from us on call without owner. Killing this dialog.");
                }
+               check_pendings(p);
                sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT);
                break;
        case 415: /* Unsupported media type */
@@ -21308,8 +21314,9 @@ static void handle_response(struct sip_pvt *p, int resp, const char *rest, struc
        }
 
        /* If this is a NOTIFY for a subscription clear the flag that indicates that we have a NOTIFY pending */
-       if (!p->owner && sipmethod == SIP_NOTIFY && p->pendinginvite)
+       if (!p->owner && sipmethod == SIP_NOTIFY && p->pendinginvite) {
                p->pendinginvite = 0;
+       }
 
        /* Get their tag if we haven't already */
        if (ast_strlen_zero(p->theirtag) || (resp >= 200)) {
index a79aab2229ae38a18d095bbee8cc70fa092098b2..2dda95f1b92a805fb4bff3d774c2ad1de82aafa2 100644 (file)
@@ -7314,8 +7314,6 @@ int ast_do_pickup(struct ast_channel *chan, struct ast_channel *target)
        ast_connected_line_copy_from_caller(&connected_caller, &chan->caller);
        ast_channel_unlock(chan);
        connected_caller.source = AST_CONNECTED_LINE_UPDATE_SOURCE_ANSWER;
-       ast_channel_queue_connected_line_update(chan, &connected_caller, NULL);
-       ast_party_connected_line_free(&connected_caller);
 
        ast_cel_report_event(target, AST_CEL_PICKUP, NULL, NULL, chan);
 
@@ -7329,6 +7327,8 @@ int ast_do_pickup(struct ast_channel *chan, struct ast_channel *target)
                goto pickup_failed;
        }
        
+       ast_channel_queue_connected_line_update(chan, &connected_caller, NULL);
+
        /* setting this flag to generate a reason header in the cancel message to the ringing channel */
        ast_set_flag(chan, AST_FLAG_ANSWERED_ELSEWHERE);
 
@@ -7353,6 +7353,7 @@ pickup_failed:
        if (!ast_channel_datastore_remove(target, ds_pickup)) {
                ast_datastore_free(ds_pickup);
        }
+       ast_party_connected_line_free(&connected_caller);
 
        return res;
 }