diff options
author | Matthew Jordan <mjordan@digium.com> | 2013-07-25 04:06:32 +0000 |
---|---|---|
committer | Matthew Jordan <mjordan@digium.com> | 2013-07-25 04:06:32 +0000 |
commit | cafc1158961f28ad54ebcdc5e042bf8094cbc620 (patch) | |
tree | 2e54d30ea5d8db7e007ff5c653c5acd4ed3fb649 /include/asterisk/bridge_channel.h | |
parent | 9d8a5ceb02f6559940bd94aaf163a544ce6e6f4c (diff) |
A great big renaming patch
This patch renames the bridging* files to bridge*. This may seem pedantic
and silly, but it fits better in line with current Asterisk naming conventions:
* channel is not "channeling"
* monitor is not "monitoring"
etc.
A bridge is an object. It is a first class citizen in Asterisk. "Bridging" is
the act of using a bridge on a set of channels - and the API that fulfills that
role is more than just the action.
(closes issue ASTERISK-22130)
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@395378 65c4cc65-6c06-0410-ace0-fbb531ad65f3
Diffstat (limited to 'include/asterisk/bridge_channel.h')
-rw-r--r-- | include/asterisk/bridge_channel.h | 590 |
1 files changed, 590 insertions, 0 deletions
diff --git a/include/asterisk/bridge_channel.h b/include/asterisk/bridge_channel.h new file mode 100644 index 000000000..5da1653fa --- /dev/null +++ b/include/asterisk/bridge_channel.h @@ -0,0 +1,590 @@ +/* + * Asterisk -- An open source telephony toolkit. + * + * Copyright (C) 2013 Digium, Inc. + * + * Joshua Colp <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 + * \page AstBridgeChannel Bridging Channel API + * + * An API that act on a channel in a bridge. Note that while the + * \ref ast_bridge_channel is owned by a channel, it should only be used + * by members of the bridging system. The only places where this API should + * be used is: + * \arg \ref AstBridging API itself + * \arg Bridge mixing technologies + * \arg Bridge sub-classes + * + * In general, anywhere else it is unsafe to use this API. Care should be + * taken when using this API to ensure that the locking order remains + * correct. The locking order must be: + * \arg The \ref \c ast_bridge + * \arg The \ref \c ast_bridge_channel + * \arg The \ref \c ast_channel + * + * \author Joshua Colp <jcolp@digium.com> + * \author Richard Mudgett <rmudgett@digium.com> + * \author Matt Jordan <mjordan@digium.com> + * + * See Also: + * \arg \ref AstBridging + * \arg \ref AstCREDITS + */ + +#ifndef _ASTERISK_BRIDGING_CHANNEL_H +#define _ASTERISK_BRIDGING_CHANNEL_H + +#if defined(__cplusplus) || defined(c_plusplus) +extern "C" { +#endif + +#include "asterisk/bridge_technology.h" + +/*! \brief State information about a bridged channel */ +enum bridge_channel_state { + /*! Waiting for a signal (Channel in the bridge) */ + BRIDGE_CHANNEL_STATE_WAIT = 0, + /*! Bridged channel was forced out and should be hung up (Bridge may dissolve.) */ + BRIDGE_CHANNEL_STATE_END, + /*! Bridged channel was forced out. Don't dissolve the bridge regardless */ + BRIDGE_CHANNEL_STATE_END_NO_DISSOLVE, +}; + +enum bridge_channel_thread_state { + /*! Bridge channel thread is idle/waiting. */ + BRIDGE_CHANNEL_THREAD_IDLE, + /*! Bridge channel thread is writing a normal/simple frame. */ + BRIDGE_CHANNEL_THREAD_SIMPLE, + /*! Bridge channel thread is processing a frame. */ + BRIDGE_CHANNEL_THREAD_FRAME, +}; + +struct ast_bridge; +struct ast_bridge_tech_optimizations; + + /*! + * \brief Structure that contains information regarding a channel in a bridge + */ +struct ast_bridge_channel { +/* BUGBUG cond is only here because of external party suspend/unsuspend support. */ + /*! Condition, used if we want to wake up a thread waiting on the bridged channel */ + ast_cond_t cond; + /*! Current bridged channel state */ + enum bridge_channel_state state; + /*! Asterisk channel participating in the bridge */ + struct ast_channel *chan; + /*! Asterisk channel we are swapping with (if swapping) */ + struct ast_channel *swap; + /*! + * \brief Bridge this channel is participating in + * + * \note The bridge pointer cannot change while the bridge or + * bridge_channel is locked. + */ + struct ast_bridge *bridge; + /*! + * \brief Bridge class private channel data. + * + * \note This information is added when the channel is pushed + * into the bridge and removed when it is pulled from the + * bridge. + */ + void *bridge_pvt; + /*! + * \brief Private information unique to the bridge technology. + * + * \note This information is added when the channel joins the + * bridge's technology and removed when it leaves the bridge's + * technology. + */ + void *tech_pvt; + /*! Thread handling the bridged channel (Needed by ast_bridge_depart) */ + pthread_t thread; + /* v-- These flags change while the bridge is locked or before the channel is in the bridge. */ + /*! TRUE if the channel is in a bridge. */ + unsigned int in_bridge:1; + /*! TRUE if the channel just joined the bridge. */ + unsigned int just_joined:1; + /*! TRUE if the channel is suspended from the bridge. */ + unsigned int suspended:1; + /*! TRUE if the channel must wait for an ast_bridge_depart to reclaim the channel. */ + unsigned int depart_wait:1; + /* ^-- These flags change while the bridge is locked or before the channel is in the bridge. */ + /*! Features structure for features that are specific to this channel */ + struct ast_bridge_features *features; + /*! Technology optimization parameters used by bridging technologies capable of + * optimizing based upon talk detection. */ + struct ast_bridge_tech_optimizations tech_args; + /*! Copy of read format used by chan before join */ + struct ast_format read_format; + /*! Copy of write format used by chan before join */ + struct ast_format write_format; + /*! Call ID associated with bridge channel */ + struct ast_callid *callid; + /*! A clone of the roles living on chan when the bridge channel joins the bridge. This may require some opacification */ + struct bridge_roles_datastore *bridge_roles; + /*! Linked list information */ + AST_LIST_ENTRY(ast_bridge_channel) entry; + /*! Queue of outgoing frames to the channel. */ + AST_LIST_HEAD_NOLOCK(, ast_frame) wr_queue; + /*! Pipe to alert thread when frames are put into the wr_queue. */ + int alert_pipe[2]; + /*! TRUE if the bridge channel thread is waiting on channels (needs to be atomically settable) */ + int waiting; + /*! + * \brief The bridge channel thread activity. + * + * \details Used by local channel optimization to determine if + * the thread is in an acceptable state to optimize. + * + * \note Needs to be atomically settable. + */ + enum bridge_channel_thread_state activity; +}; + +/*! + * \brief Try locking the bridge_channel. + * + * \param bridge_channel What to try locking + * + * \retval 0 on success. + * \retval non-zero on error. + */ +#define ast_bridge_channel_trylock(bridge_channel) _ast_bridge_channel_trylock(bridge_channel, __FILE__, __PRETTY_FUNCTION__, __LINE__, #bridge_channel) +static inline int _ast_bridge_channel_trylock(struct ast_bridge_channel *bridge_channel, const char *file, const char *function, int line, const char *var) +{ + return __ao2_trylock(bridge_channel, AO2_LOCK_REQ_MUTEX, file, function, line, var); +} + +/*! + * \brief Lock the bridge_channel. + * + * \param bridge_channel What to lock + * + * \return Nothing + */ +#define ast_bridge_channel_lock(bridge_channel) _ast_bridge_channel_lock(bridge_channel, __FILE__, __PRETTY_FUNCTION__, __LINE__, #bridge_channel) +static inline void _ast_bridge_channel_lock(struct ast_bridge_channel *bridge_channel, const char *file, const char *function, int line, const char *var) +{ + __ao2_lock(bridge_channel, AO2_LOCK_REQ_MUTEX, file, function, line, var); +} + +/*! + * \brief Unlock the bridge_channel. + * + * \param bridge_channel What to unlock + * + * \return Nothing + */ +#define ast_bridge_channel_unlock(bridge_channel) _ast_bridge_channel_unlock(bridge_channel, __FILE__, __PRETTY_FUNCTION__, __LINE__, #bridge_channel) +static inline void _ast_bridge_channel_unlock(struct ast_bridge_channel *bridge_channel, const char *file, const char *function, int line, const char *var) +{ + __ao2_unlock(bridge_channel, file, function, line, var); +} + +/*! + * \brief Lock the bridge associated with the bridge channel. + * \since 12.0.0 + * + * \param bridge_channel Channel that wants to lock the bridge. + * + * \details + * This is an upstream lock operation. The defined locking + * order is bridge then bridge_channel. + * + * \note On entry, neither the bridge nor bridge_channel is locked. + * + * \note The bridge_channel->bridge pointer changes because of a + * bridge-merge/channel-move operation between bridges. + * + * \return Nothing + */ +void ast_bridge_channel_lock_bridge(struct ast_bridge_channel *bridge_channel); + +/*! + * \brief Lets the bridging indicate when a bridge channel has stopped or started talking. + * + * \note All DSP functionality on the bridge has been pushed down to the lowest possible + * layer, which in this case is the specific bridging technology being used. Since it + * is necessary for the knowledge of which channels are talking to make its way up to the + * application, this function has been created to allow the bridging technology to communicate + * that information with the bridging core. + * + * \param bridge_channel The bridge channel that has either started or stopped talking. + * \param started_talking set to 1 when this indicates the channel has started talking set to 0 + * when this indicates the channel has stopped talking. + * + * \retval 0 on success. + * \retval -1 on error. + */ +int ast_bridge_channel_notify_talking(struct ast_bridge_channel *bridge_channel, int started_talking); + +/*! + * \brief Set bridge channel state to leave bridge (if not leaving already). + * + * \param bridge_channel Channel to change the state on + * \param new_state The new state to place the channel into + * + * Example usage: + * + * \code + * ast_bridge_channel_leave_bridge(bridge_channel, BRIDGE_CHANNEL_STATE_END); + * \endcode + * + * This places the channel pointed to by bridge_channel into the + * state BRIDGE_CHANNEL_STATE_END if it was + * BRIDGE_CHANNEL_STATE_WAIT before. + */ +void ast_bridge_channel_leave_bridge(struct ast_bridge_channel *bridge_channel, enum bridge_channel_state new_state); + +/*! + * \brief Set bridge channel state to leave bridge (if not leaving already). + * + * \param bridge_channel Channel to change the state on + * \param new_state The new state to place the channel into + * + * Example usage: + * + * \code + * ast_bridge_channel_leave_bridge(bridge_channel, BRIDGE_CHANNEL_STATE_END); + * \endcode + * + * This places the channel pointed to by bridge_channel into the + * state BRIDGE_CHANNEL_STATE_END if it was + * BRIDGE_CHANNEL_STATE_WAIT before. + */ +void ast_bridge_channel_leave_bridge_nolock(struct ast_bridge_channel *bridge_channel, enum bridge_channel_state new_state); + +/*! + * \brief Get the peer bridge channel of a two party bridge. + * \since 12.0.0 + * + * \param bridge_channel What to get the peer of. + * + * \note On entry, bridge_channel->bridge is already locked. + * + * \note This is an internal bridge function. + * + * \retval peer on success. + * \retval NULL no peer channel. + */ +struct ast_bridge_channel *ast_bridge_channel_peer(struct ast_bridge_channel *bridge_channel); + +/*! + * \brief Restore the formats of a bridge channel's channel to how they were before bridge_channel_internal_join + * \since 12.0.0 + * + * \param bridge_channel Channel to restore + */ +void ast_bridge_channel_restore_formats(struct ast_bridge_channel *bridge_channel); + +/*! + * \brief Adjust the bridge_channel's bridge merge inhibit request count. + * \since 12.0.0 + * + * \param bridge_channel What to operate on. + * \param request Inhibit request increment. + * (Positive to add requests. Negative to remove requests.) + * + * \note This API call is meant for internal bridging operations. + * + * \retval bridge adjusted merge inhibit with reference count. + */ +struct ast_bridge *ast_bridge_channel_merge_inhibit(struct ast_bridge_channel *bridge_channel, int request); + +/*! + * \internal + * \brief Update the linkedids for all channels in a bridge + * \since 12.0.0 + * + * \param bridge_channel The channel joining the bridge + * \param swap The channel being swapped out of the bridge. May be NULL. + * + * \note The bridge must be locked prior to calling this function. This should be called + * during a \ref bridge_channel_internal_push operation, typically by a sub-class of a bridge + */ +void ast_bridge_channel_update_linkedids(struct ast_bridge_channel *bridge_channel, struct ast_bridge_channel *swap); + +/*! + * \internal + * \brief Update the accountcodes for a channel entering a bridge + * \since 12.0.0 + * + * This function updates the accountcode and peeraccount on channels in two-party + * bridges. In multi-party bridges, peeraccount is not set - it doesn't make much sense - + * however accountcode propagation will still occur if the channel joining has an + * accountcode. + * + * \param bridge_channel The channel joining the bridge + * \param swap The channel being swapped out of the bridge. May be NULL. + * + * \note The bridge must be locked prior to calling this function. This should be called + * during a \ref bridge_channel_internal_push operation, typically by a sub-class of a bridge + */ +void ast_bridge_channel_update_accountcodes(struct ast_bridge_channel *bridge_channel, struct ast_bridge_channel *swap); + +/*! + * \brief Write a frame to the specified bridge_channel. + * \since 12.0.0 + * + * \param bridge_channel Channel to queue the frame. + * \param fr Frame to write. + * + * \retval 0 on success. + * \retval -1 on error. + */ +int ast_bridge_channel_queue_frame(struct ast_bridge_channel *bridge_channel, struct ast_frame *fr); + +/*! + * \brief Queue a control frame onto the bridge channel with data. + * \since 12.0.0 + * + * \param bridge_channel Which channel to queue the frame onto. + * \param control Type of control frame. + * \param data Frame payload data to pass. + * \param datalen Frame payload data length to pass. + * + * \retval 0 on success. + * \retval -1 on error. + */ +int ast_bridge_channel_queue_control_data(struct ast_bridge_channel *bridge_channel, enum ast_control_frame_type control, const void *data, size_t datalen); + +/*! + * \brief Write a control frame into the bridge with data. + * \since 12.0.0 + * + * \param bridge_channel Which channel is putting the frame into the bridge. + * \param control Type of control frame. + * \param data Frame payload data to pass. + * \param datalen Frame payload data length to pass. + * + * \retval 0 on success. + * \retval -1 on error. + */ +int ast_bridge_channel_write_control_data(struct ast_bridge_channel *bridge_channel, enum ast_control_frame_type control, const void *data, size_t datalen); + +/*! + * \brief Write a hold frame into the bridge. + * \since 12.0.0 + * + * \param bridge_channel Which channel is putting the hold into the bridge. + * \param moh_class The suggested music class for the other end to use. + * + * \retval 0 on success. + * \retval -1 on error. + */ +int ast_bridge_channel_write_hold(struct ast_bridge_channel *bridge_channel, const char *moh_class); + +/*! + * \brief Write an unhold frame into the bridge. + * \since 12.0.0 + * + * \param bridge_channel Which channel is putting the hold into the bridge. + * + * \retval 0 on success. + * \retval -1 on error. + */ +int ast_bridge_channel_write_unhold(struct ast_bridge_channel *bridge_channel); + +/*! + * \brief Run an application on the bridge channel. + * \since 12.0.0 + * + * \param bridge_channel Which channel to run the application on. + * \param app_name Dialplan application name. + * \param app_args Arguments for the application. (NULL tolerant) + * \param moh_class MOH class to request bridge peers to hear while application is running. + * NULL if no MOH. + * Empty if default MOH class. + * + * \note This is intended to be called by bridge hooks. + * + * \return Nothing + */ +void ast_bridge_channel_run_app(struct ast_bridge_channel *bridge_channel, const char *app_name, const char *app_args, const char *moh_class); + +/*! + * \brief Write a bridge action run application frame into the bridge. + * \since 12.0.0 + * + * \param bridge_channel Which channel is putting the frame into the bridge + * \param app_name Dialplan application name. + * \param app_args Arguments for the application. (NULL or empty for no arguments) + * \param moh_class MOH class to request bridge peers to hear while application is running. + * NULL if no MOH. + * Empty if default MOH class. + * + * \note This is intended to be called by bridge hooks. + * + * \retval 0 on success. + * \retval -1 on error. + */ +int ast_bridge_channel_write_app(struct ast_bridge_channel *bridge_channel, const char *app_name, const char *app_args, const char *moh_class); + +/*! + * \brief Queue a bridge action run application frame onto the bridge channel. + * \since 12.0.0 + * + * \param bridge_channel Which channel to put the frame onto + * \param app_name Dialplan application name. + * \param app_args Arguments for the application. (NULL or empty for no arguments) + * \param moh_class MOH class to request bridge peers to hear while application is running. + * NULL if no MOH. + * Empty if default MOH class. + * + * \note This is intended to be called by bridge hooks. + * + * \retval 0 on success. + * \retval -1 on error. + */ +int ast_bridge_channel_queue_app(struct ast_bridge_channel *bridge_channel, const char *app_name, const char *app_args, const char *moh_class); + +/*! + * \brief Custom interpretation of the playfile name. + * + * \param bridge_channel Which channel to play the file on + * \param playfile Sound filename to play. + * + * \return Nothing + */ +typedef void (*ast_bridge_custom_play_fn)(struct ast_bridge_channel *bridge_channel, const char *playfile); + +/*! + * \brief Play a file on the bridge channel. + * \since 12.0.0 + * + * \param bridge_channel Which channel to play the file on + * \param custom_play Call this function to play the playfile. (NULL if normal sound file to play) + * \param playfile Sound filename to play. + * \param moh_class MOH class to request bridge peers to hear while file is played. + * NULL if no MOH. + * Empty if default MOH class. + * + * \note This is intended to be called by bridge hooks. + * + * \return Nothing + */ +void ast_bridge_channel_playfile(struct ast_bridge_channel *bridge_channel, ast_bridge_custom_play_fn custom_play, const char *playfile, const char *moh_class); + +/*! + * \brief Write a bridge action play file frame into the bridge. + * \since 12.0.0 + * + * \param bridge_channel Which channel is putting the frame into the bridge + * \param custom_play Call this function to play the playfile. (NULL if normal sound file to play) + * \param playfile Sound filename to play. + * \param moh_class MOH class to request bridge peers to hear while file is played. + * NULL if no MOH. + * Empty if default MOH class. + * + * \note This is intended to be called by bridge hooks. + * + * \retval 0 on success. + * \retval -1 on error. + */ +int ast_bridge_channel_write_playfile(struct ast_bridge_channel *bridge_channel, ast_bridge_custom_play_fn custom_play, const char *playfile, const char *moh_class); + +/*! + * \brief Queue a bridge action play file frame onto the bridge channel. + * \since 12.0.0 + * + * \param bridge_channel Which channel to put the frame onto. + * \param custom_play Call this function to play the playfile. (NULL if normal sound file to play) + * \param playfile Sound filename to play. + * \param moh_class MOH class to request bridge peers to hear while file is played. + * NULL if no MOH. + * Empty if default MOH class. + * + * \note This is intended to be called by bridge hooks. + * + * \retval 0 on success. + * \retval -1 on error. + */ +int ast_bridge_channel_queue_playfile(struct ast_bridge_channel *bridge_channel, ast_bridge_custom_play_fn custom_play, const char *playfile, const char *moh_class); + +/*! + * \brief Custom callback run on a bridge channel. + * + * \param bridge_channel Which channel to operate on. + * \param payload Data to pass to the callback. (NULL if none). + * \param payload_size Size of the payload if payload is non-NULL. A number otherwise. + * + * \note The payload MUST NOT have any resources that need to be freed. + * + * \return Nothing + */ +typedef void (*ast_bridge_custom_callback_fn)(struct ast_bridge_channel *bridge_channel, const void *payload, size_t payload_size); + +/*! + * \brief Write a bridge action custom callback frame into the bridge. + * \since 12.0.0 + * + * \param bridge_channel Which channel is putting the frame into the bridge + * \param callback Custom callback run on a bridge channel. + * \param payload Data to pass to the callback. (NULL if none). + * \param payload_size Size of the payload if payload is non-NULL. A number otherwise. + * + * \note The payload MUST NOT have any resources that need to be freed. + * + * \note This is intended to be called by bridge hooks. + * + * \retval 0 on success. + * \retval -1 on error. + */ +int ast_bridge_channel_write_callback(struct ast_bridge_channel *bridge_channel, ast_bridge_custom_callback_fn callback, const void *payload, size_t payload_size); + +/*! + * \brief Queue a bridge action custom callback frame onto the bridge channel. + * \since 12.0.0 + * + * \param bridge_channel Which channel to put the frame onto. + * \param callback Custom callback run on a bridge channel. + * \param payload Data to pass to the callback. (NULL if none). + * \param payload_size Size of the payload if payload is non-NULL. A number otherwise. + * + * \note The payload MUST NOT have any resources that need to be freed. + * + * \note This is intended to be called by bridge hooks. + * + * \retval 0 on success. + * \retval -1 on error. + */ +int ast_bridge_channel_queue_callback(struct ast_bridge_channel *bridge_channel, ast_bridge_custom_callback_fn callback, const void *payload, size_t payload_size); + +/*! + * \brief Have a bridge channel park a channel in the bridge + * \since 12.0.0 + * + * \param bridge_channel Bridge channel performing the parking + * \param parkee_uuid Unique id of the channel we want to park + * \param parker_uuid Unique id of the channel parking the call + * \param app_data string indicating data used for park application (NULL allowed) + * + * \note This is intended to be called by bridge hooks. + * + * \retval 0 on success. + * \retval -1 on error. + */ +int ast_bridge_channel_write_park(struct ast_bridge_channel *bridge_channel, const char *parkee_uuid, + const char *parker_uuid, const char *app_data); + +#if defined(__cplusplus) || defined(c_plusplus) +} +#endif + +#endif /* _ASTERISK_BRIDGING_CHANNEL_H */ |