From cafc1158961f28ad54ebcdc5e042bf8094cbc620 Mon Sep 17 00:00:00 2001 From: Matthew Jordan Date: Thu, 25 Jul 2013 04:06:32 +0000 Subject: A great big renaming patch This patch renames the bridging* files to bridge*. This may seem pedantic and silly, but it fits better in line with current Asterisk naming conventions: * channel is not "channeling" * monitor is not "monitoring" etc. A bridge is an object. It is a first class citizen in Asterisk. "Bridging" is the act of using a bridge on a set of channels - and the API that fulfills that role is more than just the action. (closes issue ASTERISK-22130) git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@395378 65c4cc65-6c06-0410-ace0-fbb531ad65f3 --- include/asterisk/bridge.h | 958 +++++++++++++++++++++++++++ include/asterisk/bridge_after.h | 244 +++++++ include/asterisk/bridge_basic.h | 133 ++++ include/asterisk/bridge_channel.h | 590 +++++++++++++++++ include/asterisk/bridge_channel_internal.h | 193 ++++++ include/asterisk/bridge_features.h | 798 ++++++++++++++++++++++ include/asterisk/bridge_internal.h | 211 ++++++ include/asterisk/bridge_roles.h | 166 +++++ include/asterisk/bridge_technology.h | 242 +++++++ include/asterisk/bridging.h | 958 --------------------------- include/asterisk/bridging_after.h | 244 ------- include/asterisk/bridging_basic.h | 133 ---- include/asterisk/bridging_channel.h | 590 ----------------- include/asterisk/bridging_channel_internal.h | 193 ------ include/asterisk/bridging_features.h | 798 ---------------------- include/asterisk/bridging_internal.h | 211 ------ include/asterisk/bridging_roles.h | 166 ----- include/asterisk/bridging_technology.h | 242 ------- include/asterisk/core_unreal.h | 2 +- include/asterisk/doxygen/architecture.h | 13 +- include/asterisk/features.h | 2 +- include/asterisk/stasis_bridges.h | 421 ++++++++++++ include/asterisk/stasis_bridging.h | 421 ------------ 23 files changed, 3966 insertions(+), 3963 deletions(-) create mode 100644 include/asterisk/bridge.h create mode 100644 include/asterisk/bridge_after.h create mode 100644 include/asterisk/bridge_basic.h create mode 100644 include/asterisk/bridge_channel.h create mode 100644 include/asterisk/bridge_channel_internal.h create mode 100644 include/asterisk/bridge_features.h create mode 100644 include/asterisk/bridge_internal.h create mode 100644 include/asterisk/bridge_roles.h create mode 100644 include/asterisk/bridge_technology.h delete mode 100644 include/asterisk/bridging.h delete mode 100644 include/asterisk/bridging_after.h delete mode 100644 include/asterisk/bridging_basic.h delete mode 100644 include/asterisk/bridging_channel.h delete mode 100644 include/asterisk/bridging_channel_internal.h delete mode 100644 include/asterisk/bridging_features.h delete mode 100644 include/asterisk/bridging_internal.h delete mode 100644 include/asterisk/bridging_roles.h delete mode 100644 include/asterisk/bridging_technology.h create mode 100644 include/asterisk/stasis_bridges.h delete mode 100644 include/asterisk/stasis_bridging.h (limited to 'include') diff --git a/include/asterisk/bridge.h b/include/asterisk/bridge.h new file mode 100644 index 000000000..3d7cf4e06 --- /dev/null +++ b/include/asterisk/bridge.h @@ -0,0 +1,958 @@ +/* + * Asterisk -- An open source telephony toolkit. + * + * Copyright (C) 2007 - 2009, 2013 Digium, Inc. + * + * Richard Mudgett + * Joshua Colp + * + * See http://www.asterisk.org for more information about + * the Asterisk project. Please do not directly contact + * any of the maintainers of this project for assistance; + * the project provides a web site, mailing lists and IRC + * channels for your use. + * + * This program is free software, distributed under the terms of + * the GNU General Public License Version 2. See the LICENSE file + * at the top of the source tree. + */ + +/*! + * \file + * \brief Bridging API + * + * \author Richard Mudgett + * \author Joshua Colp + * \ref AstBridging + * + * See Also: + * \arg \ref AstCREDITS + */ + +/*! + * \page AstBridging Bridging API + * + * The purpose of this API is to provide an easy and flexible way to bridge + * channels of different technologies with different features. + * + * Bridging technologies provide the mechanism that do the actual handling + * of frames between channels. They provide capability information, codec information, + * and preference value to assist the bridging core in choosing a bridging technology when + * creating a bridge. Different bridges may use different bridging technologies based on needs + * but once chosen they all operate under the same premise; they receive frames and send frames. + * + * Bridges are a combination of bridging technology, channels, and features. A + * developer creates a new bridge based on what they are currently expecting to do + * with it or what they will do with it in the future. The bridging core determines what + * available bridging technology will best fit the requirements and creates a new bridge. + * Once created, channels can be added to the bridge in a blocking or non-blocking fashion. + * + * Features are such things as channel muting or DTMF based features such as attended transfer, + * blind transfer, and hangup. Feature information must be set at the most granular level, on + * the channel. While you can use features on a global scope the presence of a feature structure + * on the channel will override the global scope. An example would be having the bridge muted + * at global scope and attended transfer enabled on a channel. Since the channel itself is not muted + * it would be able to speak. + * + * Feature hooks allow a developer to tell the bridging core that when a DTMF string + * is received from a channel a callback should be called in their application. For + * example, a conference bridge application may want to provide an IVR to control various + * settings on the conference bridge. This can be accomplished by attaching a feature hook + * that calls an IVR function when a DTMF string is entered. + * + */ + +#ifndef _ASTERISK_BRIDGING_H +#define _ASTERISK_BRIDGING_H + +#if defined(__cplusplus) || defined(c_plusplus) +extern "C" { +#endif + +#include "asterisk/bridge_features.h" +#include "asterisk/bridge_channel.h" +#include "asterisk/bridge_roles.h" +#include "asterisk/dsp.h" +#include "asterisk/uuid.h" + +struct ast_bridge_technology; +struct ast_bridge; +struct ast_bridge_tech_optimizations; + +/*! \brief Capabilities for a bridge technology */ +enum ast_bridge_capability { + /*! Bridge technology can service calls on hold. */ + AST_BRIDGE_CAPABILITY_HOLDING = (1 << 0), + /*! Bridge waits for channel to answer. Passes early media. (XXX Not supported yet) */ + AST_BRIDGE_CAPABILITY_EARLY = (1 << 1), + /*! Bridge is capable of natively bridging two channels. (Smart bridge only) */ + AST_BRIDGE_CAPABILITY_NATIVE = (1 << 2), + /*! Bridge is capable of mixing at most two channels. (Smart bridgeable) */ + AST_BRIDGE_CAPABILITY_1TO1MIX = (1 << 3), + /*! Bridge is capable of mixing an arbitrary number of channels. (Smart bridgeable) */ + AST_BRIDGE_CAPABILITY_MULTIMIX = (1 << 4), +}; + +/*! \brief Video source modes */ +enum ast_bridge_video_mode_type { + /*! Video is not allowed in the bridge */ + AST_BRIDGE_VIDEO_MODE_NONE = 0, + /*! A single user is picked as the only distributed of video across the bridge */ + AST_BRIDGE_VIDEO_MODE_SINGLE_SRC, + /*! A single user's video feed is distributed to all bridge channels, but + * that feed is automatically picked based on who is talking the most. */ + AST_BRIDGE_VIDEO_MODE_TALKER_SRC, +}; + +/*! \brief This is used for both SINGLE_SRC mode to set what channel + * should be the current single video feed */ +struct ast_bridge_video_single_src_data { + /*! Only accept video coming from this channel */ + struct ast_channel *chan_vsrc; +}; + +/*! \brief This is used for both SINGLE_SRC_TALKER mode to set what channel + * should be the current single video feed */ +struct ast_bridge_video_talker_src_data { + /*! Only accept video coming from this channel */ + struct ast_channel *chan_vsrc; + int average_talking_energy; + + /*! Current talker see's this person */ + struct ast_channel *chan_old_vsrc; +}; + +/*! \brief Data structure that defines a video source mode */ +struct ast_bridge_video_mode { + enum ast_bridge_video_mode_type mode; + /* Add data for all the video modes here. */ + union { + struct ast_bridge_video_single_src_data single_src_data; + struct ast_bridge_video_talker_src_data talker_src_data; + } mode_data; +}; + +/*! + * \brief Destroy the bridge. + * + * \param self Bridge to operate upon. + * + * \return Nothing + */ +typedef void (*ast_bridge_destructor_fn)(struct ast_bridge *self); + +/*! + * \brief The bridge is being dissolved. + * + * \param self Bridge to operate upon. + * + * \details + * The bridge is being dissolved. Remove any external + * references to the bridge so it can be destroyed. + * + * \note On entry, self must NOT be locked. + * + * \return Nothing + */ +typedef void (*ast_bridge_dissolving_fn)(struct ast_bridge *self); + +/*! + * \brief Push this channel into the bridge. + * + * \param self Bridge to operate upon. + * \param bridge_channel Bridge channel to push. + * \param swap Bridge channel to swap places with if not NULL. + * + * \details + * Setup any channel hooks controlled by the bridge. Allocate + * bridge_channel->bridge_pvt and initialize any resources put + * in bridge_channel->bridge_pvt if needed. If there is a swap + * channel, use it as a guide to setting up the bridge_channel. + * + * \note On entry, self is already locked. + * + * \retval 0 on success. + * \retval -1 on failure. The channel did not get pushed. + */ +typedef int (*ast_bridge_push_channel_fn)(struct ast_bridge *self, struct ast_bridge_channel *bridge_channel, struct ast_bridge_channel *swap); + +/*! + * \brief Pull this channel from the bridge. + * + * \param self Bridge to operate upon. + * \param bridge_channel Bridge channel to pull. + * + * \details + * Remove any channel hooks controlled by the bridge. Release + * any resources held by bridge_channel->bridge_pvt and release + * bridge_channel->bridge_pvt. + * + * \note On entry, self is already locked. + * + * \return Nothing + */ +typedef void (*ast_bridge_pull_channel_fn)(struct ast_bridge *self, struct ast_bridge_channel *bridge_channel); + +/*! + * \brief Notify the bridge that this channel was just masqueraded. + * + * \param self Bridge to operate upon. + * \param bridge_channel Bridge channel that was masqueraded. + * + * \details + * A masquerade just happened to this channel. The bridge needs + * to re-evaluate this a channel in the bridge. + * + * \note On entry, self is already locked. + * + * \return Nothing + */ +typedef void (*ast_bridge_notify_masquerade_fn)(struct ast_bridge *self, struct ast_bridge_channel *bridge_channel); + +/*! + * \brief Get the merge priority of this bridge. + * + * \param self Bridge to operate upon. + * + * \note On entry, self is already locked. + * + * \return Merge priority + */ +typedef int (*ast_bridge_merge_priority_fn)(struct ast_bridge *self); + +/*! + * \brief Bridge virtual methods table definition. + * + * \note Any changes to this struct must be reflected in + * bridge_alloc() validity checking. + */ +struct ast_bridge_methods { + /*! Bridge class name for log messages. */ + const char *name; + /*! Destroy the bridge. */ + ast_bridge_destructor_fn destroy; + /*! The bridge is being dissolved. Remove any references to the bridge. */ + ast_bridge_dissolving_fn dissolving; + /*! Push the bridge channel into the bridge. */ + ast_bridge_push_channel_fn push; + /*! Pull the bridge channel from the bridge. */ + ast_bridge_pull_channel_fn pull; + /*! Notify the bridge of a masquerade with the channel. */ + ast_bridge_notify_masquerade_fn notify_masquerade; + /*! Get the bridge merge priority. */ + ast_bridge_merge_priority_fn get_merge_priority; +}; + +struct ast_bridge_channel; + +/*! Softmix technology parameters. */ +struct ast_bridge_softmix { + /*! The video mode softmix is using */ + struct ast_bridge_video_mode video_mode; + /*! + * \brief The internal sample rate softmix uses to mix channels. + * + * \note If this value is 0, the sofmix may auto adjust the mixing rate. + */ + unsigned int internal_sample_rate; + /*! + * \brief The mixing interval indicates how quickly softmix + * mixing should occur to mix audio. + * + * \note When set to 0, softmix must choose a default interval + * for itself. + */ + unsigned int internal_mixing_interval; +}; + +/*! + * \brief Structure that contains information about a bridge + */ +struct ast_bridge { + /*! Bridge virtual method table. */ + const struct ast_bridge_methods *v_table; + /*! "Personality" currently exhibited by bridge subclass */ + void *personality; + /*! Bridge technology that is handling the bridge */ + struct ast_bridge_technology *technology; + /*! Private information unique to the bridge technology */ + void *tech_pvt; + /*! Call ID associated with the bridge */ + struct ast_callid *callid; + /*! Linked list of channels participating in the bridge */ + AST_LIST_HEAD_NOLOCK(, ast_bridge_channel) channels; + /*! Queue of actions to perform on the bridge. */ + AST_LIST_HEAD_NOLOCK(, ast_frame) action_queue; + /*! Softmix technology parameters. */ + struct ast_bridge_softmix softmix; + /*! Bridge flags to tweak behavior */ + struct ast_flags feature_flags; + /*! Allowed bridge technology capabilities when AST_BRIDGE_FLAG_SMART enabled. */ + uint32_t allowed_capabilities; + /*! Number of channels participating in the bridge */ + unsigned int num_channels; + /*! Number of active channels in the bridge. */ + unsigned int num_active; + /*! + * \brief Count of the active temporary requests to inhibit bridge merges. + * Zero if merges are allowed. + * + * \note Temporary as in try again in a moment. + */ + unsigned int inhibit_merge; + /*! TRUE if the bridge was reconfigured. */ + unsigned int reconfigured:1; + /*! TRUE if the bridge has been dissolved. Any channel that now tries to join is immediately ejected. */ + unsigned int dissolved:1; + /*! TRUE if the bridge construction was completed. */ + unsigned int construction_completed:1; + /*! Immutable bridge UUID. */ + char uniqueid[AST_UUID_STR_LEN]; +}; + +/*! \brief Bridge base class virtual method table. */ +extern struct ast_bridge_methods ast_bridge_base_v_table; + +/*! + * \brief Create a new base class bridge + * + * \param capabilities The capabilities that we require to be used on the bridge + * \param flags Flags that will alter the behavior of the bridge + * + * \retval a pointer to a new bridge on success + * \retval NULL on failure + * + * Example usage: + * + * \code + * struct ast_bridge *bridge; + * bridge = ast_bridge_base_new(AST_BRIDGE_CAPABILITY_1TO1MIX, AST_BRIDGE_FLAG_DISSOLVE_HANGUP); + * \endcode + * + * This creates a no frills two party bridge that will be + * destroyed once one of the channels hangs up. + */ +struct ast_bridge *ast_bridge_base_new(uint32_t capabilities, unsigned int flags); + +/*! + * \brief Try locking the bridge. + * + * \param bridge Bridge to try locking + * + * \retval 0 on success. + * \retval non-zero on error. + */ +#define ast_bridge_trylock(bridge) _ast_bridge_trylock(bridge, __FILE__, __PRETTY_FUNCTION__, __LINE__, #bridge) +static inline int _ast_bridge_trylock(struct ast_bridge *bridge, const char *file, const char *function, int line, const char *var) +{ + return __ao2_trylock(bridge, AO2_LOCK_REQ_MUTEX, file, function, line, var); +} + +/*! + * \brief Lock the bridge. + * + * \param bridge Bridge to lock + * + * \return Nothing + */ +#define ast_bridge_lock(bridge) _ast_bridge_lock(bridge, __FILE__, __PRETTY_FUNCTION__, __LINE__, #bridge) +static inline void _ast_bridge_lock(struct ast_bridge *bridge, const char *file, const char *function, int line, const char *var) +{ + __ao2_lock(bridge, AO2_LOCK_REQ_MUTEX, file, function, line, var); +} + +/*! + * \brief Unlock the bridge. + * + * \param bridge Bridge to unlock + * + * \return Nothing + */ +#define ast_bridge_unlock(bridge) _ast_bridge_unlock(bridge, __FILE__, __PRETTY_FUNCTION__, __LINE__, #bridge) +static inline void _ast_bridge_unlock(struct ast_bridge *bridge, const char *file, const char *function, int line, const char *var) +{ + __ao2_unlock(bridge, file, function, line, var); +} + +/*! \brief Lock two bridges. */ +#define ast_bridge_lock_both(bridge1, bridge2) \ + do { \ + for (;;) { \ + ast_bridge_lock(bridge1); \ + if (!ast_bridge_trylock(bridge2)) { \ + break; \ + } \ + ast_bridge_unlock(bridge1); \ + sched_yield(); \ + } \ + } while (0) + +/*! + * \brief Destroy a bridge + * + * \param bridge Bridge to destroy + * + * \retval 0 on success + * \retval -1 on failure + * + * Example usage: + * + * \code + * ast_bridge_destroy(bridge); + * \endcode + * + * This destroys a bridge that was previously created. + */ +int ast_bridge_destroy(struct ast_bridge *bridge); + +/*! + * \brief Notify bridging that this channel was just masqueraded. + * \since 12.0.0 + * + * \param chan Channel just involved in a masquerade + * + * \return Nothing + */ +void ast_bridge_notify_masquerade(struct ast_channel *chan); + +/*! + * \brief Join (blocking) a channel to a bridge + * + * \param bridge Bridge to join + * \param chan Channel to join + * \param swap Channel to swap out if swapping + * \param features Bridge features structure + * \param tech_args Optional Bridging tech optimization parameters for this channel. + * \param pass_reference TRUE if the bridge reference is being passed by the caller. + * + * \note Absolutely _NO_ locks should be held before calling + * this function since it blocks. + * + * \retval state that channel exited the bridge with + * + * Example usage: + * + * \code + * ast_bridge_join(bridge, chan, NULL, NULL, NULL, 0); + * \endcode + * + * This adds a channel pointed to by the chan pointer to the bridge pointed to by + * the bridge pointer. This function will not return until the channel has been + * removed from the bridge, swapped out for another channel, or has hung up. + * + * If this channel will be replacing another channel the other channel can be specified + * in the swap parameter. The other channel will be thrown out of the bridge in an + * atomic fashion. + * + * If channel specific features are enabled a pointer to the features structure + * can be specified in the features parameter. + */ +enum bridge_channel_state ast_bridge_join(struct ast_bridge *bridge, + struct ast_channel *chan, + struct ast_channel *swap, + struct ast_bridge_features *features, + struct ast_bridge_tech_optimizations *tech_args, + int pass_reference); + +/*! + * \brief Impart (non-blocking) a channel onto a bridge + * + * \param bridge Bridge to impart on + * \param chan Channel to impart (The channel reference is stolen if impart successful.) + * \param swap Channel to swap out if swapping. NULL if not swapping. + * \param features Bridge features structure. + * \param independent TRUE if caller does not want to reclaim the channel using ast_bridge_depart(). + * + * \note The features parameter must be NULL or obtained by + * ast_bridge_features_new(). You must not dereference features + * after calling even if the call fails. + * + * \note chan is locked by this function. + * + * \retval 0 on success + * \retval -1 on failure + * + * Example usage: + * + * \code + * ast_bridge_impart(bridge, chan, NULL, NULL, 0); + * \endcode + * + * \details + * This adds a channel pointed to by the chan pointer to the + * bridge pointed to by the bridge pointer. This function will + * return immediately and will not wait until the channel is no + * longer part of the bridge. + * + * If this channel will be replacing another channel the other + * channel can be specified in the swap parameter. The other + * channel will be thrown out of the bridge in an atomic + * fashion. + * + * If channel specific features are enabled, a pointer to the + * features structure can be specified in the features + * parameter. + * + * \note If you impart a channel as not independent you MUST + * ast_bridge_depart() the channel if this call succeeds. The + * bridge channel thread is created join-able. The implication + * is that the channel is special and will not behave like a + * normal channel. + * + * \note If you impart a channel as independent you must not + * ast_bridge_depart() the channel. The bridge channel thread + * is created non-join-able. The channel must be treated as if + * it were placed into the bridge by ast_bridge_join(). + * Channels placed into a bridge by ast_bridge_join() are + * removed by a third party using ast_bridge_remove(). + */ +int ast_bridge_impart(struct ast_bridge *bridge, struct ast_channel *chan, struct ast_channel *swap, struct ast_bridge_features *features, int independent); + +/*! + * \brief Depart a channel from a bridge + * + * \param chan Channel to depart + * + * \note chan is locked by this function. + * + * \retval 0 on success + * \retval -1 on failure + * + * Example usage: + * + * \code + * ast_bridge_depart(chan); + * \endcode + * + * This removes the channel pointed to by the chan pointer from any bridge + * it may be in and gives control to the calling thread. + * This does not hang up the channel. + * + * \note This API call can only be used on channels that were added to the bridge + * using the ast_bridge_impart API call with the independent flag FALSE. + */ +int ast_bridge_depart(struct ast_channel *chan); + +/*! + * \brief Remove a channel from a bridge + * + * \param bridge Bridge that the channel is to be removed from + * \param chan Channel to remove + * + * \retval 0 on success + * \retval -1 on failure + * + * Example usage: + * + * \code + * ast_bridge_remove(bridge, chan); + * \endcode + * + * This removes the channel pointed to by the chan pointer from the bridge + * pointed to by the bridge pointer and requests that it be hung up. Control + * over the channel will NOT be given to the calling thread. + * + * \note This API call can be used on channels that were added to the bridge + * using both ast_bridge_join and ast_bridge_impart. + */ +int ast_bridge_remove(struct ast_bridge *bridge, struct ast_channel *chan); + +/*! + * \brief Merge two bridges together + * + * \param dst_bridge Destination bridge of merge. + * \param src_bridge Source bridge of merge. + * \param merge_best_direction TRUE if don't care about which bridge merges into the other. + * \param kick_me Array of channels to kick from the bridges. + * \param num_kick Number of channels in the kick_me array. + * + * \note Absolutely _NO_ bridge or channel locks should be held + * before calling this function. + * + * \retval 0 on success + * \retval -1 on failure + * + * Example usage: + * + * \code + * ast_bridge_merge(dst_bridge, src_bridge, 0, NULL, 0); + * \endcode + * + * This moves the channels in src_bridge into the bridge pointed + * to by dst_bridge. + */ +int ast_bridge_merge(struct ast_bridge *dst_bridge, struct ast_bridge *src_bridge, int merge_best_direction, struct ast_channel **kick_me, unsigned int num_kick); + +/*! + * \brief Move a channel from one bridge to another. + * \since 12.0.0 + * + * \param dst_bridge Destination bridge of bridge channel move. + * \param src_bridge Source bridge of bridge channel move. + * \param chan Channel to move. + * \param swap Channel to replace in dst_bridge. + * \param attempt_recovery TRUE if failure attempts to push channel back into original bridge. + * + * \note Absolutely _NO_ bridge or channel locks should be held + * before calling this function. + * + * \retval 0 on success. + * \retval -1 on failure. + */ +int ast_bridge_move(struct ast_bridge *dst_bridge, struct ast_bridge *src_bridge, struct ast_channel *chan, struct ast_channel *swap, int attempt_recovery); + +/*! + * \brief Adjust the bridge merge inhibit request count. + * \since 12.0.0 + * + * \param bridge What to operate on. + * \param request Inhibit request increment. + * (Positive to add requests. Negative to remove requests.) + * + * \return Nothing + */ +void ast_bridge_merge_inhibit(struct ast_bridge *bridge, int request); + +/*! + * \brief Suspend a channel temporarily from a bridge + * + * \param bridge Bridge to suspend the channel from + * \param chan Channel to suspend + * + * \retval 0 on success + * \retval -1 on failure + * + * Example usage: + * + * \code + * ast_bridge_suspend(bridge, chan); + * \endcode + * + * This suspends the channel pointed to by chan from the bridge pointed to by bridge temporarily. + * Control of the channel is given to the calling thread. This differs from ast_bridge_depart as + * the channel will not be removed from the bridge. + * + * \note This API call can be used on channels that were added to the bridge + * using both ast_bridge_join and ast_bridge_impart. + */ +int ast_bridge_suspend(struct ast_bridge *bridge, struct ast_channel *chan); + +/*! + * \brief Unsuspend a channel from a bridge + * + * \param bridge Bridge to unsuspend the channel from + * \param chan Channel to unsuspend + * + * \retval 0 on success + * \retval -1 on failure + * + * Example usage: + * + * \code + * ast_bridge_unsuspend(bridge, chan); + * \endcode + * + * This unsuspends the channel pointed to by chan from the bridge pointed to by bridge. + * The bridge will go back to handling the channel once this function returns. + * + * \note You must not mess with the channel once this function returns. + * Doing so may result in bad things happening. + */ +int ast_bridge_unsuspend(struct ast_bridge *bridge, struct ast_channel *chan); + +struct ast_unreal_pvt; + +/*! + * \brief Check and optimize out the unreal channels between bridges. + * \since 12.0.0 + * + * \param chan Unreal channel writing a frame into the channel driver. + * \param peer Other unreal channel in the pair. + * \param pvt Private data provided by an implementation of the unreal driver that + * contains the callbacks that should be called when optimization begins/ends + * + * \note It is assumed that chan is already locked. + * + * \retval 0 if unreal channels were not optimized out. + * \retval non-zero if unreal channels were optimized out. + */ +int ast_bridge_unreal_optimize_out(struct ast_channel *chan, struct ast_channel *peer, struct ast_unreal_pvt *pvt); + +/*! + * \brief Tells, if optimization is allowed, how the optimization would be performed + */ +enum ast_bridge_optimization { + /*! Optimization would swap peer into the chan_bridge */ + AST_BRIDGE_OPTIMIZE_SWAP_TO_CHAN_BRIDGE, + /*! Optimization would swap chan into the peer_bridge */ + AST_BRIDGE_OPTIMIZE_SWAP_TO_PEER_BRIDGE, + /*! Optimization would merge peer_bridge into chan_bridge */ + AST_BRIDGE_OPTIMIZE_MERGE_TO_CHAN_BRIDGE, + /*! Optimization would merge chan_bridge into peer_bridge */ + AST_BRIDGE_OPTIMIZE_MERGE_TO_PEER_BRIDGE, + /*! Optimization is not permitted on one or both bridges */ + AST_BRIDGE_OPTIMIZE_PROHIBITED, +}; + +/*! + * \brief Determine if bridges allow for optimization to occur betweem them + * \since 12.0.0 + * + * \param chan_bridge First bridge being tested + * \param peer_bridge Second bridge being tested + * + * This determines if two bridges allow for unreal channel optimization + * to occur between them. The function does not require for unreal channels + * to already be in the bridges when called. + * + * \note It is assumed that both bridges are locked prior to calling this function + * + * \note A return other than AST_BRIDGE_OPTIMIZE_PROHIBITED does not guarantee + * that an optimization attempt will succeed. However, a return of + * AST_BRIDGE_OPTIMIZE_PROHIBITED guarantees that an optimization attempt will + * never succeed. + * + * \returns Optimization allowability for the bridges + */ +enum ast_bridge_optimization ast_bridges_allow_optimization(struct ast_bridge *chan_bridge, + struct ast_bridge *peer_bridge); + +/*! + * \brief Put an action onto the specified bridge. + * \since 12.0.0 + * + * \param bridge What to queue the action on. + * \param action What to do. + * + * \retval 0 on success. + * \retval -1 on error. + * + * \note This API call is meant for internal bridging operations. + * \note BUGBUG This may get moved. + */ +int ast_bridge_queue_action(struct ast_bridge *bridge, struct ast_frame *action); + +/*! + * \brief Queue the given frame to everyone else. + * \since 12.0.0 + * + * \param bridge What bridge to distribute frame. + * \param bridge_channel Channel to optionally not pass frame to. (NULL to pass to everyone) + * \param frame Frame to pass. + * + * \note This is intended to be called by bridge hooks and + * bridge technologies. + * + * \retval 0 Frame written to at least one channel. + * \retval -1 Frame written to no channels. + */ +int ast_bridge_queue_everyone_else(struct ast_bridge *bridge, struct ast_bridge_channel *bridge_channel, struct ast_frame *frame); + +/*! + * \brief Adjust the internal mixing sample rate of a bridge + * used during multimix mode. + * + * \param bridge Channel to change the sample rate on. + * \param sample_rate the sample rate to change to. If a + * value of 0 is passed here, the bridge will be free to pick + * what ever sample rate it chooses. + * + */ +void ast_bridge_set_internal_sample_rate(struct ast_bridge *bridge, unsigned int sample_rate); + +/*! + * \brief Adjust the internal mixing interval of a bridge used + * during multimix mode. + * + * \param bridge Channel to change the sample rate on. + * \param mixing_interval the sample rate to change to. If 0 is set + * the bridge tech is free to choose any mixing interval it uses by default. + */ +void ast_bridge_set_mixing_interval(struct ast_bridge *bridge, unsigned int mixing_interval); + +/*! + * \brief Set a bridge to feed a single video source to all participants. + */ +void ast_bridge_set_single_src_video_mode(struct ast_bridge *bridge, struct ast_channel *video_src_chan); + +/*! + * \brief Set the bridge to pick the strongest talker supporting + * video as the single source video feed + */ +void ast_bridge_set_talker_src_video_mode(struct ast_bridge *bridge); + +/*! + * \brief Update information about talker energy for talker src video mode. + */ +void ast_bridge_update_talker_src_video_mode(struct ast_bridge *bridge, struct ast_channel *chan, int talker_energy, int is_keyfame); + +/*! + * \brief Returns the number of video sources currently active in the bridge + */ +int ast_bridge_number_video_src(struct ast_bridge *bridge); + +/*! + * \brief Determine if a channel is a video src for the bridge + * + * \retval 0 Not a current video source of the bridge. + * \retval None 0, is a video source of the bridge, The number + * returned represents the priority this video stream has + * on the bridge where 1 is the highest priority. + */ +int ast_bridge_is_video_src(struct ast_bridge *bridge, struct ast_channel *chan); + +/*! + * \brief remove a channel as a source of video for the bridge. + */ +void ast_bridge_remove_video_src(struct ast_bridge *bridge, struct ast_channel *chan); + +enum ast_transfer_result { + /*! The transfer completed successfully */ + AST_BRIDGE_TRANSFER_SUCCESS, + /*! A bridge involved does not permit transferring */ + AST_BRIDGE_TRANSFER_NOT_PERMITTED, + /*! The current bridge setup makes transferring an invalid operation */ + AST_BRIDGE_TRANSFER_INVALID, + /*! The transfer operation failed for a miscellaneous reason */ + AST_BRIDGE_TRANSFER_FAIL, +}; + +enum ast_transfer_type { + /*! Transfer of a single party */ + AST_BRIDGE_TRANSFER_SINGLE_PARTY, + /*! Transfer of multiple parties */ + AST_BRIDGE_TRANSFER_MULTI_PARTY, +}; + +/*! + * \brief Callback function type called during blind transfers + * + * A caller of ast_bridge_transfer_blind() may wish to set data on + * the channel that ends up running dialplan. For instance, it may + * be useful to set channel variables on the channel. + * + * \param chan The involved channel + * \param user_data User-provided data needed in the callback + * \param transfer_type The type of transfer being completed + */ +typedef void (*transfer_channel_cb)(struct ast_channel *chan, void *user_data, + enum ast_transfer_type transfer_type); + +/*! + * \brief Blind transfer target to the extension and context provided + * + * The channel given is bridged to one or multiple channels. Depending on + * the bridge and the number of participants, the entire bridge could be + * transferred to the given destination, or a single channel may be redirected. + * + * Callers may also provide a callback to be called on the channel that will + * be running dialplan. The user data passed into ast_bridge_transfer_blind + * will be given as the argument to the callback to be interpreted as desired. + * This callback is guaranteed to be called in the same thread as + * ast_bridge_transfer_blind() and before ast_bridge_transfer_blind() returns. + * + * \note Absolutely _NO_ channel locks should be held before + * calling this function. + * + * \param is_external Indicates that transfer was initiated externally + * \param transferer The channel performing the blind transfer + * \param exten The dialplan extension to send the call to + * \param context The dialplan context to send the call to + * \param new_channel_cb A callback to be called on the channel that will + * be executing dialplan + * \param user_data Argument for new_channel_cb + * \return The success or failure result of the blind transfer + */ +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); + +/*! + * \brief Attended transfer + * + * The two channels are both transferer channels. The first is the channel + * that is bridged to the transferee (or if unbridged, the 'first' call of + * the transfer). The second is the channel that is bridged to the transfer + * target (or if unbridged, the 'second' call of the transfer). + * + * \note Absolutely _NO_ channel locks should be held before + * calling this function. + * + * \param to_transferee Transferer channel on initial call (presumably bridged to transferee) + * \param to_transfer_target Transferer channel on consultation call (presumably bridged to transfer target) + * \return The success or failure of the attended transfer + */ +enum ast_transfer_result ast_bridge_transfer_attended(struct ast_channel *to_transferee, + struct ast_channel *to_transfer_target); + +/*! + * \brief Get a container of all channels in the bridge + * \since 12.0.0 + * + * \param bridge The bridge which is already locked. + * + * \retval NULL Failed to create container + * \retval non-NULL Container of channels in the bridge + */ +struct ao2_container *ast_bridge_peers_nolock(struct ast_bridge *bridge); + +/*! + * \brief Get a container of all channels in the bridge + * \since 12.0.0 + * + * \param bridge The bridge + * + * \note The returned container is a snapshot of channels in the + * bridge when called. + * + * \retval NULL Failed to create container + * \retval non-NULL Container of channels in the bridge + */ +struct ao2_container *ast_bridge_peers(struct ast_bridge *bridge); + +/*! + * \brief Get the channel's bridge peer only if the bridge is two-party. + * \since 12.0.0 + * + * \param bridge The bridge which is already locked. + * \param chan Channel desiring the bridge peer channel. + * + * \note The returned peer channel is the current peer in the + * bridge when called. + * + * \retval NULL Channel not in a bridge or the bridge is not two-party. + * \retval non-NULL Reffed peer channel at time of calling. + */ +struct ast_channel *ast_bridge_peer_nolock(struct ast_bridge *bridge, struct ast_channel *chan); + +/*! + * \brief Get the channel's bridge peer only if the bridge is two-party. + * \since 12.0.0 + * + * \param bridge The bridge + * \param chan Channel desiring the bridge peer channel. + * + * \note The returned peer channel is the current peer in the + * bridge when called. + * + * \retval NULL Channel not in a bridge or the bridge is not two-party. + * \retval non-NULL Reffed peer channel at time of calling. + */ +struct ast_channel *ast_bridge_peer(struct ast_bridge *bridge, struct ast_channel *chan); + +/*! + * \brief Remove marked bridge channel feature hooks. + * \since 12.0.0 + * + * \param features Bridge features structure + * \param flags Determinator for whether hook is removed. + * + * \return Nothing + */ +void ast_bridge_features_remove(struct ast_bridge_features *features, enum ast_bridge_hook_remove_flags flags); + +#if defined(__cplusplus) || defined(c_plusplus) +} +#endif + +#endif /* _ASTERISK_BRIDGING_H */ diff --git a/include/asterisk/bridge_after.h b/include/asterisk/bridge_after.h new file mode 100644 index 000000000..53f30b9ad --- /dev/null +++ b/include/asterisk/bridge_after.h @@ -0,0 +1,244 @@ +/* + * Asterisk -- An open source telephony toolkit. + * + * Copyright (C) 2013 Digium, Inc. + * + * Richard Mudgett + * + * See http://www.asterisk.org for more information about + * the Asterisk project. Please do not directly contact + * any of the maintainers of this project for assistance; + * the project provides a web site, mailing lists and IRC + * channels for your use. + * + * This program is free software, distributed under the terms of + * the GNU General Public License Version 2. See the LICENSE file + * at the top of the source tree. + */ + +/*! + * \file + * \brief After Bridge Execution API + * + * \author Richard Mudgett + * + * See Also: + * \arg \ref AstCREDITS + */ + +#ifndef _ASTERISK_BRIDGING_AFTER_H +#define _ASTERISK_BRIDGING_AFTER_H + +#if defined(__cplusplus) || defined(c_plusplus) +extern "C" { +#endif + +/*! Reason the the after bridge callback will not be called. */ +enum ast_bridge_after_cb_reason { + /*! The datastore is being destroyed. Likely due to hangup. (Enum value must be zero.) */ + AST_BRIDGE_AFTER_CB_REASON_DESTROY, + /*! Something else replaced the callback with another. */ + AST_BRIDGE_AFTER_CB_REASON_REPLACED, + /*! The callback was removed because of a masquerade. (fixup) */ + AST_BRIDGE_AFTER_CB_REASON_MASQUERADE, + /*! The channel was departed from the bridge. */ + AST_BRIDGE_AFTER_CB_REASON_DEPART, + /*! Was explicitly removed by external code. */ + AST_BRIDGE_AFTER_CB_REASON_REMOVED, +}; + +/*! + * \brief Set channel to goto specific location after the bridge. + * \since 12.0.0 + * + * \param chan Channel to setup after bridge goto location. + * \param context Context to goto after bridge. + * \param exten Exten to goto after bridge. + * \param priority Priority to goto after bridge. + * + * \note chan is locked by this function. + * + * \details Add a channel datastore to setup the goto location + * when the channel leaves the bridge and run a PBX from there. + * + * \return Nothing + */ +void ast_bridge_set_after_goto(struct ast_channel *chan, const char *context, const char *exten, int priority); + +/*! + * \brief Set channel to run the h exten after the bridge. + * \since 12.0.0 + * + * \param chan Channel to setup after bridge goto location. + * \param context Context to goto after bridge. + * + * \note chan is locked by this function. + * + * \details Add a channel datastore to setup the goto location + * when the channel leaves the bridge and run a PBX from there. + * + * \return Nothing + */ +void ast_bridge_set_after_h(struct ast_channel *chan, const char *context); + +/*! + * \brief Set channel to go on in the dialplan after the bridge. + * \since 12.0.0 + * + * \param chan Channel to setup after bridge goto location. + * \param context Current context of the caller channel. + * \param exten Current exten of the caller channel. + * \param priority Current priority of the caller channel + * \param parseable_goto User specified goto string from dialplan. + * + * \note chan is locked by this function. + * + * \details Add a channel datastore to setup the goto location + * when the channel leaves the bridge and run a PBX from there. + * + * If parseable_goto then use the given context/exten/priority + * as the relative position for the parseable_goto. + * Else goto the given context/exten/priority+1. + * + * \return Nothing + */ +void ast_bridge_set_after_go_on(struct ast_channel *chan, const char *context, const char *exten, int priority, const char *parseable_goto); + +/*! + * \brief Setup any after bridge goto location to begin execution. + * \since 12.0.0 + * + * \param chan Channel to setup after bridge goto location. + * + * \note chan is locked by this function. + * + * \details Pull off any after bridge goto location datastore and + * setup for dialplan execution there. + * + * \retval 0 on success. The goto location is set for a PBX to run it. + * \retval non-zero on error or no goto location. + * + * \note If the after bridge goto is set to run an h exten it is + * run here immediately. + */ +int ast_bridge_setup_after_goto(struct ast_channel *chan); + +/*! + * \brief Run any after bridge callback. + * \since 12.0.0 + * + * \param chan Channel to run after bridge callback. + * + * \return Nothing + */ +void ast_bridge_run_after_callback(struct ast_channel *chan); + +/*! + * \brief Run discarding any after bridge callbacks. + * \since 12.0.0 + * + * \param chan Channel to run after bridge callback. + * + * \return Nothing + */ +void ast_bridge_discard_after_callback(struct ast_channel *chan, enum ast_bridge_after_cb_reason reason); + +/*! + * \brief Run a PBX on any after bridge goto location. + * \since 12.0.0 + * + * \param chan Channel to execute after bridge goto location. + * + * \note chan is locked by this function. + * + * \details Pull off any after bridge goto location datastore + * and run a PBX at that location. + * + * \note On return, the chan pointer is no longer valid because + * the channel has hung up. + * + * \return Nothing + */ +void ast_bridge_run_after_goto(struct ast_channel *chan); + +/*! + * \brief Discard channel after bridge goto location. + * \since 12.0.0 + * + * \param chan Channel to discard after bridge goto location. + * + * \note chan is locked by this function. + * + * \return Nothing + */ +void ast_bridge_discard_after_goto(struct ast_channel *chan); + +/*! + * \brief Read after bridge goto if it exists + * \since 12.0.0 + * + * \param chan Channel to read the after bridge goto parseable goto string from + * \param buffer Buffer to write the after bridge goto data to + * \param buf_size size of the buffer being written to + */ +void ast_bridge_read_after_goto(struct ast_channel *chan, char *buffer, size_t buf_size); + +/*! + * \brief After bridge callback failed. + * \since 12.0.0 + * + * \param reason Reason callback is failing. + * \param data Extra data what setup the callback wanted to pass. + * + * \note Called when the channel leaves the bridging system or + * is destroyed. + * + * \return Nothing + */ +typedef void (*ast_bridge_after_cb_failed)(enum ast_bridge_after_cb_reason reason, void *data); + +/*! + * \brief After bridge callback function. + * \since 12.0.0 + * + * \param chan Channel just leaving bridging system. + * \param data Extra data what setup the callback wanted to pass. + * + * \return Nothing + */ +typedef void (*ast_bridge_after_cb)(struct ast_channel *chan, void *data); + +/*! + * \brief Setup an after bridge callback for when the channel leaves the bridging system. + * \since 12.0.0 + * + * \param chan Channel to setup an after bridge callback on. + * \param callback Function to call when the channel leaves the bridging system. + * \param failed Function to call when it will not be calling the callback. + * \param data Extra data to pass with the callback. + * + * \note chan is locked by this function. + * + * \note failed is called when the channel leaves the bridging + * system or is destroyed. + * + * \retval 0 on success. + * \retval -1 on error. + */ +int ast_bridge_set_after_callback(struct ast_channel *chan, ast_bridge_after_cb callback, ast_bridge_after_cb_failed failed, void *data); + +/*! + * \brief Get a string representation of an after bridge callback reason + * \since 12.0.0 + * + * \param reason The reason to interpret to a string + * \retval NULL Unrecognized reason + * \retval non-NULL String representation of reason + */ +const char *ast_bridge_after_cb_reason_string(enum ast_bridge_after_cb_reason reason); + +#if defined(__cplusplus) || defined(c_plusplus) +} +#endif + +#endif /* _ASTERISK_BRIDGING_H */ diff --git a/include/asterisk/bridge_basic.h b/include/asterisk/bridge_basic.h new file mode 100644 index 000000000..4db142946 --- /dev/null +++ b/include/asterisk/bridge_basic.h @@ -0,0 +1,133 @@ +/* + * Asterisk -- An open source telephony toolkit. + * + * Copyright (C) 2013 Digium, Inc. + * + * Richard Mudgett + * + * See http://www.asterisk.org for more information about + * the Asterisk project. Please do not directly contact + * any of the maintainers of this project for assistance; + * the project provides a web site, mailing lists and IRC + * channels for your use. + * + * This program is free software, distributed under the terms of + * the GNU General Public License Version 2. See the LICENSE file + * at the top of the source tree. + */ + +/*! + * \file + * \brief Basic bridge subclass API. + * + * \author Richard Mudgett + * + * See Also: + * \arg \ref AstCREDITS + */ + +#ifndef _ASTERISK_BRIDGING_BASIC_H +#define _ASTERISK_BRIDGING_BASIC_H + +#if defined(__cplusplus) || defined(c_plusplus) +extern "C" { +#endif + +/* ------------------------------------------------------------------- */ + +/*! + * \brief Sets the features a channel will use upon being bridged. + * \since 12.0.0 + * + * \param chan Which channel to set features for + * \param features Which feature codes to set for the channel + * + * \retval 0 on success + * \retval -1 on failure + */ +int ast_bridge_features_ds_set_string(struct ast_channel *chan, const char *features); + +/*! + * \brief writes a channel's DTMF features to a buffer string + * \since 12.0.0 + * + * \param chan channel whose feature flags should be checked + * \param buffer pointer string buffer where the output should be stored + * \param buf_size size of the provided buffer (ideally enough for all features, 6+) + * + * \retval 0 on successful write + * \retval -1 on failure + */ +int ast_bridge_features_ds_get_string(struct ast_channel *chan, char *buffer, size_t buf_size); + +/*! + * \brief Get DTMF feature flags from the channel. + * \since 12.0.0 + * + * \param chan Channel to get DTMF features datastore. + * + * \note The channel should be locked before calling this function. + * \note The channel must remain locked until the flags returned have been consumed. + * + * \retval flags on success. + * \retval NULL if the datastore does not exist. + */ +struct ast_flags *ast_bridge_features_ds_get(struct ast_channel *chan); + +/*! + * \brief Set basic bridge DTMF feature flags datastore on the channel. + * \since 12.0.0 + * + * \param chan Channel to set DTMF features datastore. + * \param flags Builtin DTMF feature flags. (ast_bridge_config flags) + * + * \note The channel must be locked before calling this function. + * + * \retval 0 on success. + * \retval -1 on error. + */ +int ast_bridge_features_ds_set(struct ast_channel *chan, struct ast_flags *flags); + +/*! + * \brief Setup DTMF feature hooks using the channel features datastore property. + * \since 12.0.0 + * + * \param bridge_channel What to setup DTMF features on. + * + * \retval 0 on success. + * \retval -1 on error. + */ +int ast_bridge_channel_setup_features(struct ast_bridge_channel *bridge_channel); + +/*! \brief Bridge basic class virtual method table. */ +extern struct ast_bridge_methods ast_bridge_basic_v_table; + +/*! + * \brief Create a new basic class bridge + * + * \retval a pointer to a new bridge on success + * \retval NULL on failure + * + * Example usage: + * + * \code + * struct ast_bridge *bridge; + * bridge = ast_bridge_basic_new(); + * \endcode + * + * This creates a basic two party bridge with any configured + * DTMF features enabled that will be destroyed once one of the + * channels hangs up. + */ +struct ast_bridge *ast_bridge_basic_new(void); + +/*! Initialize the basic bridge class for use by the system. */ +void ast_bridging_init_basic(void); + +/* ------------------------------------------------------------------- */ + +#if defined(__cplusplus) || defined(c_plusplus) +} +#endif + +#endif /* _ASTERISK_BRIDGING_BASIC_H */ diff --git a/include/asterisk/bridge_channel.h b/include/asterisk/bridge_channel.h new file mode 100644 index 000000000..5da1653fa --- /dev/null +++ b/include/asterisk/bridge_channel.h @@ -0,0 +1,590 @@ +/* + * Asterisk -- An open source telephony toolkit. + * + * Copyright (C) 2013 Digium, Inc. + * + * Joshua Colp + * Richard Mudgett + * Matt Jordan + * + * See http://www.asterisk.org for more information about + * the Asterisk project. Please do not directly contact + * any of the maintainers of this project for assistance; + * the project provides a web site, mailing lists and IRC + * channels for your use. + * + * This program is free software, distributed under the terms of + * the GNU General Public License Version 2. See the LICENSE file + * at the top of the source tree. + */ + +/*! + * \file + * \page AstBridgeChannel Bridging Channel API + * + * An API that act on a channel in a bridge. Note that while the + * \ref ast_bridge_channel is owned by a channel, it should only be used + * by members of the bridging system. The only places where this API should + * be used is: + * \arg \ref AstBridging API itself + * \arg Bridge mixing technologies + * \arg Bridge sub-classes + * + * In general, anywhere else it is unsafe to use this API. Care should be + * taken when using this API to ensure that the locking order remains + * correct. The locking order must be: + * \arg The \ref \c ast_bridge + * \arg The \ref \c ast_bridge_channel + * \arg The \ref \c ast_channel + * + * \author Joshua Colp + * \author Richard Mudgett + * \author Matt Jordan + * + * See Also: + * \arg \ref AstBridging + * \arg \ref AstCREDITS + */ + +#ifndef _ASTERISK_BRIDGING_CHANNEL_H +#define _ASTERISK_BRIDGING_CHANNEL_H + +#if defined(__cplusplus) || defined(c_plusplus) +extern "C" { +#endif + +#include "asterisk/bridge_technology.h" + +/*! \brief State information about a bridged channel */ +enum bridge_channel_state { + /*! Waiting for a signal (Channel in the bridge) */ + BRIDGE_CHANNEL_STATE_WAIT = 0, + /*! Bridged channel was forced out and should be hung up (Bridge may dissolve.) */ + BRIDGE_CHANNEL_STATE_END, + /*! Bridged channel was forced out. Don't dissolve the bridge regardless */ + BRIDGE_CHANNEL_STATE_END_NO_DISSOLVE, +}; + +enum bridge_channel_thread_state { + /*! Bridge channel thread is idle/waiting. */ + BRIDGE_CHANNEL_THREAD_IDLE, + /*! Bridge channel thread is writing a normal/simple frame. */ + BRIDGE_CHANNEL_THREAD_SIMPLE, + /*! Bridge channel thread is processing a frame. */ + BRIDGE_CHANNEL_THREAD_FRAME, +}; + +struct ast_bridge; +struct ast_bridge_tech_optimizations; + + /*! + * \brief Structure that contains information regarding a channel in a bridge + */ +struct ast_bridge_channel { +/* BUGBUG cond is only here because of external party suspend/unsuspend support. */ + /*! Condition, used if we want to wake up a thread waiting on the bridged channel */ + ast_cond_t cond; + /*! Current bridged channel state */ + enum bridge_channel_state state; + /*! Asterisk channel participating in the bridge */ + struct ast_channel *chan; + /*! Asterisk channel we are swapping with (if swapping) */ + struct ast_channel *swap; + /*! + * \brief Bridge this channel is participating in + * + * \note The bridge pointer cannot change while the bridge or + * bridge_channel is locked. + */ + struct ast_bridge *bridge; + /*! + * \brief Bridge class private channel data. + * + * \note This information is added when the channel is pushed + * into the bridge and removed when it is pulled from the + * bridge. + */ + void *bridge_pvt; + /*! + * \brief Private information unique to the bridge technology. + * + * \note This information is added when the channel joins the + * bridge's technology and removed when it leaves the bridge's + * technology. + */ + void *tech_pvt; + /*! Thread handling the bridged channel (Needed by ast_bridge_depart) */ + pthread_t thread; + /* v-- These flags change while the bridge is locked or before the channel is in the bridge. */ + /*! TRUE if the channel is in a bridge. */ + unsigned int in_bridge:1; + /*! TRUE if the channel just joined the bridge. */ + unsigned int just_joined:1; + /*! TRUE if the channel is suspended from the bridge. */ + unsigned int suspended:1; + /*! TRUE if the channel must wait for an ast_bridge_depart to reclaim the channel. */ + unsigned int depart_wait:1; + /* ^-- These flags change while the bridge is locked or before the channel is in the bridge. */ + /*! Features structure for features that are specific to this channel */ + struct ast_bridge_features *features; + /*! Technology optimization parameters used by bridging technologies capable of + * optimizing based upon talk detection. */ + struct ast_bridge_tech_optimizations tech_args; + /*! Copy of read format used by chan before join */ + struct ast_format read_format; + /*! Copy of write format used by chan before join */ + struct ast_format write_format; + /*! Call ID associated with bridge channel */ + struct ast_callid *callid; + /*! A clone of the roles living on chan when the bridge channel joins the bridge. This may require some opacification */ + struct bridge_roles_datastore *bridge_roles; + /*! Linked list information */ + AST_LIST_ENTRY(ast_bridge_channel) entry; + /*! Queue of outgoing frames to the channel. */ + AST_LIST_HEAD_NOLOCK(, ast_frame) wr_queue; + /*! Pipe to alert thread when frames are put into the wr_queue. */ + int alert_pipe[2]; + /*! TRUE if the bridge channel thread is waiting on channels (needs to be atomically settable) */ + int waiting; + /*! + * \brief The bridge channel thread activity. + * + * \details Used by local channel optimization to determine if + * the thread is in an acceptable state to optimize. + * + * \note Needs to be atomically settable. + */ + enum bridge_channel_thread_state activity; +}; + +/*! + * \brief Try locking the bridge_channel. + * + * \param bridge_channel What to try locking + * + * \retval 0 on success. + * \retval non-zero on error. + */ +#define ast_bridge_channel_trylock(bridge_channel) _ast_bridge_channel_trylock(bridge_channel, __FILE__, __PRETTY_FUNCTION__, __LINE__, #bridge_channel) +static inline int _ast_bridge_channel_trylock(struct ast_bridge_channel *bridge_channel, const char *file, const char *function, int line, const char *var) +{ + return __ao2_trylock(bridge_channel, AO2_LOCK_REQ_MUTEX, file, function, line, var); +} + +/*! + * \brief Lock the bridge_channel. + * + * \param bridge_channel What to lock + * + * \return Nothing + */ +#define ast_bridge_channel_lock(bridge_channel) _ast_bridge_channel_lock(bridge_channel, __FILE__, __PRETTY_FUNCTION__, __LINE__, #bridge_channel) +static inline void _ast_bridge_channel_lock(struct ast_bridge_channel *bridge_channel, const char *file, const char *function, int line, const char *var) +{ + __ao2_lock(bridge_channel, AO2_LOCK_REQ_MUTEX, file, function, line, var); +} + +/*! + * \brief Unlock the bridge_channel. + * + * \param bridge_channel What to unlock + * + * \return Nothing + */ +#define ast_bridge_channel_unlock(bridge_channel) _ast_bridge_channel_unlock(bridge_channel, __FILE__, __PRETTY_FUNCTION__, __LINE__, #bridge_channel) +static inline void _ast_bridge_channel_unlock(struct ast_bridge_channel *bridge_channel, const char *file, const char *function, int line, const char *var) +{ + __ao2_unlock(bridge_channel, file, function, line, var); +} + +/*! + * \brief Lock the bridge associated with the bridge channel. + * \since 12.0.0 + * + * \param bridge_channel Channel that wants to lock the bridge. + * + * \details + * This is an upstream lock operation. The defined locking + * order is bridge then bridge_channel. + * + * \note On entry, neither the bridge nor bridge_channel is locked. + * + * \note The bridge_channel->bridge pointer changes because of a + * bridge-merge/channel-move operation between bridges. + * + * \return Nothing + */ +void ast_bridge_channel_lock_bridge(struct ast_bridge_channel *bridge_channel); + +/*! + * \brief Lets the bridging indicate when a bridge channel has stopped or started talking. + * + * \note All DSP functionality on the bridge has been pushed down to the lowest possible + * layer, which in this case is the specific bridging technology being used. Since it + * is necessary for the knowledge of which channels are talking to make its way up to the + * application, this function has been created to allow the bridging technology to communicate + * that information with the bridging core. + * + * \param bridge_channel The bridge channel that has either started or stopped talking. + * \param started_talking set to 1 when this indicates the channel has started talking set to 0 + * when this indicates the channel has stopped talking. + * + * \retval 0 on success. + * \retval -1 on error. + */ +int ast_bridge_channel_notify_talking(struct ast_bridge_channel *bridge_channel, int started_talking); + +/*! + * \brief Set bridge channel state to leave bridge (if not leaving already). + * + * \param bridge_channel Channel to change the state on + * \param new_state The new state to place the channel into + * + * Example usage: + * + * \code + * ast_bridge_channel_leave_bridge(bridge_channel, BRIDGE_CHANNEL_STATE_END); + * \endcode + * + * This places the channel pointed to by bridge_channel into the + * state BRIDGE_CHANNEL_STATE_END if it was + * BRIDGE_CHANNEL_STATE_WAIT before. + */ +void ast_bridge_channel_leave_bridge(struct ast_bridge_channel *bridge_channel, enum bridge_channel_state new_state); + +/*! + * \brief Set bridge channel state to leave bridge (if not leaving already). + * + * \param bridge_channel Channel to change the state on + * \param new_state The new state to place the channel into + * + * Example usage: + * + * \code + * ast_bridge_channel_leave_bridge(bridge_channel, BRIDGE_CHANNEL_STATE_END); + * \endcode + * + * This places the channel pointed to by bridge_channel into the + * state BRIDGE_CHANNEL_STATE_END if it was + * BRIDGE_CHANNEL_STATE_WAIT before. + */ +void ast_bridge_channel_leave_bridge_nolock(struct ast_bridge_channel *bridge_channel, enum bridge_channel_state new_state); + +/*! + * \brief Get the peer bridge channel of a two party bridge. + * \since 12.0.0 + * + * \param bridge_channel What to get the peer of. + * + * \note On entry, bridge_channel->bridge is already locked. + * + * \note This is an internal bridge function. + * + * \retval peer on success. + * \retval NULL no peer channel. + */ +struct ast_bridge_channel *ast_bridge_channel_peer(struct ast_bridge_channel *bridge_channel); + +/*! + * \brief Restore the formats of a bridge channel's channel to how they were before bridge_channel_internal_join + * \since 12.0.0 + * + * \param bridge_channel Channel to restore + */ +void ast_bridge_channel_restore_formats(struct ast_bridge_channel *bridge_channel); + +/*! + * \brief Adjust the bridge_channel's bridge merge inhibit request count. + * \since 12.0.0 + * + * \param bridge_channel What to operate on. + * \param request Inhibit request increment. + * (Positive to add requests. Negative to remove requests.) + * + * \note This API call is meant for internal bridging operations. + * + * \retval bridge adjusted merge inhibit with reference count. + */ +struct ast_bridge *ast_bridge_channel_merge_inhibit(struct ast_bridge_channel *bridge_channel, int request); + +/*! + * \internal + * \brief Update the linkedids for all channels in a bridge + * \since 12.0.0 + * + * \param bridge_channel The channel joining the bridge + * \param swap The channel being swapped out of the bridge. May be NULL. + * + * \note The bridge must be locked prior to calling this function. This should be called + * during a \ref bridge_channel_internal_push operation, typically by a sub-class of a bridge + */ +void ast_bridge_channel_update_linkedids(struct ast_bridge_channel *bridge_channel, struct ast_bridge_channel *swap); + +/*! + * \internal + * \brief Update the accountcodes for a channel entering a bridge + * \since 12.0.0 + * + * This function updates the accountcode and peeraccount on channels in two-party + * bridges. In multi-party bridges, peeraccount is not set - it doesn't make much sense - + * however accountcode propagation will still occur if the channel joining has an + * accountcode. + * + * \param bridge_channel The channel joining the bridge + * \param swap The channel being swapped out of the bridge. May be NULL. + * + * \note The bridge must be locked prior to calling this function. This should be called + * during a \ref bridge_channel_internal_push operation, typically by a sub-class of a bridge + */ +void ast_bridge_channel_update_accountcodes(struct ast_bridge_channel *bridge_channel, struct ast_bridge_channel *swap); + +/*! + * \brief Write a frame to the specified bridge_channel. + * \since 12.0.0 + * + * \param bridge_channel Channel to queue the frame. + * \param fr Frame to write. + * + * \retval 0 on success. + * \retval -1 on error. + */ +int ast_bridge_channel_queue_frame(struct ast_bridge_channel *bridge_channel, struct ast_frame *fr); + +/*! + * \brief Queue a control frame onto the bridge channel with data. + * \since 12.0.0 + * + * \param bridge_channel Which channel to queue the frame onto. + * \param control Type of control frame. + * \param data Frame payload data to pass. + * \param datalen Frame payload data length to pass. + * + * \retval 0 on success. + * \retval -1 on error. + */ +int ast_bridge_channel_queue_control_data(struct ast_bridge_channel *bridge_channel, enum ast_control_frame_type control, const void *data, size_t datalen); + +/*! + * \brief Write a control frame into the bridge with data. + * \since 12.0.0 + * + * \param bridge_channel Which channel is putting the frame into the bridge. + * \param control Type of control frame. + * \param data Frame payload data to pass. + * \param datalen Frame payload data length to pass. + * + * \retval 0 on success. + * \retval -1 on error. + */ +int ast_bridge_channel_write_control_data(struct ast_bridge_channel *bridge_channel, enum ast_control_frame_type control, const void *data, size_t datalen); + +/*! + * \brief Write a hold frame into the bridge. + * \since 12.0.0 + * + * \param bridge_channel Which channel is putting the hold into the bridge. + * \param moh_class The suggested music class for the other end to use. + * + * \retval 0 on success. + * \retval -1 on error. + */ +int ast_bridge_channel_write_hold(struct ast_bridge_channel *bridge_channel, const char *moh_class); + +/*! + * \brief Write an unhold frame into the bridge. + * \since 12.0.0 + * + * \param bridge_channel Which channel is putting the hold into the bridge. + * + * \retval 0 on success. + * \retval -1 on error. + */ +int ast_bridge_channel_write_unhold(struct ast_bridge_channel *bridge_channel); + +/*! + * \brief Run an application on the bridge channel. + * \since 12.0.0 + * + * \param bridge_channel Which channel to run the application on. + * \param app_name Dialplan application name. + * \param app_args Arguments for the application. (NULL tolerant) + * \param moh_class MOH class to request bridge peers to hear while application is running. + * NULL if no MOH. + * Empty if default MOH class. + * + * \note This is intended to be called by bridge hooks. + * + * \return Nothing + */ +void ast_bridge_channel_run_app(struct ast_bridge_channel *bridge_channel, const char *app_name, const char *app_args, const char *moh_class); + +/*! + * \brief Write a bridge action run application frame into the bridge. + * \since 12.0.0 + * + * \param bridge_channel Which channel is putting the frame into the bridge + * \param app_name Dialplan application name. + * \param app_args Arguments for the application. (NULL or empty for no arguments) + * \param moh_class MOH class to request bridge peers to hear while application is running. + * NULL if no MOH. + * Empty if default MOH class. + * + * \note This is intended to be called by bridge hooks. + * + * \retval 0 on success. + * \retval -1 on error. + */ +int ast_bridge_channel_write_app(struct ast_bridge_channel *bridge_channel, const char *app_name, const char *app_args, const char *moh_class); + +/*! + * \brief Queue a bridge action run application frame onto the bridge channel. + * \since 12.0.0 + * + * \param bridge_channel Which channel to put the frame onto + * \param app_name Dialplan application name. + * \param app_args Arguments for the application. (NULL or empty for no arguments) + * \param moh_class MOH class to request bridge peers to hear while application is running. + * NULL if no MOH. + * Empty if default MOH class. + * + * \note This is intended to be called by bridge hooks. + * + * \retval 0 on success. + * \retval -1 on error. + */ +int ast_bridge_channel_queue_app(struct ast_bridge_channel *bridge_channel, const char *app_name, const char *app_args, const char *moh_class); + +/*! + * \brief Custom interpretation of the playfile name. + * + * \param bridge_channel Which channel to play the file on + * \param playfile Sound filename to play. + * + * \return Nothing + */ +typedef void (*ast_bridge_custom_play_fn)(struct ast_bridge_channel *bridge_channel, const char *playfile); + +/*! + * \brief Play a file on the bridge channel. + * \since 12.0.0 + * + * \param bridge_channel Which channel to play the file on + * \param custom_play Call this function to play the playfile. (NULL if normal sound file to play) + * \param playfile Sound filename to play. + * \param moh_class MOH class to request bridge peers to hear while file is played. + * NULL if no MOH. + * Empty if default MOH class. + * + * \note This is intended to be called by bridge hooks. + * + * \return Nothing + */ +void ast_bridge_channel_playfile(struct ast_bridge_channel *bridge_channel, ast_bridge_custom_play_fn custom_play, const char *playfile, const char *moh_class); + +/*! + * \brief Write a bridge action play file frame into the bridge. + * \since 12.0.0 + * + * \param bridge_channel Which channel is putting the frame into the bridge + * \param custom_play Call this function to play the playfile. (NULL if normal sound file to play) + * \param playfile Sound filename to play. + * \param moh_class MOH class to request bridge peers to hear while file is played. + * NULL if no MOH. + * Empty if default MOH class. + * + * \note This is intended to be called by bridge hooks. + * + * \retval 0 on success. + * \retval -1 on error. + */ +int ast_bridge_channel_write_playfile(struct ast_bridge_channel *bridge_channel, ast_bridge_custom_play_fn custom_play, const char *playfile, const char *moh_class); + +/*! + * \brief Queue a bridge action play file frame onto the bridge channel. + * \since 12.0.0 + * + * \param bridge_channel Which channel to put the frame onto. + * \param custom_play Call this function to play the playfile. (NULL if normal sound file to play) + * \param playfile Sound filename to play. + * \param moh_class MOH class to request bridge peers to hear while file is played. + * NULL if no MOH. + * Empty if default MOH class. + * + * \note This is intended to be called by bridge hooks. + * + * \retval 0 on success. + * \retval -1 on error. + */ +int ast_bridge_channel_queue_playfile(struct ast_bridge_channel *bridge_channel, ast_bridge_custom_play_fn custom_play, const char *playfile, const char *moh_class); + +/*! + * \brief Custom callback run on a bridge channel. + * + * \param bridge_channel Which channel to operate on. + * \param payload Data to pass to the callback. (NULL if none). + * \param payload_size Size of the payload if payload is non-NULL. A number otherwise. + * + * \note The payload MUST NOT have any resources that need to be freed. + * + * \return Nothing + */ +typedef void (*ast_bridge_custom_callback_fn)(struct ast_bridge_channel *bridge_channel, const void *payload, size_t payload_size); + +/*! + * \brief Write a bridge action custom callback frame into the bridge. + * \since 12.0.0 + * + * \param bridge_channel Which channel is putting the frame into the bridge + * \param callback Custom callback run on a bridge channel. + * \param payload Data to pass to the callback. (NULL if none). + * \param payload_size Size of the payload if payload is non-NULL. A number otherwise. + * + * \note The payload MUST NOT have any resources that need to be freed. + * + * \note This is intended to be called by bridge hooks. + * + * \retval 0 on success. + * \retval -1 on error. + */ +int ast_bridge_channel_write_callback(struct ast_bridge_channel *bridge_channel, ast_bridge_custom_callback_fn callback, const void *payload, size_t payload_size); + +/*! + * \brief Queue a bridge action custom callback frame onto the bridge channel. + * \since 12.0.0 + * + * \param bridge_channel Which channel to put the frame onto. + * \param callback Custom callback run on a bridge channel. + * \param payload Data to pass to the callback. (NULL if none). + * \param payload_size Size of the payload if payload is non-NULL. A number otherwise. + * + * \note The payload MUST NOT have any resources that need to be freed. + * + * \note This is intended to be called by bridge hooks. + * + * \retval 0 on success. + * \retval -1 on error. + */ +int ast_bridge_channel_queue_callback(struct ast_bridge_channel *bridge_channel, ast_bridge_custom_callback_fn callback, const void *payload, size_t payload_size); + +/*! + * \brief Have a bridge channel park a channel in the bridge + * \since 12.0.0 + * + * \param bridge_channel Bridge channel performing the parking + * \param parkee_uuid Unique id of the channel we want to park + * \param parker_uuid Unique id of the channel parking the call + * \param app_data string indicating data used for park application (NULL allowed) + * + * \note This is intended to be called by bridge hooks. + * + * \retval 0 on success. + * \retval -1 on error. + */ +int ast_bridge_channel_write_park(struct ast_bridge_channel *bridge_channel, const char *parkee_uuid, + const char *parker_uuid, const char *app_data); + +#if defined(__cplusplus) || defined(c_plusplus) +} +#endif + +#endif /* _ASTERISK_BRIDGING_CHANNEL_H */ diff --git a/include/asterisk/bridge_channel_internal.h b/include/asterisk/bridge_channel_internal.h new file mode 100644 index 000000000..6c3add13b --- /dev/null +++ b/include/asterisk/bridge_channel_internal.h @@ -0,0 +1,193 @@ +/* + * Asterisk -- An open source telephony toolkit. + * + * Copyright (C) 2013 Digium, Inc. + * + * Matt Jordan + * + * See http://www.asterisk.org for more information about + * the Asterisk project. Please do not directly contact + * any of the maintainers of this project for assistance; + * the project provides a web site, mailing lists and IRC + * channels for your use. + * + * This program is free software, distributed under the terms of + * the GNU General Public License Version 2. See the LICENSE file + * at the top of the source tree. + */ + +#ifndef _ASTERISK_PRIVATE_BRIDGING_CHANNEL_H +#define _ASTERISK_PRIVATE_BRIDGING_CHANNEL_H + +/*! + * \file + * \brief Private Bridging Channel API + * + * \author Matt Jordan + * + * A private API to manipulate channels in a bridge. These can be called on a channel in + * a bridge by \ref bridging.c. These functions should not be called elsewhere, including + * by other members of the Bridging API. + * + * See Also: + * \arg \ref AstCREDITS + * \arg \ref Ast + */ + +/*! + * \internal + * \brief Actions that can be taken on a channel in a bridge + */ +enum bridge_channel_action_type { + /*! Bridged channel is to detect a feature hook */ + BRIDGE_CHANNEL_ACTION_FEATURE, + /*! Bridged channel is to send a DTMF stream out */ + BRIDGE_CHANNEL_ACTION_DTMF_STREAM, + /*! Bridged channel is to indicate talking start */ + BRIDGE_CHANNEL_ACTION_TALKING_START, + /*! Bridged channel is to indicate talking stop */ + BRIDGE_CHANNEL_ACTION_TALKING_STOP, + /*! Bridge channel is to play the indicated sound file. */ + BRIDGE_CHANNEL_ACTION_PLAY_FILE, + /*! Bridge channel is to run the indicated application. */ + BRIDGE_CHANNEL_ACTION_RUN_APP, + /*! Bridge channel is to run the custom callback routine. */ + BRIDGE_CHANNEL_ACTION_CALLBACK, + /*! Bridge channel is to get parked. */ + BRIDGE_CHANNEL_ACTION_PARK, + /*! Bridge channel is to execute a blind transfer. */ + BRIDGE_CHANNEL_ACTION_BLIND_TRANSFER, + /*! Bridge channel is to execute an attended transfer */ + BRIDGE_CHANNEL_ACTION_ATTENDED_TRANSFER, + + /* + * Bridge actions put after this comment must never be put onto + * the bridge_channel wr_queue because they have other resources + * that must be freed. + */ + + /*! Bridge reconfiguration deferred technology destruction. */ + BRIDGE_CHANNEL_ACTION_DEFERRED_TECH_DESTROY = 1000, + /*! Bridge deferred dissolving. */ + BRIDGE_CHANNEL_ACTION_DEFERRED_DISSOLVING, +}; + +/*! + * \internal + * \brief Allocate a new ao2 ref counted bridge_channel + * \since 12.0.0 + * + * \param bridge The bridge to make the bridge_channel for + * + * \retval NULL on error + * \retval ao2 ref counted object on success + */ +struct ast_bridge_channel *bridge_channel_internal_alloc(struct ast_bridge *bridge); + +/*! + * \internal + * \brief Push the bridge channel into its specified bridge. + * \since 12.0.0 + * + * \param bridge_channel Channel to push. + * + * \note On entry, bridge_channel->bridge is already locked. + * + * \retval 0 on success. + * \retval -1 on failure. The channel did not get pushed. + */ +int bridge_channel_internal_push(struct ast_bridge_channel *bridge_channel); + +/*! + * \internal + * \brief Pull the bridge channel out of its current bridge. + * \since 12.0.0 + * + * \param bridge_channel Channel to pull. + * + * \note On entry, bridge_channel->bridge is already locked. + * + * \return Nothing + */ +void bridge_channel_internal_pull(struct ast_bridge_channel *bridge_channel); + +/*! + * \internal + * \brief Join the bridge_channel to the bridge + * + * \param bridge_channel The Channel in the bridge + * + * \note This API call starts the bridge_channel's processing of events while + * it is in the bridge. It will return when the channel has been instructed to + * leave the bridge. + */ +void bridge_channel_internal_join(struct ast_bridge_channel *bridge_channel); + +/*! + * \internal + * \brief Temporarily suspend a channel from a bridge, handing control over to some + * other system + * + * \param bridge_channel The channel in the bridge + * \note This function assumes that \ref bridge_channel is already locked + */ +void bridge_channel_internal_suspend_nolock(struct ast_bridge_channel *bridge_channel); + +/*! + * \internal + * \brief Unsuspend a channel that was previously suspended + * + * \param bridge_channel The channel in the bridge + * \note This function assumes that \ref bridge_channel is already locked + */ +void bridge_channel_internal_unsuspend_nolock(struct ast_bridge_channel *bridge_channel); + +/*! + * \internal + * \brief Queue a blind transfer action on a transferee bridge channel + * + * This is only relevant for when a blind transfer is performed on a two-party + * bridge. The transferee's bridge channel will have a blind transfer bridge + * action queued onto it, resulting in the party being redirected to a new + * destination + * + * \param transferee The channel to have the action queued on + * \param exten The destination extension for the transferee + * \param context The destination context for the transferee + * \param hook Frame hook to attach to transferee + * + * \retval 0 on success. + * \retval -1 on error. + */ +int bridge_channel_internal_queue_blind_transfer(struct ast_channel *transferee, + const char *exten, const char *context, + transfer_channel_cb new_channel_cb, void *user_data); + +/*! + * \internal + * \brief Queue an attended transfer action on a transferee bridge channel + * + * This is only relevant for when an attended transfer is performed on a two-party + * bridge. The transferee's bridge channel will have an attended transfer bridge + * action queued onto it. + * + * \param transferee The channel to have the action queued on + * \param unbridged_chan The unbridged channel who is the target of the attended + * transfer + * + * \retval 0 on success. + * \retval -1 on error. + */ +int bridge_channel_internal_queue_attended_transfer(struct ast_channel *transferee, + struct ast_channel *unbridged_chan); + +/*! + * \internal + * \brief Return whether or not the bridge_channel would allow optimization + * + * \retval 0 if optimization is not allowed + * \retval non-zero if optimization is allowed + */ +int bridge_channel_internal_allows_optimization(struct ast_bridge_channel *bridge_channel); + +#endif /* _ASTERISK_PRIVATE_BRIDGING_H */ diff --git a/include/asterisk/bridge_features.h b/include/asterisk/bridge_features.h new file mode 100644 index 000000000..05fdf2587 --- /dev/null +++ b/include/asterisk/bridge_features.h @@ -0,0 +1,798 @@ +/* + * Asterisk -- An open source telephony toolkit. + * + * Copyright (C) 2009, Digium, Inc. + * + * Joshua Colp + * + * See http://www.asterisk.org for more information about + * the Asterisk project. Please do not directly contact + * any of the maintainers of this project for assistance; + * the project provides a web site, mailing lists and IRC + * channels for your use. + * + * This program is free software, distributed under the terms of + * the GNU General Public License Version 2. See the LICENSE file + * at the top of the source tree. + */ + +/*! + * \file + * \brief Channel Bridging API + * \author Joshua Colp + */ + +#ifndef _ASTERISK_BRIDGING_FEATURES_H +#define _ASTERISK_BRIDGING_FEATURES_H + +#if defined(__cplusplus) || defined(c_plusplus) +extern "C" { +#endif + +/*! \brief Flags used for bridge features */ +enum ast_bridge_feature_flags { + /*! Upon channel hangup all bridge participants should be kicked out. */ + AST_BRIDGE_FLAG_DISSOLVE_HANGUP = (1 << 0), + /*! The last channel to leave the bridge dissolves it. */ + AST_BRIDGE_FLAG_DISSOLVE_EMPTY = (1 << 1), + /*! Move between bridging technologies as needed. */ + AST_BRIDGE_FLAG_SMART = (1 << 2), + /*! Bridge channels cannot be merged from this bridge. */ + AST_BRIDGE_FLAG_MERGE_INHIBIT_FROM = (1 << 3), + /*! Bridge channels cannot be merged to this bridge. */ + AST_BRIDGE_FLAG_MERGE_INHIBIT_TO = (1 << 4), + /*! Bridge channels cannot be local channel swap optimized from this bridge. */ + AST_BRIDGE_FLAG_SWAP_INHIBIT_FROM = (1 << 5), + /*! Bridge channels cannot be local channel swap optimized to this bridge. */ + AST_BRIDGE_FLAG_SWAP_INHIBIT_TO = (1 << 6), + /*! Bridge channels can be moved to another bridge only by masquerade (ConfBridge) */ + AST_BRIDGE_FLAG_MASQUERADE_ONLY = (1 << 7), + /*! Bridge does not allow transfers of channels out */ + AST_BRIDGE_FLAG_TRANSFER_PROHIBITED = (1 << 8), + /*! Bridge transfers require transfer of entire bridge rather than individual channels */ + AST_BRIDGE_FLAG_TRANSFER_BRIDGE_ONLY = (1 << 9), +}; + +/*! \brief Flags used for per bridge channel features */ +enum ast_bridge_channel_feature_flags { + /*! Upon channel hangup all bridge participants should be kicked out. */ + AST_BRIDGE_CHANNEL_FLAG_DISSOLVE_HANGUP = (1 << 0), + /*! This channel leaves the bridge if all participants have this flag set. */ + AST_BRIDGE_CHANNEL_FLAG_LONELY = (1 << 1), + /*! This channel cannot be moved to another bridge. */ + AST_BRIDGE_CHANNEL_FLAG_IMMOVABLE = (1 << 2), +}; + +/*! \brief Built in DTMF features */ +enum ast_bridge_builtin_feature { + /*! DTMF based Blind Transfer */ + AST_BRIDGE_BUILTIN_BLINDTRANSFER, + /*! DTMF based Attended Transfer */ + AST_BRIDGE_BUILTIN_ATTENDEDTRANSFER, + /*! + * DTMF based depart bridge feature + * + * \note Imparted channels are optionally hangup depending upon + * how it was imparted. + * + * \note Joined channels exit the bridge with + * BRIDGE_CHANNEL_STATE_END_WITH_DISSOLVE. + */ + AST_BRIDGE_BUILTIN_HANGUP, + /*! + * DTMF based Park + * + * \details The bridge is parked and the channel hears the + * parking slot to which it was parked. + */ + AST_BRIDGE_BUILTIN_PARKCALL, +/* BUGBUG does Monitor and/or MixMonitor require a two party bridge? MixMonitor is used by ConfBridge so maybe it doesn't. */ + /*! + * DTMF one-touch-record toggle using Monitor app. + * + * \note Only valid on two party bridges. + */ + AST_BRIDGE_BUILTIN_AUTOMON, + /*! + * DTMF one-touch-record toggle using MixMonitor app. + * + * \note Only valid on two party bridges. + */ + AST_BRIDGE_BUILTIN_AUTOMIXMON, + + /*! End terminator for list of built in features. Must remain last. */ + AST_BRIDGE_BUILTIN_END +}; + +enum ast_bridge_builtin_interval { + /*! Apply Call Duration Limits */ + AST_BRIDGE_BUILTIN_INTERVAL_LIMITS, + + /*! End terminator for list of built in interval features. Must remain last. */ + AST_BRIDGE_BUILTIN_INTERVAL_END +}; + +struct ast_bridge; +struct ast_bridge_channel; + +/*! + * \brief Hook callback type + * + * \param bridge The bridge that the channel is part of + * \param bridge_channel Channel executing the feature + * \param hook_pvt Private data passed in when the hook was created + * + * For interval hooks: + * \retval 0 Setup to fire again at the last interval. + * \retval positive Setup to fire again at the new interval returned. + * \retval -1 Remove the callback hook. + * + * For other hooks: + * \retval 0 Keep the callback hook. + * \retval -1 Remove the callback hook. + */ +typedef int (*ast_bridge_hook_callback)(struct ast_bridge *bridge, struct ast_bridge_channel *bridge_channel, void *hook_pvt); + +/*! + * \brief Hook pvt destructor callback + * + * \param hook_pvt Private data passed in when the hook was created to destroy + */ +typedef void (*ast_bridge_hook_pvt_destructor)(void *hook_pvt); + +/*! + * \brief Talking indicator callback + * + * \details This callback can be registered with the bridge in order + * to receive updates on when a bridge_channel has started and stopped + * talking + * + * \param bridge_channel Channel executing the feature + * \param talking TRUE if the channel is now talking + * + * \retval 0 Keep the callback hook. + * \retval -1 Remove the callback hook. + */ +typedef int (*ast_bridge_talking_indicate_callback)(struct ast_bridge_channel *bridge_channel, void *pvt_data, int talking); + +enum ast_bridge_hook_remove_flags { + /*! The hook is removed when the channel is pulled from the bridge. */ + AST_BRIDGE_HOOK_REMOVE_ON_PULL = (1 << 0), + /*! The hook is removed when the bridge's personality changes. */ + AST_BRIDGE_HOOK_REMOVE_ON_PERSONALITY_CHANGE = (1 << 1), +}; + +enum ast_bridge_hook_type { + /*! The hook type has not been specified. */ + AST_BRIDGE_HOOK_TYPE_NONE, + AST_BRIDGE_HOOK_TYPE_DTMF, + AST_BRIDGE_HOOK_TYPE_TIMER, + AST_BRIDGE_HOOK_TYPE_HANGUP, + AST_BRIDGE_HOOK_TYPE_JOIN, + AST_BRIDGE_HOOK_TYPE_LEAVE, + AST_BRIDGE_HOOK_TYPE_TALK, +}; + +/* BUGBUG Need to be able to selectively remove DTMF, hangup, and interval hooks. */ +/*! \brief Structure that is the essence of a feature hook. */ +struct ast_bridge_hook { + /*! Callback that is called when hook is tripped */ + ast_bridge_hook_callback callback; + /*! Callback to destroy hook_pvt data right before destruction. */ + ast_bridge_hook_pvt_destructor destructor; + /*! Unique data that was passed into us */ + void *hook_pvt; + /*! Flags determining when hooks should be removed from a bridge channel */ + struct ast_flags remove_flags; + /*! What kind of hook this is. */ + enum ast_bridge_hook_type type; +}; + +/*! + * \brief Maximum length of a DTMF feature string + */ +#define MAXIMUM_DTMF_FEATURE_STRING (11 + 1) + +/*! Extra parameters for a DTMF feature hook. */ +struct ast_bridge_hook_dtmf_parms { + /*! DTMF String that is examined during a feature hook lookup */ + char code[MAXIMUM_DTMF_FEATURE_STRING]; +}; + +/*! DTMF specific hook. */ +struct ast_bridge_hook_dtmf { + /*! Generic feature hook information. */ + struct ast_bridge_hook generic; + /*! Extra parameters for a DTMF feature hook. */ + struct ast_bridge_hook_dtmf_parms dtmf; +}; + +/*! Extra parameters for an interval timer hook. */ +struct ast_bridge_hook_timer_parms { + /*! Time at which the hook should actually trip */ + struct timeval trip_time; + /*! Heap index for interval hook */ + ssize_t heap_index; + /*! Interval that the hook should execute at in milliseconds */ + unsigned int interval; + /*! Sequence number for the hook to ensure expiration ordering */ + unsigned int seqno; +}; + +/*! Timer specific hook. */ +struct ast_bridge_hook_timer { + /*! Generic feature hook information. */ + struct ast_bridge_hook generic; + /*! Extra parameters for an interval timer hook. */ + struct ast_bridge_hook_timer_parms timer; +}; + +/*! + * \brief Structure that contains features information + */ +struct ast_bridge_features { + /*! Attached DTMF feature hooks */ + struct ao2_container *dtmf_hooks; + /*! Attached miscellaneous other hooks. */ + struct ao2_container *other_hooks; + /*! Attached interval hooks */ + struct ast_heap *interval_hooks; + /*! Limits feature data */ + struct ast_bridge_features_limits *limits; + /*! Feature flags that are enabled */ + struct ast_flags feature_flags; + /*! Used to assign the sequence number to the next interval hook added. */ + unsigned int interval_sequence; + /*! TRUE if feature_flags is setup */ + unsigned int usable:1; + /*! TRUE if the channel/bridge is muted. */ + unsigned int mute:1; + /*! TRUE if DTMF should be passed into the bridge tech. */ + unsigned int dtmf_passthrough:1; +}; + +/*! + * \brief Structure that contains configuration information for the blind transfer built in feature + */ +struct ast_bridge_features_blind_transfer { + /*! Context to use for transfers (If not empty.) */ + char context[AST_MAX_CONTEXT]; +}; + +/*! + * \brief Structure that contains configuration information for the attended transfer built in feature + */ +struct ast_bridge_features_attended_transfer { + /*! Context to use for transfers (If not empty.) */ + char context[AST_MAX_CONTEXT]; + /*! DTMF string used to abort the transfer (If not empty.) */ + char abort[MAXIMUM_DTMF_FEATURE_STRING]; + /*! DTMF string used to turn the transfer into a three way conference (If not empty.) */ + char threeway[MAXIMUM_DTMF_FEATURE_STRING]; + /*! DTMF string used to complete the transfer (If not empty.) */ + char complete[MAXIMUM_DTMF_FEATURE_STRING]; + /*! DTMF string used to swap bridged targets (If not empty.) */ + char swap[MAXIMUM_DTMF_FEATURE_STRING]; +}; + +enum ast_bridge_features_monitor { + /*! Toggle start/stop of Monitor/MixMonitor. */ + AUTO_MONITOR_TOGGLE, + /*! Start Monitor/MixMonitor if not already started. */ + AUTO_MONITOR_START, + /*! Stop Monitor/MixMonitor if not already stopped. */ + AUTO_MONITOR_STOP, +}; + +struct ast_bridge_features_automonitor { + /*! Start/Stop behavior. */ + enum ast_bridge_features_monitor start_stop; +}; + +struct ast_bridge_features_automixmonitor { + /*! Start/Stop behavior. */ + enum ast_bridge_features_monitor start_stop; +}; + +/*! + * \brief Structure that contains configuration information for the limits feature + */ +struct ast_bridge_features_limits { + /*! Maximum duration that the channel is allowed to be in the bridge (specified in milliseconds) */ + unsigned int duration; + /*! Duration into the call when warnings should begin (specified in milliseconds or 0 to disable) */ + unsigned int warning; + /*! Interval between the warnings (specified in milliseconds or 0 to disable) */ + unsigned int frequency; + + AST_DECLARE_STRING_FIELDS( + /*! Sound file to play when the maximum duration is reached (if empty, then nothing will be played) */ + AST_STRING_FIELD(duration_sound); + /*! Sound file to play when the warning time is reached (if empty, then the remaining time will be played) */ + AST_STRING_FIELD(warning_sound); + /*! Sound file to play when the call is first entered (if empty, then the remaining time will be played) */ + AST_STRING_FIELD(connect_sound); + ); + /*! Time when the bridge will be terminated by the limits feature */ + struct timeval quitting_time; +}; + +/*! + * \brief Register a handler for a built in feature + * + * \param feature The feature that the handler will be responsible for + * \param callback The callback function that will handle it + * \param dtmf Default DTMF string used to activate the feature + * + * \retval 0 on success + * \retval -1 on failure + * + * Example usage: + * + * \code + * ast_bridge_features_register(AST_BRIDGE_BUILTIN_ATTENDED_TRANSFER, bridge_builtin_attended_transfer, "*1"); + * \endcode + * + * This registers the function bridge_builtin_attended_transfer as the function responsible for the built in + * attended transfer feature. + */ +int ast_bridge_features_register(enum ast_bridge_builtin_feature feature, ast_bridge_hook_callback callback, const char *dtmf); + +/*! + * \brief Unregister a handler for a built in feature + * + * \param feature The feature to unregister + * + * \retval 0 on success + * \retval -1 on failure + * + * Example usage: + * + * \code + * ast_bridge_features_unregister(AST_BRIDGE_BUILTIN_ATTENDED_TRANSFER); + * \endcode + * + * This unregisters the function that is handling the built in attended transfer feature. + */ +int ast_bridge_features_unregister(enum ast_bridge_builtin_feature feature); + +/*! + * \brief Invoke a built in feature hook now. + * + * \param feature The feature to invoke + * + * \note This API call is only meant to be used by bridge + * subclasses and hook callbacks to request a builtin feature + * hook to be executed. + * + * \retval 0 on success + * \retval -1 on failure + * + * Example usage: + * + * \code + * ast_bridge_features_do(AST_BRIDGE_BUILTIN_ATTENDED_TRANSFER, bridge, bridge_channel, hook_pvt); + * \endcode + */ +int ast_bridge_features_do(enum ast_bridge_builtin_feature feature, struct ast_bridge *bridge, struct ast_bridge_channel *bridge_channel, void *hook_pvt); + +/*! + * \brief Attach interval hooks to a bridge features structure + * + * \param features Bridge features structure + * \param limits Configured limits applicable to the channel + * \param remove_flags Dictates what situations the hook should be removed. + * + * \retval 0 on success + * \retval -1 on failure + */ +typedef int (*ast_bridge_builtin_set_limits_fn)(struct ast_bridge_features *features, + struct ast_bridge_features_limits *limits, enum ast_bridge_hook_remove_flags remove_flags); + +/*! + * \brief Register a handler for a built in interval feature + * + * \param interval The interval feature that the handler will be responsible for + * \param callback the Callback function that will handle it + * + * \retval 0 on success + * \retval -1 on failure + * + * Example usage: + * + * \code + * ast_bridge_interval_register(AST_BRIDGE_BUILTIN_INTERVAL_LIMITS, bridge_builtin_set_limits); + * \endcode + * + * This registers the function bridge_builtin_set_limits as the function responsible for the built in + * duration limit feature. + */ +int ast_bridge_interval_register(enum ast_bridge_builtin_interval interval, ast_bridge_builtin_set_limits_fn callback); + +/*! + * \brief Unregisters a handler for a built in interval feature + * + * \param interval the interval feature to unregister + * + * \retval 0 on success + * \retval -1 on failure + * + * Example usage: + * + * \code + * ast_bridge_interval_unregister(AST_BRIDGE_BULTIN_INTERVAL_LIMITS) + * /endcode + * + * This unregisters the function that is handling the built in duration limit feature. + */ +int ast_bridge_interval_unregister(enum ast_bridge_builtin_interval interval); + +/*! + * \brief Attach a bridge channel join hook to a bridge features structure + * + * \param features Bridge features structure + * \param callback Function to execute upon activation + * \param hook_pvt Unique data + * \param destructor Optional destructor callback for hook_pvt data + * \param remove_flags Dictates what situations the hook should be removed. + * + * \retval 0 on success + * \retval -1 on failure (The caller must cleanup any hook_pvt resources.) + * + * Example usage: + * + * \code + * struct ast_bridge_features features; + * ast_bridge_features_init(&features); + * ast_bridge_join_hook(&features, join_callback, NULL, NULL, 0); + * \endcode + * + * This makes the bridging core call join_callback when a + * channel successfully joins the bridging system. A pointer to + * useful data may be provided to the hook_pvt parameter. + */ +int ast_bridge_join_hook(struct ast_bridge_features *features, + ast_bridge_hook_callback callback, + void *hook_pvt, + ast_bridge_hook_pvt_destructor destructor, + enum ast_bridge_hook_remove_flags remove_flags); + +/*! + * \brief Attach a bridge channel leave hook to a bridge features structure + * + * \param features Bridge features structure + * \param callback Function to execute upon activation + * \param hook_pvt Unique data + * \param destructor Optional destructor callback for hook_pvt data + * \param remove_flags Dictates what situations the hook should be removed. + * + * \retval 0 on success + * \retval -1 on failure (The caller must cleanup any hook_pvt resources.) + * + * Example usage: + * + * \code + * struct ast_bridge_features features; + * ast_bridge_features_init(&features); + * ast_bridge_leave_hook(&features, leave_callback, NULL, NULL, 0); + * \endcode + * + * This makes the bridging core call leave_callback when a + * channel successfully leaves the bridging system. A pointer + * to useful data may be provided to the hook_pvt parameter. + */ +int ast_bridge_leave_hook(struct ast_bridge_features *features, + ast_bridge_hook_callback callback, + void *hook_pvt, + ast_bridge_hook_pvt_destructor destructor, + enum ast_bridge_hook_remove_flags remove_flags); + +/*! + * \brief Attach a hangup hook to a bridge features structure + * + * \param features Bridge features structure + * \param callback Function to execute upon activation + * \param hook_pvt Unique data + * \param destructor Optional destructor callback for hook_pvt data + * \param remove_flags Dictates what situations the hook should be removed. + * + * \retval 0 on success + * \retval -1 on failure (The caller must cleanup any hook_pvt resources.) + * + * Example usage: + * + * \code + * struct ast_bridge_features features; + * ast_bridge_features_init(&features); + * ast_bridge_hangup_hook(&features, hangup_callback, NULL, NULL, 0); + * \endcode + * + * This makes the bridging core call hangup_callback if a + * channel that has this hook hangs up. A pointer to useful + * data may be provided to the hook_pvt parameter. + */ +int ast_bridge_hangup_hook(struct ast_bridge_features *features, + ast_bridge_hook_callback callback, + void *hook_pvt, + ast_bridge_hook_pvt_destructor destructor, + enum ast_bridge_hook_remove_flags remove_flags); + +/*! + * \brief Attach a DTMF hook to a bridge features structure + * + * \param features Bridge features structure + * \param dtmf DTMF string to be activated upon + * \param callback Function to execute upon activation + * \param hook_pvt Unique data + * \param destructor Optional destructor callback for hook_pvt data + * \param remove_flags Dictates what situations the hook should be removed. + * + * \retval 0 on success + * \retval -1 on failure (The caller must cleanup any hook_pvt resources.) + * + * Example usage: + * + * \code + * struct ast_bridge_features features; + * ast_bridge_features_init(&features); + * ast_bridge_dtmf_hook(&features, "#", pound_callback, NULL, NULL, 0); + * \endcode + * + * This makes the bridging core call pound_callback if a channel that has this + * feature structure inputs the DTMF string '#'. A pointer to useful data may be + * provided to the hook_pvt parameter. + */ +int ast_bridge_dtmf_hook(struct ast_bridge_features *features, + const char *dtmf, + ast_bridge_hook_callback callback, + void *hook_pvt, + ast_bridge_hook_pvt_destructor destructor, + enum ast_bridge_hook_remove_flags remove_flags); + +/*! + * \brief Attach an interval hook to a bridge features structure + * + * \param features Bridge features structure + * \param interval The interval that the hook should execute at in milliseconds + * \param callback Function to execute upon activation + * \param hook_pvt Unique data + * \param destructor Optional destructor callback for hook_pvt data + * \param remove_flags Dictates what situations the hook should be removed. + * + * \retval 0 on success + * \retval -1 on failure (The caller must cleanup any hook_pvt resources.) + * + * \code + * struct ast_bridge_features features; + * ast_bridge_features_init(&features); + * ast_bridge_interval_hook(&features, 1000, playback_callback, NULL, NULL, 0); + * \endcode + * + * This makes the bridging core call playback_callback every second. A pointer to useful + * data may be provided to the hook_pvt parameter. + */ +int ast_bridge_interval_hook(struct ast_bridge_features *features, + unsigned int interval, + ast_bridge_hook_callback callback, + void *hook_pvt, + ast_bridge_hook_pvt_destructor destructor, + enum ast_bridge_hook_remove_flags remove_flags); + +/*! + * \brief Attach a bridge channel talk detection hook to a bridge features structure + * + * \param features Bridge features structure + * \param callback Function to execute upon activation + * \param hook_pvt Unique data + * \param destructor Optional destructor callback for hook_pvt data + * \param remove_flags Dictates what situations the hook should be removed. + * + * \retval 0 on success + * \retval -1 on failure (The caller must cleanup any hook_pvt resources.) + * + * Example usage: + * + * \code + * struct ast_bridge_features features; + * ast_bridge_features_init(&features); + * ast_bridge_talk_hook(&features, talk_callback, NULL, NULL, 0); + * \endcode + * + * This makes the bridging technology call talk_callback when a + * channel is recognized as starting and stopping talking. A + * pointer to useful data may be provided to the hook_pvt + * parameter. + * + * \note This hook is currently only supported by softmix. + */ +int ast_bridge_talk_detector_hook(struct ast_bridge_features *features, + ast_bridge_talking_indicate_callback callback, + void *hook_pvt, + ast_bridge_hook_pvt_destructor destructor, + enum ast_bridge_hook_remove_flags remove_flags); + +/*! + * \brief Enable a built in feature on a bridge features structure + * + * \param features Bridge features structure + * \param feature Feature to enable + * \param dtmf Optionally the DTMF stream to trigger the feature, if not specified it will be the default + * \param config Configuration structure unique to the built in type + * \param destructor Optional destructor callback for config data + * \param remove_flags Dictates what situations the hook should be removed. + * + * \retval 0 on success + * \retval -1 on failure + * + * Example usage: + * + * \code + * struct ast_bridge_features features; + * ast_bridge_features_init(&features); + * ast_bridge_features_enable(&features, AST_BRIDGE_BUILTIN_ATTENDEDTRANSFER, NULL, NULL, 0); + * \endcode + * + * This enables the attended transfer DTMF option using the default DTMF string. An alternate + * string may be provided using the dtmf parameter. Internally this is simply setting up a hook + * to a built in feature callback function. + */ +int ast_bridge_features_enable(struct ast_bridge_features *features, + enum ast_bridge_builtin_feature feature, + const char *dtmf, + void *config, + ast_bridge_hook_pvt_destructor destructor, + enum ast_bridge_hook_remove_flags remove_flags); + +/*! + * \brief Constructor function for ast_bridge_features_limits + * + * \param limits pointer to a ast_bridge_features_limits struct that has been allocted, but not initialized + * + * \retval 0 on success + * \retval -1 on failure + */ +int ast_bridge_features_limits_construct(struct ast_bridge_features_limits *limits); + +/*! + * \brief Destructor function for ast_bridge_features_limits + * + * \param limits pointer to an ast_bridge_features_limits struct that needs to be destroyed + * + * This function does not free memory allocated to the ast_bridge_features_limits struct, it only frees elements within the struct. + * You must still call ast_free on the the struct if you allocated it with malloc. + */ +void ast_bridge_features_limits_destroy(struct ast_bridge_features_limits *limits); + +/*! + * \brief Limit the amount of time a channel may stay in the bridge and optionally play warning messages as time runs out + * + * \param features Bridge features structure + * \param limits Configured limits applicable to the channel + * \param remove_flags Dictates what situations the hook should be removed. + * + * \retval 0 on success + * \retval -1 on failure + * + * Example usage: + * + * \code + * struct ast_bridge_features features; + * struct ast_bridge_features_limits limits; + * ast_bridge_features_init(&features); + * ast_bridge_features_limits_construct(&limits); + * ast_bridge_features_set_limits(&features, &limits, 0); + * ast_bridge_features_limits_destroy(&limits); + * \endcode + * + * This sets the maximum time the channel can be in the bridge to 10 seconds and does not play any warnings. + * + * \note This API call can only be used on a features structure that will be used in association with a bridge channel. + * \note The ast_bridge_features_limits structure must remain accessible for the lifetime of the features structure. + */ +int ast_bridge_features_set_limits(struct ast_bridge_features *features, struct ast_bridge_features_limits *limits, enum ast_bridge_hook_remove_flags remove_flags); + +/*! + * \brief Set a flag on a bridge channel features structure + * + * \param features Bridge channel features structure + * \param flag Flag to enable + * + * \return Nothing + * + * Example usage: + * + * \code + * struct ast_bridge_features features; + * ast_bridge_features_init(&features); + * ast_bridge_features_set_flag(&features, AST_BRIDGE_CHANNEL_FLAG_DISSOLVE_HANGUP); + * \endcode + * + * This sets the AST_BRIDGE_CHANNEL_FLAG_DISSOLVE_HANGUP feature + * to be enabled on the features structure 'features'. + */ +void ast_bridge_features_set_flag(struct ast_bridge_features *features, unsigned int flag); + +/*! + * \brief Initialize bridge features structure + * + * \param features Bridge featues structure + * + * \retval 0 on success + * \retval -1 on failure + * + * Example usage: + * + * \code + * struct ast_bridge_features features; + * ast_bridge_features_init(&features); + * \endcode + * + * This initializes the feature structure 'features' to have nothing enabled. + * + * \note This MUST be called before enabling features or flags. Failure to do so + * may result in a crash. + */ +int ast_bridge_features_init(struct ast_bridge_features *features); + +/*! + * \brief Clean up the contents of a bridge features structure + * + * \param features Bridge features structure + * + * \return Nothing + * + * Example usage: + * + * \code + * struct ast_bridge_features features; + * ast_bridge_features_init(&features); + * ast_bridge_features_cleanup(&features); + * \endcode + * + * This cleans up the feature structure 'features'. + * + * \note This MUST be called after the features structure is done being used + * or a memory leak may occur. + */ +void ast_bridge_features_cleanup(struct ast_bridge_features *features); + +/*! + * \brief Allocate a new bridge features struct. + * \since 12.0.0 + * + * Example usage: + * + * \code + * struct ast_bridge_features *features; + * features = ast_bridge_features_new(); + * ast_bridge_features_destroy(features); + * \endcode + * + * \retval features New allocated features struct. + * \retval NULL on error. + */ +struct ast_bridge_features *ast_bridge_features_new(void); + +/*! + * \brief Destroy an allocated bridge features struct. + * \since 12.0.0 + * + * \param features Bridge features structure + * + * Example usage: + * + * \code + * struct ast_bridge_features *features; + * features = ast_bridge_features_new(); + * ast_bridge_features_destroy(features); + * \endcode + * + * \return Nothing + */ +void ast_bridge_features_destroy(struct ast_bridge_features *features); + +#if defined(__cplusplus) || defined(c_plusplus) +} +#endif + +#endif /* _ASTERISK_BRIDGING_FEATURES_H */ diff --git a/include/asterisk/bridge_internal.h b/include/asterisk/bridge_internal.h new file mode 100644 index 000000000..18ef56e96 --- /dev/null +++ b/include/asterisk/bridge_internal.h @@ -0,0 +1,211 @@ +/* + * Asterisk -- An open source telephony toolkit. + * + * Copyright (C) 2013 Digium, Inc. + * + * Mark Michelson + * + * See http://www.asterisk.org for more information about + * the Asterisk project. Please do not directly contact + * any of the maintainers of this project for assistance; + * the project provides a web site, mailing lists and IRC + * channels for your use. + * + * This program is free software, distributed under the terms of + * the GNU General Public License Version 2. See the LICENSE file + * at the top of the source tree. + */ + +/*! + * \file + * \brief Private Bridging API + * + * Functions in this file are intended to be used by the Bridging API, + * bridge mixing technologies, and bridge sub-classes. Users of bridges + * that do not fit those three categories should *not* use the API + * defined in this file. + * + * \author Mark Michelson + * + * See Also: + * \arg \ref AstCREDITS + */ + +#ifndef _ASTERISK_PRIVATE_BRIDGING_H +#define _ASTERISK_PRIVATE_BRIDGING_H + +struct ast_bridge; +struct ast_bridge_channel; + +/*! + * \brief Register the new bridge with the system. + * \since 12.0.0 + * + * \param bridge What to register. (Tolerates a NULL pointer) + * + * \code + * struct ast_bridge *ast_bridge_basic_new(uint32_t capabilities, int flags, uint32 dtmf_features) + * { + * void *bridge; + * + * bridge = bridge_alloc(sizeof(struct ast_bridge_basic), &ast_bridge_basic_v_table); + * bridge = bridge_base_init(bridge, capabilities, flags); + * bridge = ast_bridge_basic_init(bridge, dtmf_features); + * bridge = bridge_register(bridge); + * return bridge; + * } + * \endcode + * + * \note This must be done after a bridge constructor has + * completed setting up the new bridge but before it returns. + * + * \note After a bridge is registered, ast_bridge_destroy() must + * eventually be called to get rid of the bridge. + * + * \retval bridge on success. + * \retval NULL on error. + */ +struct ast_bridge *bridge_register(struct ast_bridge *bridge); + +/*! + * \internal + * \brief Allocate the bridge class object memory. + * \since 12.0.0 + * + * \param size Size of the bridge class structure to allocate. + * \param v_table Bridge class virtual method table. + * + * \retval bridge on success. + * \retval NULL on error. + */ +struct ast_bridge *bridge_alloc(size_t size, const struct ast_bridge_methods *v_table); + +/*! + * \brief Initialize the base class of the bridge. + * + * \param self Bridge to operate upon. (Tolerates a NULL pointer) + * \param capabilities The capabilities that we require to be used on the bridge + * \param flags Flags that will alter the behavior of the bridge + * + * \retval self on success + * \retval NULL on failure, self is already destroyed + * + * Example usage: + * + * \code + * struct ast_bridge *bridge; + * bridge = bridge_alloc(sizeof(*bridge), &ast_bridge_base_v_table); + * bridge = bridge_base_init(bridge, AST_BRIDGE_CAPABILITY_1TO1MIX, AST_BRIDGE_FLAG_DISSOLVE_HANGUP); + * \endcode + * + * This creates a no frills two party bridge that will be + * destroyed once one of the channels hangs up. + */ +struct ast_bridge *bridge_base_init(struct ast_bridge *self, uint32_t capabilities, unsigned int flags); + +/*! + * \internal + * \brief Move a bridge channel from one bridge to another. + * \since 12.0.0 + * + * \param dst_bridge Destination bridge of bridge channel move. + * \param bridge_channel Channel moving from one bridge to another. + * \param attempt_recovery TRUE if failure attempts to push channel back into original bridge. + * \param optimized Indicates whether the move is part of an unreal channel optimization. + * + * \note The dst_bridge and bridge_channel->bridge are assumed already locked. + * + * \retval 0 on success. + * \retval -1 on failure. + */ +int bridge_do_move(struct ast_bridge *dst_bridge, struct ast_bridge_channel *bridge_channel, + int attempt_recovery, unsigned int optimized); + +/*! + * \internal + * \brief Do the merge of two bridges. + * \since 12.0.0 + * + * \param dst_bridge Destination bridge of merge. + * \param src_bridge Source bridge of merge. + * \param kick_me Array of channels to kick from the bridges. + * \param num_kick Number of channels in the kick_me array. + * \param optimized Indicates whether the merge is part of an unreal channel optimization. + * + * \return Nothing + * + * \note The two bridges are assumed already locked. + * + * This moves the channels in src_bridge into the bridge pointed + * to by dst_bridge. + */ +void bridge_do_merge(struct ast_bridge *dst_bridge, struct ast_bridge *src_bridge, + struct ast_bridge_channel **kick_me, unsigned int num_kick, unsigned int optimized); + +/*! + * \internal + * \brief Helper function to find a bridge channel given a channel. + * + * \param bridge What to search + * \param chan What to search for. + * + * \note On entry, bridge is already locked. + * + * \retval bridge_channel if channel is in the bridge. + * \retval NULL if not in bridge. + */ +struct ast_bridge_channel *bridge_find_channel(struct ast_bridge *bridge, struct ast_channel *chan); + +/*! + * \internal + * \brief Adjust the bridge merge inhibit request count. + * \since 12.0.0 + * + * \param bridge What to operate on. + * \param request Inhibit request increment. + * (Positive to add requests. Negative to remove requests.) + * + * \note This function assumes bridge is locked. + * + * \return Nothing + */ +void bridge_merge_inhibit_nolock(struct ast_bridge *bridge, int request); + +/*! + * \internal + * \brief Notify the bridge that it has been reconfigured. + * \since 12.0.0 + * + * \param bridge Reconfigured bridge. + * \param colp_update Whether to perform COLP updates. + * + * \details + * After a series of bridge_channel_internal_push and + * bridge_channel_internal_pull calls, you need to call this function + * to cause the bridge to complete restructuring for the change + * in the channel makeup of the bridge. + * + * \note On entry, the bridge is already locked. + * + * \return Nothing + */ +void bridge_reconfigured(struct ast_bridge *bridge, unsigned int colp_update); + +/*! + * \internal + * \brief Dissolve the bridge. + * \since 12.0.0 + * + * \param bridge Bridge to eject all channels + * + * \details + * Force out all channels that are not already going out of the + * bridge. Any new channels joining will leave immediately. + * + * \note On entry, bridge is already locked. + * + * \return Nothing + */ +void bridge_dissolve(struct ast_bridge *bridge); + +#endif /* _ASTERISK_PRIVATE_BRIDGING_H */ diff --git a/include/asterisk/bridge_roles.h b/include/asterisk/bridge_roles.h new file mode 100644 index 000000000..d90e564b7 --- /dev/null +++ b/include/asterisk/bridge_roles.h @@ -0,0 +1,166 @@ +/* + * Asterisk -- An open source telephony toolkit. + * + * Copyright (C) 2013, Digium, Inc. + * + * Jonathan Rose + * + * See http://www.asterisk.org for more information about + * the Asterisk project. Please do not directly contact + * any of the maintainers of this project for assistance; + * the project provides a web site, mailing lists and IRC + * channels for your use. + * + * This program is free software, distributed under the terms of + * the GNU General Public License Version 2. See the LICENSE file + * at the top of the source tree. + */ + +/*! \file + * \brief Channel Bridging Roles API + * \author Jonathan Rose + */ + +#ifndef _ASTERISK_BRIDGING_ROLES_H +#define _ASTERISK_BRIDGING_ROLES_H + +#if defined(__cplusplus) || defined(c_plusplus) +extern "C" { +#endif + +#include "asterisk/linkedlists.h" + +#define AST_ROLE_LEN 32 + +/*! + * \brief Adds a bridge role to a channel + * + * \param chan Acquirer of the requested role + * \param role_name Name of the role being attached + * + * \retval 0 on success + * \retval -1 on failure + */ +int ast_channel_add_bridge_role(struct ast_channel *chan, const char *role_name); + +/*! + * \brief Removes a bridge role from a channel + * + * \param chan Channel the role is being removed from + * \param role_name Name of the role being removed + */ +void ast_channel_remove_bridge_role(struct ast_channel *chan, const char *role_name); + +/*! + * \brief Set a role option on a channel + * \param channel Channel receiving the role option + * \param role_name Role the role option is applied to + * \param option Name of the option + * \param value Value of the option + * + * \param 0 on success + * \retval -1 on failure + */ +int ast_channel_set_bridge_role_option(struct ast_channel *channel, const char *role_name, const char *option, const char *value); + +/*! + * \brief Check if a role exists on a channel + * + * \param channel The channel to check + * \param role_name The name of the role to search for + * + * \retval 0 The requested role does not exist on the channel + * \retval 1 The requested role exists on the channel + * + * This is an alternative to \ref ast_bridge_channel_has_role that is useful if bridge + * roles have not yet been established on a channel's bridge_channel. A possible example of + * when this could be used is in a bridge v_table's push() callback. + */ +int ast_channel_has_role(struct ast_channel *channel, const char *role_name); + +/*! + * \brief Retrieve the value of a requested role option from a channel + * + * \param channel The channel to retrieve the requested option from + * \param role_name The role to which the option belongs + * \param option The name of the option to retrieve + * + * \retval NULL The option does not exist + * \retval non-NULL The value of the option + * + * This is an alternative to \ref ast_bridge_channel_get_role_option that is useful if bridge + * roles have not yet been esstablished on a channel's bridge_channel. A possible example of + * when this could be used is in a bridge v_table's push() callback. + */ +const char *ast_channel_get_role_option(struct ast_channel *channel, const char *role_name, const char *option); + +/*! + * \brief Check to see if a bridge channel inherited a specific role from its channel + * + * \param bridge_channel The bridge channel being checked + * \param role_name Name of the role being checked + * + * \retval 0 The bridge channel does not have the requested role + * \retval 1 The bridge channel does have the requested role + * + * \note Before a bridge_channel can effectively check roles against a bridge, ast_bridge_channel_establish_roles + * should be called on the bridge_channel so that roles and their respective role options can be copied from the channel + * datastore into the bridge_channel roles list. Otherwise this function will just return 0 because the list will be NULL. + */ +int ast_bridge_channel_has_role(struct ast_bridge_channel *bridge_channel, const char *role_name); + +/*! + * \brief Retrieve the value of a requested role option from a bridge channel + * + * \param bridge_channel The bridge channel we are retrieving the option from + * \param role_name Name of the role the option will be retrieved from + * \param option Name of the option we are retrieving the value of + * + * \retval NULL If either the role does not exist on the bridge_channel or the role does exist but the option has not been set + * \retval The value of the option + * + * \note See ast_channel_set_role_option note about the need to call ast_bridge_channel_establish_roles. + * + * \note The returned character pointer is only valid as long as the bridge_channel is guaranteed to be alive and hasn't had + * ast_bridge_channel_clear_roles called against it (as this will free all roles and role options in the bridge + * channel). If you need this value after one of these destruction events occurs, you must make a local copy while it is + * still valid. + */ +const char *ast_bridge_channel_get_role_option(struct ast_bridge_channel *bridge_channel, const char *role_name, const char *option); + +/*! + * \brief Clone the roles from a bridge_channel's attached ast_channel onto the bridge_channel's role list + * + * \param bridge_channel The bridge channel that we are preparing + * + * \retval 0 on success + * \retval -1 on failure + * + * \details + * This function should always be called when the bridge_channel binds to an ast_channel at some point before the bridge_channel + * joins or is imparted onto a bridge. Failure to do so will result in an empty role list. While the list remains established, + * changes to roles on the ast_channel will not propogate to the bridge channel and roles can not be re-established on the bridge + * channel without first clearing the roles with ast_bridge_roles_bridge_channel_clear_roles. + */ +int ast_bridge_channel_establish_roles(struct ast_bridge_channel *bridge_channel); + +/*! + * \brief Clear all roles from a bridge_channel's role list + * + * \param bridge_channel the bridge channel that we are scrubbing + * + * \details + * If roles are already established on a bridge channel, ast_bridge_channel_establish_roles will fail unconditionally + * without changing any roles. In order to update a bridge channel's roles, they must first be cleared from the bridge channel using + * this function. + * + * \note + * ast_bridge_channel_clear_roles also serves as the destructor for the role list of a bridge channel. + */ +void ast_bridge_channel_clear_roles(struct ast_bridge_channel *bridge_channel); + +#if defined(__cplusplus) || defined(c_plusplus) +} +#endif + +#endif /* _ASTERISK_BRIDGING_ROLES_H */ diff --git a/include/asterisk/bridge_technology.h b/include/asterisk/bridge_technology.h new file mode 100644 index 000000000..534eb5417 --- /dev/null +++ b/include/asterisk/bridge_technology.h @@ -0,0 +1,242 @@ +/* + * Asterisk -- An open source telephony toolkit. + * + * Copyright (C) 2009, Digium, Inc. + * + * Joshua Colp + * + * See http://www.asterisk.org for more information about + * the Asterisk project. Please do not directly contact + * any of the maintainers of this project for assistance; + * the project provides a web site, mailing lists and IRC + * channels for your use. + * + * This program is free software, distributed under the terms of + * the GNU General Public License Version 2. See the LICENSE file + * at the top of the source tree. + */ + +/*! \file + * \brief Channel Bridging API + * \author Joshua Colp + */ + +#ifndef _ASTERISK_BRIDGING_TECHNOLOGY_H +#define _ASTERISK_BRIDGING_TECHNOLOGY_H + +#if defined(__cplusplus) || defined(c_plusplus) +extern "C" { +#endif + +/*! + * \brief Base preference values for choosing a bridge technology. + * + * \note Higher is more preference. + */ +enum ast_bridge_preference { + AST_BRIDGE_PREFERENCE_BASE_HOLDING = 50, + AST_BRIDGE_PREFERENCE_BASE_EARLY = 100, + AST_BRIDGE_PREFERENCE_BASE_NATIVE = 90, + AST_BRIDGE_PREFERENCE_BASE_1TO1MIX = 50, + AST_BRIDGE_PREFERENCE_BASE_MULTIMIX = 10, +}; + +/*! + * \brief Structure specific to bridge technologies capable of + * performing talking optimizations. + */ +struct ast_bridge_tech_optimizations { + /*! The amount of time in ms that talking must be detected before + * the dsp determines that talking has occurred */ + unsigned int talking_threshold; + /*! The amount of time in ms that silence must be detected before + * the dsp determines that talking has stopped */ + unsigned int silence_threshold; + /*! Whether or not the bridging technology should drop audio + * detected as silence from the mix. */ + unsigned int drop_silence:1; +}; + +/*! + * \brief Structure that is the essence of a bridge technology + */ +struct ast_bridge_technology { + /*! Unique name to this bridge technology */ + const char *name; + /*! The capabilities that this bridge technology is capable of. This has nothing to do with + * format capabilities. */ + uint32_t capabilities; + /*! Preference level that should be used when determining whether to use this bridge technology or not */ + enum ast_bridge_preference preference; + /*! + * \brief Create a bridge technology instance for a bridge. + * + * \retval 0 on success + * \retval -1 on failure + * + * \note On entry, bridge may or may not already be locked. + * However, it can be accessed as if it were locked. + */ + int (*create)(struct ast_bridge *bridge); + /*! + * \brief Request a bridge technology instance start operations. + * + * \retval 0 on success + * \retval -1 on failure + * + * \note On entry, bridge may or may not already be locked. + * However, it can be accessed as if it were locked. + */ + int (*start)(struct ast_bridge *bridge); + /*! + * \brief Request a bridge technology instance stop in preparation for being destroyed. + * + * \note On entry, bridge is already locked. + */ + void (*stop)(struct ast_bridge *bridge); + /*! + * \brief Destroy a bridging technology instance for a bridge. + * + * \note On entry, bridge must NOT be locked. + */ + void (*destroy)(struct ast_bridge *bridge); + /*! + * \brief Add a channel to a bridging technology instance for a bridge. + * + * \retval 0 on success + * \retval -1 on failure + * + * \note On entry, bridge is already locked. + */ + int (*join)(struct ast_bridge *bridge, struct ast_bridge_channel *bridge_channel); + /*! + * \brief Remove a channel from a bridging technology instance for a bridge. + * + * \note On entry, bridge is already locked. + */ + void (*leave)(struct ast_bridge *bridge, struct ast_bridge_channel *bridge_channel); + /*! + * \brief Suspend a channel on a bridging technology instance for a bridge. + * + * \note On entry, bridge is already locked. + */ + void (*suspend)(struct ast_bridge *bridge, struct ast_bridge_channel *bridge_channel); + /*! + * \brief Unsuspend a channel on a bridging technology instance for a bridge. + * + * \note On entry, bridge is already locked. + */ + void (*unsuspend)(struct ast_bridge *bridge, struct ast_bridge_channel *bridge_channel); + /*! + * \brief Check if a bridge is compatible with the bridging technology. + * + * \retval 0 if not compatible + * \retval non-zero if compatible + * + * \note On entry, bridge may or may not already be locked. + * However, it can be accessed as if it were locked. + */ + int (*compatible)(struct ast_bridge *bridge); + /*! + * \brief Write a frame into the bridging technology instance for a bridge. + * + * \note The bridge must be tolerant of bridge_channel being NULL. + * + * \retval 0 Frame accepted into the bridge. + * \retval -1 Frame needs to be deferred. + * + * \note On entry, bridge is already locked. + */ + int (*write)(struct ast_bridge *bridge, struct ast_bridge_channel *bridge_channel, struct ast_frame *frame); + /*! Formats that the bridge technology supports */ + struct ast_format_cap *format_capabilities; + /*! TRUE if the bridge technology is currently suspended. */ + unsigned int suspended:1; + /*! Module this bridge technology belongs to. It is used for reference counting bridges using the technology. */ + struct ast_module *mod; + /*! Linked list information */ + AST_RWLIST_ENTRY(ast_bridge_technology) entry; +}; + +/*! + * \brief Register a bridge technology for use + * + * \param technology The bridge technology to register + * \param mod The module that is registering the bridge technology + * + * \retval 0 on success + * \retval -1 on failure + * + * Example usage: + * + * \code + * ast_bridge_technology_register(&simple_bridge_tech); + * \endcode + * + * This registers a bridge technology declared as the structure + * simple_bridge_tech with the bridging core and makes it available for + * use when creating bridges. + */ +int __ast_bridge_technology_register(struct ast_bridge_technology *technology, struct ast_module *mod); + +/*! \brief See \ref __ast_bridge_technology_register() */ +#define ast_bridge_technology_register(technology) __ast_bridge_technology_register(technology, ast_module_info->self) + +/*! + * \brief Unregister a bridge technology from use + * + * \param technology The bridge technology to unregister + * + * \retval 0 on success + * \retval -1 on failure + * + * Example usage: + * + * \code + * ast_bridge_technology_unregister(&simple_bridge_tech); + * \endcode + * + * This unregisters a bridge technlogy declared as the structure + * simple_bridge_tech with the bridging core. It will no longer be + * considered when creating a new bridge. + */ +int ast_bridge_technology_unregister(struct ast_bridge_technology *technology); + +/*! + * \brief Suspend a bridge technology from consideration + * + * \param technology The bridge technology to suspend + * + * Example usage: + * + * \code + * ast_bridge_technology_suspend(&simple_bridge_tech); + * \endcode + * + * This suspends the bridge technology simple_bridge_tech from being considered + * when creating a new bridge. Existing bridges using the bridge technology + * are not affected. + */ +void ast_bridge_technology_suspend(struct ast_bridge_technology *technology); + +/*! + * \brief Unsuspend a bridge technology + * + * \param technology The bridge technology to unsuspend + * + * Example usage: + * + * \code + * ast_bridge_technology_unsuspend(&simple_bridge_tech); + * \endcode + * + * This makes the bridge technology simple_bridge_tech considered when + * creating a new bridge again. + */ +void ast_bridge_technology_unsuspend(struct ast_bridge_technology *technology); + +#if defined(__cplusplus) || defined(c_plusplus) +} +#endif + +#endif /* _ASTERISK_BRIDGING_TECHNOLOGY_H */ diff --git a/include/asterisk/bridging.h b/include/asterisk/bridging.h deleted file mode 100644 index 7e22dba64..000000000 --- a/include/asterisk/bridging.h +++ /dev/null @@ -1,958 +0,0 @@ -/* - * Asterisk -- An open source telephony toolkit. - * - * Copyright (C) 2007 - 2009, 2013 Digium, Inc. - * - * Richard Mudgett - * Joshua Colp - * - * See http://www.asterisk.org for more information about - * the Asterisk project. Please do not directly contact - * any of the maintainers of this project for assistance; - * the project provides a web site, mailing lists and IRC - * channels for your use. - * - * This program is free software, distributed under the terms of - * the GNU General Public License Version 2. See the LICENSE file - * at the top of the source tree. - */ - -/*! - * \file - * \brief Bridging API - * - * \author Richard Mudgett - * \author Joshua Colp - * \ref AstBridging - * - * See Also: - * \arg \ref AstCREDITS - */ - -/*! - * \page AstBridging Bridging API - * - * The purpose of this API is to provide an easy and flexible way to bridge - * channels of different technologies with different features. - * - * Bridging technologies provide the mechanism that do the actual handling - * of frames between channels. They provide capability information, codec information, - * and preference value to assist the bridging core in choosing a bridging technology when - * creating a bridge. Different bridges may use different bridging technologies based on needs - * but once chosen they all operate under the same premise; they receive frames and send frames. - * - * Bridges are a combination of bridging technology, channels, and features. A - * developer creates a new bridge based on what they are currently expecting to do - * with it or what they will do with it in the future. The bridging core determines what - * available bridging technology will best fit the requirements and creates a new bridge. - * Once created, channels can be added to the bridge in a blocking or non-blocking fashion. - * - * Features are such things as channel muting or DTMF based features such as attended transfer, - * blind transfer, and hangup. Feature information must be set at the most granular level, on - * the channel. While you can use features on a global scope the presence of a feature structure - * on the channel will override the global scope. An example would be having the bridge muted - * at global scope and attended transfer enabled on a channel. Since the channel itself is not muted - * it would be able to speak. - * - * Feature hooks allow a developer to tell the bridging core that when a DTMF string - * is received from a channel a callback should be called in their application. For - * example, a conference bridge application may want to provide an IVR to control various - * settings on the conference bridge. This can be accomplished by attaching a feature hook - * that calls an IVR function when a DTMF string is entered. - * - */ - -#ifndef _ASTERISK_BRIDGING_H -#define _ASTERISK_BRIDGING_H - -#if defined(__cplusplus) || defined(c_plusplus) -extern "C" { -#endif - -#include "asterisk/bridging_features.h" -#include "asterisk/bridging_channel.h" -#include "asterisk/bridging_roles.h" -#include "asterisk/dsp.h" -#include "asterisk/uuid.h" - -struct ast_bridge_technology; -struct ast_bridge; -struct ast_bridge_tech_optimizations; - -/*! \brief Capabilities for a bridge technology */ -enum ast_bridge_capability { - /*! Bridge technology can service calls on hold. */ - AST_BRIDGE_CAPABILITY_HOLDING = (1 << 0), - /*! Bridge waits for channel to answer. Passes early media. (XXX Not supported yet) */ - AST_BRIDGE_CAPABILITY_EARLY = (1 << 1), - /*! Bridge is capable of natively bridging two channels. (Smart bridge only) */ - AST_BRIDGE_CAPABILITY_NATIVE = (1 << 2), - /*! Bridge is capable of mixing at most two channels. (Smart bridgeable) */ - AST_BRIDGE_CAPABILITY_1TO1MIX = (1 << 3), - /*! Bridge is capable of mixing an arbitrary number of channels. (Smart bridgeable) */ - AST_BRIDGE_CAPABILITY_MULTIMIX = (1 << 4), -}; - -/*! \brief Video source modes */ -enum ast_bridge_video_mode_type { - /*! Video is not allowed in the bridge */ - AST_BRIDGE_VIDEO_MODE_NONE = 0, - /*! A single user is picked as the only distributed of video across the bridge */ - AST_BRIDGE_VIDEO_MODE_SINGLE_SRC, - /*! A single user's video feed is distributed to all bridge channels, but - * that feed is automatically picked based on who is talking the most. */ - AST_BRIDGE_VIDEO_MODE_TALKER_SRC, -}; - -/*! \brief This is used for both SINGLE_SRC mode to set what channel - * should be the current single video feed */ -struct ast_bridge_video_single_src_data { - /*! Only accept video coming from this channel */ - struct ast_channel *chan_vsrc; -}; - -/*! \brief This is used for both SINGLE_SRC_TALKER mode to set what channel - * should be the current single video feed */ -struct ast_bridge_video_talker_src_data { - /*! Only accept video coming from this channel */ - struct ast_channel *chan_vsrc; - int average_talking_energy; - - /*! Current talker see's this person */ - struct ast_channel *chan_old_vsrc; -}; - -/*! \brief Data structure that defines a video source mode */ -struct ast_bridge_video_mode { - enum ast_bridge_video_mode_type mode; - /* Add data for all the video modes here. */ - union { - struct ast_bridge_video_single_src_data single_src_data; - struct ast_bridge_video_talker_src_data talker_src_data; - } mode_data; -}; - -/*! - * \brief Destroy the bridge. - * - * \param self Bridge to operate upon. - * - * \return Nothing - */ -typedef void (*ast_bridge_destructor_fn)(struct ast_bridge *self); - -/*! - * \brief The bridge is being dissolved. - * - * \param self Bridge to operate upon. - * - * \details - * The bridge is being dissolved. Remove any external - * references to the bridge so it can be destroyed. - * - * \note On entry, self must NOT be locked. - * - * \return Nothing - */ -typedef void (*ast_bridge_dissolving_fn)(struct ast_bridge *self); - -/*! - * \brief Push this channel into the bridge. - * - * \param self Bridge to operate upon. - * \param bridge_channel Bridge channel to push. - * \param swap Bridge channel to swap places with if not NULL. - * - * \details - * Setup any channel hooks controlled by the bridge. Allocate - * bridge_channel->bridge_pvt and initialize any resources put - * in bridge_channel->bridge_pvt if needed. If there is a swap - * channel, use it as a guide to setting up the bridge_channel. - * - * \note On entry, self is already locked. - * - * \retval 0 on success. - * \retval -1 on failure. The channel did not get pushed. - */ -typedef int (*ast_bridge_push_channel_fn)(struct ast_bridge *self, struct ast_bridge_channel *bridge_channel, struct ast_bridge_channel *swap); - -/*! - * \brief Pull this channel from the bridge. - * - * \param self Bridge to operate upon. - * \param bridge_channel Bridge channel to pull. - * - * \details - * Remove any channel hooks controlled by the bridge. Release - * any resources held by bridge_channel->bridge_pvt and release - * bridge_channel->bridge_pvt. - * - * \note On entry, self is already locked. - * - * \return Nothing - */ -typedef void (*ast_bridge_pull_channel_fn)(struct ast_bridge *self, struct ast_bridge_channel *bridge_channel); - -/*! - * \brief Notify the bridge that this channel was just masqueraded. - * - * \param self Bridge to operate upon. - * \param bridge_channel Bridge channel that was masqueraded. - * - * \details - * A masquerade just happened to this channel. The bridge needs - * to re-evaluate this a channel in the bridge. - * - * \note On entry, self is already locked. - * - * \return Nothing - */ -typedef void (*ast_bridge_notify_masquerade_fn)(struct ast_bridge *self, struct ast_bridge_channel *bridge_channel); - -/*! - * \brief Get the merge priority of this bridge. - * - * \param self Bridge to operate upon. - * - * \note On entry, self is already locked. - * - * \return Merge priority - */ -typedef int (*ast_bridge_merge_priority_fn)(struct ast_bridge *self); - -/*! - * \brief Bridge virtual methods table definition. - * - * \note Any changes to this struct must be reflected in - * bridge_alloc() validity checking. - */ -struct ast_bridge_methods { - /*! Bridge class name for log messages. */ - const char *name; - /*! Destroy the bridge. */ - ast_bridge_destructor_fn destroy; - /*! The bridge is being dissolved. Remove any references to the bridge. */ - ast_bridge_dissolving_fn dissolving; - /*! Push the bridge channel into the bridge. */ - ast_bridge_push_channel_fn push; - /*! Pull the bridge channel from the bridge. */ - ast_bridge_pull_channel_fn pull; - /*! Notify the bridge of a masquerade with the channel. */ - ast_bridge_notify_masquerade_fn notify_masquerade; - /*! Get the bridge merge priority. */ - ast_bridge_merge_priority_fn get_merge_priority; -}; - -struct ast_bridge_channel; - -/*! Softmix technology parameters. */ -struct ast_bridge_softmix { - /*! The video mode softmix is using */ - struct ast_bridge_video_mode video_mode; - /*! - * \brief The internal sample rate softmix uses to mix channels. - * - * \note If this value is 0, the sofmix may auto adjust the mixing rate. - */ - unsigned int internal_sample_rate; - /*! - * \brief The mixing interval indicates how quickly softmix - * mixing should occur to mix audio. - * - * \note When set to 0, softmix must choose a default interval - * for itself. - */ - unsigned int internal_mixing_interval; -}; - -/*! - * \brief Structure that contains information about a bridge - */ -struct ast_bridge { - /*! Bridge virtual method table. */ - const struct ast_bridge_methods *v_table; - /*! "Personality" currently exhibited by bridge subclass */ - void *personality; - /*! Bridge technology that is handling the bridge */ - struct ast_bridge_technology *technology; - /*! Private information unique to the bridge technology */ - void *tech_pvt; - /*! Call ID associated with the bridge */ - struct ast_callid *callid; - /*! Linked list of channels participating in the bridge */ - AST_LIST_HEAD_NOLOCK(, ast_bridge_channel) channels; - /*! Queue of actions to perform on the bridge. */ - AST_LIST_HEAD_NOLOCK(, ast_frame) action_queue; - /*! Softmix technology parameters. */ - struct ast_bridge_softmix softmix; - /*! Bridge flags to tweak behavior */ - struct ast_flags feature_flags; - /*! Allowed bridge technology capabilities when AST_BRIDGE_FLAG_SMART enabled. */ - uint32_t allowed_capabilities; - /*! Number of channels participating in the bridge */ - unsigned int num_channels; - /*! Number of active channels in the bridge. */ - unsigned int num_active; - /*! - * \brief Count of the active temporary requests to inhibit bridge merges. - * Zero if merges are allowed. - * - * \note Temporary as in try again in a moment. - */ - unsigned int inhibit_merge; - /*! TRUE if the bridge was reconfigured. */ - unsigned int reconfigured:1; - /*! TRUE if the bridge has been dissolved. Any channel that now tries to join is immediately ejected. */ - unsigned int dissolved:1; - /*! TRUE if the bridge construction was completed. */ - unsigned int construction_completed:1; - /*! Immutable bridge UUID. */ - char uniqueid[AST_UUID_STR_LEN]; -}; - -/*! \brief Bridge base class virtual method table. */ -extern struct ast_bridge_methods ast_bridge_base_v_table; - -/*! - * \brief Create a new base class bridge - * - * \param capabilities The capabilities that we require to be used on the bridge - * \param flags Flags that will alter the behavior of the bridge - * - * \retval a pointer to a new bridge on success - * \retval NULL on failure - * - * Example usage: - * - * \code - * struct ast_bridge *bridge; - * bridge = ast_bridge_base_new(AST_BRIDGE_CAPABILITY_1TO1MIX, AST_BRIDGE_FLAG_DISSOLVE_HANGUP); - * \endcode - * - * This creates a no frills two party bridge that will be - * destroyed once one of the channels hangs up. - */ -struct ast_bridge *ast_bridge_base_new(uint32_t capabilities, unsigned int flags); - -/*! - * \brief Try locking the bridge. - * - * \param bridge Bridge to try locking - * - * \retval 0 on success. - * \retval non-zero on error. - */ -#define ast_bridge_trylock(bridge) _ast_bridge_trylock(bridge, __FILE__, __PRETTY_FUNCTION__, __LINE__, #bridge) -static inline int _ast_bridge_trylock(struct ast_bridge *bridge, const char *file, const char *function, int line, const char *var) -{ - return __ao2_trylock(bridge, AO2_LOCK_REQ_MUTEX, file, function, line, var); -} - -/*! - * \brief Lock the bridge. - * - * \param bridge Bridge to lock - * - * \return Nothing - */ -#define ast_bridge_lock(bridge) _ast_bridge_lock(bridge, __FILE__, __PRETTY_FUNCTION__, __LINE__, #bridge) -static inline void _ast_bridge_lock(struct ast_bridge *bridge, const char *file, const char *function, int line, const char *var) -{ - __ao2_lock(bridge, AO2_LOCK_REQ_MUTEX, file, function, line, var); -} - -/*! - * \brief Unlock the bridge. - * - * \param bridge Bridge to unlock - * - * \return Nothing - */ -#define ast_bridge_unlock(bridge) _ast_bridge_unlock(bridge, __FILE__, __PRETTY_FUNCTION__, __LINE__, #bridge) -static inline void _ast_bridge_unlock(struct ast_bridge *bridge, const char *file, const char *function, int line, const char *var) -{ - __ao2_unlock(bridge, file, function, line, var); -} - -/*! \brief Lock two bridges. */ -#define ast_bridge_lock_both(bridge1, bridge2) \ - do { \ - for (;;) { \ - ast_bridge_lock(bridge1); \ - if (!ast_bridge_trylock(bridge2)) { \ - break; \ - } \ - ast_bridge_unlock(bridge1); \ - sched_yield(); \ - } \ - } while (0) - -/*! - * \brief Destroy a bridge - * - * \param bridge Bridge to destroy - * - * \retval 0 on success - * \retval -1 on failure - * - * Example usage: - * - * \code - * ast_bridge_destroy(bridge); - * \endcode - * - * This destroys a bridge that was previously created. - */ -int ast_bridge_destroy(struct ast_bridge *bridge); - -/*! - * \brief Notify bridging that this channel was just masqueraded. - * \since 12.0.0 - * - * \param chan Channel just involved in a masquerade - * - * \return Nothing - */ -void ast_bridge_notify_masquerade(struct ast_channel *chan); - -/*! - * \brief Join (blocking) a channel to a bridge - * - * \param bridge Bridge to join - * \param chan Channel to join - * \param swap Channel to swap out if swapping - * \param features Bridge features structure - * \param tech_args Optional Bridging tech optimization parameters for this channel. - * \param pass_reference TRUE if the bridge reference is being passed by the caller. - * - * \note Absolutely _NO_ locks should be held before calling - * this function since it blocks. - * - * \retval state that channel exited the bridge with - * - * Example usage: - * - * \code - * ast_bridge_join(bridge, chan, NULL, NULL, NULL, 0); - * \endcode - * - * This adds a channel pointed to by the chan pointer to the bridge pointed to by - * the bridge pointer. This function will not return until the channel has been - * removed from the bridge, swapped out for another channel, or has hung up. - * - * If this channel will be replacing another channel the other channel can be specified - * in the swap parameter. The other channel will be thrown out of the bridge in an - * atomic fashion. - * - * If channel specific features are enabled a pointer to the features structure - * can be specified in the features parameter. - */ -enum bridge_channel_state ast_bridge_join(struct ast_bridge *bridge, - struct ast_channel *chan, - struct ast_channel *swap, - struct ast_bridge_features *features, - struct ast_bridge_tech_optimizations *tech_args, - int pass_reference); - -/*! - * \brief Impart (non-blocking) a channel onto a bridge - * - * \param bridge Bridge to impart on - * \param chan Channel to impart (The channel reference is stolen if impart successful.) - * \param swap Channel to swap out if swapping. NULL if not swapping. - * \param features Bridge features structure. - * \param independent TRUE if caller does not want to reclaim the channel using ast_bridge_depart(). - * - * \note The features parameter must be NULL or obtained by - * ast_bridge_features_new(). You must not dereference features - * after calling even if the call fails. - * - * \note chan is locked by this function. - * - * \retval 0 on success - * \retval -1 on failure - * - * Example usage: - * - * \code - * ast_bridge_impart(bridge, chan, NULL, NULL, 0); - * \endcode - * - * \details - * This adds a channel pointed to by the chan pointer to the - * bridge pointed to by the bridge pointer. This function will - * return immediately and will not wait until the channel is no - * longer part of the bridge. - * - * If this channel will be replacing another channel the other - * channel can be specified in the swap parameter. The other - * channel will be thrown out of the bridge in an atomic - * fashion. - * - * If channel specific features are enabled, a pointer to the - * features structure can be specified in the features - * parameter. - * - * \note If you impart a channel as not independent you MUST - * ast_bridge_depart() the channel if this call succeeds. The - * bridge channel thread is created join-able. The implication - * is that the channel is special and will not behave like a - * normal channel. - * - * \note If you impart a channel as independent you must not - * ast_bridge_depart() the channel. The bridge channel thread - * is created non-join-able. The channel must be treated as if - * it were placed into the bridge by ast_bridge_join(). - * Channels placed into a bridge by ast_bridge_join() are - * removed by a third party using ast_bridge_remove(). - */ -int ast_bridge_impart(struct ast_bridge *bridge, struct ast_channel *chan, struct ast_channel *swap, struct ast_bridge_features *features, int independent); - -/*! - * \brief Depart a channel from a bridge - * - * \param chan Channel to depart - * - * \note chan is locked by this function. - * - * \retval 0 on success - * \retval -1 on failure - * - * Example usage: - * - * \code - * ast_bridge_depart(chan); - * \endcode - * - * This removes the channel pointed to by the chan pointer from any bridge - * it may be in and gives control to the calling thread. - * This does not hang up the channel. - * - * \note This API call can only be used on channels that were added to the bridge - * using the ast_bridge_impart API call with the independent flag FALSE. - */ -int ast_bridge_depart(struct ast_channel *chan); - -/*! - * \brief Remove a channel from a bridge - * - * \param bridge Bridge that the channel is to be removed from - * \param chan Channel to remove - * - * \retval 0 on success - * \retval -1 on failure - * - * Example usage: - * - * \code - * ast_bridge_remove(bridge, chan); - * \endcode - * - * This removes the channel pointed to by the chan pointer from the bridge - * pointed to by the bridge pointer and requests that it be hung up. Control - * over the channel will NOT be given to the calling thread. - * - * \note This API call can be used on channels that were added to the bridge - * using both ast_bridge_join and ast_bridge_impart. - */ -int ast_bridge_remove(struct ast_bridge *bridge, struct ast_channel *chan); - -/*! - * \brief Merge two bridges together - * - * \param dst_bridge Destination bridge of merge. - * \param src_bridge Source bridge of merge. - * \param merge_best_direction TRUE if don't care about which bridge merges into the other. - * \param kick_me Array of channels to kick from the bridges. - * \param num_kick Number of channels in the kick_me array. - * - * \note Absolutely _NO_ bridge or channel locks should be held - * before calling this function. - * - * \retval 0 on success - * \retval -1 on failure - * - * Example usage: - * - * \code - * ast_bridge_merge(dst_bridge, src_bridge, 0, NULL, 0); - * \endcode - * - * This moves the channels in src_bridge into the bridge pointed - * to by dst_bridge. - */ -int ast_bridge_merge(struct ast_bridge *dst_bridge, struct ast_bridge *src_bridge, int merge_best_direction, struct ast_channel **kick_me, unsigned int num_kick); - -/*! - * \brief Move a channel from one bridge to another. - * \since 12.0.0 - * - * \param dst_bridge Destination bridge of bridge channel move. - * \param src_bridge Source bridge of bridge channel move. - * \param chan Channel to move. - * \param swap Channel to replace in dst_bridge. - * \param attempt_recovery TRUE if failure attempts to push channel back into original bridge. - * - * \note Absolutely _NO_ bridge or channel locks should be held - * before calling this function. - * - * \retval 0 on success. - * \retval -1 on failure. - */ -int ast_bridge_move(struct ast_bridge *dst_bridge, struct ast_bridge *src_bridge, struct ast_channel *chan, struct ast_channel *swap, int attempt_recovery); - -/*! - * \brief Adjust the bridge merge inhibit request count. - * \since 12.0.0 - * - * \param bridge What to operate on. - * \param request Inhibit request increment. - * (Positive to add requests. Negative to remove requests.) - * - * \return Nothing - */ -void ast_bridge_merge_inhibit(struct ast_bridge *bridge, int request); - -/*! - * \brief Suspend a channel temporarily from a bridge - * - * \param bridge Bridge to suspend the channel from - * \param chan Channel to suspend - * - * \retval 0 on success - * \retval -1 on failure - * - * Example usage: - * - * \code - * ast_bridge_suspend(bridge, chan); - * \endcode - * - * This suspends the channel pointed to by chan from the bridge pointed to by bridge temporarily. - * Control of the channel is given to the calling thread. This differs from ast_bridge_depart as - * the channel will not be removed from the bridge. - * - * \note This API call can be used on channels that were added to the bridge - * using both ast_bridge_join and ast_bridge_impart. - */ -int ast_bridge_suspend(struct ast_bridge *bridge, struct ast_channel *chan); - -/*! - * \brief Unsuspend a channel from a bridge - * - * \param bridge Bridge to unsuspend the channel from - * \param chan Channel to unsuspend - * - * \retval 0 on success - * \retval -1 on failure - * - * Example usage: - * - * \code - * ast_bridge_unsuspend(bridge, chan); - * \endcode - * - * This unsuspends the channel pointed to by chan from the bridge pointed to by bridge. - * The bridge will go back to handling the channel once this function returns. - * - * \note You must not mess with the channel once this function returns. - * Doing so may result in bad things happening. - */ -int ast_bridge_unsuspend(struct ast_bridge *bridge, struct ast_channel *chan); - -struct ast_unreal_pvt; - -/*! - * \brief Check and optimize out the unreal channels between bridges. - * \since 12.0.0 - * - * \param chan Unreal channel writing a frame into the channel driver. - * \param peer Other unreal channel in the pair. - * \param pvt Private data provided by an implementation of the unreal driver that - * contains the callbacks that should be called when optimization begins/ends - * - * \note It is assumed that chan is already locked. - * - * \retval 0 if unreal channels were not optimized out. - * \retval non-zero if unreal channels were optimized out. - */ -int ast_bridge_unreal_optimize_out(struct ast_channel *chan, struct ast_channel *peer, struct ast_unreal_pvt *pvt); - -/*! - * \brief Tells, if optimization is allowed, how the optimization would be performed - */ -enum ast_bridge_optimization { - /*! Optimization would swap peer into the chan_bridge */ - AST_BRIDGE_OPTIMIZE_SWAP_TO_CHAN_BRIDGE, - /*! Optimization would swap chan into the peer_bridge */ - AST_BRIDGE_OPTIMIZE_SWAP_TO_PEER_BRIDGE, - /*! Optimization would merge peer_bridge into chan_bridge */ - AST_BRIDGE_OPTIMIZE_MERGE_TO_CHAN_BRIDGE, - /*! Optimization would merge chan_bridge into peer_bridge */ - AST_BRIDGE_OPTIMIZE_MERGE_TO_PEER_BRIDGE, - /*! Optimization is not permitted on one or both bridges */ - AST_BRIDGE_OPTIMIZE_PROHIBITED, -}; - -/*! - * \brief Determine if bridges allow for optimization to occur betweem them - * \since 12.0.0 - * - * \param chan_bridge First bridge being tested - * \param peer_bridge Second bridge being tested - * - * This determines if two bridges allow for unreal channel optimization - * to occur between them. The function does not require for unreal channels - * to already be in the bridges when called. - * - * \note It is assumed that both bridges are locked prior to calling this function - * - * \note A return other than AST_BRIDGE_OPTIMIZE_PROHIBITED does not guarantee - * that an optimization attempt will succeed. However, a return of - * AST_BRIDGE_OPTIMIZE_PROHIBITED guarantees that an optimization attempt will - * never succeed. - * - * \returns Optimization allowability for the bridges - */ -enum ast_bridge_optimization ast_bridges_allow_optimization(struct ast_bridge *chan_bridge, - struct ast_bridge *peer_bridge); - -/*! - * \brief Put an action onto the specified bridge. - * \since 12.0.0 - * - * \param bridge What to queue the action on. - * \param action What to do. - * - * \retval 0 on success. - * \retval -1 on error. - * - * \note This API call is meant for internal bridging operations. - * \note BUGBUG This may get moved. - */ -int ast_bridge_queue_action(struct ast_bridge *bridge, struct ast_frame *action); - -/*! - * \brief Queue the given frame to everyone else. - * \since 12.0.0 - * - * \param bridge What bridge to distribute frame. - * \param bridge_channel Channel to optionally not pass frame to. (NULL to pass to everyone) - * \param frame Frame to pass. - * - * \note This is intended to be called by bridge hooks and - * bridge technologies. - * - * \retval 0 Frame written to at least one channel. - * \retval -1 Frame written to no channels. - */ -int ast_bridge_queue_everyone_else(struct ast_bridge *bridge, struct ast_bridge_channel *bridge_channel, struct ast_frame *frame); - -/*! - * \brief Adjust the internal mixing sample rate of a bridge - * used during multimix mode. - * - * \param bridge Channel to change the sample rate on. - * \param sample_rate the sample rate to change to. If a - * value of 0 is passed here, the bridge will be free to pick - * what ever sample rate it chooses. - * - */ -void ast_bridge_set_internal_sample_rate(struct ast_bridge *bridge, unsigned int sample_rate); - -/*! - * \brief Adjust the internal mixing interval of a bridge used - * during multimix mode. - * - * \param bridge Channel to change the sample rate on. - * \param mixing_interval the sample rate to change to. If 0 is set - * the bridge tech is free to choose any mixing interval it uses by default. - */ -void ast_bridge_set_mixing_interval(struct ast_bridge *bridge, unsigned int mixing_interval); - -/*! - * \brief Set a bridge to feed a single video source to all participants. - */ -void ast_bridge_set_single_src_video_mode(struct ast_bridge *bridge, struct ast_channel *video_src_chan); - -/*! - * \brief Set the bridge to pick the strongest talker supporting - * video as the single source video feed - */ -void ast_bridge_set_talker_src_video_mode(struct ast_bridge *bridge); - -/*! - * \brief Update information about talker energy for talker src video mode. - */ -void ast_bridge_update_talker_src_video_mode(struct ast_bridge *bridge, struct ast_channel *chan, int talker_energy, int is_keyfame); - -/*! - * \brief Returns the number of video sources currently active in the bridge - */ -int ast_bridge_number_video_src(struct ast_bridge *bridge); - -/*! - * \brief Determine if a channel is a video src for the bridge - * - * \retval 0 Not a current video source of the bridge. - * \retval None 0, is a video source of the bridge, The number - * returned represents the priority this video stream has - * on the bridge where 1 is the highest priority. - */ -int ast_bridge_is_video_src(struct ast_bridge *bridge, struct ast_channel *chan); - -/*! - * \brief remove a channel as a source of video for the bridge. - */ -void ast_bridge_remove_video_src(struct ast_bridge *bridge, struct ast_channel *chan); - -enum ast_transfer_result { - /*! The transfer completed successfully */ - AST_BRIDGE_TRANSFER_SUCCESS, - /*! A bridge involved does not permit transferring */ - AST_BRIDGE_TRANSFER_NOT_PERMITTED, - /*! The current bridge setup makes transferring an invalid operation */ - AST_BRIDGE_TRANSFER_INVALID, - /*! The transfer operation failed for a miscellaneous reason */ - AST_BRIDGE_TRANSFER_FAIL, -}; - -enum ast_transfer_type { - /*! Transfer of a single party */ - AST_BRIDGE_TRANSFER_SINGLE_PARTY, - /*! Transfer of multiple parties */ - AST_BRIDGE_TRANSFER_MULTI_PARTY, -}; - -/*! - * \brief Callback function type called during blind transfers - * - * A caller of ast_bridge_transfer_blind() may wish to set data on - * the channel that ends up running dialplan. For instance, it may - * be useful to set channel variables on the channel. - * - * \param chan The involved channel - * \param user_data User-provided data needed in the callback - * \param transfer_type The type of transfer being completed - */ -typedef void (*transfer_channel_cb)(struct ast_channel *chan, void *user_data, - enum ast_transfer_type transfer_type); - -/*! - * \brief Blind transfer target to the extension and context provided - * - * The channel given is bridged to one or multiple channels. Depending on - * the bridge and the number of participants, the entire bridge could be - * transferred to the given destination, or a single channel may be redirected. - * - * Callers may also provide a callback to be called on the channel that will - * be running dialplan. The user data passed into ast_bridge_transfer_blind - * will be given as the argument to the callback to be interpreted as desired. - * This callback is guaranteed to be called in the same thread as - * ast_bridge_transfer_blind() and before ast_bridge_transfer_blind() returns. - * - * \note Absolutely _NO_ channel locks should be held before - * calling this function. - * - * \param is_external Indicates that transfer was initiated externally - * \param transferer The channel performing the blind transfer - * \param exten The dialplan extension to send the call to - * \param context The dialplan context to send the call to - * \param new_channel_cb A callback to be called on the channel that will - * be executing dialplan - * \param user_data Argument for new_channel_cb - * \return The success or failure result of the blind transfer - */ -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); - -/*! - * \brief Attended transfer - * - * The two channels are both transferer channels. The first is the channel - * that is bridged to the transferee (or if unbridged, the 'first' call of - * the transfer). The second is the channel that is bridged to the transfer - * target (or if unbridged, the 'second' call of the transfer). - * - * \note Absolutely _NO_ channel locks should be held before - * calling this function. - * - * \param to_transferee Transferer channel on initial call (presumably bridged to transferee) - * \param to_transfer_target Transferer channel on consultation call (presumably bridged to transfer target) - * \return The success or failure of the attended transfer - */ -enum ast_transfer_result ast_bridge_transfer_attended(struct ast_channel *to_transferee, - struct ast_channel *to_transfer_target); - -/*! - * \brief Get a container of all channels in the bridge - * \since 12.0.0 - * - * \param bridge The bridge which is already locked. - * - * \retval NULL Failed to create container - * \retval non-NULL Container of channels in the bridge - */ -struct ao2_container *ast_bridge_peers_nolock(struct ast_bridge *bridge); - -/*! - * \brief Get a container of all channels in the bridge - * \since 12.0.0 - * - * \param bridge The bridge - * - * \note The returned container is a snapshot of channels in the - * bridge when called. - * - * \retval NULL Failed to create container - * \retval non-NULL Container of channels in the bridge - */ -struct ao2_container *ast_bridge_peers(struct ast_bridge *bridge); - -/*! - * \brief Get the channel's bridge peer only if the bridge is two-party. - * \since 12.0.0 - * - * \param bridge The bridge which is already locked. - * \param chan Channel desiring the bridge peer channel. - * - * \note The returned peer channel is the current peer in the - * bridge when called. - * - * \retval NULL Channel not in a bridge or the bridge is not two-party. - * \retval non-NULL Reffed peer channel at time of calling. - */ -struct ast_channel *ast_bridge_peer_nolock(struct ast_bridge *bridge, struct ast_channel *chan); - -/*! - * \brief Get the channel's bridge peer only if the bridge is two-party. - * \since 12.0.0 - * - * \param bridge The bridge - * \param chan Channel desiring the bridge peer channel. - * - * \note The returned peer channel is the current peer in the - * bridge when called. - * - * \retval NULL Channel not in a bridge or the bridge is not two-party. - * \retval non-NULL Reffed peer channel at time of calling. - */ -struct ast_channel *ast_bridge_peer(struct ast_bridge *bridge, struct ast_channel *chan); - -/*! - * \brief Remove marked bridge channel feature hooks. - * \since 12.0.0 - * - * \param features Bridge features structure - * \param flags Determinator for whether hook is removed. - * - * \return Nothing - */ -void ast_bridge_features_remove(struct ast_bridge_features *features, enum ast_bridge_hook_remove_flags flags); - -#if defined(__cplusplus) || defined(c_plusplus) -} -#endif - -#endif /* _ASTERISK_BRIDGING_H */ diff --git a/include/asterisk/bridging_after.h b/include/asterisk/bridging_after.h deleted file mode 100644 index 53f30b9ad..000000000 --- a/include/asterisk/bridging_after.h +++ /dev/null @@ -1,244 +0,0 @@ -/* - * Asterisk -- An open source telephony toolkit. - * - * Copyright (C) 2013 Digium, Inc. - * - * Richard Mudgett - * - * See http://www.asterisk.org for more information about - * the Asterisk project. Please do not directly contact - * any of the maintainers of this project for assistance; - * the project provides a web site, mailing lists and IRC - * channels for your use. - * - * This program is free software, distributed under the terms of - * the GNU General Public License Version 2. See the LICENSE file - * at the top of the source tree. - */ - -/*! - * \file - * \brief After Bridge Execution API - * - * \author Richard Mudgett - * - * See Also: - * \arg \ref AstCREDITS - */ - -#ifndef _ASTERISK_BRIDGING_AFTER_H -#define _ASTERISK_BRIDGING_AFTER_H - -#if defined(__cplusplus) || defined(c_plusplus) -extern "C" { -#endif - -/*! Reason the the after bridge callback will not be called. */ -enum ast_bridge_after_cb_reason { - /*! The datastore is being destroyed. Likely due to hangup. (Enum value must be zero.) */ - AST_BRIDGE_AFTER_CB_REASON_DESTROY, - /*! Something else replaced the callback with another. */ - AST_BRIDGE_AFTER_CB_REASON_REPLACED, - /*! The callback was removed because of a masquerade. (fixup) */ - AST_BRIDGE_AFTER_CB_REASON_MASQUERADE, - /*! The channel was departed from the bridge. */ - AST_BRIDGE_AFTER_CB_REASON_DEPART, - /*! Was explicitly removed by external code. */ - AST_BRIDGE_AFTER_CB_REASON_REMOVED, -}; - -/*! - * \brief Set channel to goto specific location after the bridge. - * \since 12.0.0 - * - * \param chan Channel to setup after bridge goto location. - * \param context Context to goto after bridge. - * \param exten Exten to goto after bridge. - * \param priority Priority to goto after bridge. - * - * \note chan is locked by this function. - * - * \details Add a channel datastore to setup the goto location - * when the channel leaves the bridge and run a PBX from there. - * - * \return Nothing - */ -void ast_bridge_set_after_goto(struct ast_channel *chan, const char *context, const char *exten, int priority); - -/*! - * \brief Set channel to run the h exten after the bridge. - * \since 12.0.0 - * - * \param chan Channel to setup after bridge goto location. - * \param context Context to goto after bridge. - * - * \note chan is locked by this function. - * - * \details Add a channel datastore to setup the goto location - * when the channel leaves the bridge and run a PBX from there. - * - * \return Nothing - */ -void ast_bridge_set_after_h(struct ast_channel *chan, const char *context); - -/*! - * \brief Set channel to go on in the dialplan after the bridge. - * \since 12.0.0 - * - * \param chan Channel to setup after bridge goto location. - * \param context Current context of the caller channel. - * \param exten Current exten of the caller channel. - * \param priority Current priority of the caller channel - * \param parseable_goto User specified goto string from dialplan. - * - * \note chan is locked by this function. - * - * \details Add a channel datastore to setup the goto location - * when the channel leaves the bridge and run a PBX from there. - * - * If parseable_goto then use the given context/exten/priority - * as the relative position for the parseable_goto. - * Else goto the given context/exten/priority+1. - * - * \return Nothing - */ -void ast_bridge_set_after_go_on(struct ast_channel *chan, const char *context, const char *exten, int priority, const char *parseable_goto); - -/*! - * \brief Setup any after bridge goto location to begin execution. - * \since 12.0.0 - * - * \param chan Channel to setup after bridge goto location. - * - * \note chan is locked by this function. - * - * \details Pull off any after bridge goto location datastore and - * setup for dialplan execution there. - * - * \retval 0 on success. The goto location is set for a PBX to run it. - * \retval non-zero on error or no goto location. - * - * \note If the after bridge goto is set to run an h exten it is - * run here immediately. - */ -int ast_bridge_setup_after_goto(struct ast_channel *chan); - -/*! - * \brief Run any after bridge callback. - * \since 12.0.0 - * - * \param chan Channel to run after bridge callback. - * - * \return Nothing - */ -void ast_bridge_run_after_callback(struct ast_channel *chan); - -/*! - * \brief Run discarding any after bridge callbacks. - * \since 12.0.0 - * - * \param chan Channel to run after bridge callback. - * - * \return Nothing - */ -void ast_bridge_discard_after_callback(struct ast_channel *chan, enum ast_bridge_after_cb_reason reason); - -/*! - * \brief Run a PBX on any after bridge goto location. - * \since 12.0.0 - * - * \param chan Channel to execute after bridge goto location. - * - * \note chan is locked by this function. - * - * \details Pull off any after bridge goto location datastore - * and run a PBX at that location. - * - * \note On return, the chan pointer is no longer valid because - * the channel has hung up. - * - * \return Nothing - */ -void ast_bridge_run_after_goto(struct ast_channel *chan); - -/*! - * \brief Discard channel after bridge goto location. - * \since 12.0.0 - * - * \param chan Channel to discard after bridge goto location. - * - * \note chan is locked by this function. - * - * \return Nothing - */ -void ast_bridge_discard_after_goto(struct ast_channel *chan); - -/*! - * \brief Read after bridge goto if it exists - * \since 12.0.0 - * - * \param chan Channel to read the after bridge goto parseable goto string from - * \param buffer Buffer to write the after bridge goto data to - * \param buf_size size of the buffer being written to - */ -void ast_bridge_read_after_goto(struct ast_channel *chan, char *buffer, size_t buf_size); - -/*! - * \brief After bridge callback failed. - * \since 12.0.0 - * - * \param reason Reason callback is failing. - * \param data Extra data what setup the callback wanted to pass. - * - * \note Called when the channel leaves the bridging system or - * is destroyed. - * - * \return Nothing - */ -typedef void (*ast_bridge_after_cb_failed)(enum ast_bridge_after_cb_reason reason, void *data); - -/*! - * \brief After bridge callback function. - * \since 12.0.0 - * - * \param chan Channel just leaving bridging system. - * \param data Extra data what setup the callback wanted to pass. - * - * \return Nothing - */ -typedef void (*ast_bridge_after_cb)(struct ast_channel *chan, void *data); - -/*! - * \brief Setup an after bridge callback for when the channel leaves the bridging system. - * \since 12.0.0 - * - * \param chan Channel to setup an after bridge callback on. - * \param callback Function to call when the channel leaves the bridging system. - * \param failed Function to call when it will not be calling the callback. - * \param data Extra data to pass with the callback. - * - * \note chan is locked by this function. - * - * \note failed is called when the channel leaves the bridging - * system or is destroyed. - * - * \retval 0 on success. - * \retval -1 on error. - */ -int ast_bridge_set_after_callback(struct ast_channel *chan, ast_bridge_after_cb callback, ast_bridge_after_cb_failed failed, void *data); - -/*! - * \brief Get a string representation of an after bridge callback reason - * \since 12.0.0 - * - * \param reason The reason to interpret to a string - * \retval NULL Unrecognized reason - * \retval non-NULL String representation of reason - */ -const char *ast_bridge_after_cb_reason_string(enum ast_bridge_after_cb_reason reason); - -#if defined(__cplusplus) || defined(c_plusplus) -} -#endif - -#endif /* _ASTERISK_BRIDGING_H */ diff --git a/include/asterisk/bridging_basic.h b/include/asterisk/bridging_basic.h deleted file mode 100644 index 4db142946..000000000 --- a/include/asterisk/bridging_basic.h +++ /dev/null @@ -1,133 +0,0 @@ -/* - * Asterisk -- An open source telephony toolkit. - * - * Copyright (C) 2013 Digium, Inc. - * - * Richard Mudgett - * - * See http://www.asterisk.org for more information about - * the Asterisk project. Please do not directly contact - * any of the maintainers of this project for assistance; - * the project provides a web site, mailing lists and IRC - * channels for your use. - * - * This program is free software, distributed under the terms of - * the GNU General Public License Version 2. See the LICENSE file - * at the top of the source tree. - */ - -/*! - * \file - * \brief Basic bridge subclass API. - * - * \author Richard Mudgett - * - * See Also: - * \arg \ref AstCREDITS - */ - -#ifndef _ASTERISK_BRIDGING_BASIC_H -#define _ASTERISK_BRIDGING_BASIC_H - -#if defined(__cplusplus) || defined(c_plusplus) -extern "C" { -#endif - -/* ------------------------------------------------------------------- */ - -/*! - * \brief Sets the features a channel will use upon being bridged. - * \since 12.0.0 - * - * \param chan Which channel to set features for - * \param features Which feature codes to set for the channel - * - * \retval 0 on success - * \retval -1 on failure - */ -int ast_bridge_features_ds_set_string(struct ast_channel *chan, const char *features); - -/*! - * \brief writes a channel's DTMF features to a buffer string - * \since 12.0.0 - * - * \param chan channel whose feature flags should be checked - * \param buffer pointer string buffer where the output should be stored - * \param buf_size size of the provided buffer (ideally enough for all features, 6+) - * - * \retval 0 on successful write - * \retval -1 on failure - */ -int ast_bridge_features_ds_get_string(struct ast_channel *chan, char *buffer, size_t buf_size); - -/*! - * \brief Get DTMF feature flags from the channel. - * \since 12.0.0 - * - * \param chan Channel to get DTMF features datastore. - * - * \note The channel should be locked before calling this function. - * \note The channel must remain locked until the flags returned have been consumed. - * - * \retval flags on success. - * \retval NULL if the datastore does not exist. - */ -struct ast_flags *ast_bridge_features_ds_get(struct ast_channel *chan); - -/*! - * \brief Set basic bridge DTMF feature flags datastore on the channel. - * \since 12.0.0 - * - * \param chan Channel to set DTMF features datastore. - * \param flags Builtin DTMF feature flags. (ast_bridge_config flags) - * - * \note The channel must be locked before calling this function. - * - * \retval 0 on success. - * \retval -1 on error. - */ -int ast_bridge_features_ds_set(struct ast_channel *chan, struct ast_flags *flags); - -/*! - * \brief Setup DTMF feature hooks using the channel features datastore property. - * \since 12.0.0 - * - * \param bridge_channel What to setup DTMF features on. - * - * \retval 0 on success. - * \retval -1 on error. - */ -int ast_bridge_channel_setup_features(struct ast_bridge_channel *bridge_channel); - -/*! \brief Bridge basic class virtual method table. */ -extern struct ast_bridge_methods ast_bridge_basic_v_table; - -/*! - * \brief Create a new basic class bridge - * - * \retval a pointer to a new bridge on success - * \retval NULL on failure - * - * Example usage: - * - * \code - * struct ast_bridge *bridge; - * bridge = ast_bridge_basic_new(); - * \endcode - * - * This creates a basic two party bridge with any configured - * DTMF features enabled that will be destroyed once one of the - * channels hangs up. - */ -struct ast_bridge *ast_bridge_basic_new(void); - -/*! Initialize the basic bridge class for use by the system. */ -void ast_bridging_init_basic(void); - -/* ------------------------------------------------------------------- */ - -#if defined(__cplusplus) || defined(c_plusplus) -} -#endif - -#endif /* _ASTERISK_BRIDGING_BASIC_H */ diff --git a/include/asterisk/bridging_channel.h b/include/asterisk/bridging_channel.h deleted file mode 100644 index f58fba7dc..000000000 --- a/include/asterisk/bridging_channel.h +++ /dev/null @@ -1,590 +0,0 @@ -/* - * Asterisk -- An open source telephony toolkit. - * - * Copyright (C) 2013 Digium, Inc. - * - * Joshua Colp - * Richard Mudgett - * Matt Jordan - * - * See http://www.asterisk.org for more information about - * the Asterisk project. Please do not directly contact - * any of the maintainers of this project for assistance; - * the project provides a web site, mailing lists and IRC - * channels for your use. - * - * This program is free software, distributed under the terms of - * the GNU General Public License Version 2. See the LICENSE file - * at the top of the source tree. - */ - -/*! - * \file - * \page AstBridgeChannel Bridging Channel API - * - * An API that act on a channel in a bridge. Note that while the - * \ref ast_bridge_channel is owned by a channel, it should only be used - * by members of the bridging system. The only places where this API should - * be used is: - * \arg \ref AstBridging API itself - * \arg Bridge mixing technologies - * \arg Bridge sub-classes - * - * In general, anywhere else it is unsafe to use this API. Care should be - * taken when using this API to ensure that the locking order remains - * correct. The locking order must be: - * \arg The \ref \c ast_bridge - * \arg The \ref \c ast_bridge_channel - * \arg The \ref \c ast_channel - * - * \author Joshua Colp - * \author Richard Mudgett - * \author Matt Jordan - * - * See Also: - * \arg \ref AstBridging - * \arg \ref AstCREDITS - */ - -#ifndef _ASTERISK_BRIDGING_CHANNEL_H -#define _ASTERISK_BRIDGING_CHANNEL_H - -#if defined(__cplusplus) || defined(c_plusplus) -extern "C" { -#endif - -#include "asterisk/bridging_technology.h" - -/*! \brief State information about a bridged channel */ -enum bridge_channel_state { - /*! Waiting for a signal (Channel in the bridge) */ - BRIDGE_CHANNEL_STATE_WAIT = 0, - /*! Bridged channel was forced out and should be hung up (Bridge may dissolve.) */ - BRIDGE_CHANNEL_STATE_END, - /*! Bridged channel was forced out. Don't dissolve the bridge regardless */ - BRIDGE_CHANNEL_STATE_END_NO_DISSOLVE, -}; - -enum bridge_channel_thread_state { - /*! Bridge channel thread is idle/waiting. */ - BRIDGE_CHANNEL_THREAD_IDLE, - /*! Bridge channel thread is writing a normal/simple frame. */ - BRIDGE_CHANNEL_THREAD_SIMPLE, - /*! Bridge channel thread is processing a frame. */ - BRIDGE_CHANNEL_THREAD_FRAME, -}; - -struct ast_bridge; -struct ast_bridge_tech_optimizations; - - /*! - * \brief Structure that contains information regarding a channel in a bridge - */ -struct ast_bridge_channel { -/* BUGBUG cond is only here because of external party suspend/unsuspend support. */ - /*! Condition, used if we want to wake up a thread waiting on the bridged channel */ - ast_cond_t cond; - /*! Current bridged channel state */ - enum bridge_channel_state state; - /*! Asterisk channel participating in the bridge */ - struct ast_channel *chan; - /*! Asterisk channel we are swapping with (if swapping) */ - struct ast_channel *swap; - /*! - * \brief Bridge this channel is participating in - * - * \note The bridge pointer cannot change while the bridge or - * bridge_channel is locked. - */ - struct ast_bridge *bridge; - /*! - * \brief Bridge class private channel data. - * - * \note This information is added when the channel is pushed - * into the bridge and removed when it is pulled from the - * bridge. - */ - void *bridge_pvt; - /*! - * \brief Private information unique to the bridge technology. - * - * \note This information is added when the channel joins the - * bridge's technology and removed when it leaves the bridge's - * technology. - */ - void *tech_pvt; - /*! Thread handling the bridged channel (Needed by ast_bridge_depart) */ - pthread_t thread; - /* v-- These flags change while the bridge is locked or before the channel is in the bridge. */ - /*! TRUE if the channel is in a bridge. */ - unsigned int in_bridge:1; - /*! TRUE if the channel just joined the bridge. */ - unsigned int just_joined:1; - /*! TRUE if the channel is suspended from the bridge. */ - unsigned int suspended:1; - /*! TRUE if the channel must wait for an ast_bridge_depart to reclaim the channel. */ - unsigned int depart_wait:1; - /* ^-- These flags change while the bridge is locked or before the channel is in the bridge. */ - /*! Features structure for features that are specific to this channel */ - struct ast_bridge_features *features; - /*! Technology optimization parameters used by bridging technologies capable of - * optimizing based upon talk detection. */ - struct ast_bridge_tech_optimizations tech_args; - /*! Copy of read format used by chan before join */ - struct ast_format read_format; - /*! Copy of write format used by chan before join */ - struct ast_format write_format; - /*! Call ID associated with bridge channel */ - struct ast_callid *callid; - /*! A clone of the roles living on chan when the bridge channel joins the bridge. This may require some opacification */ - struct bridge_roles_datastore *bridge_roles; - /*! Linked list information */ - AST_LIST_ENTRY(ast_bridge_channel) entry; - /*! Queue of outgoing frames to the channel. */ - AST_LIST_HEAD_NOLOCK(, ast_frame) wr_queue; - /*! Pipe to alert thread when frames are put into the wr_queue. */ - int alert_pipe[2]; - /*! TRUE if the bridge channel thread is waiting on channels (needs to be atomically settable) */ - int waiting; - /*! - * \brief The bridge channel thread activity. - * - * \details Used by local channel optimization to determine if - * the thread is in an acceptable state to optimize. - * - * \note Needs to be atomically settable. - */ - enum bridge_channel_thread_state activity; -}; - -/*! - * \brief Try locking the bridge_channel. - * - * \param bridge_channel What to try locking - * - * \retval 0 on success. - * \retval non-zero on error. - */ -#define ast_bridge_channel_trylock(bridge_channel) _ast_bridge_channel_trylock(bridge_channel, __FILE__, __PRETTY_FUNCTION__, __LINE__, #bridge_channel) -static inline int _ast_bridge_channel_trylock(struct ast_bridge_channel *bridge_channel, const char *file, const char *function, int line, const char *var) -{ - return __ao2_trylock(bridge_channel, AO2_LOCK_REQ_MUTEX, file, function, line, var); -} - -/*! - * \brief Lock the bridge_channel. - * - * \param bridge_channel What to lock - * - * \return Nothing - */ -#define ast_bridge_channel_lock(bridge_channel) _ast_bridge_channel_lock(bridge_channel, __FILE__, __PRETTY_FUNCTION__, __LINE__, #bridge_channel) -static inline void _ast_bridge_channel_lock(struct ast_bridge_channel *bridge_channel, const char *file, const char *function, int line, const char *var) -{ - __ao2_lock(bridge_channel, AO2_LOCK_REQ_MUTEX, file, function, line, var); -} - -/*! - * \brief Unlock the bridge_channel. - * - * \param bridge_channel What to unlock - * - * \return Nothing - */ -#define ast_bridge_channel_unlock(bridge_channel) _ast_bridge_channel_unlock(bridge_channel, __FILE__, __PRETTY_FUNCTION__, __LINE__, #bridge_channel) -static inline void _ast_bridge_channel_unlock(struct ast_bridge_channel *bridge_channel, const char *file, const char *function, int line, const char *var) -{ - __ao2_unlock(bridge_channel, file, function, line, var); -} - -/*! - * \brief Lock the bridge associated with the bridge channel. - * \since 12.0.0 - * - * \param bridge_channel Channel that wants to lock the bridge. - * - * \details - * This is an upstream lock operation. The defined locking - * order is bridge then bridge_channel. - * - * \note On entry, neither the bridge nor bridge_channel is locked. - * - * \note The bridge_channel->bridge pointer changes because of a - * bridge-merge/channel-move operation between bridges. - * - * \return Nothing - */ -void ast_bridge_channel_lock_bridge(struct ast_bridge_channel *bridge_channel); - -/*! - * \brief Lets the bridging indicate when a bridge channel has stopped or started talking. - * - * \note All DSP functionality on the bridge has been pushed down to the lowest possible - * layer, which in this case is the specific bridging technology being used. Since it - * is necessary for the knowledge of which channels are talking to make its way up to the - * application, this function has been created to allow the bridging technology to communicate - * that information with the bridging core. - * - * \param bridge_channel The bridge channel that has either started or stopped talking. - * \param started_talking set to 1 when this indicates the channel has started talking set to 0 - * when this indicates the channel has stopped talking. - * - * \retval 0 on success. - * \retval -1 on error. - */ -int ast_bridge_channel_notify_talking(struct ast_bridge_channel *bridge_channel, int started_talking); - -/*! - * \brief Set bridge channel state to leave bridge (if not leaving already). - * - * \param bridge_channel Channel to change the state on - * \param new_state The new state to place the channel into - * - * Example usage: - * - * \code - * ast_bridge_channel_leave_bridge(bridge_channel, BRIDGE_CHANNEL_STATE_END); - * \endcode - * - * This places the channel pointed to by bridge_channel into the - * state BRIDGE_CHANNEL_STATE_END if it was - * BRIDGE_CHANNEL_STATE_WAIT before. - */ -void ast_bridge_channel_leave_bridge(struct ast_bridge_channel *bridge_channel, enum bridge_channel_state new_state); - -/*! - * \brief Set bridge channel state to leave bridge (if not leaving already). - * - * \param bridge_channel Channel to change the state on - * \param new_state The new state to place the channel into - * - * Example usage: - * - * \code - * ast_bridge_channel_leave_bridge(bridge_channel, BRIDGE_CHANNEL_STATE_END); - * \endcode - * - * This places the channel pointed to by bridge_channel into the - * state BRIDGE_CHANNEL_STATE_END if it was - * BRIDGE_CHANNEL_STATE_WAIT before. - */ -void ast_bridge_channel_leave_bridge_nolock(struct ast_bridge_channel *bridge_channel, enum bridge_channel_state new_state); - -/*! - * \brief Get the peer bridge channel of a two party bridge. - * \since 12.0.0 - * - * \param bridge_channel What to get the peer of. - * - * \note On entry, bridge_channel->bridge is already locked. - * - * \note This is an internal bridge function. - * - * \retval peer on success. - * \retval NULL no peer channel. - */ -struct ast_bridge_channel *ast_bridge_channel_peer(struct ast_bridge_channel *bridge_channel); - -/*! - * \brief Restore the formats of a bridge channel's channel to how they were before bridge_channel_internal_join - * \since 12.0.0 - * - * \param bridge_channel Channel to restore - */ -void ast_bridge_channel_restore_formats(struct ast_bridge_channel *bridge_channel); - -/*! - * \brief Adjust the bridge_channel's bridge merge inhibit request count. - * \since 12.0.0 - * - * \param bridge_channel What to operate on. - * \param request Inhibit request increment. - * (Positive to add requests. Negative to remove requests.) - * - * \note This API call is meant for internal bridging operations. - * - * \retval bridge adjusted merge inhibit with reference count. - */ -struct ast_bridge *ast_bridge_channel_merge_inhibit(struct ast_bridge_channel *bridge_channel, int request); - -/*! - * \internal - * \brief Update the linkedids for all channels in a bridge - * \since 12.0.0 - * - * \param bridge_channel The channel joining the bridge - * \param swap The channel being swapped out of the bridge. May be NULL. - * - * \note The bridge must be locked prior to calling this function. This should be called - * during a \ref bridge_channel_internal_push operation, typically by a sub-class of a bridge - */ -void ast_bridge_channel_update_linkedids(struct ast_bridge_channel *bridge_channel, struct ast_bridge_channel *swap); - -/*! - * \internal - * \brief Update the accountcodes for a channel entering a bridge - * \since 12.0.0 - * - * This function updates the accountcode and peeraccount on channels in two-party - * bridges. In multi-party bridges, peeraccount is not set - it doesn't make much sense - - * however accountcode propagation will still occur if the channel joining has an - * accountcode. - * - * \param bridge_channel The channel joining the bridge - * \param swap The channel being swapped out of the bridge. May be NULL. - * - * \note The bridge must be locked prior to calling this function. This should be called - * during a \ref bridge_channel_internal_push operation, typically by a sub-class of a bridge - */ -void ast_bridge_channel_update_accountcodes(struct ast_bridge_channel *bridge_channel, struct ast_bridge_channel *swap); - -/*! - * \brief Write a frame to the specified bridge_channel. - * \since 12.0.0 - * - * \param bridge_channel Channel to queue the frame. - * \param fr Frame to write. - * - * \retval 0 on success. - * \retval -1 on error. - */ -int ast_bridge_channel_queue_frame(struct ast_bridge_channel *bridge_channel, struct ast_frame *fr); - -/*! - * \brief Queue a control frame onto the bridge channel with data. - * \since 12.0.0 - * - * \param bridge_channel Which channel to queue the frame onto. - * \param control Type of control frame. - * \param data Frame payload data to pass. - * \param datalen Frame payload data length to pass. - * - * \retval 0 on success. - * \retval -1 on error. - */ -int ast_bridge_channel_queue_control_data(struct ast_bridge_channel *bridge_channel, enum ast_control_frame_type control, const void *data, size_t datalen); - -/*! - * \brief Write a control frame into the bridge with data. - * \since 12.0.0 - * - * \param bridge_channel Which channel is putting the frame into the bridge. - * \param control Type of control frame. - * \param data Frame payload data to pass. - * \param datalen Frame payload data length to pass. - * - * \retval 0 on success. - * \retval -1 on error. - */ -int ast_bridge_channel_write_control_data(struct ast_bridge_channel *bridge_channel, enum ast_control_frame_type control, const void *data, size_t datalen); - -/*! - * \brief Write a hold frame into the bridge. - * \since 12.0.0 - * - * \param bridge_channel Which channel is putting the hold into the bridge. - * \param moh_class The suggested music class for the other end to use. - * - * \retval 0 on success. - * \retval -1 on error. - */ -int ast_bridge_channel_write_hold(struct ast_bridge_channel *bridge_channel, const char *moh_class); - -/*! - * \brief Write an unhold frame into the bridge. - * \since 12.0.0 - * - * \param bridge_channel Which channel is putting the hold into the bridge. - * - * \retval 0 on success. - * \retval -1 on error. - */ -int ast_bridge_channel_write_unhold(struct ast_bridge_channel *bridge_channel); - -/*! - * \brief Run an application on the bridge channel. - * \since 12.0.0 - * - * \param bridge_channel Which channel to run the application on. - * \param app_name Dialplan application name. - * \param app_args Arguments for the application. (NULL tolerant) - * \param moh_class MOH class to request bridge peers to hear while application is running. - * NULL if no MOH. - * Empty if default MOH class. - * - * \note This is intended to be called by bridge hooks. - * - * \return Nothing - */ -void ast_bridge_channel_run_app(struct ast_bridge_channel *bridge_channel, const char *app_name, const char *app_args, const char *moh_class); - -/*! - * \brief Write a bridge action run application frame into the bridge. - * \since 12.0.0 - * - * \param bridge_channel Which channel is putting the frame into the bridge - * \param app_name Dialplan application name. - * \param app_args Arguments for the application. (NULL or empty for no arguments) - * \param moh_class MOH class to request bridge peers to hear while application is running. - * NULL if no MOH. - * Empty if default MOH class. - * - * \note This is intended to be called by bridge hooks. - * - * \retval 0 on success. - * \retval -1 on error. - */ -int ast_bridge_channel_write_app(struct ast_bridge_channel *bridge_channel, const char *app_name, const char *app_args, const char *moh_class); - -/*! - * \brief Queue a bridge action run application frame onto the bridge channel. - * \since 12.0.0 - * - * \param bridge_channel Which channel to put the frame onto - * \param app_name Dialplan application name. - * \param app_args Arguments for the application. (NULL or empty for no arguments) - * \param moh_class MOH class to request bridge peers to hear while application is running. - * NULL if no MOH. - * Empty if default MOH class. - * - * \note This is intended to be called by bridge hooks. - * - * \retval 0 on success. - * \retval -1 on error. - */ -int ast_bridge_channel_queue_app(struct ast_bridge_channel *bridge_channel, const char *app_name, const char *app_args, const char *moh_class); - -/*! - * \brief Custom interpretation of the playfile name. - * - * \param bridge_channel Which channel to play the file on - * \param playfile Sound filename to play. - * - * \return Nothing - */ -typedef void (*ast_bridge_custom_play_fn)(struct ast_bridge_channel *bridge_channel, const char *playfile); - -/*! - * \brief Play a file on the bridge channel. - * \since 12.0.0 - * - * \param bridge_channel Which channel to play the file on - * \param custom_play Call this function to play the playfile. (NULL if normal sound file to play) - * \param playfile Sound filename to play. - * \param moh_class MOH class to request bridge peers to hear while file is played. - * NULL if no MOH. - * Empty if default MOH class. - * - * \note This is intended to be called by bridge hooks. - * - * \return Nothing - */ -void ast_bridge_channel_playfile(struct ast_bridge_channel *bridge_channel, ast_bridge_custom_play_fn custom_play, const char *playfile, const char *moh_class); - -/*! - * \brief Write a bridge action play file frame into the bridge. - * \since 12.0.0 - * - * \param bridge_channel Which channel is putting the frame into the bridge - * \param custom_play Call this function to play the playfile. (NULL if normal sound file to play) - * \param playfile Sound filename to play. - * \param moh_class MOH class to request bridge peers to hear while file is played. - * NULL if no MOH. - * Empty if default MOH class. - * - * \note This is intended to be called by bridge hooks. - * - * \retval 0 on success. - * \retval -1 on error. - */ -int ast_bridge_channel_write_playfile(struct ast_bridge_channel *bridge_channel, ast_bridge_custom_play_fn custom_play, const char *playfile, const char *moh_class); - -/*! - * \brief Queue a bridge action play file frame onto the bridge channel. - * \since 12.0.0 - * - * \param bridge_channel Which channel to put the frame onto. - * \param custom_play Call this function to play the playfile. (NULL if normal sound file to play) - * \param playfile Sound filename to play. - * \param moh_class MOH class to request bridge peers to hear while file is played. - * NULL if no MOH. - * Empty if default MOH class. - * - * \note This is intended to be called by bridge hooks. - * - * \retval 0 on success. - * \retval -1 on error. - */ -int ast_bridge_channel_queue_playfile(struct ast_bridge_channel *bridge_channel, ast_bridge_custom_play_fn custom_play, const char *playfile, const char *moh_class); - -/*! - * \brief Custom callback run on a bridge channel. - * - * \param bridge_channel Which channel to operate on. - * \param payload Data to pass to the callback. (NULL if none). - * \param payload_size Size of the payload if payload is non-NULL. A number otherwise. - * - * \note The payload MUST NOT have any resources that need to be freed. - * - * \return Nothing - */ -typedef void (*ast_bridge_custom_callback_fn)(struct ast_bridge_channel *bridge_channel, const void *payload, size_t payload_size); - -/*! - * \brief Write a bridge action custom callback frame into the bridge. - * \since 12.0.0 - * - * \param bridge_channel Which channel is putting the frame into the bridge - * \param callback Custom callback run on a bridge channel. - * \param payload Data to pass to the callback. (NULL if none). - * \param payload_size Size of the payload if payload is non-NULL. A number otherwise. - * - * \note The payload MUST NOT have any resources that need to be freed. - * - * \note This is intended to be called by bridge hooks. - * - * \retval 0 on success. - * \retval -1 on error. - */ -int ast_bridge_channel_write_callback(struct ast_bridge_channel *bridge_channel, ast_bridge_custom_callback_fn callback, const void *payload, size_t payload_size); - -/*! - * \brief Queue a bridge action custom callback frame onto the bridge channel. - * \since 12.0.0 - * - * \param bridge_channel Which channel to put the frame onto. - * \param callback Custom callback run on a bridge channel. - * \param payload Data to pass to the callback. (NULL if none). - * \param payload_size Size of the payload if payload is non-NULL. A number otherwise. - * - * \note The payload MUST NOT have any resources that need to be freed. - * - * \note This is intended to be called by bridge hooks. - * - * \retval 0 on success. - * \retval -1 on error. - */ -int ast_bridge_channel_queue_callback(struct ast_bridge_channel *bridge_channel, ast_bridge_custom_callback_fn callback, const void *payload, size_t payload_size); - -/*! - * \brief Have a bridge channel park a channel in the bridge - * \since 12.0.0 - * - * \param bridge_channel Bridge channel performing the parking - * \param parkee_uuid Unique id of the channel we want to park - * \param parker_uuid Unique id of the channel parking the call - * \param app_data string indicating data used for park application (NULL allowed) - * - * \note This is intended to be called by bridge hooks. - * - * \retval 0 on success. - * \retval -1 on error. - */ -int ast_bridge_channel_write_park(struct ast_bridge_channel *bridge_channel, const char *parkee_uuid, - const char *parker_uuid, const char *app_data); - -#if defined(__cplusplus) || defined(c_plusplus) -} -#endif - -#endif /* _ASTERISK_BRIDGING_CHANNEL_H */ diff --git a/include/asterisk/bridging_channel_internal.h b/include/asterisk/bridging_channel_internal.h deleted file mode 100644 index 6c3add13b..000000000 --- a/include/asterisk/bridging_channel_internal.h +++ /dev/null @@ -1,193 +0,0 @@ -/* - * Asterisk -- An open source telephony toolkit. - * - * Copyright (C) 2013 Digium, Inc. - * - * Matt Jordan - * - * See http://www.asterisk.org for more information about - * the Asterisk project. Please do not directly contact - * any of the maintainers of this project for assistance; - * the project provides a web site, mailing lists and IRC - * channels for your use. - * - * This program is free software, distributed under the terms of - * the GNU General Public License Version 2. See the LICENSE file - * at the top of the source tree. - */ - -#ifndef _ASTERISK_PRIVATE_BRIDGING_CHANNEL_H -#define _ASTERISK_PRIVATE_BRIDGING_CHANNEL_H - -/*! - * \file - * \brief Private Bridging Channel API - * - * \author Matt Jordan - * - * A private API to manipulate channels in a bridge. These can be called on a channel in - * a bridge by \ref bridging.c. These functions should not be called elsewhere, including - * by other members of the Bridging API. - * - * See Also: - * \arg \ref AstCREDITS - * \arg \ref Ast - */ - -/*! - * \internal - * \brief Actions that can be taken on a channel in a bridge - */ -enum bridge_channel_action_type { - /*! Bridged channel is to detect a feature hook */ - BRIDGE_CHANNEL_ACTION_FEATURE, - /*! Bridged channel is to send a DTMF stream out */ - BRIDGE_CHANNEL_ACTION_DTMF_STREAM, - /*! Bridged channel is to indicate talking start */ - BRIDGE_CHANNEL_ACTION_TALKING_START, - /*! Bridged channel is to indicate talking stop */ - BRIDGE_CHANNEL_ACTION_TALKING_STOP, - /*! Bridge channel is to play the indicated sound file. */ - BRIDGE_CHANNEL_ACTION_PLAY_FILE, - /*! Bridge channel is to run the indicated application. */ - BRIDGE_CHANNEL_ACTION_RUN_APP, - /*! Bridge channel is to run the custom callback routine. */ - BRIDGE_CHANNEL_ACTION_CALLBACK, - /*! Bridge channel is to get parked. */ - BRIDGE_CHANNEL_ACTION_PARK, - /*! Bridge channel is to execute a blind transfer. */ - BRIDGE_CHANNEL_ACTION_BLIND_TRANSFER, - /*! Bridge channel is to execute an attended transfer */ - BRIDGE_CHANNEL_ACTION_ATTENDED_TRANSFER, - - /* - * Bridge actions put after this comment must never be put onto - * the bridge_channel wr_queue because they have other resources - * that must be freed. - */ - - /*! Bridge reconfiguration deferred technology destruction. */ - BRIDGE_CHANNEL_ACTION_DEFERRED_TECH_DESTROY = 1000, - /*! Bridge deferred dissolving. */ - BRIDGE_CHANNEL_ACTION_DEFERRED_DISSOLVING, -}; - -/*! - * \internal - * \brief Allocate a new ao2 ref counted bridge_channel - * \since 12.0.0 - * - * \param bridge The bridge to make the bridge_channel for - * - * \retval NULL on error - * \retval ao2 ref counted object on success - */ -struct ast_bridge_channel *bridge_channel_internal_alloc(struct ast_bridge *bridge); - -/*! - * \internal - * \brief Push the bridge channel into its specified bridge. - * \since 12.0.0 - * - * \param bridge_channel Channel to push. - * - * \note On entry, bridge_channel->bridge is already locked. - * - * \retval 0 on success. - * \retval -1 on failure. The channel did not get pushed. - */ -int bridge_channel_internal_push(struct ast_bridge_channel *bridge_channel); - -/*! - * \internal - * \brief Pull the bridge channel out of its current bridge. - * \since 12.0.0 - * - * \param bridge_channel Channel to pull. - * - * \note On entry, bridge_channel->bridge is already locked. - * - * \return Nothing - */ -void bridge_channel_internal_pull(struct ast_bridge_channel *bridge_channel); - -/*! - * \internal - * \brief Join the bridge_channel to the bridge - * - * \param bridge_channel The Channel in the bridge - * - * \note This API call starts the bridge_channel's processing of events while - * it is in the bridge. It will return when the channel has been instructed to - * leave the bridge. - */ -void bridge_channel_internal_join(struct ast_bridge_channel *bridge_channel); - -/*! - * \internal - * \brief Temporarily suspend a channel from a bridge, handing control over to some - * other system - * - * \param bridge_channel The channel in the bridge - * \note This function assumes that \ref bridge_channel is already locked - */ -void bridge_channel_internal_suspend_nolock(struct ast_bridge_channel *bridge_channel); - -/*! - * \internal - * \brief Unsuspend a channel that was previously suspended - * - * \param bridge_channel The channel in the bridge - * \note This function assumes that \ref bridge_channel is already locked - */ -void bridge_channel_internal_unsuspend_nolock(struct ast_bridge_channel *bridge_channel); - -/*! - * \internal - * \brief Queue a blind transfer action on a transferee bridge channel - * - * This is only relevant for when a blind transfer is performed on a two-party - * bridge. The transferee's bridge channel will have a blind transfer bridge - * action queued onto it, resulting in the party being redirected to a new - * destination - * - * \param transferee The channel to have the action queued on - * \param exten The destination extension for the transferee - * \param context The destination context for the transferee - * \param hook Frame hook to attach to transferee - * - * \retval 0 on success. - * \retval -1 on error. - */ -int bridge_channel_internal_queue_blind_transfer(struct ast_channel *transferee, - const char *exten, const char *context, - transfer_channel_cb new_channel_cb, void *user_data); - -/*! - * \internal - * \brief Queue an attended transfer action on a transferee bridge channel - * - * This is only relevant for when an attended transfer is performed on a two-party - * bridge. The transferee's bridge channel will have an attended transfer bridge - * action queued onto it. - * - * \param transferee The channel to have the action queued on - * \param unbridged_chan The unbridged channel who is the target of the attended - * transfer - * - * \retval 0 on success. - * \retval -1 on error. - */ -int bridge_channel_internal_queue_attended_transfer(struct ast_channel *transferee, - struct ast_channel *unbridged_chan); - -/*! - * \internal - * \brief Return whether or not the bridge_channel would allow optimization - * - * \retval 0 if optimization is not allowed - * \retval non-zero if optimization is allowed - */ -int bridge_channel_internal_allows_optimization(struct ast_bridge_channel *bridge_channel); - -#endif /* _ASTERISK_PRIVATE_BRIDGING_H */ diff --git a/include/asterisk/bridging_features.h b/include/asterisk/bridging_features.h deleted file mode 100644 index 05fdf2587..000000000 --- a/include/asterisk/bridging_features.h +++ /dev/null @@ -1,798 +0,0 @@ -/* - * Asterisk -- An open source telephony toolkit. - * - * Copyright (C) 2009, Digium, Inc. - * - * Joshua Colp - * - * See http://www.asterisk.org for more information about - * the Asterisk project. Please do not directly contact - * any of the maintainers of this project for assistance; - * the project provides a web site, mailing lists and IRC - * channels for your use. - * - * This program is free software, distributed under the terms of - * the GNU General Public License Version 2. See the LICENSE file - * at the top of the source tree. - */ - -/*! - * \file - * \brief Channel Bridging API - * \author Joshua Colp - */ - -#ifndef _ASTERISK_BRIDGING_FEATURES_H -#define _ASTERISK_BRIDGING_FEATURES_H - -#if defined(__cplusplus) || defined(c_plusplus) -extern "C" { -#endif - -/*! \brief Flags used for bridge features */ -enum ast_bridge_feature_flags { - /*! Upon channel hangup all bridge participants should be kicked out. */ - AST_BRIDGE_FLAG_DISSOLVE_HANGUP = (1 << 0), - /*! The last channel to leave the bridge dissolves it. */ - AST_BRIDGE_FLAG_DISSOLVE_EMPTY = (1 << 1), - /*! Move between bridging technologies as needed. */ - AST_BRIDGE_FLAG_SMART = (1 << 2), - /*! Bridge channels cannot be merged from this bridge. */ - AST_BRIDGE_FLAG_MERGE_INHIBIT_FROM = (1 << 3), - /*! Bridge channels cannot be merged to this bridge. */ - AST_BRIDGE_FLAG_MERGE_INHIBIT_TO = (1 << 4), - /*! Bridge channels cannot be local channel swap optimized from this bridge. */ - AST_BRIDGE_FLAG_SWAP_INHIBIT_FROM = (1 << 5), - /*! Bridge channels cannot be local channel swap optimized to this bridge. */ - AST_BRIDGE_FLAG_SWAP_INHIBIT_TO = (1 << 6), - /*! Bridge channels can be moved to another bridge only by masquerade (ConfBridge) */ - AST_BRIDGE_FLAG_MASQUERADE_ONLY = (1 << 7), - /*! Bridge does not allow transfers of channels out */ - AST_BRIDGE_FLAG_TRANSFER_PROHIBITED = (1 << 8), - /*! Bridge transfers require transfer of entire bridge rather than individual channels */ - AST_BRIDGE_FLAG_TRANSFER_BRIDGE_ONLY = (1 << 9), -}; - -/*! \brief Flags used for per bridge channel features */ -enum ast_bridge_channel_feature_flags { - /*! Upon channel hangup all bridge participants should be kicked out. */ - AST_BRIDGE_CHANNEL_FLAG_DISSOLVE_HANGUP = (1 << 0), - /*! This channel leaves the bridge if all participants have this flag set. */ - AST_BRIDGE_CHANNEL_FLAG_LONELY = (1 << 1), - /*! This channel cannot be moved to another bridge. */ - AST_BRIDGE_CHANNEL_FLAG_IMMOVABLE = (1 << 2), -}; - -/*! \brief Built in DTMF features */ -enum ast_bridge_builtin_feature { - /*! DTMF based Blind Transfer */ - AST_BRIDGE_BUILTIN_BLINDTRANSFER, - /*! DTMF based Attended Transfer */ - AST_BRIDGE_BUILTIN_ATTENDEDTRANSFER, - /*! - * DTMF based depart bridge feature - * - * \note Imparted channels are optionally hangup depending upon - * how it was imparted. - * - * \note Joined channels exit the bridge with - * BRIDGE_CHANNEL_STATE_END_WITH_DISSOLVE. - */ - AST_BRIDGE_BUILTIN_HANGUP, - /*! - * DTMF based Park - * - * \details The bridge is parked and the channel hears the - * parking slot to which it was parked. - */ - AST_BRIDGE_BUILTIN_PARKCALL, -/* BUGBUG does Monitor and/or MixMonitor require a two party bridge? MixMonitor is used by ConfBridge so maybe it doesn't. */ - /*! - * DTMF one-touch-record toggle using Monitor app. - * - * \note Only valid on two party bridges. - */ - AST_BRIDGE_BUILTIN_AUTOMON, - /*! - * DTMF one-touch-record toggle using MixMonitor app. - * - * \note Only valid on two party bridges. - */ - AST_BRIDGE_BUILTIN_AUTOMIXMON, - - /*! End terminator for list of built in features. Must remain last. */ - AST_BRIDGE_BUILTIN_END -}; - -enum ast_bridge_builtin_interval { - /*! Apply Call Duration Limits */ - AST_BRIDGE_BUILTIN_INTERVAL_LIMITS, - - /*! End terminator for list of built in interval features. Must remain last. */ - AST_BRIDGE_BUILTIN_INTERVAL_END -}; - -struct ast_bridge; -struct ast_bridge_channel; - -/*! - * \brief Hook callback type - * - * \param bridge The bridge that the channel is part of - * \param bridge_channel Channel executing the feature - * \param hook_pvt Private data passed in when the hook was created - * - * For interval hooks: - * \retval 0 Setup to fire again at the last interval. - * \retval positive Setup to fire again at the new interval returned. - * \retval -1 Remove the callback hook. - * - * For other hooks: - * \retval 0 Keep the callback hook. - * \retval -1 Remove the callback hook. - */ -typedef int (*ast_bridge_hook_callback)(struct ast_bridge *bridge, struct ast_bridge_channel *bridge_channel, void *hook_pvt); - -/*! - * \brief Hook pvt destructor callback - * - * \param hook_pvt Private data passed in when the hook was created to destroy - */ -typedef void (*ast_bridge_hook_pvt_destructor)(void *hook_pvt); - -/*! - * \brief Talking indicator callback - * - * \details This callback can be registered with the bridge in order - * to receive updates on when a bridge_channel has started and stopped - * talking - * - * \param bridge_channel Channel executing the feature - * \param talking TRUE if the channel is now talking - * - * \retval 0 Keep the callback hook. - * \retval -1 Remove the callback hook. - */ -typedef int (*ast_bridge_talking_indicate_callback)(struct ast_bridge_channel *bridge_channel, void *pvt_data, int talking); - -enum ast_bridge_hook_remove_flags { - /*! The hook is removed when the channel is pulled from the bridge. */ - AST_BRIDGE_HOOK_REMOVE_ON_PULL = (1 << 0), - /*! The hook is removed when the bridge's personality changes. */ - AST_BRIDGE_HOOK_REMOVE_ON_PERSONALITY_CHANGE = (1 << 1), -}; - -enum ast_bridge_hook_type { - /*! The hook type has not been specified. */ - AST_BRIDGE_HOOK_TYPE_NONE, - AST_BRIDGE_HOOK_TYPE_DTMF, - AST_BRIDGE_HOOK_TYPE_TIMER, - AST_BRIDGE_HOOK_TYPE_HANGUP, - AST_BRIDGE_HOOK_TYPE_JOIN, - AST_BRIDGE_HOOK_TYPE_LEAVE, - AST_BRIDGE_HOOK_TYPE_TALK, -}; - -/* BUGBUG Need to be able to selectively remove DTMF, hangup, and interval hooks. */ -/*! \brief Structure that is the essence of a feature hook. */ -struct ast_bridge_hook { - /*! Callback that is called when hook is tripped */ - ast_bridge_hook_callback callback; - /*! Callback to destroy hook_pvt data right before destruction. */ - ast_bridge_hook_pvt_destructor destructor; - /*! Unique data that was passed into us */ - void *hook_pvt; - /*! Flags determining when hooks should be removed from a bridge channel */ - struct ast_flags remove_flags; - /*! What kind of hook this is. */ - enum ast_bridge_hook_type type; -}; - -/*! - * \brief Maximum length of a DTMF feature string - */ -#define MAXIMUM_DTMF_FEATURE_STRING (11 + 1) - -/*! Extra parameters for a DTMF feature hook. */ -struct ast_bridge_hook_dtmf_parms { - /*! DTMF String that is examined during a feature hook lookup */ - char code[MAXIMUM_DTMF_FEATURE_STRING]; -}; - -/*! DTMF specific hook. */ -struct ast_bridge_hook_dtmf { - /*! Generic feature hook information. */ - struct ast_bridge_hook generic; - /*! Extra parameters for a DTMF feature hook. */ - struct ast_bridge_hook_dtmf_parms dtmf; -}; - -/*! Extra parameters for an interval timer hook. */ -struct ast_bridge_hook_timer_parms { - /*! Time at which the hook should actually trip */ - struct timeval trip_time; - /*! Heap index for interval hook */ - ssize_t heap_index; - /*! Interval that the hook should execute at in milliseconds */ - unsigned int interval; - /*! Sequence number for the hook to ensure expiration ordering */ - unsigned int seqno; -}; - -/*! Timer specific hook. */ -struct ast_bridge_hook_timer { - /*! Generic feature hook information. */ - struct ast_bridge_hook generic; - /*! Extra parameters for an interval timer hook. */ - struct ast_bridge_hook_timer_parms timer; -}; - -/*! - * \brief Structure that contains features information - */ -struct ast_bridge_features { - /*! Attached DTMF feature hooks */ - struct ao2_container *dtmf_hooks; - /*! Attached miscellaneous other hooks. */ - struct ao2_container *other_hooks; - /*! Attached interval hooks */ - struct ast_heap *interval_hooks; - /*! Limits feature data */ - struct ast_bridge_features_limits *limits; - /*! Feature flags that are enabled */ - struct ast_flags feature_flags; - /*! Used to assign the sequence number to the next interval hook added. */ - unsigned int interval_sequence; - /*! TRUE if feature_flags is setup */ - unsigned int usable:1; - /*! TRUE if the channel/bridge is muted. */ - unsigned int mute:1; - /*! TRUE if DTMF should be passed into the bridge tech. */ - unsigned int dtmf_passthrough:1; -}; - -/*! - * \brief Structure that contains configuration information for the blind transfer built in feature - */ -struct ast_bridge_features_blind_transfer { - /*! Context to use for transfers (If not empty.) */ - char context[AST_MAX_CONTEXT]; -}; - -/*! - * \brief Structure that contains configuration information for the attended transfer built in feature - */ -struct ast_bridge_features_attended_transfer { - /*! Context to use for transfers (If not empty.) */ - char context[AST_MAX_CONTEXT]; - /*! DTMF string used to abort the transfer (If not empty.) */ - char abort[MAXIMUM_DTMF_FEATURE_STRING]; - /*! DTMF string used to turn the transfer into a three way conference (If not empty.) */ - char threeway[MAXIMUM_DTMF_FEATURE_STRING]; - /*! DTMF string used to complete the transfer (If not empty.) */ - char complete[MAXIMUM_DTMF_FEATURE_STRING]; - /*! DTMF string used to swap bridged targets (If not empty.) */ - char swap[MAXIMUM_DTMF_FEATURE_STRING]; -}; - -enum ast_bridge_features_monitor { - /*! Toggle start/stop of Monitor/MixMonitor. */ - AUTO_MONITOR_TOGGLE, - /*! Start Monitor/MixMonitor if not already started. */ - AUTO_MONITOR_START, - /*! Stop Monitor/MixMonitor if not already stopped. */ - AUTO_MONITOR_STOP, -}; - -struct ast_bridge_features_automonitor { - /*! Start/Stop behavior. */ - enum ast_bridge_features_monitor start_stop; -}; - -struct ast_bridge_features_automixmonitor { - /*! Start/Stop behavior. */ - enum ast_bridge_features_monitor start_stop; -}; - -/*! - * \brief Structure that contains configuration information for the limits feature - */ -struct ast_bridge_features_limits { - /*! Maximum duration that the channel is allowed to be in the bridge (specified in milliseconds) */ - unsigned int duration; - /*! Duration into the call when warnings should begin (specified in milliseconds or 0 to disable) */ - unsigned int warning; - /*! Interval between the warnings (specified in milliseconds or 0 to disable) */ - unsigned int frequency; - - AST_DECLARE_STRING_FIELDS( - /*! Sound file to play when the maximum duration is reached (if empty, then nothing will be played) */ - AST_STRING_FIELD(duration_sound); - /*! Sound file to play when the warning time is reached (if empty, then the remaining time will be played) */ - AST_STRING_FIELD(warning_sound); - /*! Sound file to play when the call is first entered (if empty, then the remaining time will be played) */ - AST_STRING_FIELD(connect_sound); - ); - /*! Time when the bridge will be terminated by the limits feature */ - struct timeval quitting_time; -}; - -/*! - * \brief Register a handler for a built in feature - * - * \param feature The feature that the handler will be responsible for - * \param callback The callback function that will handle it - * \param dtmf Default DTMF string used to activate the feature - * - * \retval 0 on success - * \retval -1 on failure - * - * Example usage: - * - * \code - * ast_bridge_features_register(AST_BRIDGE_BUILTIN_ATTENDED_TRANSFER, bridge_builtin_attended_transfer, "*1"); - * \endcode - * - * This registers the function bridge_builtin_attended_transfer as the function responsible for the built in - * attended transfer feature. - */ -int ast_bridge_features_register(enum ast_bridge_builtin_feature feature, ast_bridge_hook_callback callback, const char *dtmf); - -/*! - * \brief Unregister a handler for a built in feature - * - * \param feature The feature to unregister - * - * \retval 0 on success - * \retval -1 on failure - * - * Example usage: - * - * \code - * ast_bridge_features_unregister(AST_BRIDGE_BUILTIN_ATTENDED_TRANSFER); - * \endcode - * - * This unregisters the function that is handling the built in attended transfer feature. - */ -int ast_bridge_features_unregister(enum ast_bridge_builtin_feature feature); - -/*! - * \brief Invoke a built in feature hook now. - * - * \param feature The feature to invoke - * - * \note This API call is only meant to be used by bridge - * subclasses and hook callbacks to request a builtin feature - * hook to be executed. - * - * \retval 0 on success - * \retval -1 on failure - * - * Example usage: - * - * \code - * ast_bridge_features_do(AST_BRIDGE_BUILTIN_ATTENDED_TRANSFER, bridge, bridge_channel, hook_pvt); - * \endcode - */ -int ast_bridge_features_do(enum ast_bridge_builtin_feature feature, struct ast_bridge *bridge, struct ast_bridge_channel *bridge_channel, void *hook_pvt); - -/*! - * \brief Attach interval hooks to a bridge features structure - * - * \param features Bridge features structure - * \param limits Configured limits applicable to the channel - * \param remove_flags Dictates what situations the hook should be removed. - * - * \retval 0 on success - * \retval -1 on failure - */ -typedef int (*ast_bridge_builtin_set_limits_fn)(struct ast_bridge_features *features, - struct ast_bridge_features_limits *limits, enum ast_bridge_hook_remove_flags remove_flags); - -/*! - * \brief Register a handler for a built in interval feature - * - * \param interval The interval feature that the handler will be responsible for - * \param callback the Callback function that will handle it - * - * \retval 0 on success - * \retval -1 on failure - * - * Example usage: - * - * \code - * ast_bridge_interval_register(AST_BRIDGE_BUILTIN_INTERVAL_LIMITS, bridge_builtin_set_limits); - * \endcode - * - * This registers the function bridge_builtin_set_limits as the function responsible for the built in - * duration limit feature. - */ -int ast_bridge_interval_register(enum ast_bridge_builtin_interval interval, ast_bridge_builtin_set_limits_fn callback); - -/*! - * \brief Unregisters a handler for a built in interval feature - * - * \param interval the interval feature to unregister - * - * \retval 0 on success - * \retval -1 on failure - * - * Example usage: - * - * \code - * ast_bridge_interval_unregister(AST_BRIDGE_BULTIN_INTERVAL_LIMITS) - * /endcode - * - * This unregisters the function that is handling the built in duration limit feature. - */ -int ast_bridge_interval_unregister(enum ast_bridge_builtin_interval interval); - -/*! - * \brief Attach a bridge channel join hook to a bridge features structure - * - * \param features Bridge features structure - * \param callback Function to execute upon activation - * \param hook_pvt Unique data - * \param destructor Optional destructor callback for hook_pvt data - * \param remove_flags Dictates what situations the hook should be removed. - * - * \retval 0 on success - * \retval -1 on failure (The caller must cleanup any hook_pvt resources.) - * - * Example usage: - * - * \code - * struct ast_bridge_features features; - * ast_bridge_features_init(&features); - * ast_bridge_join_hook(&features, join_callback, NULL, NULL, 0); - * \endcode - * - * This makes the bridging core call join_callback when a - * channel successfully joins the bridging system. A pointer to - * useful data may be provided to the hook_pvt parameter. - */ -int ast_bridge_join_hook(struct ast_bridge_features *features, - ast_bridge_hook_callback callback, - void *hook_pvt, - ast_bridge_hook_pvt_destructor destructor, - enum ast_bridge_hook_remove_flags remove_flags); - -/*! - * \brief Attach a bridge channel leave hook to a bridge features structure - * - * \param features Bridge features structure - * \param callback Function to execute upon activation - * \param hook_pvt Unique data - * \param destructor Optional destructor callback for hook_pvt data - * \param remove_flags Dictates what situations the hook should be removed. - * - * \retval 0 on success - * \retval -1 on failure (The caller must cleanup any hook_pvt resources.) - * - * Example usage: - * - * \code - * struct ast_bridge_features features; - * ast_bridge_features_init(&features); - * ast_bridge_leave_hook(&features, leave_callback, NULL, NULL, 0); - * \endcode - * - * This makes the bridging core call leave_callback when a - * channel successfully leaves the bridging system. A pointer - * to useful data may be provided to the hook_pvt parameter. - */ -int ast_bridge_leave_hook(struct ast_bridge_features *features, - ast_bridge_hook_callback callback, - void *hook_pvt, - ast_bridge_hook_pvt_destructor destructor, - enum ast_bridge_hook_remove_flags remove_flags); - -/*! - * \brief Attach a hangup hook to a bridge features structure - * - * \param features Bridge features structure - * \param callback Function to execute upon activation - * \param hook_pvt Unique data - * \param destructor Optional destructor callback for hook_pvt data - * \param remove_flags Dictates what situations the hook should be removed. - * - * \retval 0 on success - * \retval -1 on failure (The caller must cleanup any hook_pvt resources.) - * - * Example usage: - * - * \code - * struct ast_bridge_features features; - * ast_bridge_features_init(&features); - * ast_bridge_hangup_hook(&features, hangup_callback, NULL, NULL, 0); - * \endcode - * - * This makes the bridging core call hangup_callback if a - * channel that has this hook hangs up. A pointer to useful - * data may be provided to the hook_pvt parameter. - */ -int ast_bridge_hangup_hook(struct ast_bridge_features *features, - ast_bridge_hook_callback callback, - void *hook_pvt, - ast_bridge_hook_pvt_destructor destructor, - enum ast_bridge_hook_remove_flags remove_flags); - -/*! - * \brief Attach a DTMF hook to a bridge features structure - * - * \param features Bridge features structure - * \param dtmf DTMF string to be activated upon - * \param callback Function to execute upon activation - * \param hook_pvt Unique data - * \param destructor Optional destructor callback for hook_pvt data - * \param remove_flags Dictates what situations the hook should be removed. - * - * \retval 0 on success - * \retval -1 on failure (The caller must cleanup any hook_pvt resources.) - * - * Example usage: - * - * \code - * struct ast_bridge_features features; - * ast_bridge_features_init(&features); - * ast_bridge_dtmf_hook(&features, "#", pound_callback, NULL, NULL, 0); - * \endcode - * - * This makes the bridging core call pound_callback if a channel that has this - * feature structure inputs the DTMF string '#'. A pointer to useful data may be - * provided to the hook_pvt parameter. - */ -int ast_bridge_dtmf_hook(struct ast_bridge_features *features, - const char *dtmf, - ast_bridge_hook_callback callback, - void *hook_pvt, - ast_bridge_hook_pvt_destructor destructor, - enum ast_bridge_hook_remove_flags remove_flags); - -/*! - * \brief Attach an interval hook to a bridge features structure - * - * \param features Bridge features structure - * \param interval The interval that the hook should execute at in milliseconds - * \param callback Function to execute upon activation - * \param hook_pvt Unique data - * \param destructor Optional destructor callback for hook_pvt data - * \param remove_flags Dictates what situations the hook should be removed. - * - * \retval 0 on success - * \retval -1 on failure (The caller must cleanup any hook_pvt resources.) - * - * \code - * struct ast_bridge_features features; - * ast_bridge_features_init(&features); - * ast_bridge_interval_hook(&features, 1000, playback_callback, NULL, NULL, 0); - * \endcode - * - * This makes the bridging core call playback_callback every second. A pointer to useful - * data may be provided to the hook_pvt parameter. - */ -int ast_bridge_interval_hook(struct ast_bridge_features *features, - unsigned int interval, - ast_bridge_hook_callback callback, - void *hook_pvt, - ast_bridge_hook_pvt_destructor destructor, - enum ast_bridge_hook_remove_flags remove_flags); - -/*! - * \brief Attach a bridge channel talk detection hook to a bridge features structure - * - * \param features Bridge features structure - * \param callback Function to execute upon activation - * \param hook_pvt Unique data - * \param destructor Optional destructor callback for hook_pvt data - * \param remove_flags Dictates what situations the hook should be removed. - * - * \retval 0 on success - * \retval -1 on failure (The caller must cleanup any hook_pvt resources.) - * - * Example usage: - * - * \code - * struct ast_bridge_features features; - * ast_bridge_features_init(&features); - * ast_bridge_talk_hook(&features, talk_callback, NULL, NULL, 0); - * \endcode - * - * This makes the bridging technology call talk_callback when a - * channel is recognized as starting and stopping talking. A - * pointer to useful data may be provided to the hook_pvt - * parameter. - * - * \note This hook is currently only supported by softmix. - */ -int ast_bridge_talk_detector_hook(struct ast_bridge_features *features, - ast_bridge_talking_indicate_callback callback, - void *hook_pvt, - ast_bridge_hook_pvt_destructor destructor, - enum ast_bridge_hook_remove_flags remove_flags); - -/*! - * \brief Enable a built in feature on a bridge features structure - * - * \param features Bridge features structure - * \param feature Feature to enable - * \param dtmf Optionally the DTMF stream to trigger the feature, if not specified it will be the default - * \param config Configuration structure unique to the built in type - * \param destructor Optional destructor callback for config data - * \param remove_flags Dictates what situations the hook should be removed. - * - * \retval 0 on success - * \retval -1 on failure - * - * Example usage: - * - * \code - * struct ast_bridge_features features; - * ast_bridge_features_init(&features); - * ast_bridge_features_enable(&features, AST_BRIDGE_BUILTIN_ATTENDEDTRANSFER, NULL, NULL, 0); - * \endcode - * - * This enables the attended transfer DTMF option using the default DTMF string. An alternate - * string may be provided using the dtmf parameter. Internally this is simply setting up a hook - * to a built in feature callback function. - */ -int ast_bridge_features_enable(struct ast_bridge_features *features, - enum ast_bridge_builtin_feature feature, - const char *dtmf, - void *config, - ast_bridge_hook_pvt_destructor destructor, - enum ast_bridge_hook_remove_flags remove_flags); - -/*! - * \brief Constructor function for ast_bridge_features_limits - * - * \param limits pointer to a ast_bridge_features_limits struct that has been allocted, but not initialized - * - * \retval 0 on success - * \retval -1 on failure - */ -int ast_bridge_features_limits_construct(struct ast_bridge_features_limits *limits); - -/*! - * \brief Destructor function for ast_bridge_features_limits - * - * \param limits pointer to an ast_bridge_features_limits struct that needs to be destroyed - * - * This function does not free memory allocated to the ast_bridge_features_limits struct, it only frees elements within the struct. - * You must still call ast_free on the the struct if you allocated it with malloc. - */ -void ast_bridge_features_limits_destroy(struct ast_bridge_features_limits *limits); - -/*! - * \brief Limit the amount of time a channel may stay in the bridge and optionally play warning messages as time runs out - * - * \param features Bridge features structure - * \param limits Configured limits applicable to the channel - * \param remove_flags Dictates what situations the hook should be removed. - * - * \retval 0 on success - * \retval -1 on failure - * - * Example usage: - * - * \code - * struct ast_bridge_features features; - * struct ast_bridge_features_limits limits; - * ast_bridge_features_init(&features); - * ast_bridge_features_limits_construct(&limits); - * ast_bridge_features_set_limits(&features, &limits, 0); - * ast_bridge_features_limits_destroy(&limits); - * \endcode - * - * This sets the maximum time the channel can be in the bridge to 10 seconds and does not play any warnings. - * - * \note This API call can only be used on a features structure that will be used in association with a bridge channel. - * \note The ast_bridge_features_limits structure must remain accessible for the lifetime of the features structure. - */ -int ast_bridge_features_set_limits(struct ast_bridge_features *features, struct ast_bridge_features_limits *limits, enum ast_bridge_hook_remove_flags remove_flags); - -/*! - * \brief Set a flag on a bridge channel features structure - * - * \param features Bridge channel features structure - * \param flag Flag to enable - * - * \return Nothing - * - * Example usage: - * - * \code - * struct ast_bridge_features features; - * ast_bridge_features_init(&features); - * ast_bridge_features_set_flag(&features, AST_BRIDGE_CHANNEL_FLAG_DISSOLVE_HANGUP); - * \endcode - * - * This sets the AST_BRIDGE_CHANNEL_FLAG_DISSOLVE_HANGUP feature - * to be enabled on the features structure 'features'. - */ -void ast_bridge_features_set_flag(struct ast_bridge_features *features, unsigned int flag); - -/*! - * \brief Initialize bridge features structure - * - * \param features Bridge featues structure - * - * \retval 0 on success - * \retval -1 on failure - * - * Example usage: - * - * \code - * struct ast_bridge_features features; - * ast_bridge_features_init(&features); - * \endcode - * - * This initializes the feature structure 'features' to have nothing enabled. - * - * \note This MUST be called before enabling features or flags. Failure to do so - * may result in a crash. - */ -int ast_bridge_features_init(struct ast_bridge_features *features); - -/*! - * \brief Clean up the contents of a bridge features structure - * - * \param features Bridge features structure - * - * \return Nothing - * - * Example usage: - * - * \code - * struct ast_bridge_features features; - * ast_bridge_features_init(&features); - * ast_bridge_features_cleanup(&features); - * \endcode - * - * This cleans up the feature structure 'features'. - * - * \note This MUST be called after the features structure is done being used - * or a memory leak may occur. - */ -void ast_bridge_features_cleanup(struct ast_bridge_features *features); - -/*! - * \brief Allocate a new bridge features struct. - * \since 12.0.0 - * - * Example usage: - * - * \code - * struct ast_bridge_features *features; - * features = ast_bridge_features_new(); - * ast_bridge_features_destroy(features); - * \endcode - * - * \retval features New allocated features struct. - * \retval NULL on error. - */ -struct ast_bridge_features *ast_bridge_features_new(void); - -/*! - * \brief Destroy an allocated bridge features struct. - * \since 12.0.0 - * - * \param features Bridge features structure - * - * Example usage: - * - * \code - * struct ast_bridge_features *features; - * features = ast_bridge_features_new(); - * ast_bridge_features_destroy(features); - * \endcode - * - * \return Nothing - */ -void ast_bridge_features_destroy(struct ast_bridge_features *features); - -#if defined(__cplusplus) || defined(c_plusplus) -} -#endif - -#endif /* _ASTERISK_BRIDGING_FEATURES_H */ diff --git a/include/asterisk/bridging_internal.h b/include/asterisk/bridging_internal.h deleted file mode 100644 index 18ef56e96..000000000 --- a/include/asterisk/bridging_internal.h +++ /dev/null @@ -1,211 +0,0 @@ -/* - * Asterisk -- An open source telephony toolkit. - * - * Copyright (C) 2013 Digium, Inc. - * - * Mark Michelson - * - * See http://www.asterisk.org for more information about - * the Asterisk project. Please do not directly contact - * any of the maintainers of this project for assistance; - * the project provides a web site, mailing lists and IRC - * channels for your use. - * - * This program is free software, distributed under the terms of - * the GNU General Public License Version 2. See the LICENSE file - * at the top of the source tree. - */ - -/*! - * \file - * \brief Private Bridging API - * - * Functions in this file are intended to be used by the Bridging API, - * bridge mixing technologies, and bridge sub-classes. Users of bridges - * that do not fit those three categories should *not* use the API - * defined in this file. - * - * \author Mark Michelson - * - * See Also: - * \arg \ref AstCREDITS - */ - -#ifndef _ASTERISK_PRIVATE_BRIDGING_H -#define _ASTERISK_PRIVATE_BRIDGING_H - -struct ast_bridge; -struct ast_bridge_channel; - -/*! - * \brief Register the new bridge with the system. - * \since 12.0.0 - * - * \param bridge What to register. (Tolerates a NULL pointer) - * - * \code - * struct ast_bridge *ast_bridge_basic_new(uint32_t capabilities, int flags, uint32 dtmf_features) - * { - * void *bridge; - * - * bridge = bridge_alloc(sizeof(struct ast_bridge_basic), &ast_bridge_basic_v_table); - * bridge = bridge_base_init(bridge, capabilities, flags); - * bridge = ast_bridge_basic_init(bridge, dtmf_features); - * bridge = bridge_register(bridge); - * return bridge; - * } - * \endcode - * - * \note This must be done after a bridge constructor has - * completed setting up the new bridge but before it returns. - * - * \note After a bridge is registered, ast_bridge_destroy() must - * eventually be called to get rid of the bridge. - * - * \retval bridge on success. - * \retval NULL on error. - */ -struct ast_bridge *bridge_register(struct ast_bridge *bridge); - -/*! - * \internal - * \brief Allocate the bridge class object memory. - * \since 12.0.0 - * - * \param size Size of the bridge class structure to allocate. - * \param v_table Bridge class virtual method table. - * - * \retval bridge on success. - * \retval NULL on error. - */ -struct ast_bridge *bridge_alloc(size_t size, const struct ast_bridge_methods *v_table); - -/*! - * \brief Initialize the base class of the bridge. - * - * \param self Bridge to operate upon. (Tolerates a NULL pointer) - * \param capabilities The capabilities that we require to be used on the bridge - * \param flags Flags that will alter the behavior of the bridge - * - * \retval self on success - * \retval NULL on failure, self is already destroyed - * - * Example usage: - * - * \code - * struct ast_bridge *bridge; - * bridge = bridge_alloc(sizeof(*bridge), &ast_bridge_base_v_table); - * bridge = bridge_base_init(bridge, AST_BRIDGE_CAPABILITY_1TO1MIX, AST_BRIDGE_FLAG_DISSOLVE_HANGUP); - * \endcode - * - * This creates a no frills two party bridge that will be - * destroyed once one of the channels hangs up. - */ -struct ast_bridge *bridge_base_init(struct ast_bridge *self, uint32_t capabilities, unsigned int flags); - -/*! - * \internal - * \brief Move a bridge channel from one bridge to another. - * \since 12.0.0 - * - * \param dst_bridge Destination bridge of bridge channel move. - * \param bridge_channel Channel moving from one bridge to another. - * \param attempt_recovery TRUE if failure attempts to push channel back into original bridge. - * \param optimized Indicates whether the move is part of an unreal channel optimization. - * - * \note The dst_bridge and bridge_channel->bridge are assumed already locked. - * - * \retval 0 on success. - * \retval -1 on failure. - */ -int bridge_do_move(struct ast_bridge *dst_bridge, struct ast_bridge_channel *bridge_channel, - int attempt_recovery, unsigned int optimized); - -/*! - * \internal - * \brief Do the merge of two bridges. - * \since 12.0.0 - * - * \param dst_bridge Destination bridge of merge. - * \param src_bridge Source bridge of merge. - * \param kick_me Array of channels to kick from the bridges. - * \param num_kick Number of channels in the kick_me array. - * \param optimized Indicates whether the merge is part of an unreal channel optimization. - * - * \return Nothing - * - * \note The two bridges are assumed already locked. - * - * This moves the channels in src_bridge into the bridge pointed - * to by dst_bridge. - */ -void bridge_do_merge(struct ast_bridge *dst_bridge, struct ast_bridge *src_bridge, - struct ast_bridge_channel **kick_me, unsigned int num_kick, unsigned int optimized); - -/*! - * \internal - * \brief Helper function to find a bridge channel given a channel. - * - * \param bridge What to search - * \param chan What to search for. - * - * \note On entry, bridge is already locked. - * - * \retval bridge_channel if channel is in the bridge. - * \retval NULL if not in bridge. - */ -struct ast_bridge_channel *bridge_find_channel(struct ast_bridge *bridge, struct ast_channel *chan); - -/*! - * \internal - * \brief Adjust the bridge merge inhibit request count. - * \since 12.0.0 - * - * \param bridge What to operate on. - * \param request Inhibit request increment. - * (Positive to add requests. Negative to remove requests.) - * - * \note This function assumes bridge is locked. - * - * \return Nothing - */ -void bridge_merge_inhibit_nolock(struct ast_bridge *bridge, int request); - -/*! - * \internal - * \brief Notify the bridge that it has been reconfigured. - * \since 12.0.0 - * - * \param bridge Reconfigured bridge. - * \param colp_update Whether to perform COLP updates. - * - * \details - * After a series of bridge_channel_internal_push and - * bridge_channel_internal_pull calls, you need to call this function - * to cause the bridge to complete restructuring for the change - * in the channel makeup of the bridge. - * - * \note On entry, the bridge is already locked. - * - * \return Nothing - */ -void bridge_reconfigured(struct ast_bridge *bridge, unsigned int colp_update); - -/*! - * \internal - * \brief Dissolve the bridge. - * \since 12.0.0 - * - * \param bridge Bridge to eject all channels - * - * \details - * Force out all channels that are not already going out of the - * bridge. Any new channels joining will leave immediately. - * - * \note On entry, bridge is already locked. - * - * \return Nothing - */ -void bridge_dissolve(struct ast_bridge *bridge); - -#endif /* _ASTERISK_PRIVATE_BRIDGING_H */ diff --git a/include/asterisk/bridging_roles.h b/include/asterisk/bridging_roles.h deleted file mode 100644 index d90e564b7..000000000 --- a/include/asterisk/bridging_roles.h +++ /dev/null @@ -1,166 +0,0 @@ -/* - * Asterisk -- An open source telephony toolkit. - * - * Copyright (C) 2013, Digium, Inc. - * - * Jonathan Rose - * - * See http://www.asterisk.org for more information about - * the Asterisk project. Please do not directly contact - * any of the maintainers of this project for assistance; - * the project provides a web site, mailing lists and IRC - * channels for your use. - * - * This program is free software, distributed under the terms of - * the GNU General Public License Version 2. See the LICENSE file - * at the top of the source tree. - */ - -/*! \file - * \brief Channel Bridging Roles API - * \author Jonathan Rose - */ - -#ifndef _ASTERISK_BRIDGING_ROLES_H -#define _ASTERISK_BRIDGING_ROLES_H - -#if defined(__cplusplus) || defined(c_plusplus) -extern "C" { -#endif - -#include "asterisk/linkedlists.h" - -#define AST_ROLE_LEN 32 - -/*! - * \brief Adds a bridge role to a channel - * - * \param chan Acquirer of the requested role - * \param role_name Name of the role being attached - * - * \retval 0 on success - * \retval -1 on failure - */ -int ast_channel_add_bridge_role(struct ast_channel *chan, const char *role_name); - -/*! - * \brief Removes a bridge role from a channel - * - * \param chan Channel the role is being removed from - * \param role_name Name of the role being removed - */ -void ast_channel_remove_bridge_role(struct ast_channel *chan, const char *role_name); - -/*! - * \brief Set a role option on a channel - * \param channel Channel receiving the role option - * \param role_name Role the role option is applied to - * \param option Name of the option - * \param value Value of the option - * - * \param 0 on success - * \retval -1 on failure - */ -int ast_channel_set_bridge_role_option(struct ast_channel *channel, const char *role_name, const char *option, const char *value); - -/*! - * \brief Check if a role exists on a channel - * - * \param channel The channel to check - * \param role_name The name of the role to search for - * - * \retval 0 The requested role does not exist on the channel - * \retval 1 The requested role exists on the channel - * - * This is an alternative to \ref ast_bridge_channel_has_role that is useful if bridge - * roles have not yet been established on a channel's bridge_channel. A possible example of - * when this could be used is in a bridge v_table's push() callback. - */ -int ast_channel_has_role(struct ast_channel *channel, const char *role_name); - -/*! - * \brief Retrieve the value of a requested role option from a channel - * - * \param channel The channel to retrieve the requested option from - * \param role_name The role to which the option belongs - * \param option The name of the option to retrieve - * - * \retval NULL The option does not exist - * \retval non-NULL The value of the option - * - * This is an alternative to \ref ast_bridge_channel_get_role_option that is useful if bridge - * roles have not yet been esstablished on a channel's bridge_channel. A possible example of - * when this could be used is in a bridge v_table's push() callback. - */ -const char *ast_channel_get_role_option(struct ast_channel *channel, const char *role_name, const char *option); - -/*! - * \brief Check to see if a bridge channel inherited a specific role from its channel - * - * \param bridge_channel The bridge channel being checked - * \param role_name Name of the role being checked - * - * \retval 0 The bridge channel does not have the requested role - * \retval 1 The bridge channel does have the requested role - * - * \note Before a bridge_channel can effectively check roles against a bridge, ast_bridge_channel_establish_roles - * should be called on the bridge_channel so that roles and their respective role options can be copied from the channel - * datastore into the bridge_channel roles list. Otherwise this function will just return 0 because the list will be NULL. - */ -int ast_bridge_channel_has_role(struct ast_bridge_channel *bridge_channel, const char *role_name); - -/*! - * \brief Retrieve the value of a requested role option from a bridge channel - * - * \param bridge_channel The bridge channel we are retrieving the option from - * \param role_name Name of the role the option will be retrieved from - * \param option Name of the option we are retrieving the value of - * - * \retval NULL If either the role does not exist on the bridge_channel or the role does exist but the option has not been set - * \retval The value of the option - * - * \note See ast_channel_set_role_option note about the need to call ast_bridge_channel_establish_roles. - * - * \note The returned character pointer is only valid as long as the bridge_channel is guaranteed to be alive and hasn't had - * ast_bridge_channel_clear_roles called against it (as this will free all roles and role options in the bridge - * channel). If you need this value after one of these destruction events occurs, you must make a local copy while it is - * still valid. - */ -const char *ast_bridge_channel_get_role_option(struct ast_bridge_channel *bridge_channel, const char *role_name, const char *option); - -/*! - * \brief Clone the roles from a bridge_channel's attached ast_channel onto the bridge_channel's role list - * - * \param bridge_channel The bridge channel that we are preparing - * - * \retval 0 on success - * \retval -1 on failure - * - * \details - * This function should always be called when the bridge_channel binds to an ast_channel at some point before the bridge_channel - * joins or is imparted onto a bridge. Failure to do so will result in an empty role list. While the list remains established, - * changes to roles on the ast_channel will not propogate to the bridge channel and roles can not be re-established on the bridge - * channel without first clearing the roles with ast_bridge_roles_bridge_channel_clear_roles. - */ -int ast_bridge_channel_establish_roles(struct ast_bridge_channel *bridge_channel); - -/*! - * \brief Clear all roles from a bridge_channel's role list - * - * \param bridge_channel the bridge channel that we are scrubbing - * - * \details - * If roles are already established on a bridge channel, ast_bridge_channel_establish_roles will fail unconditionally - * without changing any roles. In order to update a bridge channel's roles, they must first be cleared from the bridge channel using - * this function. - * - * \note - * ast_bridge_channel_clear_roles also serves as the destructor for the role list of a bridge channel. - */ -void ast_bridge_channel_clear_roles(struct ast_bridge_channel *bridge_channel); - -#if defined(__cplusplus) || defined(c_plusplus) -} -#endif - -#endif /* _ASTERISK_BRIDGING_ROLES_H */ diff --git a/include/asterisk/bridging_technology.h b/include/asterisk/bridging_technology.h deleted file mode 100644 index 534eb5417..000000000 --- a/include/asterisk/bridging_technology.h +++ /dev/null @@ -1,242 +0,0 @@ -/* - * Asterisk -- An open source telephony toolkit. - * - * Copyright (C) 2009, Digium, Inc. - * - * Joshua Colp - * - * See http://www.asterisk.org for more information about - * the Asterisk project. Please do not directly contact - * any of the maintainers of this project for assistance; - * the project provides a web site, mailing lists and IRC - * channels for your use. - * - * This program is free software, distributed under the terms of - * the GNU General Public License Version 2. See the LICENSE file - * at the top of the source tree. - */ - -/*! \file - * \brief Channel Bridging API - * \author Joshua Colp - */ - -#ifndef _ASTERISK_BRIDGING_TECHNOLOGY_H -#define _ASTERISK_BRIDGING_TECHNOLOGY_H - -#if defined(__cplusplus) || defined(c_plusplus) -extern "C" { -#endif - -/*! - * \brief Base preference values for choosing a bridge technology. - * - * \note Higher is more preference. - */ -enum ast_bridge_preference { - AST_BRIDGE_PREFERENCE_BASE_HOLDING = 50, - AST_BRIDGE_PREFERENCE_BASE_EARLY = 100, - AST_BRIDGE_PREFERENCE_BASE_NATIVE = 90, - AST_BRIDGE_PREFERENCE_BASE_1TO1MIX = 50, - AST_BRIDGE_PREFERENCE_BASE_MULTIMIX = 10, -}; - -/*! - * \brief Structure specific to bridge technologies capable of - * performing talking optimizations. - */ -struct ast_bridge_tech_optimizations { - /*! The amount of time in ms that talking must be detected before - * the dsp determines that talking has occurred */ - unsigned int talking_threshold; - /*! The amount of time in ms that silence must be detected before - * the dsp determines that talking has stopped */ - unsigned int silence_threshold; - /*! Whether or not the bridging technology should drop audio - * detected as silence from the mix. */ - unsigned int drop_silence:1; -}; - -/*! - * \brief Structure that is the essence of a bridge technology - */ -struct ast_bridge_technology { - /*! Unique name to this bridge technology */ - const char *name; - /*! The capabilities that this bridge technology is capable of. This has nothing to do with - * format capabilities. */ - uint32_t capabilities; - /*! Preference level that should be used when determining whether to use this bridge technology or not */ - enum ast_bridge_preference preference; - /*! - * \brief Create a bridge technology instance for a bridge. - * - * \retval 0 on success - * \retval -1 on failure - * - * \note On entry, bridge may or may not already be locked. - * However, it can be accessed as if it were locked. - */ - int (*create)(struct ast_bridge *bridge); - /*! - * \brief Request a bridge technology instance start operations. - * - * \retval 0 on success - * \retval -1 on failure - * - * \note On entry, bridge may or may not already be locked. - * However, it can be accessed as if it were locked. - */ - int (*start)(struct ast_bridge *bridge); - /*! - * \brief Request a bridge technology instance stop in preparation for being destroyed. - * - * \note On entry, bridge is already locked. - */ - void (*stop)(struct ast_bridge *bridge); - /*! - * \brief Destroy a bridging technology instance for a bridge. - * - * \note On entry, bridge must NOT be locked. - */ - void (*destroy)(struct ast_bridge *bridge); - /*! - * \brief Add a channel to a bridging technology instance for a bridge. - * - * \retval 0 on success - * \retval -1 on failure - * - * \note On entry, bridge is already locked. - */ - int (*join)(struct ast_bridge *bridge, struct ast_bridge_channel *bridge_channel); - /*! - * \brief Remove a channel from a bridging technology instance for a bridge. - * - * \note On entry, bridge is already locked. - */ - void (*leave)(struct ast_bridge *bridge, struct ast_bridge_channel *bridge_channel); - /*! - * \brief Suspend a channel on a bridging technology instance for a bridge. - * - * \note On entry, bridge is already locked. - */ - void (*suspend)(struct ast_bridge *bridge, struct ast_bridge_channel *bridge_channel); - /*! - * \brief Unsuspend a channel on a bridging technology instance for a bridge. - * - * \note On entry, bridge is already locked. - */ - void (*unsuspend)(struct ast_bridge *bridge, struct ast_bridge_channel *bridge_channel); - /*! - * \brief Check if a bridge is compatible with the bridging technology. - * - * \retval 0 if not compatible - * \retval non-zero if compatible - * - * \note On entry, bridge may or may not already be locked. - * However, it can be accessed as if it were locked. - */ - int (*compatible)(struct ast_bridge *bridge); - /*! - * \brief Write a frame into the bridging technology instance for a bridge. - * - * \note The bridge must be tolerant of bridge_channel being NULL. - * - * \retval 0 Frame accepted into the bridge. - * \retval -1 Frame needs to be deferred. - * - * \note On entry, bridge is already locked. - */ - int (*write)(struct ast_bridge *bridge, struct ast_bridge_channel *bridge_channel, struct ast_frame *frame); - /*! Formats that the bridge technology supports */ - struct ast_format_cap *format_capabilities; - /*! TRUE if the bridge technology is currently suspended. */ - unsigned int suspended:1; - /*! Module this bridge technology belongs to. It is used for reference counting bridges using the technology. */ - struct ast_module *mod; - /*! Linked list information */ - AST_RWLIST_ENTRY(ast_bridge_technology) entry; -}; - -/*! - * \brief Register a bridge technology for use - * - * \param technology The bridge technology to register - * \param mod The module that is registering the bridge technology - * - * \retval 0 on success - * \retval -1 on failure - * - * Example usage: - * - * \code - * ast_bridge_technology_register(&simple_bridge_tech); - * \endcode - * - * This registers a bridge technology declared as the structure - * simple_bridge_tech with the bridging core and makes it available for - * use when creating bridges. - */ -int __ast_bridge_technology_register(struct ast_bridge_technology *technology, struct ast_module *mod); - -/*! \brief See \ref __ast_bridge_technology_register() */ -#define ast_bridge_technology_register(technology) __ast_bridge_technology_register(technology, ast_module_info->self) - -/*! - * \brief Unregister a bridge technology from use - * - * \param technology The bridge technology to unregister - * - * \retval 0 on success - * \retval -1 on failure - * - * Example usage: - * - * \code - * ast_bridge_technology_unregister(&simple_bridge_tech); - * \endcode - * - * This unregisters a bridge technlogy declared as the structure - * simple_bridge_tech with the bridging core. It will no longer be - * considered when creating a new bridge. - */ -int ast_bridge_technology_unregister(struct ast_bridge_technology *technology); - -/*! - * \brief Suspend a bridge technology from consideration - * - * \param technology The bridge technology to suspend - * - * Example usage: - * - * \code - * ast_bridge_technology_suspend(&simple_bridge_tech); - * \endcode - * - * This suspends the bridge technology simple_bridge_tech from being considered - * when creating a new bridge. Existing bridges using the bridge technology - * are not affected. - */ -void ast_bridge_technology_suspend(struct ast_bridge_technology *technology); - -/*! - * \brief Unsuspend a bridge technology - * - * \param technology The bridge technology to unsuspend - * - * Example usage: - * - * \code - * ast_bridge_technology_unsuspend(&simple_bridge_tech); - * \endcode - * - * This makes the bridge technology simple_bridge_tech considered when - * creating a new bridge again. - */ -void ast_bridge_technology_unsuspend(struct ast_bridge_technology *technology); - -#if defined(__cplusplus) || defined(c_plusplus) -} -#endif - -#endif /* _ASTERISK_BRIDGING_TECHNOLOGY_H */ diff --git a/include/asterisk/core_unreal.h b/include/asterisk/core_unreal.h index 751c5d455..c7a82ef92 100644 --- a/include/asterisk/core_unreal.h +++ b/include/asterisk/core_unreal.h @@ -31,7 +31,7 @@ #include "asterisk/astobj2.h" #include "asterisk/channel.h" -#include "asterisk/bridging.h" +#include "asterisk/bridge.h" #include "asterisk/abstract_jb.h" #if defined(__cplusplus) || defined(c_plusplus) diff --git a/include/asterisk/doxygen/architecture.h b/include/asterisk/doxygen/architecture.h index 5d5c706d2..9cf15c723 100644 --- a/include/asterisk/doxygen/architecture.h +++ b/include/asterisk/doxygen/architecture.h @@ -53,7 +53,7 @@ -# \ref ArchConceptBridging -# \ref ArchCodeFlows -# \ref ArchCodeFlowPlayback - -# \ref ArchCodeFlowBridge + -# \ref ArchCodeFlowBridge -# \ref ArchDataStructures -# \ref ArchAstobj2 -# \ref ArchLinkedLists @@ -258,11 +258,14 @@ in the source tree. For a list of bridge technology implementations, see \ref bridges. For additional information on the bridging API, see -include/asterisk/bridging.h and -include/asterisk/bridging_technology.h. +\arg include/asterisk/bridge.h +\arg include/asterisk/bridge_technology.h +\arg include/asterisk/bridge_channel.h +\arg include/asterisk/bridge_features.h +\arg include/asterisk/bridge_after.h For additional implementation details regarding the core bridging API, see -main/bridging.c. +main/bridging.c and main/bridging_channel.c. \subsection ArchInterfaceCDR Call Detail Record (CDR) Handlers @@ -436,7 +439,7 @@ Asterisk CLI operates using connections to a UNIX %domain socket. There are other miscellaneous threads throughout the system that perform a specific task. For example, the event API (include/asterisk/event.h) uses a thread internally (main/event.c) to handle asychronous event dispatching. The devicestate API -(include/asterisk/devicestate.h) uses a thread internally (main/devicestate.c) +(include/asterisk/devicestate.h) uses a thread internally (main/devicestate.c) to asynchronously process device state changes. diff --git a/include/asterisk/features.h b/include/asterisk/features.h index 96eec98c8..5293e6505 100644 --- a/include/asterisk/features.h +++ b/include/asterisk/features.h @@ -26,7 +26,7 @@ #include "asterisk/pbx.h" #include "asterisk/linkedlists.h" -#include "asterisk/bridging.h" +#include "asterisk/bridge.h" #define FEATURE_MAX_LEN 11 #define FEATURE_APP_LEN 64 diff --git a/include/asterisk/stasis_bridges.h b/include/asterisk/stasis_bridges.h new file mode 100644 index 000000000..973b00c47 --- /dev/null +++ b/include/asterisk/stasis_bridges.h @@ -0,0 +1,421 @@ +/* + * Asterisk -- An open source telephony toolkit. + * + * Copyright (C) 2013 Digium, Inc. + * + * Kinsey Moore + * + * See http://www.asterisk.org for more information about + * the Asterisk project. Please do not directly contact + * any of the maintainers of this project for assistance; + * the project provides a web site, mailing lists and IRC + * channels for your use. + * + * This program is free software, distributed under the terms of + * the GNU General Public License Version 2. See the LICENSE file + * at the top of the source tree. + */ + +#ifndef _STASIS_BRIDGING_H +#define _STASIS_BRIDGING_H + +#if defined(__cplusplus) || defined(c_plusplus) +extern "C" { +#endif + +#include "asterisk/stringfields.h" +#include "asterisk/utils.h" +#include "asterisk/lock.h" +#include "asterisk/linkedlists.h" +#include "asterisk/channel.h" +#include "asterisk/bridge.h" +#include "asterisk/pbx.h" + +/*! + * \brief Structure that contains a snapshot of information about a bridge + */ +struct ast_bridge_snapshot { + AST_DECLARE_STRING_FIELDS( + /*! Immutable bridge UUID. */ + AST_STRING_FIELD(uniqueid); + /*! Bridge technology that is handling the bridge */ + AST_STRING_FIELD(technology); + /*! Bridge subclass that is handling the bridge */ + AST_STRING_FIELD(subclass); + ); + /*! AO2 container of bare channel uniqueid strings participating in the bridge. + * Allocated from ast_str_container_alloc() */ + struct ao2_container *channels; + /*! Bridge flags to tweak behavior */ + struct ast_flags feature_flags; + /*! Bridge capabilities */ + uint32_t capabilities; + /*! Number of channels participating in the bridge */ + unsigned int num_channels; + /*! Number of active channels in the bridge. */ + unsigned int num_active; +}; + +/*! + * \since 12 + * \brief Generate a snapshot of the bridge state. This is an ao2 object, so + * ao2_cleanup() to deallocate. + * + * \param bridge The bridge from which to generate a snapshot + * + * \retval AO2 refcounted snapshot on success + * \retval NULL on error + */ +struct ast_bridge_snapshot *ast_bridge_snapshot_create(struct ast_bridge *bridge); + +/*! + * \since 12 + * \brief Message type for \ref ast_bridge_snapshot. + * + * \retval Message type for \ref ast_bridge_snapshot. + */ +struct stasis_message_type *ast_bridge_snapshot_type(void); + +/*! + * \since 12 + * \brief A topic which publishes the events for a particular bridge. + * + * If the given \a bridge is \c NULL, ast_bridge_topic_all() is returned. + * + * \param bridge Bridge for which to get a topic or \c NULL. + * + * \retval Topic for bridge's events. + * \retval ast_bridge_topic_all() if \a bridge is \c NULL. + */ +struct stasis_topic *ast_bridge_topic(struct ast_bridge *bridge); + +/*! + * \since 12 + * \brief A topic which publishes the events for all bridges. + * \retval Topic for all bridge events. + */ +struct stasis_topic *ast_bridge_topic_all(void); + +/*! + * \since 12 + * \brief A caching topic which caches \ref ast_bridge_snapshot messages from + * ast_bridge_events_all(void). + * + * \retval Caching topic for all bridge events. + */ +struct stasis_caching_topic *ast_bridge_topic_all_cached(void); + +/*! + * \since 12 + * \brief Publish the state of a bridge + * + * \param bridge The bridge for which to publish state + */ +void ast_bridge_publish_state(struct ast_bridge *bridge); + +/*! \brief Message representing the merge of two bridges */ +struct ast_bridge_merge_message { + struct ast_bridge_snapshot *from; /*!< Bridge from which channels will be removed during the merge */ + struct ast_bridge_snapshot *to; /*!< Bridge to which channels will be added during the merge */ +}; + +/*! + * \since 12 + * \brief Message type for \ref ast_bridge_merge_message. + * + * \retval Message type for \ref ast_bridge_merge_message. + */ +struct stasis_message_type *ast_bridge_merge_message_type(void); + +/*! + * \since 12 + * \brief Publish a bridge merge + * + * \param to The bridge to which channels are being added + * \param from The bridge from which channels are being removed + */ +void ast_bridge_publish_merge(struct ast_bridge *to, struct ast_bridge *from); + +/*! + * \since 12 + * \brief Blob of data associated with a bridge. + * + * The \c blob is actually a JSON object of structured data. It has a "type" field + * which contains the type string describing this blob. + */ +struct ast_bridge_blob { + /*! Bridge blob is associated with (or NULL for global/all bridges) */ + struct ast_bridge_snapshot *bridge; + /*! Channel blob is associated with (may be NULL for some messages) */ + struct ast_channel_snapshot *channel; + /*! JSON blob of data */ + struct ast_json *blob; +}; + +/*! + * \since 12 + * \brief Message type for \ref channel enter bridge blob messages. + * + * \retval Message type for \ref channel enter bridge blob messages. + */ +struct stasis_message_type *ast_channel_entered_bridge_type(void); + +/*! + * \since 12 + * \brief Message type for \ref channel leave bridge blob messages. + * + * \retval Message type for \ref channel leave bridge blob messages. + */ +struct stasis_message_type *ast_channel_left_bridge_type(void); + +/*! + * \since 12 + * \brief Creates a \ref ast_bridge_blob message. + * + * The \a blob JSON object requires a \c "type" field describing the blob. It + * should also be treated as immutable and not modified after it is put into the + * message. + * + * \param bridge Channel blob is associated with, or NULL for global/all bridges. + * \param blob JSON object representing the data. + * \return \ref ast_bridge_blob message. + * \return \c NULL on error + */ +struct stasis_message *ast_bridge_blob_create(struct stasis_message_type *type, + struct ast_bridge *bridge, + struct ast_channel *chan, + struct ast_json *blob); + +/*! + * \since 12 + * \brief Publish a bridge channel enter event + * + * \param bridge The bridge a channel entered + * \param chan The channel that entered the bridge + */ +void ast_bridge_publish_enter(struct ast_bridge *bridge, struct ast_channel *chan); + +/*! + * \since 12 + * \brief Publish a bridge channel leave event + * + * \param bridge The bridge a channel left + * \param chan The channel that left the bridge + */ +void ast_bridge_publish_leave(struct ast_bridge *bridge, struct ast_channel *chan); + +/*! + * \brief Build a JSON object from a \ref ast_bridge_snapshot. + * \return JSON object representing bridge snapshot. + * \return \c NULL on error + */ +struct ast_json *ast_bridge_snapshot_to_json(const struct ast_bridge_snapshot *snapshot); + +/*! + * \brief Pair showing a bridge snapshot and a specific channel snapshot belonging to the bridge + */ +struct ast_bridge_channel_snapshot_pair { + struct ast_bridge_snapshot *bridge_snapshot; + struct ast_channel_snapshot *channel_snapshot; +}; + +/*! + * \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. + * + * \retval Message type for \ref ast_blind_transfer_message. + */ +struct stasis_message_type *ast_blind_transfer_type(void); + +/*! + * \brief Publish a blind transfer event + * + * \param is_external Whether the blind transfer was initiated externally (e.g. via AMI or native protocol) + * \param result The success or failure of the transfer + * \param to_transferee The bridge between the transferer and transferee plus the transferer channel + * \param context The destination context for the blind transfer + * \param exten The destination extension for the blind transfer + */ +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); + +enum ast_attended_transfer_dest_type { + /*! The transfer failed, so there is no appropriate final state */ + AST_ATTENDED_TRANSFER_DEST_FAIL, + /*! The transfer results in a single bridge remaining due to a merge or swap */ + AST_ATTENDED_TRANSFER_DEST_BRIDGE_MERGE, + /*! The transfer results in a channel or bridge running an application */ + AST_ATTENDED_TRANSFER_DEST_APP, + /*! The transfer results in both bridges remaining with a local channel linking them */ + AST_ATTENDED_TRANSFER_DEST_LINK, + /*! The transfer results in a threeway call between transferer, transferee, and transfer target */ + AST_ATTENDED_TRANSFER_DEST_THREEWAY, +}; + +/*! + * \brief Message representing attended transfer + */ +struct ast_attended_transfer_message { + /*! Result of the attended transfer */ + enum ast_transfer_result result; + /*! Indicates if the transfer was initiated externally*/ + int is_external; + /*! Bridge between transferer <-> transferee and the transferer channel in that bridge. May be NULL */ + struct ast_bridge_channel_snapshot_pair to_transferee; + /*! Bridge between transferer <-> transfer target and the transferer channel in that bridge. May be NULL */ + struct ast_bridge_channel_snapshot_pair to_transfer_target; + /*! Indicates the final state of the transfer */ + enum ast_attended_transfer_dest_type dest_type; + union { + /*! ID of the surviving bridge. Applicable for AST_ATTENDED_TRANSFER_DEST_BRIDGE_MERGE */ + char bridge[AST_UUID_STR_LEN]; + /*! Destination application of transfer. Applicable for AST_ATTENDED_TRANSFER_DEST_APP */ + char app[AST_MAX_APP]; + /*! Pair of local channels linking the bridges. Applicable for AST_ATTENDED_TRANSFER_DEST_LINK */ + struct ast_channel_snapshot *links[2]; + /*! Transferer channel and bridge that survived the transition to a threeway call. Applicable for AST_ATTENDED_TRANSFER_DEST_THREEWAY */ + struct ast_bridge_channel_snapshot_pair threeway; + } dest; +}; + +/*! + * \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. + * + * \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 + */ +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); + +/*! + * \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. + * + * \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. + */ +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); + +/*! + * \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 + * + * \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. + */ +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); + +/*! + * \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) + * + * \param is_external Indicates if the transfer was initiated externally + * \param result The result of the transfer. + * \param transferee The bridge between the transferer and transferees as well as the transferer channel from that bridge + * \param target The bridge between the transferer and transfer targets as well as the transferer channel from that bridge + * \param dest_app The application that the channel or bridge is running upon transfer completion. + */ +void ast_bridge_publish_attended_transfer_app(int is_external, enum ast_transfer_result result, + struct ast_bridge_channel_pair *transferee, struct ast_bridge_channel_pair *target, + const char *dest_app); + +/*! + * \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. + * + * \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. + */ +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]); + +/*! + * \brief Returns the most recent snapshot for the bridge. + * + * The returned pointer is AO2 managed, so ao2_cleanup() when you're done. + * + * \param bridge_id Uniqueid of the bridge for which to get the snapshot. + * \return Most recent snapshot. ao2_cleanup() when done. + * \return \c NULL if channel isn't in cache. + */ +struct ast_bridge_snapshot *ast_bridge_snapshot_get_latest( + const char *bridge_id); + +/*! + * \brief Initialize the stasis bridging topic and message types + * \retval 0 on success + * \retval -1 on failure + */ +int ast_stasis_bridging_init(void); + +#if defined(__cplusplus) || defined(c_plusplus) +} +#endif + +#endif /* _STASIS_BRIDGING_H */ diff --git a/include/asterisk/stasis_bridging.h b/include/asterisk/stasis_bridging.h deleted file mode 100644 index 336d7dd5d..000000000 --- a/include/asterisk/stasis_bridging.h +++ /dev/null @@ -1,421 +0,0 @@ -/* - * Asterisk -- An open source telephony toolkit. - * - * Copyright (C) 2013 Digium, Inc. - * - * Kinsey Moore - * - * See http://www.asterisk.org for more information about - * the Asterisk project. Please do not directly contact - * any of the maintainers of this project for assistance; - * the project provides a web site, mailing lists and IRC - * channels for your use. - * - * This program is free software, distributed under the terms of - * the GNU General Public License Version 2. See the LICENSE file - * at the top of the source tree. - */ - -#ifndef _STASIS_BRIDGING_H -#define _STASIS_BRIDGING_H - -#if defined(__cplusplus) || defined(c_plusplus) -extern "C" { -#endif - -#include "asterisk/stringfields.h" -#include "asterisk/utils.h" -#include "asterisk/lock.h" -#include "asterisk/linkedlists.h" -#include "asterisk/channel.h" -#include "asterisk/bridging.h" -#include "asterisk/pbx.h" - -/*! - * \brief Structure that contains a snapshot of information about a bridge - */ -struct ast_bridge_snapshot { - AST_DECLARE_STRING_FIELDS( - /*! Immutable bridge UUID. */ - AST_STRING_FIELD(uniqueid); - /*! Bridge technology that is handling the bridge */ - AST_STRING_FIELD(technology); - /*! Bridge subclass that is handling the bridge */ - AST_STRING_FIELD(subclass); - ); - /*! AO2 container of bare channel uniqueid strings participating in the bridge. - * Allocated from ast_str_container_alloc() */ - struct ao2_container *channels; - /*! Bridge flags to tweak behavior */ - struct ast_flags feature_flags; - /*! Bridge capabilities */ - uint32_t capabilities; - /*! Number of channels participating in the bridge */ - unsigned int num_channels; - /*! Number of active channels in the bridge. */ - unsigned int num_active; -}; - -/*! - * \since 12 - * \brief Generate a snapshot of the bridge state. This is an ao2 object, so - * ao2_cleanup() to deallocate. - * - * \param bridge The bridge from which to generate a snapshot - * - * \retval AO2 refcounted snapshot on success - * \retval NULL on error - */ -struct ast_bridge_snapshot *ast_bridge_snapshot_create(struct ast_bridge *bridge); - -/*! - * \since 12 - * \brief Message type for \ref ast_bridge_snapshot. - * - * \retval Message type for \ref ast_bridge_snapshot. - */ -struct stasis_message_type *ast_bridge_snapshot_type(void); - -/*! - * \since 12 - * \brief A topic which publishes the events for a particular bridge. - * - * If the given \a bridge is \c NULL, ast_bridge_topic_all() is returned. - * - * \param bridge Bridge for which to get a topic or \c NULL. - * - * \retval Topic for bridge's events. - * \retval ast_bridge_topic_all() if \a bridge is \c NULL. - */ -struct stasis_topic *ast_bridge_topic(struct ast_bridge *bridge); - -/*! - * \since 12 - * \brief A topic which publishes the events for all bridges. - * \retval Topic for all bridge events. - */ -struct stasis_topic *ast_bridge_topic_all(void); - -/*! - * \since 12 - * \brief A caching topic which caches \ref ast_bridge_snapshot messages from - * ast_bridge_events_all(void). - * - * \retval Caching topic for all bridge events. - */ -struct stasis_caching_topic *ast_bridge_topic_all_cached(void); - -/*! - * \since 12 - * \brief Publish the state of a bridge - * - * \param bridge The bridge for which to publish state - */ -void ast_bridge_publish_state(struct ast_bridge *bridge); - -/*! \brief Message representing the merge of two bridges */ -struct ast_bridge_merge_message { - struct ast_bridge_snapshot *from; /*!< Bridge from which channels will be removed during the merge */ - struct ast_bridge_snapshot *to; /*!< Bridge to which channels will be added during the merge */ -}; - -/*! - * \since 12 - * \brief Message type for \ref ast_bridge_merge_message. - * - * \retval Message type for \ref ast_bridge_merge_message. - */ -struct stasis_message_type *ast_bridge_merge_message_type(void); - -/*! - * \since 12 - * \brief Publish a bridge merge - * - * \param to The bridge to which channels are being added - * \param from The bridge from which channels are being removed - */ -void ast_bridge_publish_merge(struct ast_bridge *to, struct ast_bridge *from); - -/*! - * \since 12 - * \brief Blob of data associated with a bridge. - * - * The \c blob is actually a JSON object of structured data. It has a "type" field - * which contains the type string describing this blob. - */ -struct ast_bridge_blob { - /*! Bridge blob is associated with (or NULL for global/all bridges) */ - struct ast_bridge_snapshot *bridge; - /*! Channel blob is associated with (may be NULL for some messages) */ - struct ast_channel_snapshot *channel; - /*! JSON blob of data */ - struct ast_json *blob; -}; - -/*! - * \since 12 - * \brief Message type for \ref channel enter bridge blob messages. - * - * \retval Message type for \ref channel enter bridge blob messages. - */ -struct stasis_message_type *ast_channel_entered_bridge_type(void); - -/*! - * \since 12 - * \brief Message type for \ref channel leave bridge blob messages. - * - * \retval Message type for \ref channel leave bridge blob messages. - */ -struct stasis_message_type *ast_channel_left_bridge_type(void); - -/*! - * \since 12 - * \brief Creates a \ref ast_bridge_blob message. - * - * The \a blob JSON object requires a \c "type" field describing the blob. It - * should also be treated as immutable and not modified after it is put into the - * message. - * - * \param bridge Channel blob is associated with, or NULL for global/all bridges. - * \param blob JSON object representing the data. - * \return \ref ast_bridge_blob message. - * \return \c NULL on error - */ -struct stasis_message *ast_bridge_blob_create(struct stasis_message_type *type, - struct ast_bridge *bridge, - struct ast_channel *chan, - struct ast_json *blob); - -/*! - * \since 12 - * \brief Publish a bridge channel enter event - * - * \param bridge The bridge a channel entered - * \param chan The channel that entered the bridge - */ -void ast_bridge_publish_enter(struct ast_bridge *bridge, struct ast_channel *chan); - -/*! - * \since 12 - * \brief Publish a bridge channel leave event - * - * \param bridge The bridge a channel left - * \param chan The channel that left the bridge - */ -void ast_bridge_publish_leave(struct ast_bridge *bridge, struct ast_channel *chan); - -/*! - * \brief Build a JSON object from a \ref ast_bridge_snapshot. - * \return JSON object representing bridge snapshot. - * \return \c NULL on error - */ -struct ast_json *ast_bridge_snapshot_to_json(const struct ast_bridge_snapshot *snapshot); - -/*! - * \brief Pair showing a bridge snapshot and a specific channel snapshot belonging to the bridge - */ -struct ast_bridge_channel_snapshot_pair { - struct ast_bridge_snapshot *bridge_snapshot; - struct ast_channel_snapshot *channel_snapshot; -}; - -/*! - * \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. - * - * \retval Message type for \ref ast_blind_transfer_message. - */ -struct stasis_message_type *ast_blind_transfer_type(void); - -/*! - * \brief Publish a blind transfer event - * - * \param is_external Whether the blind transfer was initiated externally (e.g. via AMI or native protocol) - * \param result The success or failure of the transfer - * \param to_transferee The bridge between the transferer and transferee plus the transferer channel - * \param context The destination context for the blind transfer - * \param exten The destination extension for the blind transfer - */ -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); - -enum ast_attended_transfer_dest_type { - /*! The transfer failed, so there is no appropriate final state */ - AST_ATTENDED_TRANSFER_DEST_FAIL, - /*! The transfer results in a single bridge remaining due to a merge or swap */ - AST_ATTENDED_TRANSFER_DEST_BRIDGE_MERGE, - /*! The transfer results in a channel or bridge running an application */ - AST_ATTENDED_TRANSFER_DEST_APP, - /*! The transfer results in both bridges remaining with a local channel linking them */ - AST_ATTENDED_TRANSFER_DEST_LINK, - /*! The transfer results in a threeway call between transferer, transferee, and transfer target */ - AST_ATTENDED_TRANSFER_DEST_THREEWAY, -}; - -/*! - * \brief Message representing attended transfer - */ -struct ast_attended_transfer_message { - /*! Result of the attended transfer */ - enum ast_transfer_result result; - /*! Indicates if the transfer was initiated externally*/ - int is_external; - /*! Bridge between transferer <-> transferee and the transferer channel in that bridge. May be NULL */ - struct ast_bridge_channel_snapshot_pair to_transferee; - /*! Bridge between transferer <-> transfer target and the transferer channel in that bridge. May be NULL */ - struct ast_bridge_channel_snapshot_pair to_transfer_target; - /*! Indicates the final state of the transfer */ - enum ast_attended_transfer_dest_type dest_type; - union { - /*! ID of the surviving bridge. Applicable for AST_ATTENDED_TRANSFER_DEST_BRIDGE_MERGE */ - char bridge[AST_UUID_STR_LEN]; - /*! Destination application of transfer. Applicable for AST_ATTENDED_TRANSFER_DEST_APP */ - char app[AST_MAX_APP]; - /*! Pair of local channels linking the bridges. Applicable for AST_ATTENDED_TRANSFER_DEST_LINK */ - struct ast_channel_snapshot *links[2]; - /*! Transferer channel and bridge that survived the transition to a threeway call. Applicable for AST_ATTENDED_TRANSFER_DEST_THREEWAY */ - struct ast_bridge_channel_snapshot_pair threeway; - } dest; -}; - -/*! - * \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. - * - * \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 - */ -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); - -/*! - * \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. - * - * \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. - */ -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); - -/*! - * \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 - * - * \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. - */ -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); - -/*! - * \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) - * - * \param is_external Indicates if the transfer was initiated externally - * \param result The result of the transfer. - * \param transferee The bridge between the transferer and transferees as well as the transferer channel from that bridge - * \param target The bridge between the transferer and transfer targets as well as the transferer channel from that bridge - * \param dest_app The application that the channel or bridge is running upon transfer completion. - */ -void ast_bridge_publish_attended_transfer_app(int is_external, enum ast_transfer_result result, - struct ast_bridge_channel_pair *transferee, struct ast_bridge_channel_pair *target, - const char *dest_app); - -/*! - * \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. - * - * \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. - */ -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]); - -/*! - * \brief Returns the most recent snapshot for the bridge. - * - * The returned pointer is AO2 managed, so ao2_cleanup() when you're done. - * - * \param bridge_id Uniqueid of the bridge for which to get the snapshot. - * \return Most recent snapshot. ao2_cleanup() when done. - * \return \c NULL if channel isn't in cache. - */ -struct ast_bridge_snapshot *ast_bridge_snapshot_get_latest( - const char *bridge_id); - -/*! - * \brief Initialize the stasis bridging topic and message types - * \retval 0 on success - * \retval -1 on failure - */ -int ast_stasis_bridging_init(void); - -#if defined(__cplusplus) || defined(c_plusplus) -} -#endif - -#endif /* _STASIS_BRIDGING_H */ -- cgit v1.2.3