diff options
Diffstat (limited to 'include/asterisk')
-rw-r--r-- | include/asterisk/bridging.h | 693 | ||||
-rw-r--r-- | include/asterisk/bridging_channel.h | 576 | ||||
-rw-r--r-- | include/asterisk/bridging_channel_internal.h | 156 | ||||
-rw-r--r-- | include/asterisk/bridging_internal.h | 129 | ||||
-rw-r--r-- | include/asterisk/bridging_technology.h | 16 | ||||
-rw-r--r-- | include/asterisk/channel.h | 12 | ||||
-rw-r--r-- | include/asterisk/features.h | 14 |
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); |