[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