[asterisk-commits] kmoore: branch group/ari-greedy-atxfer r419313 - in /team/group/ari-greedy-at...

SVN commits to the Asterisk project asterisk-commits at lists.digium.com
Wed Jul 23 10:56:22 CDT 2014


Author: kmoore
Date: Wed Jul 23 10:56:18 2014
New Revision: 419313

URL: http://svnview.digium.com/svn/asterisk?view=rev&rev=419313
Log:
ARI: Add missing transfer information

This adds a new field to the ast_attended_transfer_type() and a new
subtype AST_ATTENDED_TRANSFER_DEST_LOCAL_APP to describe attended
transfers where a local channel is used to connect a dialplan
application to a bridge in cases where a single remote party can not be
moved directly into the application. Previously, the local channel half
being pushed into the bridge in place of a transferer leg was not
conveyed in the message.

ASTERISK-23941
Review: https://reviewboard.asterisk.org/r/3728/

Modified:
    team/group/ari-greedy-atxfer/apps/app_queue.c
    team/group/ari-greedy-atxfer/include/asterisk/stasis_bridges.h
    team/group/ari-greedy-atxfer/main/bridge.c
    team/group/ari-greedy-atxfer/main/cel.c
    team/group/ari-greedy-atxfer/main/stasis_bridges.c
    team/group/ari-greedy-atxfer/res/ari/ari_model_validators.c
    team/group/ari-greedy-atxfer/res/ari/ari_model_validators.h
    team/group/ari-greedy-atxfer/rest-api/api-docs/events.json

Modified: team/group/ari-greedy-atxfer/apps/app_queue.c
URL: http://svnview.digium.com/svn/asterisk/team/group/ari-greedy-atxfer/apps/app_queue.c?view=diff&rev=419313&r1=419312&r2=419313
==============================================================================
--- team/group/ari-greedy-atxfer/apps/app_queue.c (original)
+++ team/group/ari-greedy-atxfer/apps/app_queue.c Wed Jul 23 10:56:18 2014
@@ -5545,6 +5545,7 @@
 		ast_str_set(&transfer_str, 0, "BRIDGE|%s", atxfer_msg->dest.bridge);
 		break;
 	case AST_ATTENDED_TRANSFER_DEST_APP:
+	case AST_ATTENDED_TRANSFER_DEST_LOCAL_APP:
 		ast_str_set(&transfer_str, 0, "APP|%s", atxfer_msg->dest.app);
 		break;
 	case AST_ATTENDED_TRANSFER_DEST_LINK:

Modified: team/group/ari-greedy-atxfer/include/asterisk/stasis_bridges.h
URL: http://svnview.digium.com/svn/asterisk/team/group/ari-greedy-atxfer/include/asterisk/stasis_bridges.h?view=diff&rev=419313&r1=419312&r2=419313
==============================================================================
--- team/group/ari-greedy-atxfer/include/asterisk/stasis_bridges.h (original)
+++ team/group/ari-greedy-atxfer/include/asterisk/stasis_bridges.h Wed Jul 23 10:56:18 2014
@@ -305,6 +305,8 @@
 	AST_ATTENDED_TRANSFER_DEST_BRIDGE_MERGE,
 	/*! The transfer results in a channel or bridge running an application */
 	AST_ATTENDED_TRANSFER_DEST_APP,
+	/*! The transfer results in a channel or bridge running an application via a local channel */
+	AST_ATTENDED_TRANSFER_DEST_LOCAL_APP,
 	/*! The transfer results in both bridges remaining with a local channel linking them */
 	AST_ATTENDED_TRANSFER_DEST_LINK,
 	/*! The transfer results in a threeway call between transferer, transferee, and transfer target */
@@ -323,6 +325,8 @@
 	struct ast_bridge_channel_snapshot_pair to_transferee;
 	/*! Bridge between transferer <-> transfer target and the transferer channel in that bridge. May be NULL */
 	struct ast_bridge_channel_snapshot_pair to_transfer_target;
+	/*! Local channel connecting transferee bridge to application */
+	struct ast_channel_snapshot *replace_channel;
 	/*! Indicates the final state of the transfer */
 	enum ast_attended_transfer_dest_type dest_type;
 	union {
@@ -423,13 +427,18 @@
  *
  * \param is_external Indicates if the transfer was initiated externally
  * \param result The result of the transfer.
- * \param transferee The bridge between the transferer and transferees as well as the transferer channel from that bridge
- * \param target The bridge between the transferer and transfer targets as well as the transferer channel from that bridge
- * \param dest_app The application that the channel or bridge is running upon transfer completion.
+ * \param transferee The bridge between the transferer and transferees as well as the
+ *        transferer channel from that bridge
+ * \param target The bridge between the transferer and transfer targets as well as the
+ *        transferer channel from that bridge
+ * \param replace_channel The channel that will be replacing the transferee bridge
+ *        transferer channel when a local channel is involved
+ * \param dest_app The application that the channel or bridge is running upon transfer
+ *        completion.
  */
 void ast_bridge_publish_attended_transfer_app(int is_external, enum ast_transfer_result result,
 		struct ast_bridge_channel_pair *transferee, struct ast_bridge_channel_pair *target,
-		const char *dest_app);
+		struct ast_channel *replace_channel, const char *dest_app);
 
 /*!
  * \since 12

Modified: team/group/ari-greedy-atxfer/main/bridge.c
URL: http://svnview.digium.com/svn/asterisk/team/group/ari-greedy-atxfer/main/bridge.c?view=diff&rev=419313&r1=419312&r2=419313
==============================================================================
--- team/group/ari-greedy-atxfer/main/bridge.c (original)
+++ team/group/ari-greedy-atxfer/main/bridge.c Wed Jul 23 10:56:18 2014
@@ -3758,6 +3758,8 @@
 	struct ast_bridge_channel_pair to_transferee;
 	/* The bridge between the transferer and transfer target, and the transferer channel in this bridge */
 	struct ast_bridge_channel_pair to_transfer_target;
+	/* The Local;1 that will replace the transferee bridge transferer channel */
+	struct ast_channel *replace_channel;
 };
 
 static void stasis_publish_data_cleanup(struct stasis_attended_transfer_publish_data *publication)
@@ -3766,6 +3768,7 @@
 	ast_channel_unref(publication->to_transfer_target.channel);
 	ao2_cleanup(publication->to_transferee.bridge);
 	ao2_cleanup(publication->to_transfer_target.bridge);
+	ao2_cleanup(publication->replace_channel);
 }
 
 /*!
@@ -3822,7 +3825,8 @@
 		const char *app)
 {
 	ast_bridge_publish_attended_transfer_app(1, AST_BRIDGE_TRANSFER_SUCCESS,
-			&publication->to_transferee, &publication->to_transfer_target, app);
+			&publication->to_transferee, &publication->to_transfer_target,
+			publication->replace_channel, app);
 }
 
 /*
@@ -3914,9 +3918,12 @@
 		return AST_BRIDGE_TRANSFER_FAIL;
 	}
 
+	/* Get a ref for use later since this one is being stolen */
+	ao2_ref(local_chan, +1);
 	if (ast_bridge_impart(bridge1, local_chan, chan1, NULL,
 		AST_BRIDGE_IMPART_CHAN_INDEPENDENT)) {
 		ast_hangup(local_chan);
+		ao2_cleanup(local_chan);
 		return AST_BRIDGE_TRANSFER_FAIL;
 	}
 
@@ -3932,8 +3939,11 @@
 		publish_attended_transfer_link(publication,
 				local_chan, local_chan2);
 	} else {
+		publication->replace_channel = ao2_bump(local_chan);
 		publish_attended_transfer_app(publication, app);
 	}
+
+	ao2_cleanup(local_chan);
 	return AST_BRIDGE_TRANSFER_SUCCESS;
 }
 

Modified: team/group/ari-greedy-atxfer/main/cel.c
URL: http://svnview.digium.com/svn/asterisk/team/group/ari-greedy-atxfer/main/cel.c?view=diff&rev=419313&r1=419312&r2=419313
==============================================================================
--- team/group/ari-greedy-atxfer/main/cel.c (original)
+++ team/group/ari-greedy-atxfer/main/cel.c Wed Jul 23 10:56:18 2014
@@ -1436,6 +1436,7 @@
 		}
 		break;
 	case AST_ATTENDED_TRANSFER_DEST_APP:
+	case AST_ATTENDED_TRANSFER_DEST_LOCAL_APP:
 		extra = ast_json_pack("{s: s, s: s, s: s}",
 			"bridge1_id", bridge1->uniqueid,
 			"channel2_name", channel2->name,

Modified: team/group/ari-greedy-atxfer/main/stasis_bridges.c
URL: http://svnview.digium.com/svn/asterisk/team/group/ari-greedy-atxfer/main/stasis_bridges.c?view=diff&rev=419313&r1=419312&r2=419313
==============================================================================
--- team/group/ari-greedy-atxfer/main/stasis_bridges.c (original)
+++ team/group/ari-greedy-atxfer/main/stasis_bridges.c Wed Jul 23 10:56:18 2014
@@ -782,6 +782,9 @@
 		res |= ast_json_object_set(out, "destination_type", ast_json_string_create("bridge"));
 		res |= ast_json_object_set(out, "destination_bridge", ast_json_string_create(transfer_msg->dest.bridge));
 		break;
+	case AST_ATTENDED_TRANSFER_DEST_LOCAL_APP:
+		res |= ast_json_object_set(out, "replace_channel", ast_channel_snapshot_to_json(transfer_msg->replace_channel, sanitize));
+		/* fallthrough */
 	case AST_ATTENDED_TRANSFER_DEST_APP:
 		res |= ast_json_object_set(out, "destination_type", ast_json_string_create("application"));
 		res |= ast_json_object_set(out, "destination_application", ast_json_string_create(transfer_msg->dest.app));
@@ -873,6 +876,7 @@
 		ast_str_append(&variable_data, 0, "DestBridgeUniqueid: %s\r\n", transfer_msg->dest.bridge);
 		break;
 	case AST_ATTENDED_TRANSFER_DEST_APP:
+	case AST_ATTENDED_TRANSFER_DEST_LOCAL_APP:
 		ast_str_append(&variable_data, 0, "DestType: App\r\n");
 		ast_str_append(&variable_data, 0, "DestApp: %s\r\n", transfer_msg->dest.app);
 		break;
@@ -920,6 +924,7 @@
 
 	bridge_channel_snapshot_pair_cleanup(&msg->to_transferee);
 	bridge_channel_snapshot_pair_cleanup(&msg->to_transfer_target);
+	ao2_cleanup(msg->replace_channel);
 
 	if (msg->dest_type != AST_ATTENDED_TRANSFER_DEST_LINK) {
 		return;
@@ -930,8 +935,9 @@
 	}
 }
 
-static struct ast_attended_transfer_message *attended_transfer_message_create(int is_external, enum ast_transfer_result result,
-		struct ast_bridge_channel_pair *transferee, struct ast_bridge_channel_pair *target)
+static struct ast_attended_transfer_message *attended_transfer_message_create(int is_external,
+		enum ast_transfer_result result, struct ast_bridge_channel_pair *transferee,
+		struct ast_bridge_channel_pair *target, struct ast_channel *replace_channel)
 {
 	RAII_VAR(struct ast_attended_transfer_message *, msg, NULL, ao2_cleanup);
 
@@ -945,6 +951,13 @@
 		return NULL;
 	}
 
+	if (replace_channel) {
+		msg->replace_channel = ast_channel_snapshot_get_latest(ast_channel_uniqueid(replace_channel));
+		if (!msg->replace_channel) {
+			return NULL;
+		}
+	}
+
 	msg->is_external = is_external;
 	msg->result = result;
 
@@ -958,7 +971,7 @@
 	RAII_VAR(struct ast_attended_transfer_message *, transfer_msg, NULL, ao2_cleanup);
 	RAII_VAR(struct stasis_message *, msg, NULL, ao2_cleanup);
 
-	transfer_msg = attended_transfer_message_create(is_external, result, transferee, target);
+	transfer_msg = attended_transfer_message_create(is_external, result, transferee, target, NULL);
 	if (!transfer_msg) {
 		return;
 	}
@@ -980,7 +993,7 @@
 	RAII_VAR(struct ast_attended_transfer_message *, transfer_msg, NULL, ao2_cleanup);
 	RAII_VAR(struct stasis_message *, msg, NULL, ao2_cleanup);
 
-	transfer_msg = attended_transfer_message_create(is_external, result, transferee, target);
+	transfer_msg = attended_transfer_message_create(is_external, result, transferee, target, NULL);
 	if (!transfer_msg) {
 		return;
 	}
@@ -1004,7 +1017,7 @@
 	RAII_VAR(struct ast_attended_transfer_message *, transfer_msg, NULL, ao2_cleanup);
 	RAII_VAR(struct stasis_message *, msg, NULL, ao2_cleanup);
 
-	transfer_msg = attended_transfer_message_create(is_external, result, transferee, target);
+	transfer_msg = attended_transfer_message_create(is_external, result, transferee, target, NULL);
 	if (!transfer_msg) {
 		return;
 	}
@@ -1032,17 +1045,17 @@
 
 void ast_bridge_publish_attended_transfer_app(int is_external, enum ast_transfer_result result,
 		struct ast_bridge_channel_pair *transferee, struct ast_bridge_channel_pair *target,
-		const char *dest_app)
+		struct ast_channel *replace_channel, const char *dest_app)
 {
 	RAII_VAR(struct ast_attended_transfer_message *, transfer_msg, NULL, ao2_cleanup);
 	RAII_VAR(struct stasis_message *, msg, NULL, ao2_cleanup);
 
-	transfer_msg = attended_transfer_message_create(is_external, result, transferee, target);
+	transfer_msg = attended_transfer_message_create(is_external, result, transferee, target, replace_channel);
 	if (!transfer_msg) {
 		return;
 	}
 
-	transfer_msg->dest_type = AST_ATTENDED_TRANSFER_DEST_APP;
+	transfer_msg->dest_type = replace_channel ? AST_ATTENDED_TRANSFER_DEST_LOCAL_APP : AST_ATTENDED_TRANSFER_DEST_APP;
 	ast_copy_string(transfer_msg->dest.app, dest_app, sizeof(transfer_msg->dest.app));
 
 	msg = stasis_message_create(ast_attended_transfer_type(), transfer_msg);
@@ -1061,7 +1074,7 @@
 	RAII_VAR(struct stasis_message *, msg, NULL, ao2_cleanup);
 	int i;
 
-	transfer_msg = attended_transfer_message_create(is_external, result, transferee, target);
+	transfer_msg = attended_transfer_message_create(is_external, result, transferee, target, NULL);
 	if (!transfer_msg) {
 		return;
 	}

Modified: team/group/ari-greedy-atxfer/res/ari/ari_model_validators.c
URL: http://svnview.digium.com/svn/asterisk/team/group/ari-greedy-atxfer/res/ari/ari_model_validators.c?view=diff&rev=419313&r1=419312&r2=419313
==============================================================================
--- team/group/ari-greedy-atxfer/res/ari/ari_model_validators.c (original)
+++ team/group/ari-greedy-atxfer/res/ari/ari_model_validators.c Wed Jul 23 10:56:18 2014
@@ -1684,6 +1684,15 @@
 				res = 0;
 			}
 		} else
+		if (strcmp("replace_channel", ast_json_object_iter_key(iter)) == 0) {
+			int prop_is_valid;
+			prop_is_valid = ast_ari_validate_channel(
+				ast_json_object_iter_value(iter));
+			if (!prop_is_valid) {
+				ast_log(LOG_ERROR, "ARI BridgeAttendedTransfer field replace_channel failed validation\n");
+				res = 0;
+			}
+		} else
 		if (strcmp("result", ast_json_object_iter_key(iter)) == 0) {
 			int prop_is_valid;
 			has_result = 1;

Modified: team/group/ari-greedy-atxfer/res/ari/ari_model_validators.h
URL: http://svnview.digium.com/svn/asterisk/team/group/ari-greedy-atxfer/res/ari/ari_model_validators.h?view=diff&rev=419313&r1=419312&r2=419313
==============================================================================
--- team/group/ari-greedy-atxfer/res/ari/ari_model_validators.h (original)
+++ team/group/ari-greedy-atxfer/res/ari/ari_model_validators.h Wed Jul 23 10:56:18 2014
@@ -1222,6 +1222,7 @@
  * - destination_threeway_channel: Channel
  * - destination_type: string (required)
  * - is_external: boolean (required)
+ * - replace_channel: Channel
  * - result: string (required)
  * - transferer_first_leg: Channel (required)
  * - transferer_first_leg_bridge: Bridge

Modified: team/group/ari-greedy-atxfer/rest-api/api-docs/events.json
URL: http://svnview.digium.com/svn/asterisk/team/group/ari-greedy-atxfer/rest-api/api-docs/events.json?view=diff&rev=419313&r1=419312&r2=419313
==============================================================================
--- team/group/ari-greedy-atxfer/rest-api/api-docs/events.json (original)
+++ team/group/ari-greedy-atxfer/rest-api/api-docs/events.json Wed Jul 23 10:56:18 2014
@@ -324,6 +324,11 @@
 					"required": true,
 					"type": "Channel"
 				},
+				"replace_channel": {
+					"description": "The channel that is replacing transferer_first_leg in the swap",
+					"required": false,
+					"type": "Channel"
+				},
 				"result": {
 					"description": "The result of the transfer attempt",
 					"required": true,




More information about the asterisk-commits mailing list