[asterisk-commits] mmichelson: branch mmichelson/sip_transfer r387200 - /team/mmichelson/sip_tra...
SVN commits to the Asterisk project
asterisk-commits at lists.digium.com
Wed May 1 15:21:57 CDT 2013
Author: mmichelson
Date: Wed May 1 15:21:54 2013
New Revision: 387200
URL: http://svnview.digium.com/svn/asterisk?view=rev&rev=387200
Log:
Use a blind transfer callback to set data on the outbound channel.
This way, remote attended transfers will work properly and
diagnostic information will be readily available on the dialplan.
Modified:
team/mmichelson/sip_transfer/channels/chan_sip.c
Modified: team/mmichelson/sip_transfer/channels/chan_sip.c
URL: http://svnview.digium.com/svn/asterisk/team/mmichelson/sip_transfer/channels/chan_sip.c?view=diff&rev=387200&r1=387199&r2=387200
==============================================================================
--- team/mmichelson/sip_transfer/channels/chan_sip.c (original)
+++ team/mmichelson/sip_transfer/channels/chan_sip.c Wed May 1 15:21:54 2013
@@ -26169,6 +26169,24 @@
return 1;
}
+struct blind_transfer_cb_data {
+ const char *referred_by;
+ const char *domain;
+ char replaces[SIPBUFSIZE];
+ struct ast_party_redirecting redirecting;
+ struct ast_set_party_redirecting update_redirecting;
+};
+
+static void blind_transfer_cb(struct ast_channel *chan, void *user_data)
+{
+ struct blind_transfer_cb_data *cb_data = user_data;
+
+ pbx_builtin_setvar_helper(chan, "SIPTRANSFER", "yes");
+ pbx_builtin_setvar_helper(chan, "SIPTRANSFER_REFERER", cb_data->referred_by);
+ pbx_builtin_setvar_helper(chan, "SIPTRANSFER_REPLACES", cb_data->replaces);
+ pbx_builtin_setvar_helper(chan, "SIPDOMAIN", cb_data->domain);
+ ast_channel_update_redirecting(chan, &cb_data->redirecting, &cb_data->update_redirecting);
+}
/*! \brief Handle incoming REFER request */
/*! \page SIP_REFER SIP transfer Support (REFER)
@@ -26242,66 +26260,16 @@
* handle_request_refer(), we pass a NULL sip_dual into local_attended_transfer now,
* so it is completely broken at this point.
*
- * 2) There are several channel variables that are no longer set on the transferee
- * channel during blind transfers. This is because we cannot be making assumptions
- * about the nature of the transfer, such as that we are bridged to only one party.
- * The following is a list of the channel variable settings that are currently missing:
- *
- * a) BLINDTRANSFER = transferer channel name
- * b) SIP_DOMAIN = refer_to_domain
- * c) _SIP_TRANSFER = "yes"
- * d) _SIP_TRANSFER_REFERER = referred_by
- * e) _SIPTRANSFER_REPLACES = callid;to-tag=blah;from-tag=blah
- *
- * We likely will need to add a new parameter to ast_bridge_transfer_blind() so
- * that either a callback can be called to set data on the channel that goes out
- * to the dialplan.
- *
- * 3) We no longer update redirecting information on the transferee if there is
- * a diversion header in the REFER. This was useful for determining a "reason" for
- * the transfer, such as a transfer to voicemail. The solution provided for
- * point 2) will help here too.
- *
- * 4) Some debugging and history are gone. While it likely won't be possible
+ * 2) Some debugging and history are gone. While it likely won't be possible
* to have the same level of debugging and history as before, we should still
* strive to put in as much as possible.
- *
- * And the following are things that have changed but are likely not a problem:
- *
- * 1) We no longer queue a hold and unhold frame on the transferer channel if
- * bridged to a transferee channel when doing a blind transfer. Performing the
- * hold/unhold was odd because a) the transferee was likely already on hold
- * anyway during the time the transferer was dialing the remote party, and
- * b) the time between the hold and unhold would be fractions of a second.
- *
- * 2) We no longer send a SIP NOTIFY with sipfrag "180 Ringing". There are
- * two reasons why:
- * a) We were faking the ringing in the first place.
- * b) Many devices will interpret a ringing notification as a successful transfer.
- * This means that if we were to send the ringing notification and then a failure,
- * the blind transfer would fail and would be unrecoverable.
- *
- * 3) Some failures are indicated differently now. A lot of the failures are not
- * fleshed out at this point, but it's safe to say that some failures (such as
- * a lack of a bridge on a blind transfer) will have a different error response
- * than previously. This is really not an issue since communicating failure is
- * the biggest thing needed.
- *
- * 4) Manager events are now gone. This is on purpose because the idea now is for
- * the bridging core to issue general-purpose stasis events for transfers instead.
- * This will make transfers easier to indicate. It does, however, result in some
- * information, such as SIP Call-IDs missing from such transfer events.
*/
static int handle_request_refer(struct sip_pvt *p, struct sip_request *req, uint32_t seqno, int *nounlock)
{
char *refer_to = NULL;
- char *refer_to_domain = NULL;
char *refer_to_context = NULL;
- char *referred_by = NULL;
- char *callid = NULL;
- int localtransfer = 0;
- int attendedtransfer = 0;
int res = 0;
+ struct blind_transfer_cb_data cb_data;
RAII_VAR(struct ast_channel *, transferer, NULL, ao2_cleanup);
if (req->debug) {
@@ -26437,12 +26405,24 @@
/* Copy data we can not safely access after letting the pvt lock go. */
refer_to = ast_strdupa(p->refer->refer_to);
- refer_to_domain = ast_strdupa(p->refer->refer_to_domain);
refer_to_context = ast_strdupa(p->refer->refer_to_context);
- referred_by = ast_strdupa(p->refer->referred_by);
- callid = ast_strdupa(p->callid);
- localtransfer = p->refer->localtransfer;
- attendedtransfer = p->refer->attendedtransfer;
+
+ ast_party_redirecting_init(&cb_data.redirecting);
+ memset(&cb_data.update_redirecting, 0, sizeof(cb_data.update_redirecting));
+ change_redirecting_information(p, req, &cb_data.redirecting, &cb_data.update_redirecting, 0);
+
+ cb_data.domain = ast_strdupa(p->refer->refer_to_domain);
+ cb_data.referred_by = ast_strdupa(p->refer->referred_by);
+
+ if (!ast_strlen_zero(p->refer->replaces_callid)) {
+ snprintf(cb_data.replaces, sizeof(cb_data.replaces), "%s%s%s%s%s", p->refer->replaces_callid,
+ !ast_strlen_zero(p->refer->replaces_callid_totag) ? ";to-tag=" : "",
+ S_OR(p->refer->replaces_callid_totag, ""),
+ !ast_strlen_zero(p->refer->replaces_callid_fromtag) ? ";from-tag=" : "",
+ S_OR(p->refer->replaces_callid_fromtag, ""));
+ } else {
+ cb_data.replaces[0] = '\0';
+ }
if (!*nounlock) {
ast_channel_unlock(p->owner);
@@ -26450,7 +26430,8 @@
}
sip_pvt_unlock(p);
- switch (ast_bridge_transfer_blind(transferer, refer_to, refer_to_context, NULL)) {
+
+ switch (ast_bridge_transfer_blind(transferer, refer_to, refer_to_context, blind_transfer_cb, &cb_data)) {
case AST_BRIDGE_TRANSFER_INVALID:
case AST_BRIDGE_TRANSFER_NOT_PERMITTED:
case AST_BRIDGE_TRANSFER_FAIL:
@@ -26466,6 +26447,8 @@
default:
break;
}
+
+ ast_party_redirecting_free(&cb_data.redirecting);
sip_pvt_lock(p);
handle_refer_cleanup:
More information about the asterisk-commits
mailing list