[asterisk-commits] rmudgett: branch rmudgett/bridge_tasks r427909 - in /team/rmudgett/bridge_tas...

SVN commits to the Asterisk project asterisk-commits at lists.digium.com
Fri Nov 14 12:18:55 CST 2014


Author: rmudgett
Date: Fri Nov 14 12:18:41 2014
New Revision: 427909

URL: http://svnview.digium.com/svn/asterisk?view=rev&rev=427909
Log:
Resolve; reset automerge.

Modified:
    team/rmudgett/bridge_tasks/   (props changed)
    team/rmudgett/bridge_tasks/apps/app_queue.c
    team/rmudgett/bridge_tasks/configs/samples/cdr.conf.sample
    team/rmudgett/bridge_tasks/include/asterisk/stasis_bridges.h
    team/rmudgett/bridge_tasks/main/bridge.c
    team/rmudgett/bridge_tasks/main/bridge_basic.c
    team/rmudgett/bridge_tasks/main/cdr.c
    team/rmudgett/bridge_tasks/main/cel.c
    team/rmudgett/bridge_tasks/main/stasis_bridges.c
    team/rmudgett/bridge_tasks/main/stun.c
    team/rmudgett/bridge_tasks/res/stasis/app.c
    team/rmudgett/bridge_tasks/tests/test_cel.c

Propchange: team/rmudgett/bridge_tasks/
------------------------------------------------------------------------------
    automerge = *

Propchange: team/rmudgett/bridge_tasks/
------------------------------------------------------------------------------
Binary property 'branch-13-merged' - no diff available.

Propchange: team/rmudgett/bridge_tasks/
------------------------------------------------------------------------------
--- bridge_tasks-integrated (original)
+++ bridge_tasks-integrated Fri Nov 14 12:18:41 2014
@@ -1,1 +1,1 @@
-/trunk:1-427871
+/trunk:1-427903

Modified: team/rmudgett/bridge_tasks/apps/app_queue.c
URL: http://svnview.digium.com/svn/asterisk/team/rmudgett/bridge_tasks/apps/app_queue.c?view=diff&rev=427909&r1=427908&r2=427909
==============================================================================
--- team/rmudgett/bridge_tasks/apps/app_queue.c (original)
+++ team/rmudgett/bridge_tasks/apps/app_queue.c Fri Nov 14 12:18:41 2014
@@ -5772,7 +5772,7 @@
 	ao2_lock(queue_data);
 
 	if (ast_strlen_zero(queue_data->bridge_uniqueid) ||
-			strcmp(queue_data->bridge_uniqueid, transfer_msg->to_transferee.bridge_snapshot->uniqueid)) {
+			strcmp(queue_data->bridge_uniqueid, transfer_msg->bridge->uniqueid)) {
 		ao2_unlock(queue_data);
 		return;
 	}

Modified: team/rmudgett/bridge_tasks/configs/samples/cdr.conf.sample
URL: http://svnview.digium.com/svn/asterisk/team/rmudgett/bridge_tasks/configs/samples/cdr.conf.sample?view=diff&rev=427909&r1=427908&r2=427909
==============================================================================
--- team/rmudgett/bridge_tasks/configs/samples/cdr.conf.sample (original)
+++ team/rmudgett/bridge_tasks/configs/samples/cdr.conf.sample Fri Nov 14 12:18:41 2014
@@ -13,20 +13,13 @@
 ; any loading of backend CDR modules.  Default is "yes".
 ;enable=yes
 
-; Define whether or not to log unanswered calls. Setting this to "yes" will
-; report every attempt to ring a phone in dialing attempts, when it was not
-; answered. For example, if you try to dial 3 extensions, and this option is "yes",
-; you will get 3 CDR's, one for each phone that was rung. Default is "no". Some
-; find this information horribly useless. Others find it very valuable. Note, in "yes"
-; mode, you will see one CDR, with one of the call targets on one side, and the originating
-; channel on the other, and then one CDR for each channel attempted. This may seem
-; redundant, but cannot be helped.
-;
-; In brief, this option controls the reporting of unanswered calls which only have an A 
-; party. Calls which get offered to an outgoing line, but are unanswered, are still 
-; logged, and that is the intended behaviour. (It also results in some B side CDRs being
-; output, as they have the B side channel as their source channel, and no destination 
-; channel.)
+; Define whether or not to log unanswered calls that don't involve an outgoing
+; party. Setting this to "yes" will make calls to extensions that don't answer
+; and don't set a B side channel (such as by using the Dial application)
+; receive CDR log entries. If this option is set to "no", then those log
+; entries will not be created. Unasnwered Calls which get offered to an
+; outgoing line will always receive log entries regardless of this option, and
+; that is the intended behaviour.
 ;unanswered = no
 
 ; Define whether or not to log congested calls. Setting this to "yes" will

Modified: team/rmudgett/bridge_tasks/include/asterisk/stasis_bridges.h
URL: http://svnview.digium.com/svn/asterisk/team/rmudgett/bridge_tasks/include/asterisk/stasis_bridges.h?view=diff&rev=427909&r1=427908&r2=427909
==============================================================================
--- team/rmudgett/bridge_tasks/include/asterisk/stasis_bridges.h (original)
+++ team/rmudgett/bridge_tasks/include/asterisk/stasis_bridges.h Fri Nov 14 12:18:41 2014
@@ -269,14 +269,6 @@
 };
 
 /*!
- * \brief Pair showing a bridge and a specific channel belonging to the bridge
- */
-struct ast_bridge_channel_pair {
-	struct ast_bridge *bridge;
-	struct ast_channel *channel;
-};
-
-/*!
  * \since 12
  * \brief Message type for \ref ast_blind_transfer_message.
  *
@@ -292,8 +284,10 @@
 	enum ast_transfer_result result;
 	/*! True if the transfer was initiated by an external source (i.e. not DTMF-initiated) */
 	int is_external;
-	/*! Transferer and its bridge */
-	struct ast_bridge_channel_snapshot_pair to_transferee;
+	/*! The transferring channel */
+	struct ast_channel_snapshot *transferer;
+	/*! The bridge between the transferer and the transferee */
+	struct ast_bridge_snapshot *bridge;
 	/*! Destination context */
 	char context[AST_MAX_CONTEXT];
 	/*! Destination extension */
@@ -303,6 +297,21 @@
 	/*! The channel replacing the transferer when multiple parties are being transferred */
 	struct ast_channel_snapshot *replace_channel;
 };
+
+/*!
+ * \brief Create a blind transfer message to be published
+ *
+ * \param is_external Whether the blind transfer was initiated externally (e.g. via AMI or native protocol)
+ * \param transferer The transferer's channel that is bridged to the transferee
+ * \param bridge The bridge the transferer and transferee are in
+ * \param context The destination context for the blind transfer
+ * \param exten The destination extension for the blind transfer
+ *
+ * \retval NULL Failure to allocate or create snapshots
+ * \retval non-NULL The created blind transfer message
+ */
+struct ast_blind_transfer_message *ast_blind_transfer_message_create(int is_external,
+		struct ast_channel *transferer, const char *exten, const char *context);
 
 /*!
  * \brief Publish a blind transfer event
@@ -320,9 +329,7 @@
  *                        cannot reach across the bridge due to bridge flags, this is
  *                        the channel connecting their bridge to the destination.
  */
-void ast_bridge_publish_blind_transfer(int is_external, enum ast_transfer_result result,
-		struct ast_bridge_channel_pair *to_transferee, const char *context, const char *exten,
-		struct ast_channel *transferee_channel, struct ast_channel *replace_channel);
+void ast_bridge_publish_blind_transfer(struct ast_blind_transfer_message *transfer_message);
 
 enum ast_attended_transfer_dest_type {
 	/*! The transfer failed, so there is no appropriate final state */
@@ -372,145 +379,111 @@
 };
 
 /*!
+ * \brief Create an Attended transfer message to be published.
+ *
+ * The parameters to this function are the basic necessities in order to create the
+ * initial attended transfer message.
+ *
+ * The transferee and transfer_target parameters are optional. If not provided, then this
+ * function will attempt to determine who the transferee and transfer target are based on
+ * the input transferer channels and bridges. You typically will not need to provide an
+ * explicit transferee and transfer target channel unless your attended transfer is implemented
+ * in a strange way.
+ *
+ * \param is_external Non-zero if the transfer was initiated by a native channel driver protocol.
+ * \param to_transferee The transferer channel that is bridged to the transferee channel.
+ * \param transferee_bridge The bridge between the transferer and transferee. May be NULL.
+ * \param to_transfer_target The transferer channel that is bridged to the transfer target.
+ * \param target_bridge The bridge between the transferer and transfer target. May be NULL.
+ * \param transferee The channel that is being transferred. Optional.
+ * \param transfer_target The channel that is being transferred to. Optional.
+ *
+ * \retval NULL Failure to allocate or create snapshots
+ * \retval non-NULL The created attended transfer message
+ */
+struct ast_attended_transfer_message *ast_attended_transfer_message_create(
+		int is_external, struct ast_channel *to_transferee, struct ast_bridge *transferee_bridge,
+		struct ast_channel *to_transfer_target, struct ast_bridge *target_bridge,
+		struct ast_channel *transferee, struct ast_channel *transfer_target);
+
+/*!
+ * \brief Add details for a bridge merge to an attended transfer message.
+ *
+ * If the transfer is accomplished by a bridge merge (or swap optimization), then this should
+ * be called on the created attended transfer message to have the appropriate details added on.
+ *
+ * \param transfer_msg The transfer message to add details to
+ * \param final_bridge The bridge where the surviving parties reside
+ *
+ * \retval 0 Success
+ * \retval -1 Failure
+ */
+int ast_attended_transfer_message_add_merge(struct ast_attended_transfer_message *transfer_msg,
+		struct ast_bridge *final_bridge);
+
+/*!
+ * \brief Add details for an attended transfer that was resolved as a three-way call
+ *
+ * If the transfer results in a three-way call between the transferer, the transferee, and the
+ * transfer target, then this should be called in order to add appropriate details to the
+ * transfer message to be published.
+ *
+ * \param transfer_msg The message to add details to
+ * \param survivor_channel The transferer channel that exists in the three-way call
+ * \param survivor_bridge The bridge where the three-way call takes place.
+ *
+ * \retval 0 Success
+ * \retval -1 Failure
+ */
+int ast_attended_transfer_message_add_threeway(struct ast_attended_transfer_message *transfer_msg,
+		struct ast_channel *survivor_channel, struct ast_bridge *survivor_bridge);
+
+/*!
+ * \brief Add details for an attended transfer to an application
+ *
+ * If the transfer is sending one or more parties into an application, then this should be called
+ * to add appropriate details to the transfer message being published.
+ *
+ * \param transfer_msg The message to add details to
+ * \param app The name of the application that the parties are being transferred to
+ * \param replace_channel The local channel that is in the bridge and running the application
+ *
+ * \retval 0 Success
+ * \retval -1 Failure
+ */
+int ast_attended_transfer_message_add_app(struct ast_attended_transfer_message *transfer_msg,
+		const char *app, struct ast_channel *replace_channel);
+
+/*!
+ * \brief Add details for an attended transfer that has a link between bridges.
+ *
+ * An attended transfer may be accomplished by linking two bridges together with local channels.
+ * If this is how the transfer is to be completed, call this function in order to fill in details
+ * about the transfer.
+ *
+ * \param transfer_msg The message to add details to.
+ * \param locals An array of local channel halves that each are in one of the involved bridges.
+ *
+ * \retval 0 Success
+ * \retval -1 Failure
+ */
+int ast_attended_transfer_message_add_link(struct ast_attended_transfer_message *transfer_msg,
+		struct ast_channel *locals[2]);
+
+/*!
+ * \brief Publish an attended transfer
+ *
+ * \param transfer_msg The transfer message to publish
+ */
+void ast_bridge_publish_attended_transfer(struct ast_attended_transfer_message *transfer_msg);
+
+/*!
  * \since 12
  * \brief Message type for \ref ast_attended_transfer_message.
  *
  * \retval Message type for \ref ast_attended_transfer_message.
  */
 struct stasis_message_type *ast_attended_transfer_type(void);
-
-/*!
- * \since 12
- * \brief Publish an attended transfer failure
- *
- * Publish an \ref ast_attended_transfer_message with the dest_type set to
- * \c AST_ATTENDED_TRANSFER_DEST_FAIL.
- *
- * \pre Bridges involved are locked. Channels involved are not locked.
- *
- * \param is_external Indicates if the transfer was initiated externally
- * \param result The result of the transfer. Will always be a type of failure.
- * \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 transferee_channel If a single channel is being transferred, this is it. If multiple parties are being transferred, this is NULL.
- * \param target_channel If a single channel is being transferred to, this is it. If multiple parties are being transferred to, this is NULL.
- */
-void ast_bridge_publish_attended_transfer_fail(int is_external, enum ast_transfer_result result,
-		struct ast_bridge_channel_pair *transferee, struct ast_bridge_channel_pair *target,
-		struct ast_channel *transferee_channel, struct ast_channel *target_channel);
-
-/*!
- * \since 12
- * \brief Publish an attended transfer that results in two bridges becoming one.
- *
- * Publish an \ref ast_attended_transfer_message with the dest_type set to
- * \c AST_ATTENDED_TRANSFER_DEST_BRIDGE_MERGE. This type of attended transfer results from
- * having two bridges involved and either
- *
- * \li Merging the two bridges together
- * \li Moving a channel from one bridge to the other, thus emptying a bridge
- *
- * In either case, two bridges enter, one leaves.
- *
- * \pre Bridges involved are locked. Channels involved are not locked.
- *
- * \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 final_bridge The bridge that the parties end up in. Will be a bridge from the transferee or target pair.
- * \param transferee_channel If a single channel is being transferred, this is it. If multiple parties are being transferred, this is NULL.
- * \param target_channel If a single channel is being transferred to, this is it. If multiple parties are being transferred to, this is NULL.
- */
-void ast_bridge_publish_attended_transfer_bridge_merge(int is_external, enum ast_transfer_result result,
-		struct ast_bridge_channel_pair *transferee, struct ast_bridge_channel_pair *target,
-		struct ast_bridge *final_bridge, struct ast_channel *transferee_channel,
-		struct ast_channel *target_channel);
-
-/*!
- * \since 12
- * \brief Publish an attended transfer that results in a threeway call.
- *
- * Publish an \ref ast_attended_transfer_message with the dest_type set to
- * \c AST_ATTENDED_TRANSFER_DEST_THREEWAY. Like with \ref ast_bridge_publish_attended_transfer_bridge_merge,
- * this results from merging two bridges together. The difference is that a
- * transferer channel survives the bridge merge
- *
- * \pre Bridges involved are locked. Channels involved are not locked.
- *
- * \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 final_pair The bridge that the parties end up in, and the transferer channel that is in this bridge.
- * \param transferee_channel If a single channel is being transferred, this is it. If multiple parties are being transferred, this is NULL.
- * \param target_channel If a single channel is being transferred to, this is it. If multiple parties are being transferred to, this is NULL.
- */
-void ast_bridge_publish_attended_transfer_threeway(int is_external, enum ast_transfer_result result,
-		struct ast_bridge_channel_pair *transferee, struct ast_bridge_channel_pair *target,
-		struct ast_bridge_channel_pair *final_pair, struct ast_channel *transferee_channel,
-		struct ast_channel *target_channel);
-
-/*!
- * \since 12
- * \brief Publish an attended transfer that results in an application being run
- *
- * Publish an \ref ast_attended_transfer_message with the dest_type set to
- * \c AST_ATTENDED_TRANSFER_DEST_APP. This occurs when an attended transfer
- * results in either:
- *
- * \li A transferee channel leaving a bridge to run an app
- * \li A bridge of transferees running an app (via a local channel)
- *
- * \pre Bridges involved are locked. Channels involved are not locked.
- *
- * \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 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.
- * \param transferee_channel If a single channel is being transferred, this is it.
- *        If multiple parties are being transferred, this is NULL.
- * \param target_channel If a single channel is being transferred to, this is it.
- *        If multiple parties are being transferred to, this is NULL.
- */
-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,
-		struct ast_channel *replace_channel, const char *dest_app,
-		struct ast_channel *transferee_channel, struct ast_channel *target_channel);
-
-/*!
- * \since 12
- * \brief Publish an attended transfer that results in two bridges linked by a local channel
- *
- * Publish an \ref ast_attended_transfer_message with the dest_type set to
- * \c AST_ATTENDED_TRANSFER_DEST_LINK. This occurs when two bridges are involved
- * in an attended transfer, but their properties do not allow for the bridges to
- * merge or to have channels moved off of the bridge. An example of this occurs when
- * attempting to transfer a ConfBridge to another bridge.
- *
- * When this type of transfer occurs, the two bridges continue to exist after the
- * transfer and a local channel is used to link the two bridges together.
- *
- * \pre Bridges involved are locked. Channels involved are not locked.
- *
- * \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 locals The local channels linking the bridges together.
- * \param transferee_channel If a single channel is being transferred, this is it. If multiple parties are being transferred, this is NULL.
- * \param target_channel If a single channel is being transferred to, this is it. If multiple parties are being transferred to, this is NULL.
- */
-void ast_bridge_publish_attended_transfer_link(int is_external, enum ast_transfer_result result,
-		struct ast_bridge_channel_pair *transferee, struct ast_bridge_channel_pair *target,
-		struct ast_channel *locals[2], struct ast_channel *transferee_channel,
-		struct ast_channel *target_channel);
 
 /*!
  * \brief Returns the most recent snapshot for the bridge.

Modified: team/rmudgett/bridge_tasks/main/bridge.c
URL: http://svnview.digium.com/svn/asterisk/team/rmudgett/bridge_tasks/main/bridge.c?view=diff&rev=427909&r1=427908&r2=427909
==============================================================================
--- team/rmudgett/bridge_tasks/main/bridge.c (original)
+++ team/rmudgett/bridge_tasks/main/bridge.c Fri Nov 14 12:18:41 2014
@@ -3862,26 +3862,6 @@
 	return mute;
 }
 
-static void publish_blind_transfer_full(int is_external, enum ast_transfer_result result,
-		struct ast_channel *transferer, struct ast_bridge *bridge,
-		const char *context, const char *exten, struct ast_channel *transferee_channel,
-		struct ast_channel *replace_channel)
-{
-	struct ast_bridge_channel_pair pair;
-
-	pair.channel = transferer;
-	pair.bridge = bridge;
-
-	if (bridge) {
-		ast_bridge_lock(bridge);
-	}
-	ast_bridge_publish_blind_transfer(is_external, result, &pair, context, exten,
-		transferee_channel, replace_channel);
-	if (bridge) {
-		ast_bridge_unlock(bridge);
-	}
-}
-
 /*!
  * \internal
  * \brief Transfer an entire bridge to a specific destination.
@@ -3898,9 +3878,12 @@
  * \param transferer The channel performing a transfer
  * \param bridge The bridge where the transfer is being performed
  * \param exten The destination extension for the blind transfer
+ * \param context The destination context for the blind transfer
  * \param transferee The party being transferred if there is only one
- * \param context The destination context for the blind transfer
- * \param hook Framehook to attach to local channel
+ * \param new_channel_cb Callback to call on channel that is created to
+ *        facilitate the blind transfer.
+ * \param user_data_wrapper User-provided data needed in new_channel_cb
+ * \param transfer_message The Stasis publication for this transfer.
  *
  * \return The success or failure of the operation
  */
@@ -3908,7 +3891,8 @@
 		struct ast_channel *transferer, struct ast_bridge *bridge,
 		const char *exten, const char *context, struct ast_channel *transferee,
 		transfer_channel_cb new_channel_cb,
-		struct transfer_channel_data *user_data_wrapper)
+		struct transfer_channel_data *user_data_wrapper,
+		struct ast_blind_transfer_message *transfer_message)
 {
 	struct ast_channel *local;
 	char chan_name[AST_MAX_EXTENSION + AST_MAX_CONTEXT + 2];
@@ -3923,6 +3907,13 @@
 
 	ast_channel_lock_both(local, transferer);
 	ast_channel_req_accountcodes(local, transferer, AST_CHANNEL_REQUESTOR_REPLACEMENT);
+
+	transfer_message->replace_channel = ast_channel_snapshot_get_latest(ast_channel_uniqueid(local));
+	if (!transfer_message->replace_channel) {
+		ast_hangup(local);
+		return AST_BRIDGE_TRANSFER_FAIL;
+	}
+
 	pbx_builtin_setvar_helper(local, BLINDTRANSFER, ast_channel_name(transferer));
 	ast_channel_unlock(local);
 	ast_channel_unlock(transferer);
@@ -3935,32 +3926,15 @@
 		ast_hangup(local);
 		return AST_BRIDGE_TRANSFER_FAIL;
 	}
+
 	if (ast_bridge_impart(bridge, local, transferer, NULL,
 		AST_BRIDGE_IMPART_CHAN_INDEPENDENT)) {
 		ast_hangup(local);
 		return AST_BRIDGE_TRANSFER_FAIL;
 	}
-	publish_blind_transfer_full(is_external, AST_BRIDGE_TRANSFER_SUCCESS, transferer, bridge,
-		context, exten, transferee, local);
+
 	return AST_BRIDGE_TRANSFER_SUCCESS;
 }
-
-/*!
- * \internal
- * \brief Base data to publish for stasis attended transfer messages
- */
-struct stasis_attended_transfer_publish_data {
-	/* The bridge between the transferer and transferee, and the transferer channel in this bridge */
-	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;
-	/* The transferee channel. NULL if there is no transferee channel or if multiple parties are transferred */
-	struct ast_channel *transferee_channel;
-	/* The transfer target channel. NULL if there is no transfer target channel or if multiple parties are transferred */
-	struct ast_channel *target_channel;
-};
 
 /*!
  * \internal
@@ -3991,118 +3965,6 @@
 
 	ao2_iterator_destroy(&channel_iter);
 	return transferee;
-}
-
-
-static void stasis_publish_data_cleanup(struct stasis_attended_transfer_publish_data *publication)
-{
-	ast_channel_unref(publication->to_transferee.channel);
-	ast_channel_unref(publication->to_transfer_target.channel);
-	ast_channel_cleanup(publication->transferee_channel);
-	ast_channel_cleanup(publication->target_channel);
-	ao2_cleanup(publication->to_transferee.bridge);
-	ao2_cleanup(publication->to_transfer_target.bridge);
-	ao2_cleanup(publication->replace_channel);
-}
-
-/*!
- * \internal
- * \brief Set up base data for an attended transfer stasis publication
- *
- * \param to_transferee The original transferer channel, which may be bridged to a transferee
- * \param to_transferee_bridge The bridge that to_transferee is in.
- * \param to_transfer_target The second transferer channel, which may be bridged to a transfer target
- * \param to_target_bridge The bridge that to_transfer_target_is in.
- * \param[out] publication A structure to hold the other parameters
- */
-static void stasis_publish_data_init(struct ast_channel *to_transferee,
-		struct ast_bridge *to_transferee_bridge, struct ast_channel *to_transfer_target,
-		struct ast_bridge *to_target_bridge,
-		struct stasis_attended_transfer_publish_data *publication)
-{
-	memset(publication, 0, sizeof(*publication));
-	publication->to_transferee.channel = ast_channel_ref(to_transferee);
-	if (to_transferee_bridge) {
-		ao2_ref(to_transferee_bridge, +1);
-		publication->to_transferee.bridge = to_transferee_bridge;
-	}
-
-	publication->to_transfer_target.channel = ast_channel_ref(to_transfer_target);
-	if (to_target_bridge) {
-		ao2_ref(to_target_bridge, +1);
-		publication->to_transfer_target.bridge = to_target_bridge;
-	}
-
-	if (to_transferee_bridge) {
-		publication->transferee_channel = ast_bridge_peer(to_transferee_bridge, to_transferee);
-	}
-	if (to_target_bridge) {
-		publication->target_channel = ast_bridge_peer(to_target_bridge, to_transfer_target);
-	}
-}
-
-/*
- * \internal
- * \brief Publish a stasis attended transfer resulting in a bridge merge
- *
- * \param publication Base data about the attended transfer
- * \param final_bridge The surviving bridge of the attended transfer
- */
-static void publish_attended_transfer_bridge_merge(struct stasis_attended_transfer_publish_data *publication,
-		struct ast_bridge *final_bridge)
-{
-	ast_bridge_publish_attended_transfer_bridge_merge(1, AST_BRIDGE_TRANSFER_SUCCESS,
-			&publication->to_transferee, &publication->to_transfer_target, final_bridge,
-			publication->transferee_channel, publication->target_channel);
-}
-
-/*
- * \internal
- * \brief Publish a stasis attended transfer to an application
- *
- * \param publication Base data about the attended transfer
- * \param app The app that is running at the conclusion of the transfer
- */
-static void publish_attended_transfer_app(struct stasis_attended_transfer_publish_data *publication,
-		const char *app)
-{
-	ast_bridge_publish_attended_transfer_app(1, AST_BRIDGE_TRANSFER_SUCCESS,
-			&publication->to_transferee, &publication->to_transfer_target,
-			publication->replace_channel, app,
-			publication->transferee_channel, publication->target_channel);
-}
-
-/*
- * \internal
- * \brief Publish a stasis attended transfer showing a link between bridges
- *
- * \param publication Base data about the attended transfer
- * \param local_channel1 Local channel in the original bridge
- * \param local_channel2 Local channel in the second bridge
- */
-static void publish_attended_transfer_link(struct stasis_attended_transfer_publish_data *publication,
-		struct ast_channel *local_channel1, struct ast_channel *local_channel2)
-{
-	struct ast_channel *locals[2] = { local_channel1, local_channel2 };
-
-	ast_bridge_publish_attended_transfer_link(1, AST_BRIDGE_TRANSFER_SUCCESS,
-			&publication->to_transferee, &publication->to_transfer_target, locals,
-			publication->transferee_channel, publication->target_channel);
-}
-
-/*
- * \internal
- * \brief Publish a stasis attended transfer failure
- *
- * \param publication Base data about the attended transfer
- * \param result The transfer result
- */
-static void publish_attended_transfer_fail(struct stasis_attended_transfer_publish_data *publication,
-		enum ast_transfer_result result)
-{
-	ast_bridge_publish_attended_transfer_fail(1, result, &publication->to_transferee,
-			&publication->to_transfer_target, publication->transferee_channel,
-			publication->target_channel);
 }
 
 /*!
@@ -4129,7 +3991,7 @@
  */
 static enum ast_transfer_result attended_transfer_bridge(struct ast_channel *chan1,
 		struct ast_channel *chan2, struct ast_bridge *bridge1, struct ast_bridge *bridge2,
-		struct stasis_attended_transfer_publish_data *publication)
+		struct ast_attended_transfer_message *transfer_msg)
 {
 	static const char *dest = "_attended at transfer/m";
 	struct ast_channel *local_chan;
@@ -4177,6 +4039,7 @@
 
 	if (bridge2) {
 		RAII_VAR(struct ast_channel *, local_chan2, NULL, ao2_cleanup);
+		struct ast_channel *locals[2];
 
 		ast_channel_lock(local_chan);
 		local_chan2 = ast_local_get_peer(local_chan);
@@ -4184,11 +4047,12 @@
 
 		ast_assert(local_chan2 != NULL);
 
-		publish_attended_transfer_link(publication,
-				local_chan, local_chan2);
+		locals[0] = local_chan;
+		locals[1] = local_chan2;
+
+		ast_attended_transfer_message_add_link(transfer_msg, locals);
 	} else {
-		publication->replace_channel = ao2_bump(local_chan);
-		publish_attended_transfer_app(publication, app);
+		ast_attended_transfer_message_add_app(transfer_msg, app, local_chan);
 	}
 
 	ao2_cleanup(local_chan);
@@ -4294,14 +4158,6 @@
 	return bridge;
 }
 
-static void publish_blind_transfer(int is_external, enum ast_transfer_result result,
-		struct ast_channel *transferer, struct ast_bridge *bridge,
-		const char *context, const char *exten, struct ast_channel *transferee_channel)
-{
-	publish_blind_transfer_full(is_external, result, transferer, bridge, context,
-		exten, transferee_channel, NULL);
-}
-
 enum ast_transfer_result ast_bridge_transfer_blind(int is_external,
 		struct ast_channel *transferer, const char *exten, const char *context,
 		transfer_channel_cb new_channel_cb, void *user_data)
@@ -4311,9 +4167,20 @@
 	RAII_VAR(struct ao2_container *, channels, NULL, ao2_cleanup);
 	RAII_VAR(struct ast_channel *, transferee, NULL, ast_channel_cleanup);
 	RAII_VAR(struct transfer_channel_data *, user_data_wrapper, NULL, ao2_cleanup);
+	RAII_VAR(struct ast_blind_transfer_message *, transfer_message, NULL, ao2_cleanup);
 	int do_bridge_transfer;
 	int transfer_prohibited;
 	enum ast_transfer_result transfer_result;
+
+	transfer_message = ast_blind_transfer_message_create(is_external, transferer, exten, context);
+	if (!transfer_message) {
+		/* Out of memory. Not even possible to publish a Stasis message about the
+		 * failure
+		 */
+		ast_log(LOG_ERROR, "Unable to allocate memory for blind transfer publication from %s\n",
+				ast_channel_name(transferer));
+		return AST_BRIDGE_TRANSFER_FAIL;
+	}
 
 	bridge = acquire_bridge(transferer);
 	if (!bridge) {
@@ -4321,7 +4188,22 @@
 		goto publish;
 	}
 
+	ast_bridge_lock(bridge);
+	transfer_message->bridge = ast_bridge_snapshot_create(bridge);
+	ast_bridge_unlock(bridge);
+	if (!transfer_message->bridge) {
+		transfer_result = AST_BRIDGE_TRANSFER_FAIL;
+		goto publish;
+	}
+
 	transferee = ast_bridge_peer(bridge, transferer);
+	if (transferee) {
+		transfer_message->transferee = ast_channel_snapshot_get_latest(ast_channel_uniqueid(transferee));
+		if (!transfer_message->transferee) {
+			transfer_result = AST_BRIDGE_TRANSFER_FAIL;
+			goto publish;
+		}
+	}
 
 	ast_channel_lock(transferer);
 	bridge_channel = ast_channel_get_bridge_channel(transferer);
@@ -4377,12 +4259,8 @@
 	set_transfer_variables_all(transferer, channels, 0);
 
 	if (do_bridge_transfer) {
-		/* if blind_transfer_bridge succeeds, it publishes its own message */
 		transfer_result = blind_transfer_bridge(is_external, transferer, bridge,
-			exten, context, transferee, new_channel_cb, user_data_wrapper);
-		if (transfer_result == AST_BRIDGE_TRANSFER_SUCCESS)  {
-			return transfer_result;
-		}
+			exten, context, transferee, new_channel_cb, user_data_wrapper, transfer_message);
 		goto publish;
 	}
 
@@ -4403,7 +4281,8 @@
 	transfer_result = AST_BRIDGE_TRANSFER_SUCCESS;
 
 publish:
-	publish_blind_transfer(is_external, transfer_result, transferer, bridge, context, exten, transferee);
+	transfer_message->result = transfer_result;
+	ast_bridge_publish_blind_transfer(transfer_message);
 	return transfer_result;
 }
 
@@ -4470,7 +4349,7 @@
 		struct ast_channel *to_transfer_target,
 		struct ast_bridge_channel *to_target_bridge_channel,
 		struct ast_bridge *to_transferee_bridge, struct ast_bridge *to_target_bridge,
-		struct stasis_attended_transfer_publish_data *publication)
+		struct ast_attended_transfer_message *transfer_msg)
 {
 	struct ast_bridge_channel *kick_me[] = {
 			to_transferee_bridge_channel,
@@ -4516,20 +4395,16 @@
 		 */
 		if (to_transferee_bridge->inhibit_merge || to_transferee_bridge->dissolved ||
 				to_target_bridge->inhibit_merge || to_target_bridge->dissolved) {
-			res = AST_BRIDGE_TRANSFER_INVALID;
-			goto end;
-		}
-
-		/* Don't goto end here. attended_transfer_bridge will publish its own
-		 * stasis message if it succeeds
-		 */
+			return AST_BRIDGE_TRANSFER_INVALID;
+		}
+
 		return attended_transfer_bridge(to_transferee, to_transfer_target,
-			to_transferee_bridge, to_target_bridge, publication);
+			to_transferee_bridge, to_target_bridge, transfer_msg);
 	}
 
 end:
 	if (res == AST_BRIDGE_TRANSFER_SUCCESS) {
-		publish_attended_transfer_bridge_merge(publication, final_bridge);
+		ast_attended_transfer_message_add_merge(transfer_msg, final_bridge);
 	}
 
 	return res;
@@ -4544,6 +4419,7 @@
 	RAII_VAR(struct ast_bridge_channel *, to_target_bridge_channel, NULL, ao2_cleanup);
 	RAII_VAR(struct ao2_container *, channels, NULL, ao2_cleanup);
 	RAII_VAR(struct ast_channel *, transferee, NULL, ao2_cleanup);
+	RAII_VAR(struct ast_attended_transfer_message *, transfer_msg, NULL, ao2_cleanup);
 	struct ast_bridge *the_bridge = NULL;
 	struct ast_channel *chan_bridged;
 	struct ast_channel *chan_unbridged;
@@ -4551,13 +4427,17 @@
 	int do_bridge_transfer;
 	enum ast_transfer_result res;
 	const char *app = NULL;
-	struct stasis_attended_transfer_publish_data publication;
 
 	to_transferee_bridge = acquire_bridge(to_transferee);
 	to_target_bridge = acquire_bridge(to_transfer_target);
 
-	stasis_publish_data_init(to_transferee, to_transferee_bridge,
-			to_transfer_target, to_target_bridge, &publication);
+	transfer_msg = ast_attended_transfer_message_create(1, to_transferee, to_transferee_bridge,
+			to_transfer_target, to_target_bridge, NULL, NULL);
+	if (!transfer_msg) {
+		ast_log(LOG_ERROR, "Unable to create Stasis publication for attended transfer from %s\n",
+				ast_channel_name(to_transferee));
+		return AST_BRIDGE_TRANSFER_FAIL;
+	}
 
 	/* They can't both be unbridged, you silly goose! */
 	if (!to_transferee_bridge && !to_target_bridge) {
@@ -4622,7 +4502,7 @@
 		ast_bridge_lock_both(to_transferee_bridge, to_target_bridge);
 		res = two_bridge_attended_transfer(to_transferee, to_transferee_bridge_channel,
 				to_transfer_target, to_target_bridge_channel,
-				to_transferee_bridge, to_target_bridge, &publication);
+				to_transferee_bridge, to_target_bridge, transfer_msg);
 		ast_bridge_unlock(to_transferee_bridge);
 		ast_bridge_unlock(to_target_bridge);
 
@@ -4663,7 +4543,7 @@
 
 	if (do_bridge_transfer) {
 		ast_bridge_lock(the_bridge);
-		res = attended_transfer_bridge(chan_bridged, chan_unbridged, the_bridge, NULL, &publication);
+		res = attended_transfer_bridge(chan_bridged, chan_unbridged, the_bridge, NULL, transfer_msg);
 		ast_bridge_unlock(the_bridge);
 		goto end;
 	}
@@ -4682,32 +4562,12 @@
 
 	ast_bridge_remove(the_bridge, chan_bridged);
 
-	ast_bridge_lock(the_bridge);
-	publish_attended_transfer_app(&publication, app);
-	ast_bridge_unlock(the_bridge);
+	ast_attended_transfer_message_add_app(transfer_msg, app, NULL);
 	res = AST_BRIDGE_TRANSFER_SUCCESS;
 
 end:
-	/* All successful transfer paths have published an appropriate stasis message.
-	 * All failure paths have deferred publishing a stasis message until this point
-	 */
-	if (res != AST_BRIDGE_TRANSFER_SUCCESS) {
-		if (to_transferee_bridge && to_target_bridge) {
-			ast_bridge_lock_both(to_transferee_bridge, to_target_bridge);
-		} else if (the_bridge) {
-			ast_bridge_lock(the_bridge);
-		}
-
-		publish_attended_transfer_fail(&publication, res);
-
-		if (to_transferee_bridge && to_target_bridge) {
-			ast_bridge_unlock(to_transferee_bridge);
-			ast_bridge_unlock(to_target_bridge);
-		} else if (the_bridge) {
-			ast_bridge_unlock(the_bridge);
-		}
-	}
-	stasis_publish_data_cleanup(&publication);
+	transfer_msg->result = res;
+	ast_bridge_publish_attended_transfer(transfer_msg);
 	return res;
 }
 

Modified: team/rmudgett/bridge_tasks/main/bridge_basic.c
URL: http://svnview.digium.com/svn/asterisk/team/rmudgett/bridge_tasks/main/bridge_basic.c?view=diff&rev=427909&r1=427908&r2=427909
==============================================================================
--- team/rmudgett/bridge_tasks/main/bridge_basic.c (original)
+++ team/rmudgett/bridge_tasks/main/bridge_basic.c Fri Nov 14 12:18:41 2014
@@ -1606,33 +1606,21 @@
 static void publish_transfer_success(struct attended_transfer_properties *props,
 		struct ast_channel *transferee_channel, struct ast_channel *target_channel)
 {
-	struct ast_bridge_channel_pair transferee = {
-		.channel = props->transferer,
-		.bridge = props->transferee_bridge,
-	};
-	struct ast_bridge_channel_pair transfer_target = {
-		.channel = props->transferer,
-		.bridge = props->target_bridge,
-	};
-
-	if (transferee.bridge && transfer_target.bridge) {
-		ast_bridge_lock_both(transferee.bridge, transfer_target.bridge);
-	} else if (transferee.bridge) {
-		ast_bridge_lock(transferee.bridge);
-	} else if (transfer_target.bridge) {
-		ast_bridge_lock(transfer_target.bridge);
-	}
-
-	ast_bridge_publish_attended_transfer_bridge_merge(0, AST_BRIDGE_TRANSFER_SUCCESS,
-			&transferee, &transfer_target, props->transferee_bridge, transferee_channel,
-			target_channel);
-
-	if (transferee.bridge) {
-		ast_bridge_unlock(transferee.bridge);
-	}
-	if (transfer_target.bridge) {
-		ast_bridge_unlock(transfer_target.bridge);
-	}
+	struct ast_attended_transfer_message *transfer_msg;
+
+	transfer_msg = ast_attended_transfer_message_create(0, props->transferer,
+			props->transferee_bridge, props->transferer, props->target_bridge,
+			transferee_channel, target_channel);
+
+	if (!transfer_msg) {
+		ast_log(LOG_ERROR, "Unable to publish successful attended transfer from %s\n",
+				ast_channel_name(props->transferer));
+		return;
+	}
+
+	ast_attended_transfer_message_add_merge(transfer_msg, props->transferee_bridge);
+	ast_bridge_publish_attended_transfer(transfer_msg);
+	ao2_cleanup(transfer_msg);
 }
 
 /*!
@@ -1641,37 +1629,22 @@
 static void publish_transfer_threeway(struct attended_transfer_properties *props,
 		struct ast_channel *transferee_channel, struct ast_channel *target_channel)
 {
-	struct ast_bridge_channel_pair transferee = {
-		.channel = props->transferer,
-		.bridge = props->transferee_bridge,
-	};
-	struct ast_bridge_channel_pair transfer_target = {
-		.channel = props->transferer,
-		.bridge = props->target_bridge,
-	};
-	struct ast_bridge_channel_pair threeway = {
-		.channel = props->transferer,
-		.bridge = props->transferee_bridge,
-	};
-
-	if (transferee.bridge && transfer_target.bridge) {
-		ast_bridge_lock_both(transferee.bridge, transfer_target.bridge);

[... 674 lines stripped ...]



More information about the asterisk-commits mailing list