diff options
Diffstat (limited to 'channels/chan_sip.c')
-rw-r--r-- | channels/chan_sip.c | 20 |
1 files changed, 16 insertions, 4 deletions
diff --git a/channels/chan_sip.c b/channels/chan_sip.c index f744e073b..b1358175a 100644 --- a/channels/chan_sip.c +++ b/channels/chan_sip.c @@ -14395,7 +14395,7 @@ static int handle_request_invite(struct sip_pvt *p, struct sip_request *req, int } /* Check if this is a loop */ - if (ast_test_flag(&p->flags[0], SIP_OUTGOING) && p->owner && (p->owner->_state != AST_STATE_UP)) { + if (ast_test_flag(&p->flags[0], SIP_OUTGOING) && p->owner && (p->invitestate != INV_TERMINATED && p->invitestate != INV_CONFIRMED)) { /* This is a call to ourself. Send ourselves an error code and stop processing immediately, as SIP really has no good mechanism for being able to call yourself */ @@ -14824,9 +14824,21 @@ static int handle_request_invite(struct sip_pvt *p, struct sip_request *req, int p->invitestate = INV_PROCEEDING; break; case AST_STATE_RINGING: - transmit_response(p, "180 Ringing", req); - p->invitestate = INV_PROCEEDING; - break; + if (reinvite && (p->invitestate == INV_TERMINATED || p->invitestate == INV_CONFIRMED)) { + /* If these conditions are true, and the channel is still in the 'ringing' + * state, then this likely means that we have a situation where the initial + * INVITE transaction has completed *but* the channel's state has not yet been + * changed to UP. The reason this could happen is if the reinvite is received + * on the SIP socket prior to an application calling ast_read on this channel + * to read the answer frame we earlier queued on it. In this case, the reinvite + * is completely legitimate so we need to handle this the same as if the channel + * were already UP. Thus we are purposely falling through to the AST_STATE_UP case. + */ + } else { + transmit_response(p, "180 Ringing", req); + p->invitestate = INV_PROCEEDING; + break; + } case AST_STATE_UP: if (option_debug > 1) ast_log(LOG_DEBUG, "%s: This call is UP.... \n", c->name); |