Ensure ACK retransmit & hangup on non-200 response to INVITE
[asterisk/asterisk.git] / channels / chan_sip.c
index f26d7d5..548199f 100644 (file)
@@ -20400,7 +20400,7 @@ static void handle_response_invite(struct sip_pvt *p, int resp, const char *rest
         */
        if (!reinvite) {
                set_pvt_allowed_methods(p, req);
-       }               
+       }
 
        switch (resp) {
        case 100:       /* Trying */
@@ -20708,19 +20708,16 @@ static void handle_response_invite(struct sip_pvt *p, int resp, const char *rest
                ast_log(LOG_WARNING, "Received response: \"Forbidden\" from '%s'\n", sip_get_header(&p->initreq, "From"));
                if (!req->ignore && p->owner) {
                        ast_set_hangupsource(p->owner, ast_channel_name(p->owner), 0);
-                       ast_queue_control(p->owner, AST_CONTROL_CONGESTION);
+                       ast_queue_hangup_with_cause(p->owner, AST_CAUSE_CONGESTION);
                }
-               pvt_set_needdestroy(p, "received 403 response");
-               sip_alreadygone(p);
                break;
 
        case 404: /* Not found */
                xmitres = transmit_request(p, SIP_ACK, seqno, XMIT_UNRELIABLE, FALSE);
                if (p->owner && !req->ignore) {
                        ast_set_hangupsource(p->owner, ast_channel_name(p->owner), 0);
-                       ast_queue_control(p->owner, AST_CONTROL_CONGESTION);
+                       ast_queue_hangup_with_cause(p->owner, AST_CAUSE_CONGESTION);
                }
-               sip_alreadygone(p);
                break;
 
        case 408: /* Request timeout */
@@ -20729,9 +20726,8 @@ static void handle_response_invite(struct sip_pvt *p, int resp, const char *rest
                ast_log(LOG_WARNING, "Re-invite to non-existing call leg on other UA. SIP dialog '%s'. Giving up.\n", p->callid);
                xmitres = transmit_request(p, SIP_ACK, seqno, XMIT_UNRELIABLE, FALSE);
                if (p->owner) {
-                       ast_queue_control(p->owner, AST_CONTROL_CONGESTION);
+                       ast_queue_hangup_with_cause(p->owner, AST_CAUSE_CONGESTION);
                }
-               sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT);
                break;
 
        case 422: /* Session-Timers: Session interval too small */
@@ -20744,13 +20740,11 @@ static void handle_response_invite(struct sip_pvt *p, int resp, const char *rest
                xmitres = transmit_request(p, SIP_ACK, seqno, XMIT_UNRELIABLE, FALSE);
                append_history(p, "Identity", "SIP identity is required. Not supported by Asterisk.");
                ast_log(LOG_WARNING, "SIP identity required by proxy. SIP dialog '%s'. Giving up.\n", p->callid);
-               if (p->owner) {
-                       ast_queue_control(p->owner, AST_CONTROL_CONGESTION);
+               if (p->owner && !req->ignore) {
+                       ast_queue_hangup_with_cause(p->owner, AST_CAUSE_CONGESTION);
                }
                break;
 
-               
-
        case 487: /* Cancelled transaction */
                /* We have sent CANCEL on an outbound INVITE
                        This transaction is already scheduled to be killed by sip_hangup().
@@ -20762,9 +20756,8 @@ static void handle_response_invite(struct sip_pvt *p, int resp, const char *rest
                } else if (!req->ignore) {
                        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.");
-                       pvt_set_needdestroy(p, "received 487 response");
-                       sip_alreadygone(p);
                }
+               sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT);
                break;
        case 415: /* Unsupported media type */
        case 488: /* Not acceptable here */
@@ -20781,12 +20774,7 @@ static void handle_response_invite(struct sip_pvt *p, int resp, const char *rest
                } else {
                        /* We can't set up this call, so give up */
                        if (p->owner && !req->ignore) {
-                               ast_queue_control(p->owner, AST_CONTROL_CONGESTION);
-                       }
-                       pvt_set_needdestroy(p, "received 488 response");
-                       /* If there's no dialog to end, then mark p as already gone */
-                       if (!reinvite) {
-                               sip_alreadygone(p);
+                               ast_queue_hangup_with_cause(p->owner, AST_CAUSE_CONGESTION);
                        }
                }
                break;
@@ -20794,8 +20782,7 @@ static void handle_response_invite(struct sip_pvt *p, int resp, const char *rest
                xmitres = transmit_request(p, SIP_ACK, seqno, XMIT_UNRELIABLE, FALSE);
                if (p->owner && !req->ignore) {
                        if (p->owner->_state != AST_STATE_UP) {
-                               ast_queue_control(p->owner, AST_CONTROL_CONGESTION);
-                               pvt_set_needdestroy(p, "received 491 response");
+                               ast_queue_hangup_with_cause(p->owner, AST_CAUSE_CONGESTION);
                        } else {
                                /* This is a re-invite that failed. */
                                /* Reset the flag after a while
@@ -20819,7 +20806,7 @@ static void handle_response_invite(struct sip_pvt *p, int resp, const char *rest
        case 501: /* Not implemented */
                xmitres = transmit_request(p, SIP_ACK, seqno, XMIT_UNRELIABLE, FALSE);
                if (p->owner) {
-                       ast_queue_control(p->owner, AST_CONTROL_CONGESTION);
+                       ast_queue_hangup_with_cause(p->owner, AST_CAUSE_CONGESTION);
                }
                break;
        }
@@ -21608,6 +21595,7 @@ static void handle_response(struct sip_pvt *p, int resp, const char *rest, struc
                        }
                        break;
 
+               case 428:
                case 422: /* Session-Timers: Session Interval Too Small */
                        if (sipmethod == SIP_INVITE) {
                                handle_response_invite(p, resp, rest, req, seqno);