[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