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@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 ...]

-- 
_____________________________________________________________________
-- Bandwidth and Colocation Provided by http://www.api-digital.com --

svn-commits mailing list
To UNSUBSCRIBE or update options visit:
   http://lists.digium.com/mailman/listinfo/svn-commits

Reply via email to