]> git.ipfire.org Git - thirdparty/asterisk.git/commitdiff
- handle re-invites properly in sip_hangup()
authorOlle Johansson <oej@edvina.net>
Tue, 9 Jan 2007 11:25:20 +0000 (11:25 +0000)
committerOlle Johansson <oej@edvina.net>
Tue, 9 Jan 2007 11:25:20 +0000 (11:25 +0000)
- Add some invitestate status changes just to be sure

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

channels/chan_sip.c

index 89651fffc03e4ce2a24370ecb8be630ce00784c4..b9de083f13f8fa31f88d2891daeb77e7d6f587e5 100644 (file)
@@ -3285,7 +3285,7 @@ static int sip_hangup(struct ast_channel *ast)
                return 0;
        }
        /* If the call is not UP, we need to send CANCEL instead of BYE */
-       if (ast->_state == AST_STATE_RING || ast->_state == AST_STATE_RINGING || p->invitestate < INV_COMPLETED) {
+       if (ast->_state == AST_STATE_RING || ast->_state == AST_STATE_RINGING || (p->invitestate < INV_COMPLETED && ast->_state != AST_STATE_UP)) {
                needcancel = TRUE;
                if (option_debug > 3)
                        ast_log(LOG_DEBUG, "Hanging up channel in state %s (not UP)\n", ast_state2str(ast->_state));
@@ -3643,7 +3643,7 @@ static int sip_indicate(struct ast_channel *ast, int condition, const void *data
        case AST_CONTROL_BUSY:
                if (ast->_state != AST_STATE_UP) {
                        transmit_response(p, "486 Busy Here", &p->initreq);
-                       p->invitestate = INV_TERMINATED;
+                       p->invitestate = INV_COMPLETED;
                        sip_alreadygone(p);
                        ast_softhangup_nolock(ast, AST_SOFTHANGUP_DEV);
                        break;
@@ -3653,7 +3653,7 @@ static int sip_indicate(struct ast_channel *ast, int condition, const void *data
        case AST_CONTROL_CONGESTION:
                if (ast->_state != AST_STATE_UP) {
                        transmit_response(p, "503 Service Unavailable", &p->initreq);
-                       p->invitestate = INV_TERMINATED;
+                       p->invitestate = INV_COMPLETED;
                        sip_alreadygone(p);
                        ast_softhangup_nolock(ast, AST_SOFTHANGUP_DEV);
                        break;
@@ -13059,6 +13059,7 @@ static int handle_request_invite(struct sip_pvt *p, struct sip_request *req, int
                        /* At this point we only support REPLACES */
                        transmit_response_with_unsupported(p, "420 Bad extension (unsupported)", req, required);
                        ast_log(LOG_WARNING,"Received SIP INVITE with unsupported required extension: %s\n", required);
+                       p->invitestate = INV_COMPLETED;
                        if (!p->lastinvite)
                                sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT);
                        return -1;
@@ -13073,6 +13074,7 @@ static int handle_request_invite(struct sip_pvt *p, struct sip_request *req, int
                /* If pedantic is on, we need to check the tags. If they're different, this is
                in fact a forked call through a SIP proxy somewhere. */
                transmit_response(p, "482 Loop Detected", req);
+               p->invitestate = INV_COMPLETED;
                sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT);
                return 0;
        }
@@ -13113,6 +13115,7 @@ static int handle_request_invite(struct sip_pvt *p, struct sip_request *req, int
                        transmit_response(p, "500 Server Internal Error", req);
                        append_history(p, "Xfer", "INVITE/Replace Failed. Out of memory.");
                        sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT);
+                       p->invitestate = INV_COMPLETED;
                        return -1;
                }
 
@@ -13186,6 +13189,7 @@ static int handle_request_invite(struct sip_pvt *p, struct sip_request *req, int
                                ast_mutex_unlock(&p->refer->refer_call->lock);
                                ast_channel_unlock(p->refer->refer_call->owner);
                        }
+                       p->invitestate = INV_COMPLETED;
                        return -1;
                }
        }
@@ -13236,6 +13240,7 @@ static int handle_request_invite(struct sip_pvt *p, struct sip_request *req, int
                /* Handle authentication if this is our first invite */
                res = check_user(p, req, SIP_INVITE, e, XMIT_RELIABLE, sin);
                if (res == AUTH_CHALLENGE_SENT)
+                       p->invitestate = INV_COMPLETED;         /* Needs to restart in another INVITE transaction */
                        return 0; 
                if (res < 0) { /* Something failed in authentication */
                        if (res == AUTH_FAKE_AUTH) {
@@ -13245,6 +13250,7 @@ static int handle_request_invite(struct sip_pvt *p, struct sip_request *req, int
                                ast_log(LOG_NOTICE, "Failed to authenticate user %s\n", get_header(req, "From"));
                                transmit_response_reliable(p, "403 Forbidden", req);
                        }
+                       p->invitestate = INV_COMPLETED; 
                        sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT);
                        ast_string_field_free(p, theirtag);
                        return 0;
@@ -13255,6 +13261,7 @@ static int handle_request_invite(struct sip_pvt *p, struct sip_request *req, int
                        if (process_sdp(p, req)) {
                                /* Unacceptable codecs */
                                transmit_response_reliable(p, "488 Not acceptable here", req);
+                               p->invitestate = INV_COMPLETED; 
                                sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT);
                                if (option_debug)
                                        ast_log(LOG_DEBUG, "No compatible codecs for this SIP call.\n");
@@ -13285,6 +13292,7 @@ static int handle_request_invite(struct sip_pvt *p, struct sip_request *req, int
                                ast_log(LOG_NOTICE, "Failed to place call for user %s, too many calls\n", p->username);
                                transmit_response_reliable(p, "480 Temporarily Unavailable (Call limit) ", req);
                                sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT);
+                               p->invitestate = INV_COMPLETED; 
                        }
                        return 0;
                }
@@ -13303,6 +13311,7 @@ static int handle_request_invite(struct sip_pvt *p, struct sip_request *req, int
                                transmit_response_reliable(p, "484 Address Incomplete", req);
                        else
                                transmit_response_reliable(p, "404 Not Found", req);
+                       p->invitestate = INV_COMPLETED; 
                        update_call_counter(p, DEC_CALL_LIMIT);
                        sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT);
                        return 0;
@@ -13503,6 +13512,7 @@ static int handle_request_invite(struct sip_pvt *p, struct sip_request *req, int
                                                /* No bridged peer with T38 enabled*/
                                        }
                                } 
+                               /* Respond to normal re-invite */
                                if (sendok)
                                        transmit_response_with_sdp(p, "200 OK", req, XMIT_CRITICAL);
 
@@ -14590,7 +14600,7 @@ static int handle_request(struct sip_pvt *p, struct sip_request *req, struct soc
        case SIP_ACK:
                /* Make sure we don't ignore this */
                if (seqno == p->pendinginvite) {
-                       p->invitestate = INV_CONFIRMED;
+                       p->invitestate = INV_TERMINATED;
                        p->pendinginvite = 0;
                        __sip_ack(p, seqno, FLAG_RESPONSE, 0);
                        if (find_sdp(req)) {