diff --git a/channels/chan_sip.c b/channels/chan_sip.c index 89651fffc0..b9de083f13 100644 --- a/channels/chan_sip.c +++ b/channels/chan_sip.c @@ -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)) {