summaryrefslogtreecommitdiff
path: root/include
diff options
context:
space:
mode:
authorMatthew Jordan <mjordan@digium.com>2013-07-24 15:38:18 +0000
committerMatthew Jordan <mjordan@digium.com>2013-07-24 15:38:18 +0000
commitd91dc6d1a8a6e364d9edd6738c20ac5b8545db97 (patch)
tree6ed5d5a62860460e387714b9f334cc5d1fae779a /include
parent1f0ac51f49ca72d4f36490295ece83fb8e8fe151 (diff)
Perform the initial renaming of the Bridging API
This patch does the following: * It pulls out bridge_channel and puts it into its own translation unit * It adds public and protected headers for bridging_channel. Protected functions are appropriate only for the Bridging API and sub-classes of a bridge. (issue ASTERISK-22130) git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@395253 65c4cc65-6c06-0410-ace0-fbb531ad65f3
Diffstat (limited to 'include')
-rw-r--r--include/asterisk/bridging.h693
-rw-r--r--include/asterisk/bridging_channel.h576
-rw-r--r--include/asterisk/bridging_channel_internal.h156
-rw-r--r--include/asterisk/bridging_internal.h129
-rw-r--r--include/asterisk/bridging_technology.h16
-rw-r--r--include/asterisk/channel.h12
-rw-r--r--include/asterisk/features.h14
7 files changed, 902 insertions, 694 deletions
diff --git a/include/asterisk/bridging.h b/include/asterisk/bridging.h
index 0bba61434..bc16ae0bc 100644
--- a/include/asterisk/bridging.h
+++ b/include/asterisk/bridging.h
@@ -19,7 +19,7 @@
/*!
* \file
- * \brief Channel Bridging API
+ * \brief Bridging API
*
* \author Richard Mudgett <rmudgett@digium.com>
* \author Joshua Colp <jcolp@digium.com>
@@ -30,7 +30,7 @@
*/
/*!
- * \page AstBridging Channel Bridging API
+ * \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.
@@ -70,10 +70,15 @@ 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. */
@@ -88,160 +93,7 @@ enum ast_bridge_capability {
AST_BRIDGE_CAPABILITY_MULTIMIX = (1 << 4),
};
-/*! \brief State information about a bridged channel */
-enum ast_bridge_channel_state {
- /*! Waiting for a signal (Channel in the bridge) */
- AST_BRIDGE_CHANNEL_STATE_WAIT = 0,
- /*! Bridged channel was forced out and should be hung up (Bridge may dissolve.) */
- AST_BRIDGE_CHANNEL_STATE_END,
- /*! Bridged channel was forced out and should be hung up */
- AST_BRIDGE_CHANNEL_STATE_HANGUP,
-};
-
-enum ast_bridge_channel_thread_state {
- /*! Bridge channel thread is idle/waiting. */
- AST_BRIDGE_CHANNEL_THREAD_IDLE,
- /*! Bridge channel thread is writing a normal/simple frame. */
- AST_BRIDGE_CHANNEL_THREAD_SIMPLE,
- /*! Bridge channel thread is processing a frame. */
- AST_BRIDGE_CHANNEL_THREAD_FRAME,
-};
-
-struct ast_bridge_technology;
-struct ast_bridge;
-
-/*!
- * \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 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 ast_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 ast_bridge_channel_thread_state activity;
-};
-
-enum ast_bridge_action_type {
- /*! Bridged channel is to detect a feature hook */
- AST_BRIDGE_ACTION_FEATURE,
- /*! Bridged channel is to act on an interval hook */
- AST_BRIDGE_ACTION_INTERVAL,
- /*! Bridged channel is to send a DTMF stream out */
- AST_BRIDGE_ACTION_DTMF_STREAM,
- /*! Bridged channel is to indicate talking start */
- AST_BRIDGE_ACTION_TALKING_START,
- /*! Bridged channel is to indicate talking stop */
- AST_BRIDGE_ACTION_TALKING_STOP,
- /*! Bridge channel is to play the indicated sound file. */
- AST_BRIDGE_ACTION_PLAY_FILE,
- /*! Bridge channel is to run the indicated application. */
- AST_BRIDGE_ACTION_RUN_APP,
- /*! Bridge channel is to run the custom callback routine. */
- AST_BRIDGE_ACTION_CALLBACK,
- /*! Bridge channel is to get parked. */
- AST_BRIDGE_ACTION_PARK,
- /*! Bridge channel is to execute a blind transfer. */
- AST_BRIDGE_ACTION_BLIND_TRANSFER,
- /*! Bridge channel is to execute an attended transfer */
- AST_BRIDGE_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. */
- AST_BRIDGE_ACTION_DEFERRED_TECH_DESTROY = 1000,
- /*! Bridge deferred dissolving. */
- AST_BRIDGE_ACTION_DEFERRED_DISSOLVING,
-};
-
+/*! \brief Video source modes */
enum ast_bridge_video_mode_type {
/*! Video is not allowed in the bridge */
AST_BRIDGE_VIDEO_MODE_NONE = 0,
@@ -252,14 +104,14 @@ enum ast_bridge_video_mode_type {
AST_BRIDGE_VIDEO_MODE_TALKER_SRC,
};
-/*! This is used for both SINGLE_SRC mode to set what channel
+/*! \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;
};
-/*! This is used for both SINGLE_SRC_TALKER mode to set what channel
+/*! \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 */
@@ -270,6 +122,7 @@ struct ast_bridge_video_talker_src_data {
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. */
@@ -371,7 +224,7 @@ 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
- * ast_bridge_alloc() validity checking.
+ * bridge_alloc() validity checking.
*/
struct ast_bridge_methods {
/*! Bridge class name for log messages. */
@@ -390,6 +243,8 @@ struct ast_bridge_methods {
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 */
@@ -455,76 +310,10 @@ struct ast_bridge {
char uniqueid[AST_UUID_STR_LEN];
};
-/*!
- * \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 = ast_bridge_alloc(sizeof(struct ast_bridge_basic), &ast_bridge_basic_v_table);
- * bridge = ast_bridge_base_init(bridge, capabilities, flags);
- * bridge = ast_bridge_basic_init(bridge, dtmf_features);
- * bridge = ast_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 *ast_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 *ast_bridge_alloc(size_t size, const struct ast_bridge_methods *v_table);
-
/*! \brief Bridge base class virtual method table. */
extern struct ast_bridge_methods ast_bridge_base_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 = ast_bridge_alloc(sizeof(*bridge), &ast_bridge_base_v_table);
- * bridge = ast_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 *ast_bridge_base_init(struct ast_bridge *self, uint32_t capabilities, unsigned int flags);
-
-/*!
* \brief Create a new base class bridge
*
* \param capabilities The capabilities that we require to be used on the bridge
@@ -825,20 +614,6 @@ int ast_bridge_move(struct ast_bridge *dst_bridge, struct ast_bridge *src_bridge
void ast_bridge_merge_inhibit(struct ast_bridge *bridge, int request);
/*!
- * \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);
-
-/*!
* \brief Suspend a channel temporarily from a bridge
*
* \param bridge Bridge to suspend the channel from
@@ -943,101 +718,6 @@ enum ast_bridge_optimization ast_bridges_allow_optimization(struct ast_bridge *c
struct ast_bridge *peer_bridge);
/*!
- * \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 Set bridge channel state to leave bridge (if not leaving already) with no lock.
- *
- * \param bridge_channel Channel to change the state on
- * \param new_state The new state to place the channel into
- *
- * \note This API call is only meant to be used within the
- * bridging module and hook callbacks to request the channel
- * exit the bridge.
- *
- * \note This function assumes the bridge_channel is locked.
- */
-void ast_bridge_change_state_nolock(struct ast_bridge_channel *bridge_channel, enum ast_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_change_state(bridge_channel, AST_BRIDGE_CHANNEL_STATE_HANGUP);
- * \endcode
- *
- * This places the channel pointed to by bridge_channel into the
- * state AST_BRIDGE_CHANNEL_STATE_HANGUP if it was
- * AST_BRIDGE_CHANNEL_STATE_WAIT before.
- *
- * \note This API call is only meant to be used within the
- * bridging module and hook callbacks to request the channel
- * exit the bridge.
- */
-void ast_bridge_change_state(struct ast_bridge_channel *bridge_channel, enum ast_bridge_channel_state new_state);
-
-/*!
* \brief Put an action onto the specified bridge.
* \since 12.0.0
*
@@ -1053,37 +733,6 @@ void ast_bridge_change_state(struct ast_bridge_channel *bridge_channel, enum ast
int ast_bridge_queue_action(struct ast_bridge *bridge, struct ast_frame *action);
/*!
- * \brief Update the linkedid for all channels in a bridge
- * \since 12.0.0
- *
- * \param bridge The bridge to update the linkedids on
- * \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.
- * \note This API call is meant for internal bridging operations.
- */
-void ast_bridge_update_linkedids(struct ast_bridge *bridge, struct ast_bridge_channel *bridge_channel, struct ast_bridge_channel *swap);
-
-/*!
- * \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 The bridge to update the accountcodes in
- * \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.
- * \note This API call is meant for internal bridging operations.
- */
-void ast_bridge_update_accountcodes(struct ast_bridge *bridge, struct ast_bridge_channel *bridge_channel, struct ast_bridge_channel *swap);
-
-/*!
* \brief Queue the given frame to everyone else.
* \since 12.0.0
*
@@ -1100,319 +749,6 @@ void ast_bridge_update_accountcodes(struct ast_bridge *bridge, struct ast_bridge
int ast_bridge_queue_everyone_else(struct ast_bridge *bridge, struct ast_bridge_channel *bridge_channel, struct ast_frame *frame);
/*!
- * \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.
- *
- * \note This API call is meant for internal bridging operations.
- * \note BUGBUG This may get moved.
- */
-int ast_bridge_channel_queue_frame(struct ast_bridge_channel *bridge_channel, struct ast_frame *fr);
-
-/*!
- * \brief Used to queue an action frame onto a bridge channel and write an action frame into a bridge.
- * \since 12.0.0
- *
- * \param bridge_channel Which channel work with.
- * \param action Type of bridge action frame.
- * \param data Frame payload data to pass.
- * \param datalen Frame payload data length to pass.
- *
- * \retval 0 on success.
- * \retval -1 on error.
- */
-typedef int (*ast_bridge_channel_post_action_data)(struct ast_bridge_channel *bridge_channel, enum ast_bridge_action_type action, const void *data, size_t datalen);
-
-/*!
- * \brief Queue an action frame onto the bridge channel with data.
- * \since 12.0.0
- *
- * \param bridge_channel Which channel to queue the frame onto.
- * \param action Type of bridge action 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_action_data(struct ast_bridge_channel *bridge_channel, enum ast_bridge_action_type action, const void *data, size_t datalen);
-
-/*!
- * \brief Write an action frame into the bridge with data.
- * \since 12.0.0
- *
- * \param bridge_channel Which channel is putting the frame into the bridge.
- * \param action Type of bridge action 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_action_data(struct ast_bridge_channel *bridge_channel, enum ast_bridge_action_type action, const void *data, size_t datalen);
-
-/*!
- * \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);
-
-/*!
- * \brief Restore the formats of a bridge channel's channel to how they were before bridge_channel_join
- * \since 12.0.0
- *
- * \param bridge_channel Channel to restore
- */
-void ast_bridge_channel_restore_formats(struct ast_bridge_channel *bridge_channel);
-
-/*!
- * \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 Adjust the internal mixing sample rate of a bridge
* used during multimix mode.
*
@@ -1810,6 +1146,7 @@ struct ast_channel *ast_bridge_peer(struct ast_bridge *bridge, struct ast_channe
* \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
diff --git a/include/asterisk/bridging_channel.h b/include/asterisk/bridging_channel.h
new file mode 100644
index 000000000..dc559030c
--- /dev/null
+++ b/include/asterisk/bridging_channel.h
@@ -0,0 +1,576 @@
+/*
+ * Asterisk -- An open source telephony toolkit.
+ *
+ * Copyright (C) 2013 Digium, Inc.
+ *
+ * Joshua Colp <jcolp@digium.com>
+ * Richard Mudgett <rmudgett@digium.com>
+ * Matt Jordan <mjordan@digium.com>
+ *
+ * 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 Channel API
+ *
+ * An API that act on a channel in a bridge
+ *
+ * \author Joshua Colp <jcolp@digium.com>
+ * \author Richard Mudgett <rmudgett@digium.com>
+ * \author Matt Jordan <mjordan@digium.com>
+ *
+ * See Also:
+ * \ref bridging.h
+ * \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 ast_bridge_channel_state {
+ /*! Waiting for a signal (Channel in the bridge) */
+ AST_BRIDGE_CHANNEL_STATE_WAIT = 0,
+ /*! Bridged channel was forced out and should be hung up (Bridge may dissolve.) */
+ AST_BRIDGE_CHANNEL_STATE_END,
+ /*! Bridged channel was forced out and should be hung up */
+ AST_BRIDGE_CHANNEL_STATE_HANGUP,
+};
+
+enum ast_bridge_channel_thread_state {
+ /*! Bridge channel thread is idle/waiting. */
+ AST_BRIDGE_CHANNEL_THREAD_IDLE,
+ /*! Bridge channel thread is writing a normal/simple frame. */
+ AST_BRIDGE_CHANNEL_THREAD_SIMPLE,
+ /*! Bridge channel thread is processing a frame. */
+ AST_BRIDGE_CHANNEL_THREAD_FRAME,
+};
+
+/*! \brief Actions that can be taken on a channel in a bridge */
+enum ast_bridge_action_type {
+ /*! Bridged channel is to detect a feature hook */
+ AST_BRIDGE_ACTION_FEATURE,
+ /*! Bridged channel is to act on an interval hook */
+ AST_BRIDGE_ACTION_INTERVAL,
+ /*! Bridged channel is to send a DTMF stream out */
+ AST_BRIDGE_ACTION_DTMF_STREAM,
+ /*! Bridged channel is to indicate talking start */
+ AST_BRIDGE_ACTION_TALKING_START,
+ /*! Bridged channel is to indicate talking stop */
+ AST_BRIDGE_ACTION_TALKING_STOP,
+ /*! Bridge channel is to play the indicated sound file. */
+ AST_BRIDGE_ACTION_PLAY_FILE,
+ /*! Bridge channel is to run the indicated application. */
+ AST_BRIDGE_ACTION_RUN_APP,
+ /*! Bridge channel is to run the custom callback routine. */
+ AST_BRIDGE_ACTION_CALLBACK,
+ /*! Bridge channel is to get parked. */
+ AST_BRIDGE_ACTION_PARK,
+ /*! Bridge channel is to execute a blind transfer. */
+ AST_BRIDGE_ACTION_BLIND_TRANSFER,
+ /*! Bridge channel is to execute an attended transfer */
+ AST_BRIDGE_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. */
+ AST_BRIDGE_ACTION_DEFERRED_TECH_DESTROY = 1000,
+ /*! Bridge deferred dissolving. */
+ AST_BRIDGE_ACTION_DEFERRED_DISSOLVING,
+};
+
+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 ast_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 ast_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 Ask the bridged channel to leave the bridge it is currently in
+ *
+ * \param bridge_channel Channel to leave the bridge
+ */
+void ast_bridge_channel_leave_bridge(struct ast_bridge_channel *bridge_channel);
+
+/*!
+ * \brief Ask the bridged channel to leave the bridge it is currently in
+ *
+ * \param bridge_channel Channel to leave the bridge
+ *
+ * \note This function assumes the bridge_channel is locked.
+ */
+void ast_bridge_channel_leave_bridge_nolock(struct ast_bridge_channel *bridge_channel);
+
+/*!
+ * \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.
+ *
+ * \note This API call is meant for internal bridging operations.
+ * \note BUGBUG This may get moved.
+ */
+int ast_bridge_channel_queue_frame(struct ast_bridge_channel *bridge_channel, struct ast_frame *fr);
+
+/*!
+ * \brief Used to queue an action frame onto a bridge channel and write an action frame into a bridge.
+ * \since 12.0.0
+ *
+ * \param bridge_channel Which channel work with.
+ * \param action Type of bridge action frame.
+ * \param data Frame payload data to pass.
+ * \param datalen Frame payload data length to pass.
+ *
+ * \retval 0 on success.
+ * \retval -1 on error.
+ */
+typedef int (*ast_bridge_channel_post_action_data)(struct ast_bridge_channel *bridge_channel, enum ast_bridge_action_type action, const void *data, size_t datalen);
+
+/*!
+ * \brief Queue an action frame onto the bridge channel with data.
+ * \since 12.0.0
+ *
+ * \param bridge_channel Which channel to queue the frame onto.
+ * \param action Type of bridge action 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_action_data(struct ast_bridge_channel *bridge_channel, enum ast_bridge_action_type action, const void *data, size_t datalen);
+
+/*!
+ * \brief Write an action frame into the bridge with data.
+ * \since 12.0.0
+ *
+ * \param bridge_channel Which channel is putting the frame into the bridge.
+ * \param action Type of bridge action 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_action_data(struct ast_bridge_channel *bridge_channel, enum ast_bridge_action_type action, const void *data, size_t datalen);
+
+/*!
+ * \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);
+
+/*!
+ * \brief Restore the formats of a bridge channel's channel to how they were before bridge_channel_join
+ * \since 12.0.0
+ *
+ * \param bridge_channel Channel to restore
+ */
+void ast_bridge_channel_restore_formats(struct ast_bridge_channel *bridge_channel);
+
+/*!
+ * \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);
+
+#if defined(__cplusplus) || defined(c_plusplus)
+}
+#endif
+
+#endif /* _ASTERISK_BRIDGING_CHANNEL_H */ \ No newline at end of file
diff --git a/include/asterisk/bridging_channel_internal.h b/include/asterisk/bridging_channel_internal.h
new file mode 100644
index 000000000..8f5eb4dd8
--- /dev/null
+++ b/include/asterisk/bridging_channel_internal.h
@@ -0,0 +1,156 @@
+/*
+ * Asterisk -- An open source telephony toolkit.
+ *
+ * Copyright (C) 2013 Digium, Inc.
+ *
+ * Matt Jordan <mjordan@digium.com>
+ *
+ * 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 Channel API
+ *
+ * \author Matt Jordan <mjordan@digium.com>
+ *
+ * A private API to manipulate channels in a bridge. These can be called on a channel in
+ * a bridge by the bridging API, but should not be called by external consumers of the
+ * Bridging API.
+ *
+ * See Also:
+ * \arg \ref AstCREDITS
+ */
+
+#ifndef _ASTERISK_PRIVATE_BRIDGING_CHANNEL_H
+#define _ASTERISK_PRIVATE_BRIDGING_CHANNEL_H
+
+struct blind_transfer_data {
+ char exten[AST_MAX_EXTENSION];
+ char context[AST_MAX_CONTEXT];
+};
+
+/*!
+ * \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 *bridge_channel_merge_inhibit(struct ast_bridge_channel *bridge_channel, int request);
+
+/*!
+ * \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_pull(struct ast_bridge_channel *bridge_channel);
+
+/*!
+ * \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_push(struct ast_bridge_channel *bridge_channel);
+
+void bridge_channel_join(struct ast_bridge_channel *bridge_channel);
+
+void bridge_channel_suspend_nolock(struct ast_bridge_channel *bridge_channel);
+
+void bridge_channel_unsuspend_nolock(struct ast_bridge_channel *bridge_channel);
+
+/*!
+ * \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_push operation, typically by a sub-class of a bridge
+ */
+void 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_push operation, typically by a sub-class of a bridge
+ */
+void bridge_channel_update_accountcodes(struct ast_bridge_channel *bridge_channel, struct ast_bridge_channel *swap);
+
+
+/*!
+ * \brief Set bridge channel state to leave bridge (if not leaving already) with no lock.
+ *
+ * \param bridge_channel Channel to change the state on
+ * \param new_state The new state to place the channel into
+ *
+ * \note This API call is only meant to be used within the
+ * bridging module and hook callbacks to request the channel
+ * exit the bridge.
+ *
+ * \note This function assumes the bridge_channel is locked.
+ */
+void ast_bridge_change_state_nolock(struct ast_bridge_channel *bridge_channel, enum ast_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_change_state(bridge_channel, AST_BRIDGE_CHANNEL_STATE_HANGUP);
+ * \endcode
+ *
+ * This places the channel pointed to by bridge_channel into the
+ * state AST_BRIDGE_CHANNEL_STATE_HANGUP if it was
+ * AST_BRIDGE_CHANNEL_STATE_WAIT before.
+ *
+ * \note This API call is only meant to be used within the
+ * bridging module and hook callbacks to request the channel
+ * exit the bridge.
+ */
+void ast_bridge_change_state(struct ast_bridge_channel *bridge_channel, enum ast_bridge_channel_state new_state);
+
+#endif /* _ASTERISK_PRIVATE_BRIDGING_H */ \ No newline at end of file
diff --git a/include/asterisk/bridging_internal.h b/include/asterisk/bridging_internal.h
index 132c42b76..cafa693f5 100644
--- a/include/asterisk/bridging_internal.h
+++ b/include/asterisk/bridging_internal.h
@@ -20,6 +20,11 @@
* \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 <mmichelson@digium.com>
*
* See Also:
@@ -33,6 +38,72 @@ 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
@@ -47,7 +118,7 @@ struct ast_bridge_channel;
* \retval 0 on success.
* \retval -1 on failure.
*/
-int bridge_move_do(struct ast_bridge *dst_bridge, struct ast_bridge_channel *bridge_channel,
+int bridge_do_move(struct ast_bridge *dst_bridge, struct ast_bridge_channel *bridge_channel,
int attempt_recovery, unsigned int optimized);
/*!
@@ -68,7 +139,7 @@ int bridge_move_do(struct ast_bridge *dst_bridge, struct ast_bridge_channel *bri
* This moves the channels in src_bridge into the bridge pointed
* to by dst_bridge.
*/
-void bridge_merge_do(struct ast_bridge *dst_bridge, struct ast_bridge *src_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);
/*!
@@ -83,6 +154,58 @@ void bridge_merge_do(struct ast_bridge *dst_bridge, struct ast_bridge *src_bridg
* \retval bridge_channel if channel is in the bridge.
* \retval NULL if not in bridge.
*/
-struct ast_bridge_channel *find_bridge_channel(struct ast_bridge *bridge, struct ast_channel *chan);
+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_push and
+ * bridge_channel_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_technology.h b/include/asterisk/bridging_technology.h
index 4e680679e..e037b7490 100644
--- a/include/asterisk/bridging_technology.h
+++ b/include/asterisk/bridging_technology.h
@@ -42,6 +42,22 @@ enum ast_bridge_preference {
};
/*!
+ * \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 {
diff --git a/include/asterisk/channel.h b/include/asterisk/channel.h
index d8db4705d..f6cdd4e62 100644
--- a/include/asterisk/channel.h
+++ b/include/asterisk/channel.h
@@ -4385,4 +4385,16 @@ int ast_channel_suppress(struct ast_channel *chan, unsigned int direction, enum
*/
int ast_channel_unsuppress(struct ast_channel *chan, unsigned int direction, enum ast_frame_type frametype);
+/*!
+ * \brief Simulate a DTMF end on a broken bridge channel.
+ *
+ * \param chan Channel sending DTMF that has not ended.
+ * \param digit DTMF digit to stop.
+ * \param start DTMF digit start time.
+ * \param why Reason bridge broken.
+ *
+ * \return Nothing
+ */
+void ast_channel_end_dtmf(struct ast_channel *chan, char digit, struct timeval start, const char *why);
+
#endif /* _ASTERISK_CHANNEL_H */
diff --git a/include/asterisk/features.h b/include/asterisk/features.h
index 162a7fc37..96eec98c8 100644
--- a/include/asterisk/features.h
+++ b/include/asterisk/features.h
@@ -146,25 +146,13 @@ int ast_masq_park_call(struct ast_channel *park_me, struct ast_channel *parker,
*/
int ast_masq_park_call_exten(struct ast_channel *park_me, struct ast_channel *parker, const char *park_exten, const char *park_context, int timeout, int *extout);
-/*!
+/*!
* \brief Determine if parking extension exists in a given context
* \retval 0 if extension does not exist
* \retval 1 if extension does exist
*/
int ast_parking_ext_valid(const char *exten_str, struct ast_channel *chan, const char *context);
-/*!
- * \brief Simulate a DTMF end on a broken bridge channel.
- *
- * \param chan Channel sending DTMF that has not ended.
- * \param digit DTMF digit to stop.
- * \param start DTMF digit start time.
- * \param why Reason bridge broken.
- *
- * \return Nothing
- */
-void ast_bridge_end_dtmf(struct ast_channel *chan, char digit, struct timeval start, const char *why);
-
/*! \brief Bridge a call, optionally allowing redirection */
int ast_bridge_call(struct ast_channel *chan, struct ast_channel *peer,struct ast_bridge_config *config);