[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