[asterisk-commits] rizzo: branch rizzo/astobj2 r48245 - /team/rizzo/astobj2/channels/chan_sip.c

asterisk-commits at lists.digium.com asterisk-commits at lists.digium.com
Mon Dec 4 14:13:21 MST 2006


Author: rizzo
Date: Mon Dec  4 15:13:20 2006
New Revision: 48245

URL: http://svn.digium.com/view/asterisk?view=rev&rev=48245
Log:
merge from trunk 48213 48220.
This aligns chan_sip.c with the version in trunk as of today.

Modified:
    team/rizzo/astobj2/channels/chan_sip.c

Modified: team/rizzo/astobj2/channels/chan_sip.c
URL: http://svn.digium.com/view/asterisk/team/rizzo/astobj2/channels/chan_sip.c?view=diff&rev=48245&r1=48244&r2=48245
==============================================================================
--- team/rizzo/astobj2/channels/chan_sip.c (original)
+++ team/rizzo/astobj2/channels/chan_sip.c Mon Dec  4 15:13:20 2006
@@ -244,15 +244,15 @@
 	\note this is for the INVITE that sets up the dialog
 */
 enum invitestates {
-	INV_NONE = 0,	/*!< No state at all, maybe not an INVITE dialog */
-	INV_CALLING,	/*!< Invite sent, no answer */
-	INV_PROCEEDING,	/*!< We got 1xx message */
-	INV_EARLY_MEDIA, /*!< We got 18x message with to-tag back */
-	INV_COMPLETED,	/*!< Got final response with error. Wait for ACK, then CONFIRMED */
-	INV_CONFIRMED,	/*!< Confirmed response - we've got an ack (Incoming calls only) */
-	INV_TERMINATED,	/*!< Transaction done - either successful (AST_STATE_UP) or failed, but done 
-				The only way out of this is a BYE from one side */
-	INV_CANCELLED	/*!< Transaction cancelled by client or server in non-terminated state */
+	INV_NONE = 0,		/*!< No state at all, maybe not an INVITE dialog */
+	INV_CALLING,		/*!< Invite sent, no answer */
+	INV_PROCEEDING,		/*!< We got/sent 1xx message */
+	INV_EARLY_MEDIA,	/*!< We got 18x message with to-tag back */
+	INV_COMPLETED,		/*!< Got final response with error. Wait for ACK, then CONFIRMED */
+	INV_CONFIRMED,		/*!< Confirmed response - we've got an ack (Incoming calls only) */
+	INV_TERMINATED,		/*!< Transaction done - either successful (AST_STATE_UP) or failed, but done 
+					The only way out of this is a BYE from one side */
+	INV_CANCELLED		/*!< Transaction cancelled by client or server in non-terminated state */
 };
 
 /* Do _NOT_ make any changes to this enum, or the array following it;
@@ -1818,6 +1818,14 @@
 		ast_verbose("Initreq: %d headers, %d lines\n", p->initreq.headers, p->initreq.lines);
 }
 
+/*! \brief Encapsulate setting of SIP_ALREADYGONE to be able to trace it with debugging */
+static void sip_alreadygone(struct sip_pvt *dialog)
+{
+	if (option_debug > 2)
+		ast_log(LOG_DEBUG, "Setting SIP_ALREADYGONE on dialog %s\n", dialog->callid);
+	ast_set_flag(&dialog->flags[0], SIP_ALREADYGONE);
+}
+  	 
 
 /*! \brief returns true if 'name' (with optional trailing whitespace)
  * matches the sip method 'id'.
@@ -2129,7 +2137,7 @@
 		 */
 		lock_pvt_and_owner(pvt, 0 /* try forever */);
 		if (pvt->owner) {
-			ast_set_flag(&pvt->flags[0], SIP_ALREADYGONE);
+			sip_alreadygone(pvt);
 			ast_log(LOG_WARNING, "Hanging up call %s - no reply to our critical packet.\n", pvt->callid);
 			ast_queue_hangup(pvt->owner);
 			ast_channel_unlock(pvt->owner);
@@ -3636,7 +3644,7 @@
 		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) {
+	if (p->invitestate < INV_COMPLETED) {
 		needcancel = TRUE;
 		if (option_debug > 3)
 			ast_log(LOG_DEBUG, "Hanging up channel in state %s (not UP)\n", ast_state2str(ast->_state));
@@ -3658,7 +3666,7 @@
 	*/
 	if (ast_test_flag(&p->flags[0], SIP_ALREADYGONE))
 		needdestroy = 1;	/* Set destroy flag at end of this function */
-	else
+	else if (p->invitestate != INV_CALLING)
 		sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT);
 
 	/* Start the process if it's not already started */
@@ -3720,6 +3728,7 @@
 				   but we can't send one while we have "INVITE" outstanding. */
 				ast_set_flag(&p->flags[0], SIP_PENDINGBYE);	
 				ast_clear_flag(&p->flags[0], SIP_NEEDREINVITE);	
+				sip_cancel_destroy(p);
 			}
 		}
 	}
@@ -3969,6 +3978,7 @@
 	switch(condition) {
 	case AST_CONTROL_RINGING:
 		if (ast->_state == AST_STATE_RING) {
+			p->invitestate = INV_EARLY_MEDIA;
 			if (!ast_test_flag(&p->flags[0], SIP_PROGRESS_SENT) ||
 			    (ast_test_flag(&p->flags[0], SIP_PROG_INBAND) == SIP_PROG_INBAND_NEVER)) {				
 				/* Send 180 ringing if out-of-band seems reasonable */
@@ -3985,7 +3995,8 @@
 	case AST_CONTROL_BUSY:
 		if (ast->_state != AST_STATE_UP) {
 			transmit_response(p, "486 Busy Here", &p->initreq);
-			ast_set_flag(&p->flags[0], SIP_ALREADYGONE);	
+			p->invitestate = INV_TERMINATED;
+			sip_alreadygone(p);
 			ast_softhangup_nolock(ast, AST_SOFTHANGUP_DEV);
 			break;
 		}
@@ -3994,7 +4005,8 @@
 	case AST_CONTROL_CONGESTION:
 		if (ast->_state != AST_STATE_UP) {
 			transmit_response(p, "503 Service Unavailable", &p->initreq);
-			ast_set_flag(&p->flags[0], SIP_ALREADYGONE);	
+			p->invitestate = INV_TERMINATED;
+			sip_alreadygone(p);
 			ast_softhangup_nolock(ast, AST_SOFTHANGUP_DEV);
 			break;
 		}
@@ -4005,6 +4017,7 @@
 		    !ast_test_flag(&p->flags[0], SIP_PROGRESS_SENT) &&
 		    !ast_test_flag(&p->flags[0], SIP_OUTGOING)) {
 			transmit_response(p, "100 Trying", &p->initreq);
+			p->invitestate = INV_PROCEEDING;
 			break;
 		}
 		res = -1;
@@ -4013,6 +4026,7 @@
 		if ((ast->_state != AST_STATE_UP) &&
 		    !ast_test_flag(&p->flags[0], SIP_PROGRESS_SENT) &&
 		    !ast_test_flag(&p->flags[0], SIP_OUTGOING)) {
+			p->invitestate = INV_EARLY_MEDIA;
 			transmit_response_with_sdp(p, "183 Session Progress", &p->initreq, XMIT_UNRELIABLE);
 			ast_set_flag(&p->flags[0], SIP_PROGRESS_SENT);	
 			break;
@@ -12316,7 +12330,7 @@
 			if (p->authtries == MAX_AUTHTRIES || do_proxy_auth(p, req, resp, SIP_INVITE, 1)) {
 				ast_log(LOG_NOTICE, "Failed to authenticate on INVITE to '%s'\n", get_header(&p->initreq, "From"));
 				set_destroy(p);	
-				ast_set_flag(&p->flags[0], SIP_ALREADYGONE);	
+				sip_alreadygone(p);
 				if (p->owner)
 					ast_queue_control(p->owner, AST_CONTROL_CONGESTION);
 			}
@@ -12330,20 +12344,23 @@
 		if (!req_ignore(req) && p->owner)
 			ast_queue_control(p->owner, AST_CONTROL_CONGESTION);
 		set_destroy(p);	
-		ast_set_flag(&p->flags[0], SIP_ALREADYGONE);	
+		sip_alreadygone(p);
 		break;
 
 	case 404: /* Not found */
 		transmit_request(p, SIP_ACK, seqno, XMIT_UNRELIABLE, FALSE);
 		if (p->owner && !req_ignore(req))
 			ast_queue_control(p->owner, AST_CONTROL_CONGESTION);
-		ast_set_flag(&p->flags[0], SIP_ALREADYGONE);	
+		sip_alreadygone(p);
 		break;
 
 	case 481: /* Call leg does not exist */
-		/* Could be REFER or INVITE */
+		/* Could be REFER or INVITE with replaces */
 		ast_log(LOG_WARNING, "Re-invite to non-existing call leg on other UA. SIP dialog '%s'. Giving up.\n", p->callid);
 		transmit_request(p, SIP_ACK, seqno, XMIT_UNRELIABLE, FALSE);
+		if (p->owner)
+			ast_queue_control(p->owner, AST_CONTROL_CONGESTION);
+		sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT);
 		break;
 
 	case 491: /* Pending */
@@ -12396,7 +12413,16 @@
 			set_destroy(p);
 		}
 		break;
-
+	case 481: /* Call leg does not exist */
+		/* A transfer with Replaces did not work */
+		/* OEJ: We should Set flag, cancel the REFER, go back
+			to original call - but right now we can't */
+		ast_log(LOG_WARNING, "Remote host can't match REFER request to call '%s'. Giving up.\n", p->callid);
+		if (p->owner)
+			ast_queue_control(p->owner, AST_CONTROL_CONGESTION);
+		set_destroy(p);
+		break;
+ 
 	case 500:   /* Server error */
 	case 501:   /* Method not implemented */
 		/* Return to the current call onhold */
@@ -12818,21 +12844,9 @@
 			break;
 		case 481: /* Call leg does not exist */
 			if (sipmethod == SIP_INVITE) {
-				/* First we ACK */
-				transmit_request(p, SIP_ACK, seqno, XMIT_UNRELIABLE, FALSE);
-				if (option_debug)
-					ast_log(LOG_DEBUG, "Got 481 on Invite. Assuming INVITE with REPLACEs failed to '%s'\n", get_header(&p->initreq, "From"));
-				if (owner)
-					ast_queue_control(p->owner, AST_CONTROL_CONGESTION);
-				sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT);
+				handle_response_invite(p, resp, rest, req, seqno);
 			} else if (sipmethod == SIP_REFER) {
-				/* A transfer with Replaces did not work */
-				/* OEJ: We should Set flag, cancel the REFER, go back
-				to original call - but right now we can't */
-				ast_log(LOG_WARNING, "Remote host can't match request %s to call '%s'. Giving up.\n", sip_methods[sipmethod].text, p->callid);
-				if (owner)
-					ast_queue_control(p->owner, AST_CONTROL_CONGESTION);
-				set_destroy(p);
+				handle_response_refer(p, resp, rest, req, seqno);
 			} else if (sipmethod == SIP_BYE) {
 				/* The other side has no transaction to bye,
 				just assume it's all right then */
@@ -12874,7 +12888,6 @@
 				/* Fatal response */
 				if ((option_verbose > 2) && (resp != 487))
 					ast_verbose(VERBOSE_PREFIX_3 "Got SIP response %d \"%s\" back from %s\n", resp, rest, ast_inet_ntoa(p->sa.sin_addr));
-				ast_set_flag(&p->flags[0], SIP_ALREADYGONE);	
 	
 				stop_media_flows(p); /* Immediately stop RTP, VRTP and UDPTL as applicable */
 
@@ -12933,7 +12946,7 @@
 				/* ACK on invite */
 				if (sipmethod == SIP_INVITE) 
 					transmit_request(p, SIP_ACK, seqno, XMIT_UNRELIABLE, FALSE);
-				ast_set_flag(&p->flags[0], SIP_ALREADYGONE);	
+				sip_alreadygone(p);
 				if (!p->owner)
 					set_destroy(p);
 			} else if ((resp >= 100) && (resp < 200)) {
@@ -14033,7 +14046,7 @@
 						transmit_response(p, "503 Unavailable", req);	/* OEJ - Right answer? */
 					else
 						transmit_response_reliable(p, "503 Unavailable", req);
-					ast_set_flag(&p->flags[0], SIP_ALREADYGONE);	
+					sip_alreadygone(p);
 					/* Unlock locks so ast_hangup can do its magic */
 					sip_pvt_unlock(p);
 					c->hangupcause = AST_CAUSE_CALL_REJECTED;
@@ -14358,7 +14371,7 @@
 		transmit_response(p, "603 Declined (No dialog)", req);
 		if (!req_ignore(req)) {
 			append_history(p, "Xfer", "Refer failed. Outside of dialog.");
-			ast_set_flag(&p->flags[0], SIP_ALREADYGONE);	
+			sip_alreadygone(p);
 			set_destroy(p);
 		}
 		return 0;
@@ -14617,7 +14630,7 @@
 {
 		
 	check_via(p, req);
-	ast_set_flag(&p->flags[0], SIP_ALREADYGONE);	
+	sip_alreadygone(p);
 	p->invitestate = INV_CANCELLED;
 	
 	if (p->owner && p->owner->_state == AST_STATE_UP) {
@@ -14661,7 +14674,7 @@
 	if (sipdebug && option_debug)
 		ast_log(LOG_DEBUG, "Initializing initreq for method %s - callid %s\n", sip_methods[req->method].text, p->callid);
 	check_via(p, req);
-	ast_set_flag(&p->flags[0], SIP_ALREADYGONE);	
+	sip_alreadygone(p);
 
 	/* Get RTCP quality before end of call */
 	if (record_history(p) || p->owner) {



More information about the asterisk-commits mailing list