From 9eb92ed083a0c2b45137a225e717d6da44c9a56a Mon Sep 17 00:00:00 2001 From: Olle Johansson Date: Mon, 4 Sep 2006 15:46:07 +0000 Subject: [PATCH] Don't kill the pvt before we have sent ACK on CANCEL (needs more testing before making a release) git-svn-id: https://origsvn.digium.com/svn/asterisk/branches/1.2@41989 65c4cc65-6c06-0410-ace0-fbb531ad65f3 --- channels/chan_sip.c | 37 ++++++++++++++++++++++++++++--------- 1 file changed, 28 insertions(+), 9 deletions(-) diff --git a/channels/chan_sip.c b/channels/chan_sip.c index 7c7552f638..b51ed4b5b7 100644 --- a/channels/chan_sip.c +++ b/channels/chan_sip.c @@ -2415,7 +2415,7 @@ static int sip_hangup(struct ast_channel *ast) { struct sip_pvt *p = ast->tech_pvt; int needcancel = 0; - struct ast_flags locflags = {0}; + int needdestroy = 0; if (!p) { ast_log(LOG_DEBUG, "Asked to hangup channel not connected\n"); @@ -2443,7 +2443,6 @@ static int sip_hangup(struct ast_channel *ast) needcancel = 1; /* Disconnect */ - p = ast->tech_pvt; if (p->vad) { ast_dsp_free(p->vad); } @@ -2455,7 +2454,16 @@ static int sip_hangup(struct ast_channel *ast) ast_mutex_unlock(&usecnt_lock); ast_update_use_count(); - ast_set_flag(&locflags, SIP_NEEDDESTROY); + /* Do not destroy this pvt until we have timeout or + get an answer to the BYE or INVITE/CANCEL + If we get no answer during retransmit period, drop the call anyway. + (Sorry, mother-in-law, you can't deny a hangup by sending + 603 declined to BYE...) + */ + if (ast_test_flag(p, SIP_ALREADYGONE)) + needdestroy = 1; /* Set destroy flag at end of this function */ + else + sip_scheddestroy(p, 32000); /* Start the process if it's not already started */ if (!ast_test_flag(p, SIP_ALREADYGONE) && !ast_strlen_zero(p->initreq.data)) { @@ -2468,13 +2476,12 @@ static int sip_hangup(struct ast_channel *ast) it pending */ if (!ast_test_flag(p, SIP_CAN_BYE)) { ast_set_flag(p, SIP_PENDINGBYE); + /* Do we need a timer here if we don't hear from them at all? */ } else { /* Send a new request: CANCEL */ transmit_request_with_auth(p, SIP_CANCEL, p->ocseq, 1, 0); /* 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. */ - ast_clear_flag(&locflags, SIP_NEEDDESTROY); - sip_scheddestroy(p, 32000); } if ( p->initid != -1 ) { /* channel still up - reverse dec of inUse counter @@ -2500,7 +2507,8 @@ static int sip_hangup(struct ast_channel *ast) } } } - ast_copy_flags(p, (&locflags), SIP_NEEDDESTROY); + if (needdestroy) + ast_set_flag(p, SIP_NEEDDESTROY); ast_mutex_unlock(&p->lock); return 0; } @@ -9988,6 +9996,9 @@ static void handle_response(struct sip_pvt *p, int resp, char *rest, struct sip_ handle_response_invite(p, resp, rest, req, ignore, seqno); } else if (sipmethod == SIP_REGISTER) { res = handle_response_register(p, resp, rest, req, ignore, seqno); + } else if (sipmethod == SIP_BYE) { + /* Ok, we're ready to go */ + ast_set_flag(p, SIP_NEEDDESTROY); } break; case 401: /* Not www-authorized on SIP method */ @@ -10139,9 +10150,12 @@ static void handle_response(struct sip_pvt *p, int resp, char *rest, struct sip_ handle_response_invite(p, resp, rest, req, ignore, seqno); } else if (sipmethod == SIP_CANCEL) { ast_log(LOG_DEBUG, "Got 200 OK on CANCEL\n"); - } else if (sipmethod == SIP_MESSAGE) + } else if (sipmethod == SIP_MESSAGE) /* We successfully transmitted a message */ ast_set_flag(p, SIP_NEEDDESTROY); + else if (sipmethod == SIP_BYE) + /* Ok, we're ready to go */ + ast_set_flag(p, SIP_NEEDDESTROY); break; case 401: /* www-auth */ case 407: @@ -10814,10 +10828,15 @@ static int handle_request_bye(struct sip_pvt *p, struct sip_request *req, int de if (p->owner) ast_queue_hangup(p->owner); } - } else if (p->owner) + } else if (p->owner) { ast_queue_hangup(p->owner); - else + if (option_debug > 2) + ast_log(LOG_DEBUG, "Received bye, issuing owner hangup\n."); + } else { ast_set_flag(p, SIP_NEEDDESTROY); + if (option_debug > 2) + ast_log(LOG_DEBUG, "Received bye, no owner, selfdestruct soon.\n."); + } transmit_response(p, "200 OK", req); return 1;