aboutsummaryrefslogtreecommitdiffstats
path: root/channels/chan_sip.c
diff options
context:
space:
mode:
Diffstat (limited to 'channels/chan_sip.c')
-rw-r--r--channels/chan_sip.c20
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);