[asterisk-commits] mmichelson: branch mmichelson/sip_attended_transfer r387659 - /team/mmichelso...

SVN commits to the Asterisk project asterisk-commits at lists.digium.com
Sun May 5 14:31:44 CDT 2013


Author: mmichelson
Date: Sun May  5 14:31:41 2013
New Revision: 387659

URL: http://svnview.digium.com/svn/asterisk?view=rev&rev=387659
Log:
Initial draft of handle_invite_replaces() changes.

We no longer care much about the current state of calls initially.
We mostly just care about if the call to replace is bridged.


Modified:
    team/mmichelson/sip_attended_transfer/channels/chan_sip.c

Modified: team/mmichelson/sip_attended_transfer/channels/chan_sip.c
URL: http://svnview.digium.com/svn/asterisk/team/mmichelson/sip_attended_transfer/channels/chan_sip.c?view=diff&rev=387659&r1=387658&r2=387659
==============================================================================
--- team/mmichelson/sip_attended_transfer/channels/chan_sip.c (original)
+++ team/mmichelson/sip_attended_transfer/channels/chan_sip.c Sun May  5 14:31:41 2013
@@ -24956,31 +24956,8 @@
 		uint32_t seqno, int *nounlock, struct sip_pvt *replaces_pvt,
 		struct ast_channel *replaces_chan)
 {
-	int earlyreplace = 0;
-	int oneleggedreplace = 0;		/* Call with no bridge, propably IVR or voice message */
-	struct ast_channel *c = p->owner;	/* Our incoming call */
-	struct ast_channel *replacecall = replaces_chan;	/* The channel we're about to take over */
-	struct ast_channel *targetcall;		/* The bridge to the take-over target */
-
-	/* Check if we're in ring state */
-	if (ast_channel_state(replacecall) == AST_STATE_RING)
-		earlyreplace = 1;
-
-	/* Check if we have a bridge */
-	if (!(targetcall = ast_bridged_channel(replacecall))) {
-		/* We have no bridge */
-		if (!earlyreplace) {
-			ast_debug(2, "	Attended transfer attempted to replace call with no bridge (maybe ringing). Channel %s!\n", ast_channel_name(replacecall));
-			oneleggedreplace = 1;
-		}
-	}
-	if (targetcall && ast_channel_state(targetcall) == AST_STATE_RINGING)
-		ast_debug(4, "SIP transfer: Target channel is in ringing state\n");
-
-	if (targetcall)
-		ast_debug(4, "SIP transfer: Invite Replace incoming channel should bridge to channel %s while hanging up channel %s\n", ast_channel_name(targetcall), ast_channel_name(replacecall));
-	else
-		ast_debug(4, "SIP transfer: Invite Replace incoming channel should replace and hang up channel %s (one call leg)\n", ast_channel_name(replacecall));
+	RAII_VAR(struct ast_bridge *, bridge, NULL, ao2_cleanup);
+	RAII_VAR(struct ast_channel *, c, p->owner, ao2_cleanup);
 
 	if (req->ignore) {
 		ast_log(LOG_NOTICE, "Ignoring this INVITE with replaces in a stupid way.\n");
@@ -24995,6 +24972,7 @@
 		}
 		return 1;
 	}
+
 	if (!c) {
 		/* What to do if no channel ??? */
 		ast_log(LOG_ERROR, "Unable to create new channel.  Invite/replace failed.\n");
@@ -25004,65 +24982,32 @@
 		return 1;
 	}
 	append_history(p, "Xfer", "INVITE/Replace received");
-	/* We have three channels to play with
-		channel c: New incoming call
-		targetcall: Call from PBX to target
-		replaces_pvt: SIP pvt dialog from transferer to pbx.
-		replacecall: The owner of the previous
-		We need to masq C into refer_call to connect to
-		targetcall;
-		If we are talking to internal audio stream, target call is null.
-	*/
 
 	/* Fake call progress */
 	transmit_response(p, "100 Trying", req);
 	ast_setstate(c, AST_STATE_RING);
 
-	/* Masquerade the new call into the referred call to connect to target call
-	   Targetcall is not touched by the masq */
-
 	/* Answer the incoming call and set channel to UP state */
 	transmit_response_with_sdp(p, "200 OK", req, XMIT_RELIABLE, FALSE, FALSE);
 
 	ast_setstate(c, AST_STATE_UP);
 
 	/* Stop music on hold and other generators */
-	ast_quiet_chan(replacecall);
-	ast_quiet_chan(targetcall);
-	ast_debug(4, "Invite/Replaces: preparing to masquerade %s into %s\n", ast_channel_name(c), ast_channel_name(replacecall));
-
-	/* Make sure that the masq does not free our PVT for the old call */
-	if (! earlyreplace && ! oneleggedreplace )
-		ast_set_flag(&replaces_pvt->flags[0], SIP_DEFER_BYE_ON_TRANSFER);	/* Delay hangup */
-
-	/* Prepare the masquerade - if this does not happen, we will be gone */
-	if(ast_channel_masquerade(replacecall, c))
-		ast_log(LOG_ERROR, "Failed to masquerade C into Replacecall\n");
-	else
-		ast_debug(4, "Invite/Replaces: Going to masquerade %s into %s\n", ast_channel_name(c), ast_channel_name(replacecall));
-
-	/* C should now be in place of replacecall. all channel locks and pvt locks should be removed
-	 * before issuing the masq.  Since we are unlocking both the pvt (p) and its owner channel (c)
-	 * it is possible for channel c to be destroyed on us.  To prevent this, we must give c a reference
-	 * before any unlocking takes place and remove it only once we are completely done with it */
-	ast_channel_ref(c);
+	ast_quiet_chan(replaces_chan);
+	ast_debug(4, "Invite/Replaces: preparing to masquerade %s into %s\n", ast_channel_name(c), ast_channel_name(replaces_chan));
+
+	bridge = ast_channel_get_bridge(c);
+	*nounlock = 1;
 	ast_channel_unlock(c);
 	sip_pvt_unlock(p);
-	ast_do_masquerade(replacecall);
-	ast_channel_lock(c);
-	if (earlyreplace || oneleggedreplace ) {
-		ast_channel_hangupcause_set(c, AST_CAUSE_SWITCH_CONGESTION);
-	}
-	ast_setstate(c, AST_STATE_DOWN);
-	ast_channel_unlock(c);
-
-	/* c and c's tech pvt must be unlocked at this point for ast_hangup */
+
+	if (bridge) {
+		ast_bridge_impart(bridge, replaces_chan, c, NULL, 1);
+	} else {
+		ast_channel_move(replaces_chan, c);
+	}
 	ast_hangup(c);
-	/* this indicates to handle_request_do that the owner channel has already been unlocked */
-	*nounlock = 1;
-	/* lock PVT structure again after hangup */
 	sip_pvt_lock(p);
-	ast_channel_unref(c);
 	return 0;
 }
 




More information about the asterisk-commits mailing list