[asterisk-commits] mmichelson: branch mmichelson/transfer r386393 - /team/mmichelson/transfer/main/

SVN commits to the Asterisk project asterisk-commits at lists.digium.com
Tue Apr 23 16:53:43 CDT 2013


Author: mmichelson
Date: Tue Apr 23 16:53:39 2013
New Revision: 386393

URL: http://svnview.digium.com/svn/asterisk?view=rev&rev=386393
Log:
Add a manager blindtransfer command to help in testing blind transfers.

Right now, the blind transfer fails on a two-party bridge because using
ast_bridged_channel() returns non-NULL. I've removed the XXX comment about
this not being the recommended way of retrieving the bridged channel because
it's not only "not recommended" it's actually completely broken.


Modified:
    team/mmichelson/transfer/main/bridging.c
    team/mmichelson/transfer/main/manager.c

Modified: team/mmichelson/transfer/main/bridging.c
URL: http://svnview.digium.com/svn/asterisk/team/mmichelson/transfer/main/bridging.c?view=diff&rev=386393&r1=386392&r2=386393
==============================================================================
--- team/mmichelson/transfer/main/bridging.c (original)
+++ team/mmichelson/transfer/main/bridging.c Tue Apr 23 16:53:39 2013
@@ -4260,20 +4260,19 @@
 	struct blind_transfer_data blind_data;
 	struct ast_channel *transferee;
 
-	/* XXX This method of getting the bridged channel is not
-	 * the preferred way of doing it. The problem is that the
-	 * preferred way hasn't actually been written yet
-	 */
 	ast_channel_lock(transferer);
 	transferer_bridge_channel = ast_channel_internal_bridge_channel(transferer);
 	if (!transferer_bridge_channel) {
 		ast_channel_unlock(transferer);
+		ast_log(LOG_WARNING, "Failed to get transferer %s bridge channel\n",
+				ast_channel_name(transferer));
 		return AST_BRIDGE_TRANSFER_FAIL;
 	}
 	ao2_ref(transferer_bridge_channel, +1);
 	transferee = ast_bridged_channel(transferer);
 	if (!transferee) {
 		ast_channel_unlock(transferer);
+		ast_log(LOG_NOTICE, "Failed to get transferee channel\n");
 		return AST_BRIDGE_TRANSFER_FAIL;
 	}
 	ast_copy_string(blind_data.transferee_name, ast_channel_name(transferee),
@@ -4325,7 +4324,6 @@
 	}
 
 	return queue_blind_transfer_bridge_action(bridge, transferer, exten, context);
-
 }
 
 enum ast_transfer_result ast_bridge_attended_transfer(struct ast_channel *to_transferee,

Modified: team/mmichelson/transfer/main/manager.c
URL: http://svnview.digium.com/svn/asterisk/team/mmichelson/transfer/main/manager.c?view=diff&rev=386393&r1=386392&r2=386393
==============================================================================
--- team/mmichelson/transfer/main/manager.c (original)
+++ team/mmichelson/transfer/main/manager.c Tue Apr 23 16:53:39 2013
@@ -94,6 +94,7 @@
 #include "asterisk/stasis.h"
 #include "asterisk/test.h"
 #include "asterisk/json.h"
+#include "asterisk/bridging.h"
 
 /*** DOCUMENTATION
 	<manager name="Ping" language="en_US">
@@ -965,6 +966,23 @@
 			<para>The filters displayed are for the current session.  Only those filters defined in
                         manager.conf will be present upon starting a new session.</para>
 		</description>
+	</manager>
+	<manager name="BlindTransfer" language="en_US">
+		<synopsis>
+			Blind transfer channel(s) to the given destination
+		</synopsis>
+		<description>
+			<para>Redirect all channels currently bridged to the specified channel to the specified destination.</para>
+		</description>
+		<parameter name="Channel" required="true">
+		</parameter>
+		<parameter name="Context">
+		</parameter>
+		<parameter name="Exten">
+		</parameter>
+		<see-also>
+			<ref type="manager">Redirect</ref>
+		</see-also>
 	</manager>
  ***/
 
@@ -3874,6 +3892,51 @@
 	return 0;
 }
 
+static int action_blind_transfer(struct mansession *s, const struct message *m)
+{
+	const char *name = astman_get_header(m, "Channel");
+	const char *exten = astman_get_header(m, "Exten");
+	const char *context = astman_get_header(m, "Context");
+	RAII_VAR(struct ast_channel *, chan, NULL, ao2_cleanup);
+
+	if (ast_strlen_zero(name)) {
+		astman_send_error(s, m, "No channel specified");
+		return 0;
+	}
+
+	if (ast_strlen_zero(exten)) {
+		astman_send_error(s, m, "No extension specified");
+		return 0;
+	}
+
+	chan = ast_channel_get_by_name(name);
+	if (!chan) {
+		astman_send_error(s, m, "Channel specified does not exist");
+		return 0;
+	}
+
+	if (ast_strlen_zero(context)) {
+		context = ast_channel_context(chan);
+	}
+	
+	switch (ast_bridge_blind_transfer(chan, exten, context, NULL)) {
+	case AST_BRIDGE_TRANSFER_NOT_PERMITTED:
+		astman_send_error(s, m, "Transfer not permitted");
+		break;
+	case AST_BRIDGE_TRANSFER_INVALID:
+		astman_send_error(s, m, "Transfer invalid");
+		break;
+	case AST_BRIDGE_TRANSFER_FAIL:
+		astman_send_error(s, m, "Transfer failed");
+		break;
+	case AST_BRIDGE_TRANSFER_SUCCESS:
+		astman_send_ack(s, m, "Transfer succeeded");
+		break;
+	}
+	
+	return 0;
+}
+
 static int action_atxfer(struct mansession *s, const struct message *m)
 {
 	const char *name = astman_get_header(m, "Channel");
@@ -7541,6 +7604,7 @@
 		ast_manager_register_xml_core("ModuleCheck", EVENT_FLAG_SYSTEM, manager_modulecheck);
 		ast_manager_register_xml_core("AOCMessage", EVENT_FLAG_AOC, action_aocmessage);
 		ast_manager_register_xml_core("Filter", EVENT_FLAG_SYSTEM, action_filter);
+		ast_manager_register_xml_core("BlindTransfer", EVENT_FLAG_CALL, action_blind_transfer);
 
 #ifdef TEST_FRAMEWORK
 		stasis_subscribe(ast_test_suite_topic(), test_suite_event_cb, NULL);




More information about the asterisk-commits mailing list