--- channels/chan_sip.c.orig Thu Jun 15 10:26:14 2006 +++ channels/chan_sip.c Fri Jun 16 14:37:05 2006 @@ -9541,36 +9568,45 @@ if (e) *e = '\0'; if (!strncasecmp(s, "sip:", 4)) s += 4; ast_log(LOG_DEBUG, "Found 302 Redirect to extension '%s'\n", s); if (p->owner) ast_copy_string(p->owner->call_forward, s, sizeof(p->owner->call_forward)); } } -/*! \brief check_pendings: Check pending actions on SIP call ---*/ -static void check_pendings(struct sip_pvt *p) +/*! \brief check_pending_bye: Check to see if we need to issue a CANCEL rather then a BYE ---*/ +static void check_pending_bye(struct sip_pvt *p) { - if (ast_test_flag(p, SIP_PENDINGBYE)) { - /* if we can't BYE, then this is really a pending CANCEL */ - if (!ast_test_flag(p, SIP_CAN_BYE)) { + if (ast_test_flag(p, SIP_PENDINGBYE)) + if (ast_test_flag(p, SIP_CAN_BYE)) + { + transmit_request_with_auth(p, SIP_BYE, 0, 1, 1); + ast_set_flag(p, SIP_NEEDDESTROY); + ast_clear_flag(p, SIP_NEEDREINVITE); + } + else + { 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. */ sip_scheddestroy(p, 32000); - } else { - transmit_request_with_auth(p, SIP_BYE, 0, 1, 1); - ast_set_flag(p, SIP_NEEDDESTROY); - ast_clear_flag(p, SIP_NEEDREINVITE); } - } else if (ast_test_flag(p, SIP_NEEDREINVITE)) { +} + +/*! \brief check_pendings: Check pending actions on SIP call ---*/ +static void check_pendings(struct sip_pvt *p) +{ + check_pending_bye(p); + + if (ast_test_flag(p, SIP_NEEDREINVITE)) { ast_log(LOG_DEBUG, "Sending pending reinvite on '%s'\n", p->callid); /* Didn't get to reinvite yet, so do it now */ transmit_reinvite_with_sdp(p); ast_clear_flag(p, SIP_NEEDREINVITE); } } /*! \brief handle_response_invite: Handle SIP response in dialogue ---*/ static void handle_response_invite(struct sip_pvt *p, int resp, char *rest, struct sip_request *req, int ignore, int seqno) { @@ -9585,57 +9621,53 @@ } if (ast_test_flag(p, SIP_ALREADYGONE)) { /* This call is already gone */ ast_log(LOG_DEBUG, "Got response on call that is already terminated: %s (ignoring)\n", p->callid); return; } switch (resp) { case 100: /* Trying */ sip_cancel_destroy(p); - /* must call check_pendings before setting CAN_BYE, so that - if PENDINGBYE is set it will know to send CANCEL instead */ - check_pendings(p); - ast_set_flag(p, SIP_CAN_BYE); break; case 180: /* 180 Ringing */ sip_cancel_destroy(p); if (!ignore && p->owner) { ast_queue_control(p->owner, AST_CONTROL_RINGING); if (p->owner->_state != AST_STATE_UP) ast_setstate(p->owner, AST_STATE_RINGING); } if (find_sdp(req)) { process_sdp(p, req); if (!ignore && p->owner) { /* Queue a progress frame only if we have SDP in 180 */ ast_queue_control(p->owner, AST_CONTROL_PROGRESS); } } /* must call check_pendings before setting CAN_BYE, so that if PENDINGBYE is set it will know to send CANCEL instead */ - check_pendings(p); + check_pending_bye(p); ast_set_flag(p, SIP_CAN_BYE); break; case 183: /* Session progress */ sip_cancel_destroy(p); /* Ignore 183 Session progress without SDP */ if (find_sdp(req)) { process_sdp(p, req); if (!ignore && p->owner) { /* Queue a progress frame */ ast_queue_control(p->owner, AST_CONTROL_PROGRESS); } } /* must call check_pendings before setting CAN_BYE, so that if PENDINGBYE is set it will know to send CANCEL instead */ - check_pendings(p); + check_pending_bye(p); ast_set_flag(p, SIP_CAN_BYE); break; case 200: /* 200 OK on invite - someone's answering our call */ sip_cancel_destroy(p); p->authtries = 0; if (find_sdp(req)) { process_sdp(p, req); } /* Parse contact header for continued conversation */