Asterisk - The Open Source Telephony Project GIT-master-754dea3
All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Macros Modules Pages
Data Structures | Macros | Enumerations | Functions | Variables
bridge.c File Reference

Bridging API. More...

#include "asterisk.h"
#include "asterisk/logger.h"
#include "asterisk/channel.h"
#include "asterisk/options.h"
#include "asterisk/utils.h"
#include "asterisk/lock.h"
#include "asterisk/linkedlists.h"
#include "asterisk/bridge.h"
#include "asterisk/bridge_internal.h"
#include "asterisk/bridge_channel_internal.h"
#include "asterisk/bridge_features.h"
#include "asterisk/bridge_basic.h"
#include "asterisk/bridge_technology.h"
#include "asterisk/bridge_channel.h"
#include "asterisk/bridge_after.h"
#include "asterisk/stasis_bridges.h"
#include "asterisk/stasis_channels.h"
#include "asterisk/stasis_cache_pattern.h"
#include "asterisk/app.h"
#include "asterisk/file.h"
#include "asterisk/module.h"
#include "asterisk/astobj2.h"
#include "asterisk/pbx.h"
#include "asterisk/test.h"
#include "asterisk/_private.h"
#include "asterisk/heap.h"
#include "asterisk/say.h"
#include "asterisk/timing.h"
#include "asterisk/stringfields.h"
#include "asterisk/musiconhold.h"
#include "asterisk/features.h"
#include "asterisk/cli.h"
#include "asterisk/parking.h"
#include "asterisk/core_local.h"
#include "asterisk/core_unreal.h"
#include "asterisk/causes.h"
Include dependency graph for bridge.c:

Go to the source code of this file.

Data Structures

struct  bridge_channel_impart_cond
 Internal bridge impart wait condition and associated conditional. More...
 
struct  bridge_channel_impart_ds_head
 
struct  bridge_manager_controller
 
struct  bridge_manager_request
 
struct  bridge_technologies
 
struct  merge_direction
 
struct  tech_deferred_destroy
 

Macros

#define ATTENDEDTRANSFER   "ATTENDEDTRANSFER"
 
#define BLINDTRANSFER   "BLINDTRANSFER"
 
#define BRIDGE_ARRAY_GROW   32
 
#define BRIDGE_ARRAY_START   128
 
#define BRIDGE_LOCK_ONE_OR_BOTH(b1, b2)
 
#define FORMAT_HDR   "%-36s %-36s %5s %-15s %-15s %s\n"
 
#define FORMAT_HDR   "%-20s %-20s %8s %s\n"
 
#define FORMAT_ROW   "%-36s %-36s %5u %-15s %-15s %s\n"
 
#define FORMAT_ROW   "%-20s %-20s %8u %s\n"
 
#define MAX_BRIDGEPEER_CHANS   (10 + 1)
 
#define UPDATE_BRIDGE_VARS_GET(chan, name, pvtid)
 

Enumerations

enum  bridge_allow_merge { MERGE_PROHIBITED , MERGE_NOT_ENOUGH_CHANNELS , MERGE_NO_MULTIMIX , MERGE_ALLOWED }
 
enum  bridge_allow_swap { SWAP_PROHIBITED , SWAP_TO_CHAN_BRIDGE , SWAP_TO_PEER_BRIDGE }
 

Functions

int __ast_bridge_technology_register (struct ast_bridge_technology *technology, struct ast_module *module)
 Register a bridge technology for use. More...
 
int ast_bridge_add_channel (struct ast_bridge *bridge, struct ast_channel *chan, struct ast_bridge_features *features, int play_tone, const char *xfersound)
 Add an arbitrary channel to a bridge. More...
 
struct ast_bridgeast_bridge_base_new (uint32_t capabilities, unsigned int flags, const char *creator, const char *name, const char *id)
 Create a new base class bridge. More...
 
int ast_bridge_depart (struct ast_channel *chan)
 Depart a channel from a bridge. More...
 
int ast_bridge_destroy (struct ast_bridge *bridge, int cause)
 Destroy a bridge. More...
 
int ast_bridge_dtmf_hook (struct ast_bridge_features *features, const char *dtmf, ast_bridge_hook_callback callback, void *hook_pvt, ast_bridge_hook_pvt_destructor destructor, enum ast_bridge_hook_remove_flags remove_flags)
 Attach a DTMF hook to a bridge features structure. More...
 
void ast_bridge_features_cleanup (struct ast_bridge_features *features)
 Clean up the contents of a bridge features structure. More...
 
void ast_bridge_features_destroy (struct ast_bridge_features *features)
 Destroy an allocated bridge features struct. More...
 
int ast_bridge_features_do (enum ast_bridge_builtin_feature feature, struct ast_bridge_channel *bridge_channel, void *hook_pvt)
 Invoke a built in feature hook now. More...
 
int ast_bridge_features_enable (struct ast_bridge_features *features, enum ast_bridge_builtin_feature feature, const char *dtmf, void *config, ast_bridge_hook_pvt_destructor destructor, enum ast_bridge_hook_remove_flags remove_flags)
 Enable a built in feature on a bridge features structure. More...
 
int ast_bridge_features_init (struct ast_bridge_features *features)
 Initialize bridge features structure. More...
 
int ast_bridge_features_limits_construct (struct ast_bridge_features_limits *limits)
 Constructor function for ast_bridge_features_limits. More...
 
void ast_bridge_features_limits_destroy (struct ast_bridge_features_limits *limits)
 Destructor function for ast_bridge_features_limits. More...
 
void ast_bridge_features_merge (struct ast_bridge_features *into, const struct ast_bridge_features *from)
 Merge one ast_bridge_features into another. More...
 
struct ast_bridge_featuresast_bridge_features_new (void)
 Allocate a new bridge features struct. More...
 
int ast_bridge_features_register (enum ast_bridge_builtin_feature feature, ast_bridge_hook_callback callback, const char *dtmf)
 Register a handler for a built in feature. More...
 
void ast_bridge_features_remove (struct ast_bridge_features *features, enum ast_bridge_hook_remove_flags remove_flags)
 Remove marked bridge channel feature hooks. More...
 
void ast_bridge_features_set_flag (struct ast_bridge_features *features, unsigned int flag)
 Set a flag on a bridge channel features structure. More...
 
int ast_bridge_features_set_limits (struct ast_bridge_features *features, struct ast_bridge_features_limits *limits, enum ast_bridge_hook_remove_flags remove_flags)
 Limit the amount of time a channel may stay in the bridge and optionally play warning messages as time runs out. More...
 
int ast_bridge_features_unregister (enum ast_bridge_builtin_feature feature)
 Unregister a handler for a built in feature. More...
 
struct ast_bridgeast_bridge_find_by_id (const char *bridge_id)
 Find bridge by id. More...
 
int ast_bridge_hangup_hook (struct ast_bridge_features *features, ast_bridge_hook_callback callback, void *hook_pvt, ast_bridge_hook_pvt_destructor destructor, enum ast_bridge_hook_remove_flags remove_flags)
 Attach a hangup hook to a bridge features structure. More...
 
int ast_bridge_impart (struct ast_bridge *bridge, struct ast_channel *chan, struct ast_channel *swap, struct ast_bridge_features *features, enum ast_bridge_impart_flags flags)
 Impart a channel to a bridge (non-blocking) More...
 
int ast_bridge_interval_hook (struct ast_bridge_features *features, enum ast_bridge_hook_timer_option flags, unsigned int interval, ast_bridge_hook_callback callback, void *hook_pvt, ast_bridge_hook_pvt_destructor destructor, enum ast_bridge_hook_remove_flags remove_flags)
 Attach an interval hook to a bridge features structure. More...
 
int ast_bridge_interval_register (enum ast_bridge_builtin_interval interval, ast_bridge_builtin_set_limits_fn callback)
 Register a handler for a built in interval feature. More...
 
int ast_bridge_interval_unregister (enum ast_bridge_builtin_interval interval)
 Unregisters a handler for a built in interval feature. More...
 
int ast_bridge_is_video_src (struct ast_bridge *bridge, struct ast_channel *chan)
 Determine if a channel is a video src for the bridge. More...
 
int ast_bridge_join (struct ast_bridge *bridge, struct ast_channel *chan, struct ast_channel *swap, struct ast_bridge_features *features, struct ast_bridge_tech_optimizations *tech_args, enum ast_bridge_join_flags flags)
 Join a channel to a bridge (blocking) More...
 
int ast_bridge_join_hook (struct ast_bridge_features *features, ast_bridge_hook_callback callback, void *hook_pvt, ast_bridge_hook_pvt_destructor destructor, enum ast_bridge_hook_remove_flags remove_flags)
 Attach a bridge channel join hook to a bridge features structure. More...
 
int ast_bridge_kick (struct ast_bridge *bridge, struct ast_channel *chan)
 Kick a channel from a bridge. More...
 
int ast_bridge_leave_hook (struct ast_bridge_features *features, ast_bridge_hook_callback callback, void *hook_pvt, ast_bridge_hook_pvt_destructor destructor, enum ast_bridge_hook_remove_flags remove_flags)
 Attach a bridge channel leave hook to a bridge features structure. More...
 
int ast_bridge_merge (struct ast_bridge *dst_bridge, struct ast_bridge *src_bridge, int merge_best_direction, struct ast_channel **kick_me, unsigned int num_kick)
 Merge two bridges together. More...
 
void ast_bridge_merge_inhibit (struct ast_bridge *bridge, int request)
 Adjust the bridge merge inhibit request count. More...
 
int ast_bridge_move (struct ast_bridge *dst_bridge, struct ast_bridge *src_bridge, struct ast_channel *chan, struct ast_channel *swap, int attempt_recovery)
 Move a channel from one bridge to another. More...
 
int ast_bridge_move_hook (struct ast_bridge_features *features, ast_bridge_move_indicate_callback callback, void *hook_pvt, ast_bridge_hook_pvt_destructor destructor, enum ast_bridge_hook_remove_flags remove_flags)
 Attach a bridge channel move detection hook to a bridge features structure. More...
 
void ast_bridge_notify_masquerade (struct ast_channel *chan)
 Notify bridging that this channel was just masqueraded. More...
 
int ast_bridge_number_video_src (struct ast_bridge *bridge)
 Returns the number of video sources currently active in the bridge. More...
 
struct ast_channelast_bridge_peer (struct ast_bridge *bridge, struct ast_channel *chan)
 Get the channel's bridge peer only if the bridge is two-party. More...
 
struct ast_channelast_bridge_peer_nolock (struct ast_bridge *bridge, struct ast_channel *chan)
 Get the channel's bridge peer only if the bridge is two-party. More...
 
struct ao2_containerast_bridge_peers (struct ast_bridge *bridge)
 Get a container of all channels in the bridge. More...
 
struct ao2_containerast_bridge_peers_nolock (struct ast_bridge *bridge)
 Get a container of all channels in the bridge. More...
 
int ast_bridge_queue_action (struct ast_bridge *bridge, struct ast_frame *action)
 Put an action onto the specified bridge. More...
 
int ast_bridge_remove (struct ast_bridge *bridge, struct ast_channel *chan)
 Remove a channel from a bridge. More...
 
void ast_bridge_remove_video_src (struct ast_bridge *bridge, struct ast_channel *chan)
 remove a channel as a source of video for the bridge. More...
 
void ast_bridge_set_binaural_active (struct ast_bridge *bridge, unsigned int binaural_active)
 Activates the use of binaural signals in a conference bridge. More...
 
void ast_bridge_set_internal_sample_rate (struct ast_bridge *bridge, unsigned int sample_rate)
 Adjust the internal mixing sample rate of a bridge used during multimix mode. More...
 
void ast_bridge_set_maximum_sample_rate (struct ast_bridge *bridge, unsigned int sample_rate)
 Adjust the maximum mixing sample rate of a bridge used during multimix mode. More...
 
void ast_bridge_set_mixing_interval (struct ast_bridge *bridge, unsigned int mixing_interval)
 Adjust the internal mixing interval of a bridge used during multimix mode. More...
 
void ast_bridge_set_remb_estimated_bitrate (struct ast_bridge *bridge, float estimated_bitrate)
 Force the REMB report estimated bitrate to a specific max value. More...
 
void ast_bridge_set_remb_send_interval (struct ast_bridge *bridge, unsigned int remb_send_interval)
 Set the interval at which a combined REMB frame will be sent to video sources. More...
 
void ast_bridge_set_send_sdp_label (struct ast_bridge *bridge, unsigned int send_sdp_label)
 Controls whether to send a "label" attribute in each stream in an SDP. More...
 
void ast_bridge_set_sfu_video_mode (struct ast_bridge *bridge)
 Set the bridge to be a selective forwarding unit. More...
 
void ast_bridge_set_single_src_video_mode (struct ast_bridge *bridge, struct ast_channel *video_src_chan)
 Set a bridge to feed a single video source to all participants. More...
 
void ast_bridge_set_talker_src_video_mode (struct ast_bridge *bridge)
 Set the bridge to pick the strongest talker supporting video as the single source video feed. More...
 
void ast_bridge_set_transfer_variables (struct ast_channel *chan, const char *value, int attended)
 Set the relevant transfer variables for a single channel. More...
 
void ast_bridge_set_video_update_discard (struct ast_bridge *bridge, unsigned int video_update_discard)
 Set the amount of time to discard subsequent video updates after a video update has been sent. More...
 
int ast_bridge_suspend (struct ast_bridge *bridge, struct ast_channel *chan)
 Suspend a channel temporarily from a bridge. More...
 
int ast_bridge_talk_detector_hook (struct ast_bridge_features *features, ast_bridge_talking_indicate_callback callback, void *hook_pvt, ast_bridge_hook_pvt_destructor destructor, enum ast_bridge_hook_remove_flags remove_flags)
 Attach a bridge channel talk detection hook to a bridge features structure. More...
 
void ast_bridge_technology_suspend (struct ast_bridge_technology *technology)
 Suspend a bridge technology from consideration. More...
 
int ast_bridge_technology_unregister (struct ast_bridge_technology *technology)
 Unregister a bridge technology from use. More...
 
void ast_bridge_technology_unsuspend (struct ast_bridge_technology *technology)
 Unsuspend a bridge technology. More...
 
struct ast_bridgeast_bridge_transfer_acquire_bridge (struct ast_channel *chan)
 Acquire the channel's bridge for transfer purposes. More...
 
enum ast_transfer_result ast_bridge_transfer_attended (struct ast_channel *to_transferee, struct ast_channel *to_transfer_target)
 Attended transfer. More...
 
enum ast_transfer_result ast_bridge_transfer_blind (int is_external, struct ast_channel *transferer, const char *exten, const char *context, transfer_channel_cb new_channel_cb, void *user_data)
 Blind transfer target to the extension and context provided. More...
 
int ast_bridge_unreal_optimize_out (struct ast_channel *chan, struct ast_channel *peer, struct ast_unreal_pvt *pvt)
 Check and optimize out the unreal channels between bridges. More...
 
int ast_bridge_unsuspend (struct ast_bridge *bridge, struct ast_channel *chan)
 Unsuspend a channel from a bridge. More...
 
void ast_bridge_update_talker_src_video_mode (struct ast_bridge *bridge, struct ast_channel *chan, int talker_energy, int is_keyframe)
 Update information about talker energy for talker src video mode. More...
 
void ast_bridge_vars_set (struct ast_channel *chan, const char *name, const char *pvtid)
 Sets BRIDGECHANNEL and BRIDGEPVTCALLID for a channel. More...
 
const char * ast_bridge_video_mode_to_string (enum ast_bridge_video_mode_type video_mode)
 Converts an enum representation of a bridge video mode to string. More...
 
struct ao2_containerast_bridges (void)
 Returns the global bridges container. More...
 
enum ast_bridge_optimization ast_bridges_allow_optimization (struct ast_bridge *chan_bridge, struct ast_bridge *peer_bridge)
 Determine if bridges allow for optimization to occur betweem them. More...
 
int ast_bridging_init (void)
 Initialize the bridging system. More...
 
void ast_brige_set_remb_behavior (struct ast_bridge *bridge, enum ast_bridge_video_sfu_remb_behavior behavior)
 Set the REMB report generation behavior on a bridge. More...
 
static enum ast_transfer_result attended_transfer_bridge (struct ast_channel *chan1, struct ast_channel *chan2, struct ast_bridge *bridge1, struct ast_bridge *bridge2, struct ast_attended_transfer_message *transfer_msg)
 Perform an attended transfer of a bridge. More...
 
static enum ast_transfer_result blind_transfer_bridge (int is_external, struct ast_channel *transferer, struct ast_bridge *bridge, const char *exten, const char *context, struct ast_channel *transferee, transfer_channel_cb new_channel_cb, struct transfer_channel_data *user_data_wrapper, struct ast_blind_transfer_message *transfer_message)
 
static void bridge_action_bridge (struct ast_bridge *bridge, struct ast_frame *action)
 
struct ast_bridgebridge_alloc (size_t size, const struct ast_bridge_methods *v_table)
 
static int bridge_allows_optimization (struct ast_bridge *bridge)
 
static void bridge_base_destroy (struct ast_bridge *self)
 
static void bridge_base_dissolving (struct ast_bridge *self)
 
static int bridge_base_get_merge_priority (struct ast_bridge *self)
 
struct ast_bridgebridge_base_init (struct ast_bridge *self, uint32_t capabilities, unsigned int flags, const char *creator, const char *name, const char *id)
 Initialize the base class of the bridge. More...
 
static void bridge_base_notify_masquerade (struct ast_bridge *self, struct ast_bridge_channel *bridge_channel)
 
static void bridge_base_pull (struct ast_bridge *self, struct ast_bridge_channel *bridge_channel)
 
static int bridge_base_push (struct ast_bridge *self, struct ast_bridge_channel *bridge_channel, struct ast_bridge_channel *swap)
 
static int bridge_base_push_peek (struct ast_bridge *self, struct ast_bridge_channel *bridge_channel, struct ast_bridge_channel *swap)
 
static void bridge_channel_change_bridge (struct ast_bridge_channel *bridge_channel, struct ast_bridge *new_bridge)
 
static void bridge_channel_complete_join (struct ast_bridge *bridge, struct ast_bridge_channel *bridge_channel)
 
static void * bridge_channel_depart_thread (void *data)
 Thread responsible for imparted bridged channels to be departed. More...
 
static int bridge_channel_impart_add (struct ast_channel *chan, struct bridge_channel_impart_cond *cond)
 
static void bridge_channel_impart_ds_head_dtor (void *doomed)
 
static void bridge_channel_impart_ds_head_fixup (void *data, struct ast_channel *old_chan, struct ast_channel *new_chan)
 
static void bridge_channel_impart_ds_head_signal (struct bridge_channel_impart_ds_head *ds_head)
 
void bridge_channel_impart_signal (struct ast_channel *chan)
 
static void bridge_channel_impart_wait (struct bridge_channel_impart_cond *cond)
 
static void * bridge_channel_ind_thread (void *data)
 Thread responsible for independent imparted bridged channels. More...
 
static void bridge_channel_moving (struct ast_bridge_channel *bridge_channel, struct ast_bridge *src, struct ast_bridge *dst)
 
static void bridge_cleanup (void)
 
static void bridge_complete_join (struct ast_bridge *bridge)
 
void bridge_dissolve (struct ast_bridge *bridge, int cause)
 
static void bridge_dissolve_check_stolen (struct ast_bridge *bridge, struct ast_bridge_channel *bridge_channel)
 
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)
 
int bridge_do_move (struct ast_bridge *dst_bridge, struct ast_bridge_channel *bridge_channel, int attempt_recovery, unsigned int optimized)
 
static int bridge_dtmf_hook_sort (const void *obj_left, const void *obj_right, int flags)
 
struct ast_bridge_channelbridge_find_channel (struct ast_bridge *bridge, struct ast_channel *chan)
 
static void bridge_handle_actions (struct ast_bridge *bridge)
 
static void bridge_hook_destroy (void *vhook)
 
static struct ast_bridge_hookbridge_hook_generic (size_t size, ast_bridge_hook_callback callback, void *hook_pvt, ast_bridge_hook_pvt_destructor destructor, enum ast_bridge_hook_remove_flags remove_flags)
 
static int bridge_impart_internal (struct ast_bridge *bridge, struct ast_channel *chan, struct ast_channel *swap, struct ast_bridge_features *features, enum ast_bridge_impart_flags flags, struct bridge_channel_impart_cond *cond)
 
static struct bridge_manager_controllerbridge_manager_create (void)
 
static void bridge_manager_destroy (void *obj)
 
static void bridge_manager_service (struct ast_bridge *bridge)
 
static void bridge_manager_service_req (struct ast_bridge *bridge)
 
static void * bridge_manager_thread (void *data)
 
static struct merge_direction bridge_merge_determine_direction (struct ast_bridge *bridge1, struct ast_bridge *bridge2)
 
void bridge_merge_inhibit_nolock (struct ast_bridge *bridge, int request)
 
static int bridge_merge_locked (struct ast_bridge *dst_bridge, struct ast_bridge *src_bridge, int merge_best_direction, struct ast_channel **kick_me, unsigned int num_kick)
 
static int bridge_move_locked (struct ast_bridge *dst_bridge, struct ast_bridge *src_bridge, struct ast_channel *chan, struct ast_channel *swap, int attempt_recovery)
 
static int bridge_other_hook (struct ast_bridge_features *features, ast_bridge_hook_callback callback, void *hook_pvt, ast_bridge_hook_pvt_destructor destructor, enum ast_bridge_hook_remove_flags remove_flags, enum ast_bridge_hook_type type)
 
static void bridge_prnt_obj (void *v_obj, void *where, ao2_prnt_fn *prnt)
 
static void bridge_queue_action_nodup (struct ast_bridge *bridge, struct ast_frame *action)
 
void bridge_reconfigured (struct ast_bridge *bridge, unsigned int colp_update)
 
static void bridge_reconfigured_connected_line_update (struct ast_bridge *bridge)
 
struct ast_bridgebridge_register (struct ast_bridge *bridge)
 Register the new bridge with the system. More...
 
static int bridge_show_specific_print_channel (void *obj, void *arg, int flags)
 Internal callback function for sending channels in a bridge to the CLI. More...
 
static int bridge_sort_cmp (const void *obj_left, const void *obj_right, int flags)
 
static enum ast_transfer_result bridge_swap_attended_transfer (struct ast_bridge *dest_bridge, struct ast_bridge_channel *source_bridge_channel, struct ast_channel *swap_channel)
 
static void bridge_tech_deferred_destroy (struct ast_bridge *bridge, struct ast_frame *action)
 
static enum bridge_allow_merge bridges_allow_merge_optimization (struct ast_bridge *chan_bridge, struct ast_bridge *peer_bridge, int num_kick_channels, struct merge_direction *merge)
 
static enum bridge_allow_swap bridges_allow_swap_optimization (struct ast_bridge *chan_bridge, struct ast_bridge *peer_bridge)
 
static int channel_cmp (void *obj, void *arg, int flags)
 
static int channel_hash (const void *obj, int flags)
 
static void check_bridge_play_sound (struct ast_bridge_channel *bridge_channel)
 
static void check_bridge_play_sounds (struct ast_bridge *bridge)
 
static void cleanup_video_mode (struct ast_bridge *bridge)
 
static char * complete_bridge_live (const char *word)
 
static int complete_bridge_live_search (void *obj, void *arg, int flags)
 
static char * complete_bridge_participant (const char *bridge_name, const char *word)
 
static char * complete_bridge_technology (const char *word)
 
static void destroy_bridge (void *obj)
 
static void fill_bridgepeer_buf (char *buf, unsigned int cur_idx, const char *names[], unsigned int num_names)
 
static struct ast_bridge_technologyfind_best_technology (uint32_t capabilities, struct ast_bridge *bridge)
 Helper function used to find the "best" bridge technology given specified capabilities. More...
 
static struct ast_channelget_transferee (struct ao2_container *channels, struct ast_channel *transferer)
 
static char * handle_bridge_kick_channel (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
 
static char * handle_bridge_show_all (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
 
static char * handle_bridge_show_specific (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
 
static char * handle_bridge_technology_show (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
 
static char * handle_bridge_technology_suspend (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
 
static int handle_manager_bridge_tech_suspend (struct mansession *s, const struct message *m, int suspend)
 
static int hook_remove_match (void *obj, void *arg, int flags)
 
static void hooks_remove_container (struct ao2_container *hooks, enum ast_bridge_hook_remove_flags remove_flags)
 
static void hooks_remove_heap (struct ast_heap *hooks, enum ast_bridge_hook_remove_flags remove_flags)
 
static int interval_hook_time_cmp (void *a, void *b)
 
static int interval_wrapper_cb (struct ast_bridge_channel *bridge_channel, void *obj)
 Wrapper for interval hooks that calls into the wrapped hook. More...
 
static void interval_wrapper_pvt_dtor (void *obj)
 Destructor for the hook wrapper. More...
 
static void kick_it (struct ast_bridge_channel *bridge_channel, const void *payload, size_t payload_size)
 
static int manager_bridge_tech_list (struct mansession *s, const struct message *m)
 
static int manager_bridge_tech_suspend (struct mansession *s, const struct message *m)
 
static int manager_bridge_tech_unsuspend (struct mansession *s, const struct message *m)
 
static int merge_container_cb (void *obj, void *data, int flags)
 Callback for merging hook ao2_containers. More...
 
static struct ast_bridgeoptimize_lock_chan_stack (struct ast_channel *chan)
 
static struct ast_bridgeoptimize_lock_peer_stack (struct ast_channel *peer)
 
static void set_bridge_peer_vars (struct ast_bridge *bridge)
 
static void set_bridge_peer_vars_2party (struct ast_channel *c0, struct ast_channel *c1)
 
static void set_bridge_peer_vars_holding (struct ast_bridge *bridge)
 
static void set_bridge_peer_vars_multiparty (struct ast_bridge *bridge)
 
static void set_transfer_variables_all (struct ast_channel *transferer, struct ao2_container *channels, int is_attended)
 
static int smart_bridge_operation (struct ast_bridge *bridge)
 
static const char * tech_capability2str (uint32_t capabilities)
 
static int try_merge_optimize_out (struct ast_bridge *chan_bridge, struct ast_bridge_channel *chan_bridge_channel, struct ast_bridge *peer_bridge, struct ast_bridge_channel *peer_bridge_channel, struct ast_unreal_pvt *pvt)
 
static enum ast_transfer_result try_parking (struct ast_channel *transferer, const char *context, const char *exten, transfer_channel_cb new_channel_cb, struct transfer_channel_data *user_data_wrapper)
 
static int try_swap_optimize_out (struct ast_bridge *chan_bridge, struct ast_bridge_channel *chan_bridge_channel, struct ast_bridge *peer_bridge, struct ast_bridge_channel *peer_bridge_channel, struct ast_unreal_pvt *pvt)
 
static enum ast_transfer_result two_bridge_attended_transfer (struct ast_channel *to_transferee, struct ast_bridge_channel *to_transferee_bridge_channel, struct ast_channel *to_transfer_target, struct ast_bridge_channel *to_target_bridge_channel, struct ast_bridge *to_transferee_bridge, struct ast_bridge *to_target_bridge, struct ast_attended_transfer_message *transfer_msg)
 
static void wrap_hook (struct ast_bridge_features *features, struct ast_bridge_hook_timer *hook)
 Wrap the provided interval hook and add it to features. More...
 

Variables

struct ast_bridge_methods ast_bridge_base_v_table
 Bridge base class virtual method table. More...
 
static const struct ast_datastore_info bridge_channel_impart_ds_info
 
static struct ast_cli_entry bridge_cli []
 
static ast_mutex_t bridge_init_lock = { PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP , NULL, {1, 0} }
 
static struct bridge_manager_controllerbridge_manager
 
static struct bridge_technologies bridge_technologies = { .first = NULL, .last = NULL, .lock = { PTHREAD_RWLOCK_INITIALIZER , NULL, {1, 0} } , }
 
static struct ao2_containerbridges
 
static char builtin_features_dtmf [AST_BRIDGE_BUILTIN_END][MAXIMUM_DTMF_FEATURE_STRING]
 
static ast_bridge_hook_callback builtin_features_handlers [AST_BRIDGE_BUILTIN_END]
 
static ast_bridge_builtin_set_limits_fn builtin_interval_handlers [AST_BRIDGE_BUILTIN_INTERVAL_END]
 
static unsigned int optimization_id
 

Detailed Description

Bridging API.

Author
Joshua Colp jcolp.nosp@m.@dig.nosp@m.ium.c.nosp@m.om

Definition in file bridge.c.

Macro Definition Documentation

◆ ATTENDEDTRANSFER

#define ATTENDEDTRANSFER   "ATTENDEDTRANSFER"

Definition at line 150 of file bridge.c.

◆ BLINDTRANSFER

#define BLINDTRANSFER   "BLINDTRANSFER"

Definition at line 147 of file bridge.c.

◆ BRIDGE_ARRAY_GROW

#define BRIDGE_ARRAY_GROW   32

Definition at line 144 of file bridge.c.

◆ BRIDGE_ARRAY_START

#define BRIDGE_ARRAY_START   128

Definition at line 141 of file bridge.c.

◆ BRIDGE_LOCK_ONE_OR_BOTH

#define BRIDGE_LOCK_ONE_OR_BOTH (   b1,
  b2 
)

◆ FORMAT_HDR [1/2]

#define FORMAT_HDR   "%-36s %-36s %5s %-15s %-15s %s\n"

◆ FORMAT_HDR [2/2]

#define FORMAT_HDR   "%-20s %-20s %8s %s\n"

◆ FORMAT_ROW [1/2]

#define FORMAT_ROW   "%-36s %-36s %5u %-15s %-15s %s\n"

◆ FORMAT_ROW [2/2]

#define FORMAT_ROW   "%-20s %-20s %8u %s\n"

◆ MAX_BRIDGEPEER_CHANS

#define MAX_BRIDGEPEER_CHANS   (10 + 1)

◆ UPDATE_BRIDGE_VARS_GET

#define UPDATE_BRIDGE_VARS_GET (   chan,
  name,
  pvtid 
)

Enumeration Type Documentation

◆ bridge_allow_merge

Enumerator
MERGE_PROHIBITED 

Bridge properties prohibit merge optimization

MERGE_NOT_ENOUGH_CHANNELS 

Merge optimization cannot occur because the source bridge has too few channels

MERGE_NO_MULTIMIX 

Merge optimization cannot occur because multimix capability could not be requested

MERGE_ALLOWED 

Merge optimization allowed between bridges

Definition at line 2880 of file bridge.c.

2880 {
2881 /*! Bridge properties prohibit merge optimization */
2883 /*! Merge optimization cannot occur because the source bridge has too few channels */
2885 /*! Merge optimization cannot occur because multimix capability could not be requested */
2887 /*! Merge optimization allowed between bridges */
2889};
@ MERGE_ALLOWED
Definition: bridge.c:2888
@ MERGE_NOT_ENOUGH_CHANNELS
Definition: bridge.c:2884
@ MERGE_NO_MULTIMIX
Definition: bridge.c:2886
@ MERGE_PROHIBITED
Definition: bridge.c:2882

◆ bridge_allow_swap

Enumerator
SWAP_PROHIBITED 

Bridges cannot allow for a swap optimization to occur

SWAP_TO_CHAN_BRIDGE 

Bridge swap optimization can occur into the chan_bridge

SWAP_TO_PEER_BRIDGE 

Bridge swap optimization can occur into the peer_bridge

Definition at line 2741 of file bridge.c.

2741 {
2742 /*! Bridges cannot allow for a swap optimization to occur */
2744 /*! Bridge swap optimization can occur into the chan_bridge */
2746 /*! Bridge swap optimization can occur into the peer_bridge */
2748};
@ SWAP_PROHIBITED
Definition: bridge.c:2743
@ SWAP_TO_PEER_BRIDGE
Definition: bridge.c:2747
@ SWAP_TO_CHAN_BRIDGE
Definition: bridge.c:2745

Function Documentation

◆ __ast_bridge_technology_register()

int __ast_bridge_technology_register ( struct ast_bridge_technology technology,
struct ast_module mod 
)

Register a bridge technology for use.

Parameters
technologyThe bridge technology to register
modThe module that is registering the bridge technology
Return values
0on success
-1on failure

Example usage:

ast_bridge_technology_register(&simple_bridge_tech);
#define ast_bridge_technology_register(technology)
See __ast_bridge_technology_register()

This registers a bridge technology declared as the structure simple_bridge_tech with the bridging core and makes it available for use when creating bridges.

Definition at line 223 of file bridge.c.

224{
226
227 /* Perform a sanity check to make sure the bridge technology conforms to our needed requirements */
228 if (ast_strlen_zero(technology->name)
229 || !technology->capabilities
230 || !technology->write) {
231 ast_log(LOG_WARNING, "Bridge technology %s failed registration sanity check.\n",
232 technology->name);
233 return -1;
234 }
235
237
238 /* Look for duplicate bridge technology already using this name, or already registered */
240 if ((!strcasecmp(current->name, technology->name)) || (current == technology)) {
241 ast_log(LOG_WARNING, "A bridge technology of %s already claims to exist in our world.\n",
242 technology->name);
244 return -1;
245 }
246 }
247
248 /* Copy module pointer so reference counting can keep the module from unloading */
249 technology->mod = module;
250
251 /* Find the correct position to insert the technology. */
253 /* Put the highest preference tech's first in the list. */
254 if (technology->preference >= current->preference) {
255 AST_RWLIST_INSERT_BEFORE_CURRENT(technology, entry);
256
257 break;
258 }
259 }
261
262 if (!current) {
263 /* Insert our new bridge technology to the end of the list. */
264 AST_RWLIST_INSERT_TAIL(&bridge_technologies, technology, entry);
265 }
266
268
269 ast_verb(5, "Registered bridge technology %s\n", technology->name);
270
271 return 0;
272}
#define ast_log
Definition: astobj2.c:42
#define ast_verb(level,...)
#define LOG_WARNING
#define AST_RWLIST_TRAVERSE_SAFE_BEGIN
Definition: linkedlists.h:545
#define AST_RWLIST_WRLOCK(head)
Write locks a list.
Definition: linkedlists.h:52
#define AST_RWLIST_UNLOCK(head)
Attempts to unlock a read/write based list.
Definition: linkedlists.h:151
#define AST_RWLIST_TRAVERSE_SAFE_END
Definition: linkedlists.h:617
#define AST_RWLIST_TRAVERSE
Definition: linkedlists.h:494
#define AST_RWLIST_INSERT_TAIL
Definition: linkedlists.h:741
#define AST_RWLIST_INSERT_BEFORE_CURRENT
Definition: linkedlists.h:610
size_t current
Definition: main/cli.c:113
static force_inline int attribute_pure ast_strlen_zero(const char *s)
Definition: strings.h:65
Structure that is the essence of a bridge technology.
struct ast_module * mod
int(* write)(struct ast_bridge *bridge, struct ast_bridge_channel *bridge_channel, struct ast_frame *frame)
Write a frame into the bridging technology instance for a bridge.
enum ast_bridge_preference preference

References ast_log, AST_RWLIST_INSERT_BEFORE_CURRENT, AST_RWLIST_INSERT_TAIL, AST_RWLIST_TRAVERSE, AST_RWLIST_TRAVERSE_SAFE_BEGIN, AST_RWLIST_TRAVERSE_SAFE_END, AST_RWLIST_UNLOCK, AST_RWLIST_WRLOCK, ast_strlen_zero(), ast_verb, ast_bridge_technology::capabilities, current, LOG_WARNING, ast_bridge_technology::mod, ast_bridge_technology::name, ast_bridge_technology::preference, and ast_bridge_technology::write.

◆ ast_bridge_add_channel()

int ast_bridge_add_channel ( struct ast_bridge bridge,
struct ast_channel chan,
struct ast_bridge_features features,
int  play_tone,
const char *  xfersound 
)

Add an arbitrary channel to a bridge.

Since
12.0.0

The channel that is being added to the bridge can be in any state: unbridged, bridged, answered, unanswered, etc. The channel will be added asynchronously, meaning that when this function returns once the channel has been added to the bridge, not once the channel has been removed from the bridge.

In addition, a tone can optionally be played to the channel once the channel is placed into the bridge.

Note
When this function returns, there is no guarantee that the channel that was passed in is valid any longer. Do not attempt to operate on the channel after this function returns.
Parameters
bridgeBridge to which the channel should be added
chanThe channel to add to the bridge
featuresFeatures for this channel in the bridge
play_toneIndicates if a tone should be played to the channel
xfersoundSound that should be used to indicate transfer with play_tone
Note
The features parameter must be NULL or obtained by ast_bridge_features_new(). You must not dereference features after calling even if the call fails.
Return values
0Success
-1Failure

Definition at line 2540 of file bridge.c.

2542{
2543 RAII_VAR(struct ast_bridge *, chan_bridge, NULL, ao2_cleanup);
2544 RAII_VAR(struct ast_channel *, yanked_chan, NULL, ao2_cleanup);
2545
2546 ast_moh_stop(chan);
2547
2548 ast_channel_lock(chan);
2549 chan_bridge = ast_channel_get_bridge(chan);
2550 ast_channel_unlock(chan);
2551
2552 if (chan_bridge) {
2553 struct ast_bridge_channel *bridge_channel;
2554
2555 /* The channel is in a bridge so it is not getting any new features. */
2557
2558 ast_bridge_lock_both(bridge, chan_bridge);
2559 bridge_channel = bridge_find_channel(chan_bridge, chan);
2560
2561 if (bridge_move_locked(bridge, chan_bridge, chan, NULL, 1)) {
2562 ast_bridge_unlock(chan_bridge);
2564 return -1;
2565 }
2566
2567 /*
2568 * bridge_move_locked() will implicitly ensure that
2569 * bridge_channel is not NULL.
2570 */
2571 ast_assert(bridge_channel != NULL);
2572
2573 /*
2574 * Additional checks if the channel we just stole dissolves the
2575 * original bridge.
2576 */
2577 bridge_dissolve_check_stolen(chan_bridge, bridge_channel);
2578 ast_bridge_unlock(chan_bridge);
2580 } else {
2581 /* Slightly less easy case. We need to yank channel A from
2582 * where he currently is and impart him into our bridge.
2583 */
2584 yanked_chan = ast_channel_yank(chan);
2585 if (!yanked_chan) {
2586 ast_log(LOG_WARNING, "Could not gain control of channel %s\n", ast_channel_name(chan));
2588 return -1;
2589 }
2590 if (ast_channel_state(yanked_chan) != AST_STATE_UP) {
2591 ast_answer(yanked_chan);
2592 }
2593 ast_channel_ref(yanked_chan);
2594 if (ast_bridge_impart(bridge, yanked_chan, NULL, features,
2596 /* It is possible for us to yank a channel and have some other
2597 * thread start a PBX on the channel after we yanked it. In particular,
2598 * this can theoretically happen on the ;2 of a Local channel if we
2599 * yank it prior to the ;1 being answered. Make sure that it isn't
2600 * executing a PBX before hanging it up.
2601 */
2602 if (ast_channel_pbx(yanked_chan)) {
2603 ast_channel_unref(yanked_chan);
2604 } else {
2605 ast_hangup(yanked_chan);
2606 }
2607 return -1;
2608 }
2609 }
2610
2611 if (play_tone && !ast_strlen_zero(xfersound)) {
2612 struct ast_channel *play_chan = yanked_chan ?: chan;
2613 RAII_VAR(struct ast_bridge_channel *, play_bridge_channel, NULL, ao2_cleanup);
2614
2615 ast_channel_lock(play_chan);
2616 play_bridge_channel = ast_channel_get_bridge_channel(play_chan);
2617 ast_channel_unlock(play_chan);
2618
2619 if (!play_bridge_channel) {
2620 ast_log(LOG_WARNING, "Unable to play tone for channel %s. No longer in a bridge.\n",
2621 ast_channel_name(play_chan));
2622 } else {
2623 ast_bridge_channel_queue_playfile(play_bridge_channel, NULL, xfersound, NULL);
2624 }
2625 }
2626 return 0;
2627}
#define ao2_cleanup(obj)
Definition: astobj2.h:1934
int ast_bridge_impart(struct ast_bridge *bridge, struct ast_channel *chan, struct ast_channel *swap, struct ast_bridge_features *features, enum ast_bridge_impart_flags flags)
Impart a channel to a bridge (non-blocking)
Definition: bridge.c:1947
static int bridge_move_locked(struct ast_bridge *dst_bridge, struct ast_bridge *src_bridge, struct ast_channel *chan, struct ast_channel *swap, int attempt_recovery)
Definition: bridge.c:2468
struct ast_bridge_channel * bridge_find_channel(struct ast_bridge *bridge, struct ast_channel *chan)
Definition: bridge.c:1498
void ast_bridge_features_destroy(struct ast_bridge_features *features)
Destroy an allocated bridge features struct.
Definition: bridge.c:3743
static void bridge_dissolve_check_stolen(struct ast_bridge *bridge, struct ast_bridge_channel *bridge_channel)
Definition: bridge.c:374
#define ast_bridge_lock_both(bridge1, bridge2)
Lock two bridges.
Definition: bridge.h:492
#define ast_bridge_unlock(bridge)
Unlock the bridge.
Definition: bridge.h:485
@ AST_BRIDGE_IMPART_CHAN_INDEPENDENT
Definition: bridge.h:594
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)
Queue a bridge action play file frame onto the bridge channel.
const char * ast_channel_name(const struct ast_channel *chan)
void ast_hangup(struct ast_channel *chan)
Hang up a channel.
Definition: channel.c:2570
#define ast_channel_lock(chan)
Definition: channel.h:2970
struct ast_channel * ast_channel_yank(struct ast_channel *yankee)
Gain control of a channel in the system.
Definition: channel.c:10619
#define ast_channel_ref(c)
Increase channel reference count.
Definition: channel.h:2995
struct ast_bridge * ast_channel_get_bridge(const struct ast_channel *chan)
Get the bridge associated with a channel.
Definition: channel.c:10560
#define ast_channel_unref(c)
Decrease channel reference count.
Definition: channel.h:3006
struct ast_bridge_channel * ast_channel_get_bridge_channel(struct ast_channel *chan)
Get a reference to the channel's bridge pointer.
Definition: channel.c:10608
struct ast_pbx * ast_channel_pbx(const struct ast_channel *chan)
int ast_answer(struct ast_channel *chan)
Answer a channel.
Definition: channel.c:2834
#define ast_channel_unlock(chan)
Definition: channel.h:2971
ast_channel_state
ast_channel states
Definition: channelstate.h:35
@ AST_STATE_UP
Definition: channelstate.h:42
void ast_moh_stop(struct ast_channel *chan)
Turn off music on hold on a given channel.
Definition: channel.c:7797
#define NULL
Definition: resample.c:96
Structure that contains information regarding a channel in a bridge.
struct ast_bridge * bridge
Bridge this channel is participating in.
struct ast_bridge_features * features
struct ast_channel * chan
Structure that contains information about a bridge.
Definition: bridge.h:353
Main Channel structure associated with a channel.
#define RAII_VAR(vartype, varname, initval, dtor)
Declare a variable that will call a destructor function when it goes out of scope.
Definition: utils.h:941
#define ast_assert(a)
Definition: utils.h:739

References ao2_cleanup, ast_answer(), ast_assert, ast_bridge_channel_queue_playfile(), ast_bridge_features_destroy(), ast_bridge_impart(), AST_BRIDGE_IMPART_CHAN_INDEPENDENT, ast_bridge_lock_both, ast_bridge_unlock, ast_channel_get_bridge(), ast_channel_get_bridge_channel(), ast_channel_lock, ast_channel_name(), ast_channel_pbx(), ast_channel_ref, ast_channel_unlock, ast_channel_unref, ast_channel_yank(), ast_hangup(), ast_log, ast_moh_stop(), AST_STATE_UP, ast_strlen_zero(), ast_bridge_channel::bridge, bridge_dissolve_check_stolen(), bridge_find_channel(), bridge_move_locked(), ast_bridge_channel::chan, ast_bridge_channel::features, LOG_WARNING, NULL, and RAII_VAR.

Referenced by action_bridge(), bridge_exec(), and manager_park_unbridged().

◆ ast_bridge_base_new()

struct ast_bridge * ast_bridge_base_new ( uint32_t  capabilities,
unsigned int  flags,
const char *  creator,
const char *  name,
const char *  id 
)

Create a new base class bridge.

Parameters
capabilitiesThe capabilities that we require to be used on the bridge
flagsFlags that will alter the behavior of the bridge
creatorEntity that created the bridge (optional)
nameName given to the bridge by its creator (optional, requires named creator)
idUnique ID given to the bridge by its creator (optional)
Returns
a pointer to a new bridge on success
Return values
NULLon failure

Example usage:

struct ast_bridge *bridge;
struct ast_bridge * ast_bridge_base_new(uint32_t capabilities, unsigned int flags, const char *creator, const char *name, const char *id)
Create a new base class bridge.
Definition: bridge.c:999
@ AST_BRIDGE_CAPABILITY_1TO1MIX
Definition: bridge.h:96
@ AST_BRIDGE_FLAG_DISSOLVE_HANGUP

This creates a no frills two party bridge that will be destroyed once one of the channels hangs up.

Definition at line 999 of file bridge.c.

1000{
1001 void *bridge;
1002
1003 bridge = bridge_alloc(sizeof(struct ast_bridge), &ast_bridge_base_v_table);
1004 bridge = bridge_base_init(bridge, capabilities, flags, creator, name, id);
1005 bridge = bridge_register(bridge);
1006 return bridge;
1007}
struct ast_bridge_methods ast_bridge_base_v_table
Bridge base class virtual method table.
Definition: bridge.c:988
struct ast_bridge * bridge_register(struct ast_bridge *bridge)
Register the new bridge with the system.
Definition: bridge.c:713
struct ast_bridge * bridge_base_init(struct ast_bridge *self, uint32_t capabilities, unsigned int flags, const char *creator, const char *name, const char *id)
Initialize the base class of the bridge.
Definition: bridge.c:783
struct ast_bridge * bridge_alloc(size_t size, const struct ast_bridge_methods *v_table)
Definition: bridge.c:747
static const char name[]
Definition: format_mp3.c:68

References ast_bridge_base_v_table, bridge_alloc(), bridge_base_init(), bridge_register(), ast_bridge::creator, and name.

Referenced by AST_TEST_DEFINE(), get_wait_bridge_wrapper(), and join_conference_bridge().

◆ ast_bridge_depart()

int ast_bridge_depart ( struct ast_channel chan)

Depart a channel from a bridge.

Parameters
chanChannel to depart
Note
chan is locked by this function.
Return values
0on success
-1on failure

Example usage:

int ast_bridge_depart(struct ast_channel *chan)
Depart a channel from a bridge.
Definition: bridge.c:1975

This removes the channel pointed to by the chan pointer from any bridge it may be in and gives control to the calling thread. This does not hang up the channel.

Note
This API call can only be used on channels that were added to the bridge using the ast_bridge_impart API call with the AST_BRIDGE_IMPART_CHAN_DEPARTABLE flag.

Definition at line 1975 of file bridge.c.

1976{
1977 struct ast_bridge_channel *bridge_channel;
1978 int departable;
1979 SCOPE_TRACE(1, "%s\n", ast_channel_name(chan));
1980
1982 bridge_channel = ast_channel_internal_bridge_channel(chan);
1983 departable = bridge_channel && bridge_channel->depart_wait;
1985 if (!departable) {
1986 ast_log(LOG_ERROR, "Channel %s cannot be departed.\n",
1988 /*
1989 * Should never happen. It likely means that
1990 * ast_bridge_depart() is called by two threads for the same
1991 * channel, the channel was never imparted to be departed, or it
1992 * has already been departed.
1993 */
1994 ast_assert(0);
1995 return -1;
1996 }
1997
1998 /*
1999 * We are claiming the bridge_channel reference held by
2000 * bridge_channel_depart_thread().
2001 */
2002
2003 ast_bridge_channel_leave_bridge(bridge_channel,
2005
2006 /* Wait for the depart thread to die */
2007 ast_debug(1, "Waiting for %p(%s) bridge thread to die.\n",
2008 bridge_channel, ast_channel_name(bridge_channel->chan));
2009 pthread_join(bridge_channel->thread, NULL);
2010
2014
2015 /* We can get rid of the bridge_channel after the depart thread has died. */
2016 ao2_ref(bridge_channel, -1);
2017 return 0;
2018}
#define ao2_ref(o, delta)
Reference/unreference an object and return the old refcount.
Definition: astobj2.h:459
@ BRIDGE_CHANNEL_STATE_END_NO_DISSOLVE
void ast_bridge_channel_leave_bridge(struct ast_bridge_channel *bridge_channel, enum bridge_channel_state new_state, int cause)
Set bridge channel state to leave bridge (if not leaving already).
#define AST_CAUSE_NORMAL_CLEARING
Definition: causes.h:106
void ast_channel_internal_bridge_channel_set(struct ast_channel *chan, struct ast_bridge_channel *value)
struct ast_bridge_channel * ast_channel_internal_bridge_channel(const struct ast_channel *chan)
#define SCOPE_TRACE(__level,...)
#define ast_debug(level,...)
Log a DEBUG message.
#define LOG_ERROR
unsigned int depart_wait

References ao2_ref, ast_assert, ast_bridge_channel_leave_bridge(), AST_CAUSE_NORMAL_CLEARING, ast_channel_internal_bridge_channel(), ast_channel_internal_bridge_channel_set(), ast_channel_lock, ast_channel_name(), ast_channel_unlock, ast_debug, ast_log, BRIDGE_CHANNEL_STATE_END_NO_DISSOLVE, ast_bridge_channel::chan, ast_bridge_channel::depart_wait, LOG_ERROR, NULL, SCOPE_TRACE, and ast_bridge_channel::thread.

Referenced by app_control_continue(), AST_TEST_DEFINE(), control_swap_channel_in_bridge(), depart_channel(), and stasis_app_exec().

◆ ast_bridge_destroy()

int ast_bridge_destroy ( struct ast_bridge bridge,
int  cause 
)

Destroy a bridge.

Parameters
bridgeBridge to destroy
causeCause of bridge being destroyed. (If cause <= 0 then use AST_CAUSE_NORMAL_CLEARING)
Return values
0on success
-1on failure

Example usage:

int ast_bridge_destroy(struct ast_bridge *bridge, int cause)
Destroy a bridge.
Definition: bridge.c:1009

This destroys a bridge that was previously created.

Note
While this function will kick all channels out of the bridge, channels that were added to the bridge using ast_bridge_impart() with the flag AST_BRIDGE_IMPART_CHAN_DEPARTABLE set must have ast_bridge_depart() called on them.

Definition at line 1009 of file bridge.c.

1010{
1011 ast_debug(1, "Bridge " BRIDGE_PRINTF_SPEC ": destroying. current refcount: %d\n",
1012 BRIDGE_PRINTF_VARS(bridge), ao2_ref(bridge, 0));
1013 ast_bridge_lock(bridge);
1014 bridge_dissolve(bridge, cause);
1015 ast_bridge_unlock(bridge);
1016
1017 ast_debug(1, "Bridge " BRIDGE_PRINTF_SPEC ": unreffing. current refcount: %d\n",
1018 BRIDGE_PRINTF_VARS(bridge), ao2_ref(bridge, 0));
1019
1020 ao2_ref(bridge, -1);
1021
1022 return 0;
1023}
void bridge_dissolve(struct ast_bridge *bridge, int cause)
Definition: bridge.c:326
#define ast_bridge_lock(bridge)
Lock the bridge.
Definition: bridge.h:474
#define BRIDGE_PRINTF_VARS(bridge)
Definition: bridge.h:80
#define BRIDGE_PRINTF_SPEC
Definition: bridge.h:79

References ao2_ref, ast_bridge_lock, ast_bridge_unlock, ast_debug, bridge_dissolve(), BRIDGE_PRINTF_SPEC, BRIDGE_PRINTF_VARS, and ast_bridge::cause.

Referenced by action_bridge(), agent_connect_caller(), agent_logout(), agent_pvt_destructor(), agent_request_exec(), agent_run(), ast_bridge_call_with_flags(), attended_transfer_properties_shutdown(), bridge_base_init(), bridge_create_common(), bridge_exec(), bridge_register(), caller_abort_agent(), destroy_conference_bridge(), fail_enter(), manager_bridge_destroy(), parked_call_app_exec(), parking_lot_destructor(), safe_bridge_destroy(), stasis_app_bridge_destroy(), stasis_app_control_shutdown(), unload_module(), wait_bridge_wrapper_alloc(), and wait_bridge_wrapper_destructor().

◆ ast_bridge_dtmf_hook()

int ast_bridge_dtmf_hook ( struct ast_bridge_features features,
const char *  dtmf,
ast_bridge_hook_callback  callback,
void *  hook_pvt,
ast_bridge_hook_pvt_destructor  destructor,
enum ast_bridge_hook_remove_flags  remove_flags 
)

Attach a DTMF hook to a bridge features structure.

Parameters
featuresBridge features structure
dtmfDTMF string to be activated upon
callbackFunction to execute upon activation
hook_pvtUnique data
destructorOptional destructor callback for hook_pvt data
remove_flagsDictates what situations the hook should be removed.
Return values
0on success
-1on failure (The caller must cleanup any hook_pvt resources.)

Example usage:

struct ast_bridge_features features;
ast_bridge_dtmf_hook(&features, "#", pound_callback, NULL, NULL, 0);
int ast_bridge_features_init(struct ast_bridge_features *features)
Initialize bridge features structure.
Definition: bridge.c:3689
int ast_bridge_dtmf_hook(struct ast_bridge_features *features, const char *dtmf, ast_bridge_hook_callback callback, void *hook_pvt, ast_bridge_hook_pvt_destructor destructor, enum ast_bridge_hook_remove_flags remove_flags)
Attach a DTMF hook to a bridge features structure.
Definition: bridge.c:3251
Structure that contains features information.

This makes the bridging core call pound_callback if a channel that has this feature structure inputs the DTMF string '#'. A pointer to useful data may be provided to the hook_pvt parameter.

Definition at line 3251 of file bridge.c.

3257{
3258 struct ast_bridge_hook_dtmf *hook;
3259 int res;
3260
3261 /* Allocate new hook and setup it's various variables */
3262 hook = (struct ast_bridge_hook_dtmf *) bridge_hook_generic(sizeof(*hook), callback,
3263 hook_pvt, destructor, remove_flags);
3264 if (!hook) {
3265 return -1;
3266 }
3268 ast_copy_string(hook->dtmf.code, dtmf, sizeof(hook->dtmf.code));
3269
3270 /* Once done we put it in the container. */
3271 res = ao2_link(features->dtmf_hooks, hook) ? 0 : -1;
3272 if (res) {
3273 /*
3274 * Could not link the hook into the container.
3275 *
3276 * Remove the hook_pvt destructor call from the hook since we
3277 * are returning failure to install the hook.
3278 */
3279 hook->generic.destructor = NULL;
3280 }
3281 ao2_ref(hook, -1);
3282
3283 return res;
3284}
#define ao2_link(container, obj)
Add an object to a container.
Definition: astobj2.h:1532
static struct ast_bridge_hook * bridge_hook_generic(size_t size, ast_bridge_hook_callback callback, void *hook_pvt, ast_bridge_hook_pvt_destructor destructor, enum ast_bridge_hook_remove_flags remove_flags)
Definition: bridge.c:3231
@ AST_BRIDGE_HOOK_TYPE_DTMF
void ast_copy_string(char *dst, const char *src, size_t size)
Size-limited null-terminating string copy.
Definition: strings.h:425
struct ao2_container * dtmf_hooks
char code[MAXIMUM_DTMF_FEATURE_STRING]
struct ast_bridge_hook generic
struct ast_bridge_hook_dtmf_parms dtmf
ast_bridge_hook_pvt_destructor destructor
enum ast_bridge_hook_type type

References ao2_link, ao2_ref, AST_BRIDGE_HOOK_TYPE_DTMF, ast_copy_string(), bridge_hook_generic(), ast_bridge_hook_dtmf_parms::code, ast_bridge_hook::destructor, ast_bridge_hook_dtmf::dtmf, ast_bridge_features::dtmf_hooks, ast_bridge_hook_dtmf::generic, NULL, and ast_bridge_hook::type.

Referenced by apply_menu_to_user(), ast_bridge_features_enable(), AST_TEST_DEFINE(), bridge_agent_hold_push(), bridge_personality_atxfer_push(), and dynamic_dtmf_hook_add().

◆ ast_bridge_features_cleanup()

void ast_bridge_features_cleanup ( struct ast_bridge_features features)

Clean up the contents of a bridge features structure.

Parameters
featuresBridge features structure

Example usage:

struct ast_bridge_features features;
void ast_bridge_features_cleanup(struct ast_bridge_features *features)
Clean up the contents of a bridge features structure.
Definition: bridge.c:3722

This cleans up the feature structure 'features'.

Note
This MUST be called after the features structure is done being used or a memory leak may occur.

Definition at line 3722 of file bridge.c.

3723{
3724 struct ast_bridge_hook_timer *hook;
3725
3726 /* Destroy the interval hooks heap. */
3727 if (features->interval_hooks) {
3728 while ((hook = ast_heap_pop(features->interval_hooks))) {
3729 ao2_ref(hook, -1);
3730 }
3731 features->interval_hooks = ast_heap_destroy(features->interval_hooks);
3732 }
3733
3734 /* Destroy the miscellaneous other hooks container. */
3735 ao2_cleanup(features->other_hooks);
3736 features->other_hooks = NULL;
3737
3738 /* Destroy the DTMF hooks container. */
3739 ao2_cleanup(features->dtmf_hooks);
3740 features->dtmf_hooks = NULL;
3741}
struct ast_heap * ast_heap_destroy(struct ast_heap *h)
Destroy a max heap.
Definition: heap.c:146
void * ast_heap_pop(struct ast_heap *h)
Pop the max element off of the heap.
Definition: heap.c:262
struct ao2_container * other_hooks
struct ast_heap * interval_hooks

References ao2_cleanup, ao2_ref, ast_heap_destroy(), ast_heap_pop(), ast_bridge_features::dtmf_hooks, ast_bridge_features::interval_hooks, NULL, and ast_bridge_features::other_hooks.

Referenced by agent_request_exec(), agent_run(), ast_bridge_call_with_flags(), ast_bridge_features_destroy(), AST_TEST_DEFINE(), bridge_exec(), bridgeadd_exec(), bridgewait_exec(), channel_feature_hooks_set_full(), confbridge_exec(), park_and_announce_app_exec(), park_app_exec(), and parked_call_app_exec().

◆ ast_bridge_features_destroy()

void ast_bridge_features_destroy ( struct ast_bridge_features features)

Destroy an allocated bridge features struct.

Since
12.0.0
Parameters
featuresBridge features structure

Example usage:

struct ast_bridge_features *features;
struct ast_bridge_features * ast_bridge_features_new(void)
Allocate a new bridge features struct.
Definition: bridge.c:3752
void ast_bridge_features_destroy(struct ast_bridge_features *features)
Destroy an allocated bridge features struct.
Definition: bridge.c:3743

Definition at line 3743 of file bridge.c.

3744{
3745 if (!features) {
3746 return;
3747 }
3749 ast_free(features);
3750}
#define ast_free(a)
Definition: astmm.h:180
void ast_bridge_features_cleanup(struct ast_bridge_features *features)
Clean up the contents of a bridge features structure.
Definition: bridge.c:3722

References ast_bridge_features_cleanup(), and ast_free.

Referenced by ast_bridge_add_channel(), ast_bridge_call_with_flags(), ast_bridge_features_new(), ast_local_setup_bridge(), bridge_channel_depart_thread(), bridge_channel_ind_thread(), bridge_exec(), bridge_impart_internal(), conf_start_record(), control_dtor(), features_destroy(), and local_pvt_destructor().

◆ ast_bridge_features_do()

int ast_bridge_features_do ( enum ast_bridge_builtin_feature  feature,
struct ast_bridge_channel bridge_channel,
void *  hook_pvt 
)

Invoke a built in feature hook now.

Parameters
featureThe feature to invoke
bridge_channelChannel executing the feature
hook_pvtPrivate data passed in when the hook was created
Note
This API call is only meant to be used by bridge subclasses and hook callbacks to request a builtin feature hook to be executed.
Return values
0on success
-1on failure

Example usage:

ast_bridge_features_do(AST_BRIDGE_BUILTIN_ATTENDED_TRANSFER, bridge_channel, hook_pvt);
int ast_bridge_features_do(enum ast_bridge_builtin_feature feature, struct ast_bridge_channel *bridge_channel, void *hook_pvt)
Invoke a built in feature hook now.
Definition: bridge.c:3159

Definition at line 3159 of file bridge.c.

3160{
3161 ast_bridge_hook_callback callback;
3162
3163 if (ARRAY_LEN(builtin_features_handlers) <= feature) {
3164 return -1;
3165 }
3166
3167 callback = builtin_features_handlers[feature];
3168 if (!callback) {
3169 return -1;
3170 }
3171 callback(bridge_channel, hook_pvt);
3172
3173 return 0;
3174}
static ast_bridge_hook_callback builtin_features_handlers[AST_BRIDGE_BUILTIN_END]
Definition: bridge.c:158
int(* ast_bridge_hook_callback)(struct ast_bridge_channel *bridge_channel, void *hook_pvt)
Hook callback type.
#define ARRAY_LEN(a)
Definition: utils.h:666

References ARRAY_LEN, and builtin_features_handlers.

Referenced by agent_connect_caller().

◆ ast_bridge_features_enable()

int ast_bridge_features_enable ( struct ast_bridge_features features,
enum ast_bridge_builtin_feature  feature,
const char *  dtmf,
void *  config,
ast_bridge_hook_pvt_destructor  destructor,
enum ast_bridge_hook_remove_flags  remove_flags 
)

Enable a built in feature on a bridge features structure.

Parameters
featuresBridge features structure
featureFeature to enable
dtmfOptionally the DTMF stream to trigger the feature, if not specified it will be the default
configConfiguration structure unique to the built in type
destructorOptional destructor callback for config data
remove_flagsDictates what situations the hook should be removed.
Return values
0on success
-1on failure

Example usage:

struct ast_bridge_features features;
@ AST_BRIDGE_BUILTIN_ATTENDEDTRANSFER
int ast_bridge_features_enable(struct ast_bridge_features *features, enum ast_bridge_builtin_feature feature, const char *dtmf, void *config, ast_bridge_hook_pvt_destructor destructor, enum ast_bridge_hook_remove_flags remove_flags)
Enable a built in feature on a bridge features structure.
Definition: bridge.c:3434

This enables the attended transfer DTMF option using the default DTMF string. An alternate string may be provided using the dtmf parameter. Internally this is simply setting up a hook to a built in feature callback function.

Definition at line 3434 of file bridge.c.

3440{
3441 if (ARRAY_LEN(builtin_features_handlers) <= feature
3442 || !builtin_features_handlers[feature]) {
3443 return -1;
3444 }
3445
3446 /* If no alternate DTMF stream was provided use the default one */
3447 if (ast_strlen_zero(dtmf)) {
3448 dtmf = builtin_features_dtmf[feature];
3449 /* If no DTMF is still available (ie: it has been disabled) then error out now */
3450 if (ast_strlen_zero(dtmf)) {
3451 ast_debug(1, "Failed to enable built in feature %u on %p, no DTMF string is available for it.\n",
3452 feature, features);
3453 return -1;
3454 }
3455 }
3456
3457 /*
3458 * The rest is basically pretty easy. We create another hook
3459 * using the built in feature's DTMF callback. Easy as pie.
3460 */
3461 return ast_bridge_dtmf_hook(features, dtmf, builtin_features_handlers[feature],
3462 config, destructor, remove_flags);
3463}
static char builtin_features_dtmf[AST_BRIDGE_BUILTIN_END][MAXIMUM_DTMF_FEATURE_STRING]
Definition: bridge.c:155
int ast_bridge_dtmf_hook(struct ast_bridge_features *features, const char *dtmf, ast_bridge_hook_callback callback, void *hook_pvt, ast_bridge_hook_pvt_destructor destructor, enum ast_bridge_hook_remove_flags remove_flags)
Attach a DTMF hook to a bridge features structure.
Definition: bridge.c:3251
static const char config[]
Definition: chan_ooh323.c:111

References ARRAY_LEN, ast_bridge_dtmf_hook(), ast_debug, ast_strlen_zero(), builtin_features_dtmf, builtin_features_handlers, and config.

Referenced by builtin_features_helper().

◆ ast_bridge_features_init()

int ast_bridge_features_init ( struct ast_bridge_features features)

Initialize bridge features structure.

Parameters
featuresBridge featues structure
Return values
0on success
-1on failure

Example usage:

struct ast_bridge_features features;

This initializes the feature structure 'features' to have nothing enabled.

Note
This MUST be called before enabling features or flags. Failure to do so may result in a crash.

Definition at line 3689 of file bridge.c.

3690{
3691 /* Zero out the structure */
3692 memset(features, 0, sizeof(*features));
3693
3694 /* Initialize the DTMF hooks container */
3697 if (!features->dtmf_hooks) {
3698 return -1;
3699 }
3700
3701 /* Initialize the miscellaneous other hooks container */
3703 NULL);
3704 if (!features->other_hooks) {
3705 return -1;
3706 }
3707
3708 /* Initialize the interval hooks heap */
3710 offsetof(struct ast_bridge_hook_timer, timer.heap_index));
3711 if (!features->interval_hooks) {
3712 return -1;
3713 }
3714
3715 features->dtmf_passthrough = 1;
3716 features->text_messaging = 1;
3717
3718 return 0;
3719}
@ AO2_ALLOC_OPT_LOCK_MUTEX
Definition: astobj2.h:363
#define ao2_container_alloc_list(ao2_options, container_options, sort_fn, cmp_fn)
Allocate and initialize a list container.
Definition: astobj2.h:1327
@ AO2_CONTAINER_ALLOC_OPT_DUPS_REPLACE
Replace objects with duplicate keys in container.
Definition: astobj2.h:1211
static int interval_hook_time_cmp(void *a, void *b)
Definition: bridge.c:3577
static int bridge_dtmf_hook_sort(const void *obj_left, const void *obj_right, int flags)
Definition: bridge.c:3608
static struct ast_timer * timer
Definition: chan_iax2.c:388
#define ast_heap_create(init_height, cmp_fn, index_offset)
Create a max heap.
Definition: heap.h:100
unsigned int dtmf_passthrough
unsigned int text_messaging

References AO2_ALLOC_OPT_LOCK_MUTEX, ao2_container_alloc_list, AO2_CONTAINER_ALLOC_OPT_DUPS_REPLACE, ast_heap_create, bridge_dtmf_hook_sort(), ast_bridge_features::dtmf_hooks, ast_bridge_features::dtmf_passthrough, interval_hook_time_cmp(), ast_bridge_features::interval_hooks, NULL, ast_bridge_features::other_hooks, ast_bridge_features::text_messaging, and timer.

Referenced by agent_request_exec(), agent_run(), ast_bridge_call_with_flags(), ast_bridge_features_new(), AST_TEST_DEFINE(), bridge_exec(), bridgeadd_exec(), bridgewait_exec(), channel_feature_hooks_set_full(), confbridge_exec(), park_and_announce_app_exec(), park_app_exec(), and parked_call_app_exec().

◆ ast_bridge_features_limits_construct()

int ast_bridge_features_limits_construct ( struct ast_bridge_features_limits limits)

Constructor function for ast_bridge_features_limits.

Parameters
limitspointer to a ast_bridge_features_limits struct that has been allocated, but not initialized
Return values
0on success
-1on failure

Definition at line 3465 of file bridge.c.

3466{
3467 memset(limits, 0, sizeof(*limits));
3468
3469 if (ast_string_field_init(limits, 256)) {
3470 return -1;
3471 }
3472
3473 return 0;
3474}
#define ast_string_field_init(x, size)
Initialize a field pool and fields.
Definition: stringfields.h:359

References ast_string_field_init.

Referenced by bridge_builtin_set_limits(), and pre_bridge_setup().

◆ ast_bridge_features_limits_destroy()

void ast_bridge_features_limits_destroy ( struct ast_bridge_features_limits limits)

Destructor function for ast_bridge_features_limits.

Parameters
limitspointer to an ast_bridge_features_limits struct that needs to be destroyed

This function does not free memory allocated to the ast_bridge_features_limits struct, it only frees elements within the struct. You must still call ast_free on the struct if you allocated it with malloc.

Definition at line 3476 of file bridge.c.

3477{
3479}
#define ast_string_field_free_memory(x)
free all memory - to be called before destroying the object
Definition: stringfields.h:374

References ast_string_field_free_memory.

Referenced by bridge_features_limits_dtor(), and pre_bridge_setup().

◆ ast_bridge_features_merge()

void ast_bridge_features_merge ( struct ast_bridge_features into,
const struct ast_bridge_features from 
)

Merge one ast_bridge_features into another.

Parameters
intoThe ast_bridge_features that will be merged into
fromThe ast_bridge_features that will be merged from

Definition at line 3664 of file bridge.c.

3665{
3666 struct ast_bridge_hook_timer *hook;
3667 int idx;
3668
3669 /* Merge hook containers */
3672
3673 /* Merge hook heaps */
3675 for (idx = 1; (hook = ast_heap_peek(from->interval_hooks, idx)); idx++) {
3676 wrap_hook(into, hook);
3677 }
3679
3680 /* Merge feature flags */
3681 into->feature_flags.flags |= from->feature_flags.flags;
3682 into->usable |= from->usable;
3683
3684 into->mute |= from->mute;
3685 into->dtmf_passthrough |= from->dtmf_passthrough;
3686}
#define ao2_callback(c, flags, cb_fn, arg)
ao2_callback() is a generic function that applies cb_fn() to all objects in a container,...
Definition: astobj2.h:1693
static int merge_container_cb(void *obj, void *data, int flags)
Callback for merging hook ao2_containers.
Definition: bridge.c:3631
static void wrap_hook(struct ast_bridge_features *features, struct ast_bridge_hook_timer *hook)
Wrap the provided interval hook and add it to features.
Definition: bridge.c:3652
#define ast_heap_unlock(h)
Definition: heap.h:249
#define ast_heap_wrlock(h)
Definition: heap.h:247
void * ast_heap_peek(struct ast_heap *h, unsigned int index)
Peek at an element on a heap.
Definition: heap.c:267
struct ast_flags feature_flags
unsigned int flags
Definition: utils.h:200

References ao2_callback, ast_heap_peek(), ast_heap_unlock, ast_heap_wrlock, ast_bridge_features::dtmf_hooks, ast_bridge_features::dtmf_passthrough, ast_bridge_features::feature_flags, ast_flags::flags, ast_bridge_features::interval_hooks, merge_container_cb(), ast_bridge_features::mute, ast_bridge_features::other_hooks, ast_bridge_features::usable, and wrap_hook().

Referenced by bridge_channel_internal_join(), and channel_feature_hooks_set_full().

◆ ast_bridge_features_new()

struct ast_bridge_features * ast_bridge_features_new ( void  )

Allocate a new bridge features struct.

Since
12.0.0

Example usage:

struct ast_bridge_features *features;
Returns
features New allocated features struct.
Return values
NULLon error.

Definition at line 3752 of file bridge.c.

3753{
3754 struct ast_bridge_features *features;
3755
3756 features = ast_malloc(sizeof(*features));
3757 if (features) {
3758 if (ast_bridge_features_init(features)) {
3760 features = NULL;
3761 }
3762 }
3763
3764 return features;
3765}
#define ast_malloc(len)
A wrapper for malloc()
Definition: astmm.h:191
int ast_bridge_features_init(struct ast_bridge_features *features)
Initialize bridge features structure.
Definition: bridge.c:3689

References ast_bridge_features_destroy(), ast_bridge_features_init(), ast_malloc, and NULL.

Referenced by ast_bridge_call_with_flags(), ast_unreal_channel_push_to_bridge(), bridge_exec(), bridge_impart_internal(), channel_feature_hooks_set_full(), conf_announce_channel_push(), conf_start_record(), and stasis_app_control_bridge_features_init().

◆ ast_bridge_features_register()

int ast_bridge_features_register ( enum ast_bridge_builtin_feature  feature,
ast_bridge_hook_callback  callback,
const char *  dtmf 
)

Register a handler for a built in feature.

Parameters
featureThe feature that the handler will be responsible for
callbackThe callback function that will handle it
dtmfDefault DTMF string used to activate the feature
Return values
0on success
-1on failure

Example usage:

ast_bridge_features_register(AST_BRIDGE_BUILTIN_ATTENDED_TRANSFER, bridge_builtin_attended_transfer, "*1");
int ast_bridge_features_register(enum ast_bridge_builtin_feature feature, ast_bridge_hook_callback callback, const char *dtmf)
Register a handler for a built in feature.
Definition: bridge.c:3131

This registers the function bridge_builtin_attended_transfer as the function responsible for the built in attended transfer feature.

Definition at line 3131 of file bridge.c.

3132{
3133 if (ARRAY_LEN(builtin_features_handlers) <= feature
3134 || builtin_features_handlers[feature]) {
3135 return -1;
3136 }
3137
3138 if (!ast_strlen_zero(dtmf)) {
3139 ast_copy_string(builtin_features_dtmf[feature], dtmf, sizeof(builtin_features_dtmf[feature]));
3140 }
3141
3142 builtin_features_handlers[feature] = callback;
3143
3144 return 0;
3145}

References ARRAY_LEN, ast_copy_string(), ast_strlen_zero(), builtin_features_dtmf, and builtin_features_handlers.

Referenced by ast_bridging_init_basic(), load_module(), and load_parking_bridge_features().

◆ ast_bridge_features_remove()

void ast_bridge_features_remove ( struct ast_bridge_features features,
enum ast_bridge_hook_remove_flags  flags 
)

Remove marked bridge channel feature hooks.

Since
12.0.0
Parameters
featuresBridge features structure
flagsDeterminator for whether hook is removed.

Definition at line 3570 of file bridge.c.

3571{
3572 hooks_remove_container(features->dtmf_hooks, remove_flags);
3573 hooks_remove_container(features->other_hooks, remove_flags);
3574 hooks_remove_heap(features->interval_hooks, remove_flags);
3575}
static void hooks_remove_heap(struct ast_heap *hooks, enum ast_bridge_hook_remove_flags remove_flags)
Definition: bridge.c:3548
static void hooks_remove_container(struct ao2_container *hooks, enum ast_bridge_hook_remove_flags remove_flags)
Definition: bridge.c:3534

References ast_bridge_features::dtmf_hooks, hooks_remove_container(), hooks_remove_heap(), ast_bridge_features::interval_hooks, ast_bridge_features::other_hooks, and ast_bridge_hook::remove_flags.

Referenced by bridge_base_pull(), bridge_channel_internal_join(), bridge_do_merge(), bridge_do_move(), and remove_hooks_on_personality_change().

◆ ast_bridge_features_set_flag()

void ast_bridge_features_set_flag ( struct ast_bridge_features features,
unsigned int  flag 
)

Set a flag on a bridge channel features structure.

Parameters
featuresBridge channel features structure
flagFlag to enable

Example usage:

struct ast_bridge_features features;
void ast_bridge_features_set_flag(struct ast_bridge_features *features, unsigned int flag)
Set a flag on a bridge channel features structure.
Definition: bridge.c:3496
@ AST_BRIDGE_CHANNEL_FLAG_DISSOLVE_HANGUP

This sets the AST_BRIDGE_CHANNEL_FLAG_DISSOLVE_HANGUP feature to be enabled on the features structure 'features'.

Definition at line 3496 of file bridge.c.

3497{
3498 ast_set_flag(&features->feature_flags, flag);
3499 features->usable = 1;
3500}
long int flag
Definition: f2c.h:83
#define ast_set_flag(p, flag)
Definition: utils.h:70

References ast_set_flag, ast_bridge_features::feature_flags, and ast_bridge_features::usable.

◆ ast_bridge_features_set_limits()

int ast_bridge_features_set_limits ( struct ast_bridge_features features,
struct ast_bridge_features_limits limits,
enum ast_bridge_hook_remove_flags  remove_flags 
)

Limit the amount of time a channel may stay in the bridge and optionally play warning messages as time runs out.

Parameters
featuresBridge features structure
limitsConfigured limits applicable to the channel
remove_flagsDictates what situations the hook should be removed.
Return values
0on success
-1on failure

Example usage:

struct ast_bridge_features features;
int ast_bridge_features_set_limits(struct ast_bridge_features *features, struct ast_bridge_features_limits *limits, enum ast_bridge_hook_remove_flags remove_flags)
Limit the amount of time a channel may stay in the bridge and optionally play warning messages as tim...
Definition: bridge.c:3481
int ast_bridge_features_limits_construct(struct ast_bridge_features_limits *limits)
Constructor function for ast_bridge_features_limits.
Definition: bridge.c:3465
void ast_bridge_features_limits_destroy(struct ast_bridge_features_limits *limits)
Destructor function for ast_bridge_features_limits.
Definition: bridge.c:3476
Structure that contains configuration information for the limits feature.

This sets the maximum time the channel can be in the bridge to 10 seconds and does not play any warnings.

Note
This API call can only be used on a features structure that will be used in association with a bridge channel.
The ast_bridge_features_limits structure must remain accessible for the lifetime of the features structure.

Definition at line 3481 of file bridge.c.

3484{
3487
3489 return callback(features, limits, remove_flags);
3490 }
3491
3492 ast_log(LOG_ERROR, "Attempted to set limits without an AST_BRIDGE_BUILTIN_INTERVAL_LIMITS callback registered.\n");
3493 return -1;
3494}
static ast_bridge_builtin_set_limits_fn builtin_interval_handlers[AST_BRIDGE_BUILTIN_INTERVAL_END]
Definition: bridge.c:161
int(* ast_bridge_builtin_set_limits_fn)(struct ast_bridge_features *features, struct ast_bridge_features_limits *limits, enum ast_bridge_hook_remove_flags remove_flags)
Attach interval hooks to a bridge features structure.
@ AST_BRIDGE_BUILTIN_INTERVAL_LIMITS

References AST_BRIDGE_BUILTIN_INTERVAL_LIMITS, ast_log, builtin_interval_handlers, and LOG_ERROR.

Referenced by pre_bridge_setup().

◆ ast_bridge_features_unregister()

int ast_bridge_features_unregister ( enum ast_bridge_builtin_feature  feature)

Unregister a handler for a built in feature.

Parameters
featureThe feature to unregister
Return values
0on success
-1on failure

Example usage:

ast_bridge_features_unregister(AST_BRIDGE_BUILTIN_ATTENDED_TRANSFER);
int ast_bridge_features_unregister(enum ast_bridge_builtin_feature feature)
Unregister a handler for a built in feature.
Definition: bridge.c:3147

This unregisters the function that is handling the built in attended transfer feature.

Definition at line 3147 of file bridge.c.

3148{
3149 if (ARRAY_LEN(builtin_features_handlers) <= feature
3150 || !builtin_features_handlers[feature]) {
3151 return -1;
3152 }
3153
3155
3156 return 0;
3157}

References ARRAY_LEN, builtin_features_handlers, and NULL.

Referenced by unload_module(), and unload_parking_bridge_features().

◆ ast_bridge_find_by_id()

struct ast_bridge * ast_bridge_find_by_id ( const char *  bridge_id)

Find bridge by id.

Since
12.0.0
Parameters
bridge_idBridge identifier
Returns
NULL bridge not found
non-NULL reference to bridge

Definition at line 5081 of file bridge.c.

5082{
5083 return ao2_find(bridges, bridge_id, OBJ_SEARCH_KEY);
5084}
#define ao2_find(container, arg, flags)
Definition: astobj2.h:1736
@ OBJ_SEARCH_KEY
The arg parameter is a search key, but is not an object.
Definition: astobj2.h:1101
static struct ao2_container * bridges
Definition: bridge.c:132

References ao2_find, bridges, and OBJ_SEARCH_KEY.

Referenced by ast_bridge_get_snapshot_by_uniqueid(), bridge_register(), complete_bridge_participant(), handle_bridge_kick_channel(), manager_bridge_destroy(), and manager_bridge_kick().

◆ ast_bridge_hangup_hook()

int ast_bridge_hangup_hook ( struct ast_bridge_features features,
ast_bridge_hook_callback  callback,
void *  hook_pvt,
ast_bridge_hook_pvt_destructor  destructor,
enum ast_bridge_hook_remove_flags  remove_flags 
)

Attach a hangup hook to a bridge features structure.

Parameters
featuresBridge features structure
callbackFunction to execute upon activation
hook_pvtUnique data
destructorOptional destructor callback for hook_pvt data
remove_flagsDictates what situations the hook should be removed.
Return values
0on success
-1on failure (The caller must cleanup any hook_pvt resources.)

Example usage:

struct ast_bridge_features features;
ast_bridge_hangup_hook(&features, hangup_callback, NULL, NULL, 0);
int ast_bridge_hangup_hook(struct ast_bridge_features *features, ast_bridge_hook_callback callback, void *hook_pvt, ast_bridge_hook_pvt_destructor destructor, enum ast_bridge_hook_remove_flags remove_flags)
Attach a hangup hook to a bridge features structure.
Definition: bridge.c:3334

This makes the bridging core call hangup_callback if a channel that has this hook hangs up. A pointer to useful data may be provided to the hook_pvt parameter.

Definition at line 3334 of file bridge.c.

3339{
3340 return bridge_other_hook(features, callback, hook_pvt, destructor, remove_flags,
3342}
static int bridge_other_hook(struct ast_bridge_features *features, ast_bridge_hook_callback callback, void *hook_pvt, ast_bridge_hook_pvt_destructor destructor, enum ast_bridge_hook_remove_flags remove_flags, enum ast_bridge_hook_type type)
Definition: bridge.c:3300
@ AST_BRIDGE_HOOK_TYPE_HANGUP

References AST_BRIDGE_HOOK_TYPE_HANGUP, bridge_other_hook(), ast_bridge_hook::callback, ast_bridge_hook::destructor, ast_bridge_hook::hook_pvt, and ast_bridge_hook::remove_flags.

Referenced by add_normal_hooks(), and bridge_personality_atxfer_push().

◆ ast_bridge_impart()

int ast_bridge_impart ( struct ast_bridge bridge,
struct ast_channel chan,
struct ast_channel swap,
struct ast_bridge_features features,
enum ast_bridge_impart_flags  flags 
)

Impart a channel to a bridge (non-blocking)

Parameters
bridgeBridge to impart on
chanChannel to impart (The channel reference is stolen if impart successful.)
swapChannel to swap out if swapping. NULL if not swapping.
featuresBridge features structure.
flagsdefined by enum ast_bridge_impart_flags.
Note
The given bridge must be unlocked when calling this function.
The features parameter must be NULL or obtained by ast_bridge_features_new(). You must not dereference features after calling even if the call fails.
chan is locked by this function.
Return values
0on success
-1on failure (Caller still has ownership of chan)

Example usage:

int ast_bridge_impart(struct ast_bridge *bridge, struct ast_channel *chan, struct ast_channel *swap, struct ast_bridge_features *features, enum ast_bridge_impart_flags flags) attribute_warn_unused_result
Impart a channel to a bridge (non-blocking)
Definition: bridge.c:1947

This adds a channel pointed to by the chan pointer to the bridge pointed to by the bridge pointer. This function will return immediately and will not wait until the channel is no longer part of the bridge.

If this channel will be replacing another channel the other channel can be specified in the swap parameter. The other channel will be thrown out of the bridge in an atomic fashion.

If channel specific features are enabled, a pointer to the features structure can be specified in the features parameter.

Note
If you impart a channel with AST_BRIDGE_IMPART_CHAN_DEPARTABLE you MUST ast_bridge_depart() the channel if this call succeeds. The bridge channel thread is created join-able. The implication is that the channel is special and will not behave like a normal channel.
If you impart a channel with AST_BRIDGE_IMPART_CHAN_INDEPENDENT you must not ast_bridge_depart() the channel. The bridge channel thread is created non-join-able. The channel must be treated as if it were placed into the bridge by ast_bridge_join(). Channels placed into a bridge by ast_bridge_join() are removed by a third party using ast_bridge_remove().
Any callbacks on the channel will be invoked on failure with the reason as AST_BRIDGE_AFTER_CB_REASON_IMPART_FAILED.

Definition at line 1947 of file bridge.c.

1952{
1954 .done = 0,
1955 };
1956 int res;
1957 SCOPE_TRACE(1, "%s Bridge: %s\n", ast_channel_name(chan), bridge->uniqueid);
1958
1959 ast_mutex_init(&cond.lock);
1960 ast_cond_init(&cond.cond, NULL);
1961
1962 res = bridge_impart_internal(bridge, chan, swap, features, flags, &cond);
1963 if (res) {
1964 /* Impart failed. Signal any other waiting impart threads */
1967 }
1968
1969 ast_cond_destroy(&cond.cond);
1970 ast_mutex_destroy(&cond.lock);
1971
1972 return res;
1973}
ast_cond_t cond
Definition: app_sla.c:336
void bridge_channel_impart_signal(struct ast_channel *chan)
Definition: bridge.c:1651
static int bridge_impart_internal(struct ast_bridge *bridge, struct ast_channel *chan, struct ast_channel *swap, struct ast_bridge_features *features, enum ast_bridge_impart_flags flags, struct bridge_channel_impart_cond *cond)
Definition: bridge.c:1846
void ast_bridge_discard_after_callback(struct ast_channel *chan, enum ast_bridge_after_cb_reason reason)
Run discarding any after bridge callbacks.
Definition: bridge_after.c:239
@ AST_BRIDGE_AFTER_CB_REASON_IMPART_FAILED
Definition: bridge_after.h:49
#define ast_cond_destroy(cond)
Definition: lock.h:206
#define ast_cond_init(cond, attr)
Definition: lock.h:205
#define ast_mutex_init(pmutex)
Definition: lock.h:190
#define ast_mutex_destroy(a)
Definition: lock.h:192
const ast_string_field uniqueid
Definition: bridge.h:405
Internal bridge impart wait condition and associated conditional.
Definition: bridge.c:1544

References AST_BRIDGE_AFTER_CB_REASON_IMPART_FAILED, ast_bridge_discard_after_callback(), ast_channel_name(), ast_cond_destroy, ast_cond_init, ast_mutex_destroy, ast_mutex_init, bridge_channel_impart_signal(), bridge_impart_internal(), cond, NULL, SCOPE_TRACE, and ast_bridge::uniqueid.

Referenced by add_to_dial_bridge(), ast_bridge_add_channel(), ast_bridge_call_with_flags(), AST_TEST_DEFINE(), ast_unreal_channel_push_to_bridge(), attended_transfer_bridge(), blind_transfer_bridge(), conf_announce_channel_push(), conf_start_record(), control_swap_channel_in_bridge(), feature_attended_transfer(), local_call(), parking_blind_transfer_park(), recalling_exit(), refer_incoming_invite_request(), and retransfer_enter().

◆ ast_bridge_interval_hook()

int ast_bridge_interval_hook ( struct ast_bridge_features features,
enum ast_bridge_hook_timer_option  flags,
unsigned int  interval,
ast_bridge_hook_callback  callback,
void *  hook_pvt,
ast_bridge_hook_pvt_destructor  destructor,
enum ast_bridge_hook_remove_flags  remove_flags 
)

Attach an interval hook to a bridge features structure.

Parameters
featuresBridge features structure
flagsInterval timer callback option flags.
intervalThe interval that the hook should execute at in milliseconds
callbackFunction to execute upon activation
hook_pvtUnique data
destructorOptional destructor callback for hook_pvt data
remove_flagsDictates what situations the hook should be removed.
Return values
0on success
-1on failure (The caller must cleanup any hook_pvt resources.)
struct ast_bridge_features features;
ast_bridge_interval_hook(&features, 1000, playback_callback, NULL, NULL, 0);
int ast_bridge_interval_hook(struct ast_bridge_features *features, enum ast_bridge_hook_timer_option flags, unsigned int interval, ast_bridge_hook_callback callback, void *hook_pvt, ast_bridge_hook_pvt_destructor destructor, enum ast_bridge_hook_remove_flags remove_flags)
Attach an interval hook to a bridge features structure.
Definition: bridge.c:3388

This makes the bridging core call playback_callback every second. A pointer to useful data may be provided to the hook_pvt parameter.

Definition at line 3388 of file bridge.c.

3395{
3396 struct ast_bridge_hook_timer *hook;
3397 int res;
3398
3399 if (!features ||!interval || !callback) {
3400 return -1;
3401 }
3402
3403 /* Allocate new hook and setup it's various variables */
3404 hook = (struct ast_bridge_hook_timer *) bridge_hook_generic(sizeof(*hook), callback,
3405 hook_pvt, destructor, remove_flags);
3406 if (!hook) {
3407 return -1;
3408 }
3410 hook->timer.interval = interval;
3411 hook->timer.trip_time = ast_tvadd(ast_tvnow(), ast_samp2tv(interval, 1000));
3412 hook->timer.seqno = ast_atomic_fetchadd_int((int *) &features->interval_sequence, +1);
3413 hook->timer.flags = flags;
3414
3415 ast_debug(1, "Putting interval hook %p with interval %u in the heap on features %p\n",
3416 hook, hook->timer.interval, features);
3418 res = ast_heap_push(features->interval_hooks, hook);
3420 if (res) {
3421 /*
3422 * Could not push the hook into the heap
3423 *
3424 * Remove the hook_pvt destructor call from the hook since we
3425 * are returning failure to install the hook.
3426 */
3427 hook->generic.destructor = NULL;
3428 ao2_ref(hook, -1);
3429 }
3430
3431 return res ? -1 : 0;
3432}
@ AST_BRIDGE_HOOK_TYPE_TIMER
#define ast_heap_push(h, elm)
Push an element on to a heap.
Definition: heap.h:125
int ast_atomic_fetchadd_int(volatile int *p, int v)
Atomically add v to *p and return the previous value of *p.
Definition: lock.h:761
unsigned int interval_sequence
struct ast_bridge_hook generic
struct ast_bridge_hook_timer_parms timer
struct timeval ast_samp2tv(unsigned int _nsamp, unsigned int _rate)
Returns a timeval corresponding to the duration of n samples at rate r. Useful to convert samples to ...
Definition: time.h:282
struct timeval ast_tvadd(struct timeval a, struct timeval b)
Returns the sum of two timevals a + b.
Definition: extconf.c:2282
struct timeval ast_tvnow(void)
Returns current timeval. Meant to replace calls to gettimeofday().
Definition: time.h:159

References ao2_ref, ast_atomic_fetchadd_int(), AST_BRIDGE_HOOK_TYPE_TIMER, ast_debug, ast_heap_push, ast_heap_unlock, ast_heap_wrlock, ast_samp2tv(), ast_tvadd(), ast_tvnow(), bridge_hook_generic(), ast_bridge_hook::destructor, ast_bridge_hook_timer_parms::flags, ast_bridge_hook_timer::generic, ast_bridge_hook_timer_parms::interval, ast_bridge_features::interval_hooks, ast_bridge_features::interval_sequence, NULL, ast_bridge_hook_timer_parms::seqno, ast_bridge_hook_timer::timer, ast_bridge_hook_timer_parms::trip_time, and ast_bridge_hook::type.

Referenced by agent_request_exec(), apply_option_timeout(), AST_TEST_DEFINE(), bridge_agent_hold_push(), bridge_builtin_set_limits(), confbridge_exec(), parking_set_duration(), set_interval_hook(), and wrap_hook().

◆ ast_bridge_interval_register()

int ast_bridge_interval_register ( enum ast_bridge_builtin_interval  interval,
ast_bridge_builtin_set_limits_fn  callback 
)

Register a handler for a built in interval feature.

Parameters
intervalThe interval feature that the handler will be responsible for
callbackthe Callback function that will handle it
Return values
0on success
-1on failure

Example usage:

static int bridge_builtin_set_limits(struct ast_bridge_features *features, struct ast_bridge_features_limits *limits, enum ast_bridge_hook_remove_flags remove_flags)
int ast_bridge_interval_register(enum ast_bridge_builtin_interval interval, ast_bridge_builtin_set_limits_fn callback)
Register a handler for a built in interval feature.
Definition: bridge.c:3176

This registers the function bridge_builtin_set_limits as the function responsible for the built in duration limit feature.

Definition at line 3176 of file bridge.c.

3177{
3178 if (ARRAY_LEN(builtin_interval_handlers) <= interval
3179 || builtin_interval_handlers[interval]) {
3180 return -1;
3181 }
3182
3183 builtin_interval_handlers[interval] = callback;
3184
3185 return 0;
3186}

References ARRAY_LEN, and builtin_interval_handlers.

Referenced by load_module().

◆ ast_bridge_interval_unregister()

int ast_bridge_interval_unregister ( enum ast_bridge_builtin_interval  interval)

Unregisters a handler for a built in interval feature.

Parameters
intervalthe interval feature to unregister
Return values
0on success
-1on failure

Example usage:

ast_bridge_interval_unregister(AST_BRIDGE_BULTIN_INTERVAL_LIMITS)
int ast_bridge_interval_unregister(enum ast_bridge_builtin_interval interval)
Unregisters a handler for a built in interval feature.
Definition: bridge.c:3188

This unregisters the function that is handling the built in duration limit feature.

Definition at line 3188 of file bridge.c.

3189{
3190 if (ARRAY_LEN(builtin_interval_handlers) <= interval
3191 || !builtin_interval_handlers[interval]) {
3192 return -1;
3193 }
3194
3195 builtin_interval_handlers[interval] = NULL;
3196
3197 return 0;
3198
3199}

References ARRAY_LEN, builtin_interval_handlers, and NULL.

Referenced by unload_module().

◆ ast_bridge_is_video_src()

int ast_bridge_is_video_src ( struct ast_bridge bridge,
struct ast_channel chan 
)

Determine if a channel is a video src for the bridge.

Return values
0Not a current video source of the bridge.
non-zerois a video source of the bridge, The number returned represents the priority this video stream has on the bridge where 1 is the highest priority.

Definition at line 3960 of file bridge.c.

3961{
3962 int res = 0;
3963
3964 ast_bridge_lock(bridge);
3965 switch (bridge->softmix.video_mode.mode) {
3967 break;
3970 res = 1;
3971 }
3972 break;
3975 res = 1;
3976 } else if (bridge->softmix.video_mode.mode_data.talker_src_data.chan_old_vsrc == chan) {
3977 res = 2;
3978 }
3980 break;
3981 }
3982 ast_bridge_unlock(bridge);
3983 return res;
3984}
@ AST_BRIDGE_VIDEO_MODE_SINGLE_SRC
Definition: bridge.h:106
@ AST_BRIDGE_VIDEO_MODE_TALKER_SRC
Definition: bridge.h:109
@ AST_BRIDGE_VIDEO_MODE_NONE
Definition: bridge.h:104
@ AST_BRIDGE_VIDEO_MODE_SFU
Definition: bridge.h:113
struct ast_bridge_video_mode video_mode
Definition: bridge.h:283
struct ast_bridge_video_single_src_data single_src_data
Definition: bridge.h:167
struct ast_bridge_video_talker_src_data talker_src_data
Definition: bridge.h:168
union ast_bridge_video_mode::@191 mode_data
enum ast_bridge_video_mode_type mode
Definition: bridge.h:164
struct ast_channel * chan_vsrc
Definition: bridge.h:120
struct ast_channel * chan_old_vsrc
Definition: bridge.h:131
struct ast_channel * chan_vsrc
Definition: bridge.h:127
struct ast_bridge_softmix softmix
Definition: bridge.h:371

References ast_bridge_lock, ast_bridge_unlock, AST_BRIDGE_VIDEO_MODE_NONE, AST_BRIDGE_VIDEO_MODE_SFU, AST_BRIDGE_VIDEO_MODE_SINGLE_SRC, AST_BRIDGE_VIDEO_MODE_TALKER_SRC, ast_bridge_video_talker_src_data::chan_old_vsrc, ast_bridge_video_single_src_data::chan_vsrc, ast_bridge_video_talker_src_data::chan_vsrc, ast_bridge_video_mode::mode, ast_bridge_video_mode::mode_data, ast_bridge_video_mode::single_src_data, ast_bridge::softmix, ast_bridge_video_mode::talker_src_data, and ast_bridge_softmix::video_mode.

Referenced by handle_video_on_exit(), handle_video_on_join(), softmix_bridge_write_video(), and softmix_pass_video_top_priority().

◆ ast_bridge_join()

int ast_bridge_join ( struct ast_bridge bridge,
struct ast_channel chan,
struct ast_channel swap,
struct ast_bridge_features features,
struct ast_bridge_tech_optimizations tech_args,
enum ast_bridge_join_flags  flags 
)

Join a channel to a bridge (blocking)

Parameters
bridgeBridge to join
chanChannel to join
swapChannel to swap out if swapping (A channel reference is stolen.)
featuresBridge features structure
tech_argsOptional Bridging tech optimization parameters for this channel.
flagsdefined by enum ast_bridge_join_flags.
Note
The passed in swap channel is always unreffed on return. It is not a good idea to access the swap channel on return or for the caller to keep a reference to it.
Absolutely NO locks should be held before calling this function since it blocks.
Return values
0if the channel successfully joined the bridge before it exited.
-1if the channel failed to join the bridge

Example usage:

int ast_bridge_join(struct ast_bridge *bridge, struct ast_channel *chan, struct ast_channel *swap, struct ast_bridge_features *features, struct ast_bridge_tech_optimizations *tech_args, enum ast_bridge_join_flags flags)
Join a channel to a bridge (blocking)
Definition: bridge.c:1690
@ AST_BRIDGE_JOIN_PASS_REFERENCE
Definition: bridge.h:539

This adds a channel pointed to by the chan pointer to the bridge pointed to by the bridge pointer. This function will not return until the channel has been removed from the bridge, swapped out for another channel, or has hung up.

If this channel will be replacing another channel the other channel can be specified in the swap parameter. The other channel will be thrown out of the bridge in an atomic fashion.

If channel specific features are enabled a pointer to the features structure can be specified in the features parameter.

Definition at line 1690 of file bridge.c.

1696{
1697 struct ast_bridge_channel *bridge_channel;
1698 int res = 0;
1699 SCOPE_TRACE(1, "%s Bridge: %s\n", ast_channel_name(chan), bridge->uniqueid);
1700
1701 bridge_channel = bridge_channel_internal_alloc(bridge);
1702 if (flags & AST_BRIDGE_JOIN_PASS_REFERENCE) {
1703 ao2_ref(bridge, -1);
1704 }
1705 if (!bridge_channel) {
1706 ao2_t_cleanup(swap, "Error exit: bridge_channel alloc failed");
1707 res = -1;
1708 goto join_exit;
1709 }
1710/* XXX ASTERISK-21271 features cannot be NULL when passed in. When it is changed to allocated we can do like ast_bridge_impart() and allocate one. */
1712 if (!features) {
1713 ao2_ref(bridge_channel, -1);
1714 ao2_t_cleanup(swap, "Error exit: features is NULL");
1715 res = -1;
1716 goto join_exit;
1717 }
1718 if (tech_args) {
1719 bridge_channel->tech_args = *tech_args;
1720 }
1721
1724 res = -1;
1725 } else {
1727 }
1729 bridge_channel->thread = pthread_self();
1730 bridge_channel->chan = chan;
1731 bridge_channel->swap = swap;
1732 bridge_channel->features = features;
1733 bridge_channel->inhibit_colp = !!(flags & AST_BRIDGE_JOIN_INHIBIT_JOIN_COLP);
1734
1735 /* allow subclass to peek at upcoming push operation */
1736 if (bridge->v_table->push_peek && !res) {
1737 struct ast_bridge_channel *bcswap = NULL;
1738
1740 if (bridge_channel->swap) {
1741 bcswap = bridge_find_channel(bridge, bridge_channel->swap);
1742 }
1743 res = bridge->v_table->push_peek(bridge, bridge_channel, bcswap);
1745 }
1746
1747 if (!res) {
1748 res = bridge_channel_internal_join(bridge_channel);
1749 }
1750
1751 /* Cleanup all the data in the bridge channel after it leaves the bridge. */
1755 /* Due to a race condition, we lock the bridge channel here for ast_bridge_channel_get_chan */
1756 ao2_lock(bridge_channel);
1757 bridge_channel->chan = NULL;
1758 ao2_unlock(bridge_channel);
1759 /* If bridge_channel->swap is not NULL then the join failed. */
1760 ao2_t_cleanup(bridge_channel->swap, "Bridge complete: join failed");
1761 bridge_channel->swap = NULL;
1762 bridge_channel->features = NULL;
1763
1764 ao2_ref(bridge_channel, -1);
1765
1766join_exit:
1771 /* Claim the after bridge goto is an async goto destination. */
1775 }
1776 return res;
1777}
#define ao2_unlock(a)
Definition: astobj2.h:729
#define ao2_lock(a)
Definition: astobj2.h:717
#define ao2_t_cleanup(obj, tag)
Definition: astobj2.h:1935
@ AST_BRIDGE_JOIN_INHIBIT_JOIN_COLP
Definition: bridge.h:541
int ast_bridge_setup_after_goto(struct ast_channel *chan)
Setup any after bridge goto location to begin execution.
Definition: bridge_after.c:435
void ast_bridge_run_after_callback(struct ast_channel *chan)
Run any after bridge callback.
Definition: bridge_after.c:212
struct ast_bridge_channel * bridge_channel_internal_alloc(struct ast_bridge *bridge)
int bridge_channel_internal_join(struct ast_bridge_channel *bridge_channel)
struct ast_flags * ast_channel_flags(struct ast_channel *chan)
@ AST_FLAG_ZOMBIE
Definition: channel.h:1007
int ast_softhangup_nolock(struct ast_channel *chan, int cause)
Softly hangup up a channel (no channel lock)
Definition: channel.c:2487
int ast_channel_softhangup_internal_flag(struct ast_channel *chan)
@ AST_SOFTHANGUP_ASYNCGOTO
Definition: channel.h:1146
struct ast_channel * swap
unsigned int inhibit_colp
struct ast_bridge_tech_optimizations tech_args
ast_bridge_push_channel_fn push_peek
Definition: bridge.h:277
const struct ast_bridge_methods * v_table
Definition: bridge.h:355
#define ast_test_flag(p, flag)
Definition: utils.h:63

References ao2_lock, ao2_ref, ao2_t_cleanup, ao2_unlock, ast_assert, AST_BRIDGE_JOIN_INHIBIT_JOIN_COLP, AST_BRIDGE_JOIN_PASS_REFERENCE, ast_bridge_lock, ast_bridge_run_after_callback(), ast_bridge_setup_after_goto(), ast_bridge_unlock, ast_channel_flags(), ast_channel_internal_bridge_channel_set(), ast_channel_lock, ast_channel_name(), ast_channel_softhangup_internal_flag(), ast_channel_unlock, AST_FLAG_ZOMBIE, AST_SOFTHANGUP_ASYNCGOTO, ast_softhangup_nolock(), ast_test_flag, ast_bridge_channel::bridge, bridge_channel_impart_signal(), bridge_channel_internal_alloc(), bridge_channel_internal_join(), bridge_find_channel(), ast_bridge_channel::chan, ast_bridge_channel::features, ast_bridge_channel::inhibit_colp, NULL, ast_bridge_methods::push_peek, SCOPE_TRACE, ast_bridge_channel::swap, ast_bridge_channel::tech_args, ast_bridge_channel::thread, ast_bridge::uniqueid, and ast_bridge::v_table.

Referenced by agent_request_exec(), agent_run(), ast_bridge_call_with_flags(), bridge_exec(), bridgeadd_exec(), bridgewait_exec(), confbridge_exec(), park_and_announce_app_exec(), park_app_exec(), and parked_call_app_exec().

◆ ast_bridge_join_hook()

int ast_bridge_join_hook ( struct ast_bridge_features features,
ast_bridge_hook_callback  callback,
void *  hook_pvt,
ast_bridge_hook_pvt_destructor  destructor,
enum ast_bridge_hook_remove_flags  remove_flags 
)

Attach a bridge channel join hook to a bridge features structure.

Parameters
featuresBridge features structure
callbackFunction to execute upon activation
hook_pvtUnique data
destructorOptional destructor callback for hook_pvt data
remove_flagsDictates what situations the hook should be removed.
Return values
0on success
-1on failure (The caller must cleanup any hook_pvt resources.)

Example usage:

struct ast_bridge_features features;
static int join_callback(struct ast_bridge_channel *bridge_channel, void *ignore)
int ast_bridge_join_hook(struct ast_bridge_features *features, ast_bridge_hook_callback callback, void *hook_pvt, ast_bridge_hook_pvt_destructor destructor, enum ast_bridge_hook_remove_flags remove_flags)
Attach a bridge channel join hook to a bridge features structure.
Definition: bridge.c:3344

This makes the bridging core call join_callback when a channel successfully joins the bridging system. A pointer to useful data may be provided to the hook_pvt parameter.

Definition at line 3344 of file bridge.c.

3349{
3350 return bridge_other_hook(features, callback, hook_pvt, destructor, remove_flags,
3352}
@ AST_BRIDGE_HOOK_TYPE_JOIN

References AST_BRIDGE_HOOK_TYPE_JOIN, bridge_other_hook(), ast_bridge_hook::callback, ast_bridge_hook::destructor, ast_bridge_hook::hook_pvt, and ast_bridge_hook::remove_flags.

Referenced by agent_request_exec(), and confbridge_exec().

◆ ast_bridge_kick()

int ast_bridge_kick ( struct ast_bridge bridge,
struct ast_channel chan 
)

Kick a channel from a bridge.

Parameters
bridgeBridge that the channel is to be kicked from
chanChannel to kick
Return values
0on success
-1on failure

Example usage:

ast_bridge_kick(bridge, chan);
int ast_bridge_kick(struct ast_bridge *bridge, struct ast_channel *chan)
Kick a channel from a bridge.
Definition: bridge.c:2048

This kicks the channel pointed to by the chan pointer from the bridge pointed to by the bridge pointer and requests that it be hung up. Control over the channel will NOT be given to the calling thread.

Note
The functional difference between ast_bridge_kick() and ast_bridge_remove() is that the bridge may dissolve as a result of the channel being kicked.
This API call can be used on channels that were added to the bridge using both ast_bridge_join and ast_bridge_impart.

Definition at line 2048 of file bridge.c.

2049{
2050 struct ast_bridge_channel *bridge_channel;
2051 int res;
2052
2054
2055 /* Try to find the channel that we want to kick. */
2056 if (!(bridge_channel = bridge_find_channel(bridge, chan))) {
2058 return -1;
2059 }
2060
2061 res = ast_bridge_channel_queue_callback(bridge_channel, 0, kick_it, NULL, 0);
2062
2064
2065 return res;
2066}
static void kick_it(struct ast_bridge_channel *bridge_channel, const void *payload, size_t payload_size)
Definition: bridge.c:2043
int ast_bridge_channel_queue_callback(struct ast_bridge_channel *bridge_channel, enum ast_bridge_channel_custom_callback_option flags, ast_bridge_custom_callback_fn callback, const void *payload, size_t payload_size)
Queue a bridge action custom callback frame onto the bridge channel.

References ast_bridge_channel_queue_callback(), ast_bridge_lock, ast_bridge_unlock, ast_bridge_channel::bridge, bridge_find_channel(), ast_bridge_channel::chan, kick_it(), and NULL.

Referenced by handle_bridge_kick_channel(), and manager_bridge_kick().

◆ ast_bridge_leave_hook()

int ast_bridge_leave_hook ( struct ast_bridge_features features,
ast_bridge_hook_callback  callback,
void *  hook_pvt,
ast_bridge_hook_pvt_destructor  destructor,
enum ast_bridge_hook_remove_flags  remove_flags 
)

Attach a bridge channel leave hook to a bridge features structure.

Parameters
featuresBridge features structure
callbackFunction to execute upon activation
hook_pvtUnique data
destructorOptional destructor callback for hook_pvt data
remove_flagsDictates what situations the hook should be removed.
Return values
0on success
-1on failure (The caller must cleanup any hook_pvt resources.)

Example usage:

struct ast_bridge_features features;
ast_bridge_leave_hook(&features, leave_callback, NULL, NULL, 0);
int ast_bridge_leave_hook(struct ast_bridge_features *features, ast_bridge_hook_callback callback, void *hook_pvt, ast_bridge_hook_pvt_destructor destructor, enum ast_bridge_hook_remove_flags remove_flags)
Attach a bridge channel leave hook to a bridge features structure.
Definition: bridge.c:3354

This makes the bridging core call leave_callback when a channel successfully leaves the bridging system. A pointer to useful data may be provided to the hook_pvt parameter.

Definition at line 3354 of file bridge.c.

3359{
3360 return bridge_other_hook(features, callback, hook_pvt, destructor, remove_flags,
3362}
@ AST_BRIDGE_HOOK_TYPE_LEAVE

References AST_BRIDGE_HOOK_TYPE_LEAVE, bridge_other_hook(), ast_bridge_hook::callback, ast_bridge_hook::destructor, ast_bridge_hook::hook_pvt, and ast_bridge_hook::remove_flags.

Referenced by confbridge_exec().

◆ ast_bridge_merge()

int ast_bridge_merge ( struct ast_bridge dst_bridge,
struct ast_bridge src_bridge,
int  merge_best_direction,
struct ast_channel **  kick_me,
unsigned int  num_kick 
)

Merge two bridges together.

Parameters
dst_bridgeDestination bridge of merge.
src_bridgeSource bridge of merge.
merge_best_directionTRUE if don't care about which bridge merges into the other.
kick_meArray of channels to kick from the bridges.
num_kickNumber of channels in the kick_me array.
Note
Absolutely NO bridge or channel locks should be held before calling this function.
Return values
0on success
-1on failure

Example usage:

ast_bridge_merge(dst_bridge, src_bridge, 0, NULL, 0);
int ast_bridge_merge(struct ast_bridge *dst_bridge, struct ast_bridge *src_bridge, int merge_best_direction, struct ast_channel **kick_me, unsigned int num_kick)
Merge two bridges together.
Definition: bridge.c:2369

This moves the channels in src_bridge into the bridge pointed to by dst_bridge.

Definition at line 2369 of file bridge.c.

2370{
2371 int res;
2372
2373 /* Sanity check. */
2374 ast_assert(dst_bridge && src_bridge);
2375
2376 ast_bridge_lock_both(dst_bridge, src_bridge);
2377 res = bridge_merge_locked(dst_bridge, src_bridge, merge_best_direction, kick_me, num_kick);
2378 ast_bridge_unlock(src_bridge);
2379 ast_bridge_unlock(dst_bridge);
2380 return res;
2381}
static int bridge_merge_locked(struct ast_bridge *dst_bridge, struct ast_bridge *src_bridge, int merge_best_direction, struct ast_channel **kick_me, unsigned int num_kick)
Definition: bridge.c:2285

References ast_assert, ast_bridge_lock_both, ast_bridge_unlock, and bridge_merge_locked().

◆ ast_bridge_merge_inhibit()

void ast_bridge_merge_inhibit ( struct ast_bridge bridge,
int  request 
)

Adjust the bridge merge inhibit request count.

Since
12.0.0
Parameters
bridgeWhat to operate on.
requestInhibit request increment. (Positive to add requests. Negative to remove requests.)

Definition at line 3069 of file bridge.c.

3070{
3071 ast_bridge_lock(bridge);
3073 ast_bridge_unlock(bridge);
3074}
void bridge_merge_inhibit_nolock(struct ast_bridge *bridge, int request)
Definition: bridge.c:3060
static int request(void *obj)
Definition: chan_pjsip.c:2605

References ast_bridge_lock, ast_bridge_unlock, bridge_merge_inhibit_nolock(), and request().

Referenced by attended_transfer_properties_shutdown(), consulting_exit(), and feature_attended_transfer().

◆ ast_bridge_move()

int ast_bridge_move ( struct ast_bridge dst_bridge,
struct ast_bridge src_bridge,
struct ast_channel chan,
struct ast_channel swap,
int  attempt_recovery 
)

Move a channel from one bridge to another.

Since
12.0.0
Parameters
dst_bridgeDestination bridge of bridge channel move.
src_bridgeSource bridge of bridge channel move.
chanChannel to move.
swapChannel to replace in dst_bridge.
attempt_recoveryTRUE if failure attempts to push channel back into original bridge.
Note
Absolutely NO bridge or channel locks should be held before calling this function.
Return values
0on success.
-1on failure.

Definition at line 2529 of file bridge.c.

2530{
2531 int res;
2532
2533 ast_bridge_lock_both(dst_bridge, src_bridge);
2534 res = bridge_move_locked(dst_bridge, src_bridge, chan, swap, attempt_recovery);
2535 ast_bridge_unlock(src_bridge);
2536 ast_bridge_unlock(dst_bridge);
2537 return res;
2538}

References ast_bridge_lock_both, ast_bridge_unlock, bridge_move_locked(), ast_bridge_channel::chan, and ast_bridge_channel::swap.

Referenced by agent_connect_caller(), parked_call_app_exec(), and parking_park_bridge_channel().

◆ ast_bridge_move_hook()

int ast_bridge_move_hook ( struct ast_bridge_features features,
ast_bridge_move_indicate_callback  callback,
void *  hook_pvt,
ast_bridge_hook_pvt_destructor  destructor,
enum ast_bridge_hook_remove_flags  remove_flags 
)

Attach a bridge channel move detection hook to a bridge features structure.

Parameters
featuresBridge features structure
callbackFunction to execute upon activation
hook_pvtUnique data
destructorOptional destructor callback for hook_pvt data
remove_flagsDictates what situations the hook should be removed.
Return values
0on success
-1on failure (The caller must cleanup any hook_pvt resources.)

Example usage:

struct ast_bridge_features features;
ast_bridge_move_hook(&features, move_callback, NULL, NULL, 0);
int ast_bridge_move_hook(struct ast_bridge_features *features, ast_bridge_move_indicate_callback callback, void *hook_pvt, ast_bridge_hook_pvt_destructor destructor, enum ast_bridge_hook_remove_flags remove_flags)
Attach a bridge channel move detection hook to a bridge features structure.
Definition: bridge.c:3376

This makes the bridging core call callback when a channel is moved from one bridge to another. A pointer to useful data may be provided to the hook_pvt parameter.

Definition at line 3376 of file bridge.c.

3381{
3383
3384 return bridge_other_hook(features, hook_cb, hook_pvt, destructor, remove_flags,
3386}
@ AST_BRIDGE_HOOK_TYPE_MOVE
static int hook_cb(struct ast_config *cfg)
Definition: test_config.c:875

References AST_BRIDGE_HOOK_TYPE_MOVE, bridge_other_hook(), ast_bridge_hook::callback, ast_bridge_hook::destructor, hook_cb(), ast_bridge_hook::hook_pvt, and ast_bridge_hook::remove_flags.

Referenced by bridge_stasis_pull().

◆ ast_bridge_notify_masquerade()

void ast_bridge_notify_masquerade ( struct ast_channel chan)

Notify bridging that this channel was just masqueraded.

Since
12.0.0
Parameters
chanChannel just involved in a masquerade

Definition at line 1511 of file bridge.c.

1512{
1513 struct ast_bridge_channel *bridge_channel;
1514 struct ast_bridge *bridge;
1515
1516 /* Safely get the bridge_channel pointer for the chan. */
1517 ast_channel_lock(chan);
1518 bridge_channel = ast_channel_get_bridge_channel(chan);
1519 ast_channel_unlock(chan);
1520 if (!bridge_channel) {
1521 /* Not in a bridge */
1522 return;
1523 }
1524
1525 ast_bridge_channel_lock_bridge(bridge_channel);
1526 bridge = bridge_channel->bridge;
1527 if (bridge_channel == bridge_find_channel(bridge, chan)) {
1528/*
1529 * XXX ASTERISK-22366 this needs more work. The channels need
1530 * to be made compatible again if the formats change. The
1531 * bridge_channel thread needs to monitor for this case.
1532 */
1533 /* The channel we want to notify is still in a bridge. */
1534 bridge->v_table->notify_masquerade(bridge, bridge_channel);
1535 bridge_reconfigured(bridge, 1);
1536 }
1537 ast_bridge_unlock(bridge);
1538 ao2_ref(bridge_channel, -1);
1539}
void bridge_reconfigured(struct ast_bridge *bridge, unsigned int colp_update)
Definition: bridge.c:1472
void ast_bridge_channel_lock_bridge(struct ast_bridge_channel *bridge_channel)
Lock the bridge associated with the bridge channel.
ast_bridge_notify_masquerade_fn notify_masquerade
Definition: bridge.h:273

References ao2_ref, ast_bridge_channel_lock_bridge(), ast_bridge_unlock, ast_channel_get_bridge_channel(), ast_channel_lock, ast_channel_unlock, ast_bridge_channel::bridge, bridge_find_channel(), bridge_reconfigured(), ast_bridge_methods::notify_masquerade, and ast_bridge::v_table.

Referenced by channel_do_masquerade().

◆ ast_bridge_number_video_src()

int ast_bridge_number_video_src ( struct ast_bridge bridge)

◆ ast_bridge_peer()

struct ast_channel * ast_bridge_peer ( struct ast_bridge bridge,
struct ast_channel chan 
)

Get the channel's bridge peer only if the bridge is two-party.

Since
12.0.0
Parameters
bridgeThe bridge
chanChannel desiring the bridge peer channel.
Note
The returned peer channel is the current peer in the bridge when called.
Return values
NULLChannel not in a bridge or the bridge is not two-party.
non-NULLReffed peer channel at time of calling.

Definition at line 4144 of file bridge.c.

4145{
4146 struct ast_channel *peer;
4147
4149 peer = ast_bridge_peer_nolock(bridge, chan);
4151
4152 return peer;
4153}
struct ast_channel * ast_bridge_peer_nolock(struct ast_bridge *bridge, struct ast_channel *chan)
Get the channel's bridge peer only if the bridge is two-party.
Definition: bridge.c:4116
struct ast_bridge * bridge

References ast_bridge_lock, ast_bridge_peer_nolock(), ast_bridge_unlock, and ast_channel::bridge.

Referenced by ast_attended_transfer_message_create(), ast_bridge_transfer_blind(), ast_channel_bridge_peer(), and get_transfer_parties_transferer_bridge().

◆ ast_bridge_peer_nolock()

struct ast_channel * ast_bridge_peer_nolock ( struct ast_bridge bridge,
struct ast_channel chan 
)

Get the channel's bridge peer only if the bridge is two-party.

Since
12.0.0
Parameters
bridgeThe bridge which is already locked.
chanChannel desiring the bridge peer channel.
Note
The returned peer channel is the current peer in the bridge when called.
Return values
NULLChannel not in a bridge or the bridge is not two-party.
non-NULLReffed peer channel at time of calling.

Definition at line 4116 of file bridge.c.

4117{
4118 struct ast_channel *peer = NULL;
4119 struct ast_bridge_channel *iter;
4120
4121 /* Asking for the peer channel only makes sense on a two-party bridge. */
4122 if (bridge->num_channels == 2
4125 int in_bridge = 0;
4126
4128 if (iter->chan != chan) {
4129 peer = iter->chan;
4130 } else {
4131 in_bridge = 1;
4132 }
4133 }
4134 if (in_bridge && peer) {
4135 ast_channel_ref(peer);
4136 } else {
4137 peer = NULL;
4138 }
4139 }
4140
4141 return peer;
4142}
@ AST_BRIDGE_CAPABILITY_NATIVE
Definition: bridge.h:94
#define AST_LIST_TRAVERSE(head, var, field)
Loops over (traverses) the entries in a list.
Definition: linkedlists.h:491
struct ast_bridge_channel::@193 entry
unsigned int in_bridge
struct ast_bridge_channels_list channels
Definition: bridge.h:367
unsigned int num_channels
Definition: bridge.h:377
struct ast_bridge_technology * technology
Definition: bridge.h:359

References AST_BRIDGE_CAPABILITY_1TO1MIX, AST_BRIDGE_CAPABILITY_NATIVE, ast_channel_ref, AST_LIST_TRAVERSE, ast_bridge_channel::bridge, ast_bridge_technology::capabilities, ast_bridge_channel::chan, ast_bridge::channels, ast_bridge_channel::entry, ast_bridge_channel::in_bridge, NULL, ast_bridge::num_channels, and ast_bridge::technology.

Referenced by ast_bridge_peer(), ast_refer_notify_transfer_request(), and feature_automixmonitor().

◆ ast_bridge_peers()

struct ao2_container * ast_bridge_peers ( struct ast_bridge bridge)

Get a container of all channels in the bridge.

Since
12.0.0
Parameters
bridgeThe bridge
Note
The returned container is a snapshot of channels in the bridge when called.
Return values
NULLFailed to create container
non-NULLContainer of channels in the bridge

Definition at line 4105 of file bridge.c.

4106{
4107 struct ao2_container *channels;
4108
4109 ast_bridge_lock(bridge);
4111 ast_bridge_unlock(bridge);
4112
4113 return channels;
4114}
struct ao2_container * ast_bridge_peers_nolock(struct ast_bridge *bridge)
Get a container of all channels in the bridge.
Definition: bridge.c:4087
static struct channel_usage channels
Generic container type.

References ast_bridge_lock, ast_bridge_peers_nolock(), ast_bridge_unlock, and channels.

◆ ast_bridge_peers_nolock()

struct ao2_container * ast_bridge_peers_nolock ( struct ast_bridge bridge)

Get a container of all channels in the bridge.

Since
12.0.0
Parameters
bridgeThe bridge which is already locked.
Return values
NULLFailed to create container
non-NULLContainer of channels in the bridge

Definition at line 4087 of file bridge.c.

4088{
4089 struct ao2_container *channels;
4090 struct ast_bridge_channel *iter;
4091
4094 if (!channels) {
4095 return NULL;
4096 }
4097
4099 ao2_link(channels, iter->chan);
4100 }
4101
4102 return channels;
4103}
@ AO2_ALLOC_OPT_LOCK_NOLOCK
Definition: astobj2.h:367
#define ao2_container_alloc_hash(ao2_options, container_options, n_buckets, hash_fn, sort_fn, cmp_fn)
Allocate and initialize a hash container with the desired number of buckets.
Definition: astobj2.h:1303
static int channel_hash(const void *obj, int flags)
Definition: bridge.c:4042
static int channel_cmp(void *obj, void *arg, int flags)
Definition: bridge.c:4065

References AO2_ALLOC_OPT_LOCK_NOLOCK, ao2_container_alloc_hash, ao2_link, AST_LIST_TRAVERSE, ast_bridge_channel::bridge, ast_bridge_channel::chan, channel_cmp(), channel_hash(), channels, ast_bridge::channels, ast_bridge_channel::entry, and NULL.

Referenced by ast_bridge_peers(), ast_bridge_transfer_attended(), ast_bridge_transfer_blind(), and two_bridge_attended_transfer().

◆ ast_bridge_queue_action()

int ast_bridge_queue_action ( struct ast_bridge bridge,
struct ast_frame action 
)

Put an action onto the specified bridge.

Since
12.0.0
Parameters
bridgeWhat to queue the action on.
actionWhat to do.
Return values
0on success.
-1on error.
Note
This API call is meant for internal bridging operations.

Definition at line 314 of file bridge.c.

315{
316 struct ast_frame *dup;
317
318 dup = ast_frdup(action);
319 if (!dup) {
320 return -1;
321 }
322 bridge_queue_action_nodup(bridge, dup);
323 return 0;
324}
static void bridge_queue_action_nodup(struct ast_bridge *bridge, struct ast_frame *action)
Definition: bridge.c:303
#define ast_frdup(fr)
Copies a frame.
Data structure associated with a single frame of data.

References ast_frdup, and bridge_queue_action_nodup().

Referenced by bridge_dissolve().

◆ ast_bridge_remove()

int ast_bridge_remove ( struct ast_bridge bridge,
struct ast_channel chan 
)

Remove a channel from a bridge.

Parameters
bridgeBridge that the channel is to be removed from
chanChannel to remove
Return values
0on success
-1on failure

Example usage:

ast_bridge_remove(bridge, chan);
int ast_bridge_remove(struct ast_bridge *bridge, struct ast_channel *chan)
Remove a channel from a bridge.
Definition: bridge.c:2020

This removes the channel pointed to by the chan pointer from the bridge pointed to by the bridge pointer and requests that it be hung up. Control over the channel will NOT be given to the calling thread.

Note
This API call can be used on channels that were added to the bridge using both ast_bridge_join and ast_bridge_impart.

Definition at line 2020 of file bridge.c.

2021{
2022 struct ast_bridge_channel *bridge_channel;
2023
2024 ast_debug(1, "Removing channel %s from bridge %s\n",
2026
2028
2029 /* Try to find the channel that we want to remove */
2030 if (!(bridge_channel = bridge_find_channel(bridge, chan))) {
2032 return -1;
2033 }
2034
2035 ast_bridge_channel_leave_bridge(bridge_channel,
2037
2039
2040 return 0;
2041}

References ast_bridge_channel_leave_bridge(), ast_bridge_lock, ast_bridge_unlock, AST_CAUSE_NORMAL_CLEARING, ast_channel_name(), ast_debug, ast_bridge_channel::bridge, BRIDGE_CHANNEL_STATE_END_NO_DISSOLVE, bridge_find_channel(), ast_bridge_channel::chan, and ast_bridge::uniqueid.

Referenced by action_kick_last(), ast_bridge_transfer_attended(), ast_bridge_transfer_blind(), execute_menu_entry(), kick_conference_participant(), and leave_marked().

◆ ast_bridge_remove_video_src()

void ast_bridge_remove_video_src ( struct ast_bridge bridge,
struct ast_channel chan 
)

remove a channel as a source of video for the bridge.

Definition at line 3986 of file bridge.c.

3987{
3988 ast_bridge_lock(bridge);
3989 switch (bridge->softmix.video_mode.mode) {
3991 break;
3996 }
3998 }
3999 break;
4004 }
4007 }
4011 }
4013 }
4015 break;
4016 }
4017 ast_bridge_unlock(bridge);
4018}

References ast_bridge_lock, ast_bridge_unlock, AST_BRIDGE_VIDEO_MODE_NONE, AST_BRIDGE_VIDEO_MODE_SFU, AST_BRIDGE_VIDEO_MODE_SINGLE_SRC, AST_BRIDGE_VIDEO_MODE_TALKER_SRC, ast_channel_unref, ast_bridge_video_talker_src_data::average_talking_energy, ast_bridge_video_talker_src_data::chan_old_vsrc, ast_bridge_video_single_src_data::chan_vsrc, ast_bridge_video_talker_src_data::chan_vsrc, ast_bridge_video_mode::mode, ast_bridge_video_mode::mode_data, NULL, ast_bridge_video_mode::single_src_data, ast_bridge::softmix, ast_bridge_video_mode::talker_src_data, and ast_bridge_softmix::video_mode.

Referenced by bridge_channel_internal_join(), and handle_video_on_exit().

◆ ast_bridge_set_binaural_active()

void ast_bridge_set_binaural_active ( struct ast_bridge bridge,
unsigned int  binaural_active 
)

Activates the use of binaural signals in a conference bridge.

Parameters
bridgeChannel to activate the binaural signals.
binaural_activeIf true binaural signal processing will be active for the bridge.

Definition at line 3774 of file bridge.c.

3775{
3776 ast_bridge_lock(bridge);
3777 bridge->softmix.binaural_active = binaural_active;
3778 ast_bridge_unlock(bridge);
3779}
unsigned int binaural_active
Definition: bridge.h:299

References ast_bridge_lock, ast_bridge_unlock, ast_bridge_softmix::binaural_active, and ast_bridge::softmix.

Referenced by join_conference_bridge().

◆ ast_bridge_set_internal_sample_rate()

void ast_bridge_set_internal_sample_rate ( struct ast_bridge bridge,
unsigned int  sample_rate 
)

Adjust the internal mixing sample rate of a bridge used during multimix mode.

Parameters
bridgeChannel to change the sample rate on.
sample_ratethe sample rate to change to. If a value of 0 is passed here, the bridge will be free to pick what ever sample rate it chooses.

Definition at line 3781 of file bridge.c.

3782{
3783 ast_bridge_lock(bridge);
3784 bridge->softmix.internal_sample_rate = sample_rate;
3785 ast_bridge_unlock(bridge);
3786}
unsigned int internal_sample_rate
The internal sample rate softmix uses to mix channels.
Definition: bridge.h:289

References ast_bridge_lock, ast_bridge_unlock, ast_bridge_softmix::internal_sample_rate, and ast_bridge::softmix.

Referenced by join_conference_bridge().

◆ ast_bridge_set_maximum_sample_rate()

void ast_bridge_set_maximum_sample_rate ( struct ast_bridge bridge,
unsigned int  sample_rate 
)

Adjust the maximum mixing sample rate of a bridge used during multimix mode.

Since
13.31.0
16.8.0
17.2.0
Parameters
bridgeChannel to change the sample rate on.
sample_ratethe maximum sample rate to use. If a value of 0 is passed here, the bridge will be free to pick what ever sample rate it chooses.

Definition at line 3788 of file bridge.c.

3789{
3790 ast_bridge_lock(bridge);
3791 bridge->softmix.maximum_sample_rate = sample_rate;
3792 ast_bridge_unlock(bridge);
3793}
unsigned int maximum_sample_rate
The maximum sample rate softmix uses to mix channels.
Definition: bridge.h:310

References ast_bridge_lock, ast_bridge_unlock, ast_bridge_softmix::maximum_sample_rate, and ast_bridge::softmix.

Referenced by join_conference_bridge().

◆ ast_bridge_set_mixing_interval()

void ast_bridge_set_mixing_interval ( struct ast_bridge bridge,
unsigned int  mixing_interval 
)

Adjust the internal mixing interval of a bridge used during multimix mode.

Parameters
bridgeChannel to change the sample rate on.
mixing_intervalthe sample rate to change to. If 0 is set the bridge tech is free to choose any mixing interval it uses by default.

Definition at line 3767 of file bridge.c.

3768{
3769 ast_bridge_lock(bridge);
3770 bridge->softmix.internal_mixing_interval = mixing_interval;
3771 ast_bridge_unlock(bridge);
3772}
unsigned int internal_mixing_interval
The mixing interval indicates how quickly softmix mixing should occur to mix audio.
Definition: bridge.h:297

References ast_bridge_lock, ast_bridge_unlock, ast_bridge_softmix::internal_mixing_interval, and ast_bridge::softmix.

Referenced by join_conference_bridge().

◆ ast_bridge_set_remb_estimated_bitrate()

void ast_bridge_set_remb_estimated_bitrate ( struct ast_bridge bridge,
float  estimated_bitrate 
)

Force the REMB report estimated bitrate to a specific max value.

Parameters
bridgeBridge to set the REMB behavior on
estimated_bitrateThe estimated bitrate in bits per second
Note
This can only be called when the bridge has been set to the SFU video mode.

Definition at line 3876 of file bridge.c.

3877{
3879
3880 ast_bridge_lock(bridge);
3881 bridge->softmix.video_mode.mode_data.sfu_data.estimated_bitrate = estimated_bitrate;
3882 ast_bridge_unlock(bridge);
3883}
struct ast_bridge_video_sfu_data sfu_data
Definition: bridge.h:169

References ast_assert, ast_bridge_lock, ast_bridge_unlock, AST_BRIDGE_VIDEO_MODE_SFU, ast_bridge_video_sfu_data::estimated_bitrate, ast_bridge_video_mode::mode, ast_bridge_video_mode::mode_data, ast_bridge_video_mode::sfu_data, ast_bridge::softmix, and ast_bridge_softmix::video_mode.

Referenced by join_conference_bridge().

◆ ast_bridge_set_remb_send_interval()

void ast_bridge_set_remb_send_interval ( struct ast_bridge bridge,
unsigned int  remb_send_interval 
)

Set the interval at which a combined REMB frame will be sent to video sources.

Parameters
bridgeBridge to set the REMB send interval on
remb_send_intervalThe REMB send interval
Note
This can only be called when the bridge has been set to the SFU video mode.

Definition at line 3858 of file bridge.c.

3859{
3861
3862 ast_bridge_lock(bridge);
3863 bridge->softmix.video_mode.mode_data.sfu_data.remb_send_interval = remb_send_interval;
3864 ast_bridge_unlock(bridge);
3865}
unsigned int remb_send_interval
Definition: bridge.h:155

References ast_assert, ast_bridge_lock, ast_bridge_unlock, AST_BRIDGE_VIDEO_MODE_SFU, ast_bridge_video_mode::mode, ast_bridge_video_mode::mode_data, ast_bridge_video_sfu_data::remb_send_interval, ast_bridge_video_mode::sfu_data, ast_bridge::softmix, and ast_bridge_softmix::video_mode.

Referenced by join_conference_bridge().

◆ ast_bridge_set_send_sdp_label()

void ast_bridge_set_send_sdp_label ( struct ast_bridge bridge,
unsigned int  send_sdp_label 
)

Controls whether to send a "label" attribute in each stream in an SDP.

Since
16.1.0
Parameters
bridgeThe bridge
send_sdp_labelWhether to send the labels or not
Note
The label will contain the uniqueid of the channel related to the stream. This is used to allow the recipient to correlate the stream to the participant information events sent by app_confbridge. The bridge will be locked in this function.

Definition at line 4035 of file bridge.c.

4036{
4037 ast_bridge_lock(bridge);
4038 bridge->softmix.send_sdp_label = send_sdp_label;
4039 ast_bridge_unlock(bridge);
4040}
unsigned int send_sdp_label
Definition: bridge.h:304

References ast_bridge_lock, ast_bridge_unlock, ast_bridge_softmix::send_sdp_label, and ast_bridge::softmix.

Referenced by bridge_stasis_new(), and join_conference_bridge().

◆ ast_bridge_set_sfu_video_mode()

void ast_bridge_set_sfu_video_mode ( struct ast_bridge bridge)

Set the bridge to be a selective forwarding unit.

Definition at line 3843 of file bridge.c.

3844{
3845 ast_bridge_lock(bridge);
3846 cleanup_video_mode(bridge);
3848 ast_bridge_unlock(bridge);
3849}
static void cleanup_video_mode(struct ast_bridge *bridge)
Definition: bridge.c:3795

References ast_bridge_lock, ast_bridge_unlock, AST_BRIDGE_VIDEO_MODE_SFU, cleanup_video_mode(), ast_bridge_video_mode::mode, ast_bridge::softmix, and ast_bridge_softmix::video_mode.

Referenced by bridge_stasis_new(), and join_conference_bridge().

◆ ast_bridge_set_single_src_video_mode()

void ast_bridge_set_single_src_video_mode ( struct ast_bridge bridge,
struct ast_channel video_src_chan 
)

Set a bridge to feed a single video source to all participants.

Definition at line 3818 of file bridge.c.

3819{
3820 ast_bridge_lock(bridge);
3821 cleanup_video_mode(bridge);
3823 if (video_src_chan) {
3825 ast_verb(5, "Video source in bridge '%s' (%s) is now '%s' (%s)\n",
3826 bridge->name, bridge->uniqueid,
3827 ast_channel_name(video_src_chan),
3828 ast_channel_uniqueid(video_src_chan));
3829 ast_indicate(video_src_chan, AST_CONTROL_VIDUPDATE);
3830 }
3832 ast_bridge_unlock(bridge);
3833}
const char * ast_channel_uniqueid(const struct ast_channel *chan)
int ast_indicate(struct ast_channel *chan, int condition)
Indicates condition of channel.
Definition: channel.c:4294
@ AST_CONTROL_VIDUPDATE
void ast_bridge_publish_state(struct ast_bridge *bridge)
Publish the state of a bridge.
const ast_string_field name
Definition: bridge.h:405

References ast_bridge_lock, ast_bridge_publish_state(), ast_bridge_unlock, AST_BRIDGE_VIDEO_MODE_SINGLE_SRC, ast_channel_name(), ast_channel_ref, ast_channel_uniqueid(), AST_CONTROL_VIDUPDATE, ast_indicate(), ast_verb, ast_bridge_video_single_src_data::chan_vsrc, cleanup_video_mode(), ast_bridge_video_mode::mode, ast_bridge_video_mode::mode_data, ast_bridge::name, ast_bridge_video_mode::single_src_data, ast_bridge::softmix, ast_bridge::uniqueid, and ast_bridge_softmix::video_mode.

Referenced by action_confbridgesetsinglevideosrc(), bridge_set_video_source_cb(), bridge_stasis_new(), execute_menu_entry(), handle_video_on_exit(), and handle_video_on_join().

◆ ast_bridge_set_talker_src_video_mode()

void ast_bridge_set_talker_src_video_mode ( struct ast_bridge bridge)

Set the bridge to pick the strongest talker supporting video as the single source video feed.

Definition at line 3835 of file bridge.c.

3836{
3837 ast_bridge_lock(bridge);
3838 cleanup_video_mode(bridge);
3840 ast_bridge_unlock(bridge);
3841}

References ast_bridge_lock, ast_bridge_unlock, AST_BRIDGE_VIDEO_MODE_TALKER_SRC, cleanup_video_mode(), ast_bridge_video_mode::mode, ast_bridge::softmix, and ast_bridge_softmix::video_mode.

Referenced by ast_ari_bridges_clear_video_source(), bridge_stasis_new(), handle_video_on_exit(), and join_conference_bridge().

◆ ast_bridge_set_transfer_variables()

void ast_bridge_set_transfer_variables ( struct ast_channel chan,
const char *  value,
int  is_attended 
)

Set the relevant transfer variables for a single channel.

Sets either the ATTENDEDTRANSFER or BLINDTRANSFER variable for a channel while clearing the opposite.

Parameters
chanChannel the variable is being set for
valueValue the variable is being set to
is_attendedfalse set BLINDTRANSFER and unset ATTENDEDTRANSFER true set ATTENDEDTRANSFER and unset BLINDTRANSFER

Definition at line 4421 of file bridge.c.

4422{
4423 char *writevar;
4424 char *erasevar;
4425
4426 if (attended) {
4427 writevar = ATTENDEDTRANSFER;
4428 erasevar = BLINDTRANSFER;
4429 } else {
4430 writevar = BLINDTRANSFER;
4431 erasevar = ATTENDEDTRANSFER;
4432 }
4433
4434 pbx_builtin_setvar_helper(chan, writevar, value);
4435 pbx_builtin_setvar_helper(chan, erasevar, NULL);
4436}
#define BLINDTRANSFER
Definition: bridge.c:147
#define ATTENDEDTRANSFER
Definition: bridge.c:150
int pbx_builtin_setvar_helper(struct ast_channel *chan, const char *name, const char *value)
Add a variable to the channel variable stack, removing the most recently set value for the same name.
int value
Definition: syslog.c:37

References ATTENDEDTRANSFER, BLINDTRANSFER, NULL, pbx_builtin_setvar_helper(), and value.

Referenced by dial_transfer(), manager_park(), park_local_transfer(), parking_park_bridge_channel(), and set_transfer_variables_all().

◆ ast_bridge_set_video_update_discard()

void ast_bridge_set_video_update_discard ( struct ast_bridge bridge,
unsigned int  video_update_discard 
)

Set the amount of time to discard subsequent video updates after a video update has been sent.

Parameters
bridgeBridge to set the minimum video update wait time on
video_update_discardAmount of time after sending a video update that others should be discarded

Definition at line 3851 of file bridge.c.

3852{
3853 ast_bridge_lock(bridge);
3854 bridge->softmix.video_mode.video_update_discard = video_update_discard;
3855 ast_bridge_unlock(bridge);
3856}
unsigned int video_update_discard
Definition: bridge.h:172

References ast_bridge_lock, ast_bridge_unlock, ast_bridge::softmix, ast_bridge_softmix::video_mode, and ast_bridge_video_mode::video_update_discard.

Referenced by bridge_stasis_new(), and join_conference_bridge().

◆ ast_bridge_suspend()

int ast_bridge_suspend ( struct ast_bridge bridge,
struct ast_channel chan 
)

Suspend a channel temporarily from a bridge.

Parameters
bridgeBridge to suspend the channel from
chanChannel to suspend
Return values
0on success
-1on failure

Example usage:

ast_bridge_suspend(bridge, chan);
int ast_bridge_suspend(struct ast_bridge *bridge, struct ast_channel *chan)
Suspend a channel temporarily from a bridge.
Definition: bridge.c:3076

This suspends the channel pointed to by chan from the bridge pointed to by bridge temporarily. Control of the channel is given to the calling thread. This differs from ast_bridge_depart as the channel will not be removed from the bridge.

Note
This API call can be used on channels that were added to the bridge using both ast_bridge_join and ast_bridge_impart.

Definition at line 3076 of file bridge.c.

3077{
3078 struct ast_bridge_channel *bridge_channel;
3079/* XXX ASTERISK-21271 the case of a dissolved bridge while channel is suspended is not handled. */
3080/* XXX ASTERISK-21271 suspend/unsuspend needs to be rethought. The caller must block until it has successfully suspended the channel for temporary control. */
3081/* XXX ASTERISK-21271 external suspend/unsuspend needs to be eliminated. The channel may be playing a file at the time and stealing it then is not good. */
3082
3084
3085 if (!(bridge_channel = bridge_find_channel(bridge, chan))) {
3087 return -1;
3088 }
3089
3091
3093
3094 return 0;
3095}
void bridge_channel_internal_suspend_nolock(struct ast_bridge_channel *bridge_channel)

References ast_bridge_lock, ast_bridge_unlock, ast_bridge_channel::bridge, bridge_channel_internal_suspend_nolock(), bridge_find_channel(), and ast_bridge_channel::chan.

Referenced by conf_moh_start(), and conf_moh_stop().

◆ ast_bridge_talk_detector_hook()

int ast_bridge_talk_detector_hook ( struct ast_bridge_features features,
ast_bridge_talking_indicate_callback  callback,
void *  hook_pvt,
ast_bridge_hook_pvt_destructor  destructor,
enum ast_bridge_hook_remove_flags  remove_flags 
)

Attach a bridge channel talk detection hook to a bridge features structure.

Parameters
featuresBridge features structure
callbackFunction to execute upon activation
hook_pvtUnique data
destructorOptional destructor callback for hook_pvt data
remove_flagsDictates what situations the hook should be removed.
Return values
0on success
-1on failure (The caller must cleanup any hook_pvt resources.)

Example usage:

struct ast_bridge_features features;
ast_bridge_talk_hook(&features, talk_callback, NULL, NULL, 0);

This makes the bridging technology call talk_callback when a channel is recognized as starting and stopping talking. A pointer to useful data may be provided to the hook_pvt parameter.

Note
This hook is currently only supported by softmix.

Definition at line 3364 of file bridge.c.

3369{
3371
3372 return bridge_other_hook(features, hook_cb, hook_pvt, destructor, remove_flags,
3374}
@ AST_BRIDGE_HOOK_TYPE_TALK

References AST_BRIDGE_HOOK_TYPE_TALK, bridge_other_hook(), ast_bridge_hook::callback, ast_bridge_hook::destructor, hook_cb(), ast_bridge_hook::hook_pvt, and ast_bridge_hook::remove_flags.

Referenced by confbridge_exec().

◆ ast_bridge_technology_suspend()

void ast_bridge_technology_suspend ( struct ast_bridge_technology technology)

Suspend a bridge technology from consideration.

Parameters
technologyThe bridge technology to suspend

Example usage:

ast_bridge_technology_suspend(&simple_bridge_tech);
void ast_bridge_technology_suspend(struct ast_bridge_technology *technology)
Suspend a bridge technology from consideration.
Definition: bridge.c:3116

This suspends the bridge technology simple_bridge_tech from being considered when creating a new bridge. Existing bridges using the bridge technology are not affected.

Definition at line 3116 of file bridge.c.

3117{
3118 technology->suspended = 1;
3119}

References ast_bridge_technology::suspended.

Referenced by handle_bridge_technology_suspend(), and handle_manager_bridge_tech_suspend().

◆ ast_bridge_technology_unregister()

int ast_bridge_technology_unregister ( struct ast_bridge_technology technology)

Unregister a bridge technology from use.

Parameters
technologyThe bridge technology to unregister
Return values
0on success
-1on failure

Example usage:

ast_bridge_technology_unregister(&simple_bridge_tech);
int ast_bridge_technology_unregister(struct ast_bridge_technology *technology)
Unregister a bridge technology from use.
Definition: bridge.c:274

This unregisters a bridge technlogy declared as the structure simple_bridge_tech with the bridging core. It will no longer be considered when creating a new bridge.

Definition at line 274 of file bridge.c.

275{
277
279
280 /* Ensure the bridge technology is registered before removing it */
282 if (current == technology) {
284 ast_verb(5, "Unregistered bridge technology %s\n", technology->name);
285 break;
286 }
287 }
289
291
292 return current ? 0 : -1;
293}
#define AST_RWLIST_REMOVE_CURRENT
Definition: linkedlists.h:570

References AST_RWLIST_REMOVE_CURRENT, AST_RWLIST_TRAVERSE_SAFE_BEGIN, AST_RWLIST_TRAVERSE_SAFE_END, AST_RWLIST_UNLOCK, AST_RWLIST_WRLOCK, ast_verb, current, and ast_bridge_technology::name.

Referenced by dahdi_native_unload(), and unload_module().

◆ ast_bridge_technology_unsuspend()

void ast_bridge_technology_unsuspend ( struct ast_bridge_technology technology)

Unsuspend a bridge technology.

Parameters
technologyThe bridge technology to unsuspend

Example usage:

ast_bridge_technology_unsuspend(&simple_bridge_tech);
void ast_bridge_technology_unsuspend(struct ast_bridge_technology *technology)
Unsuspend a bridge technology.
Definition: bridge.c:3121

This makes the bridge technology simple_bridge_tech considered when creating a new bridge again.

Definition at line 3121 of file bridge.c.

3122{
3123 /*
3124 * XXX We may want the act of unsuspending a bridge technology
3125 * to prod all existing bridges to see if they should start
3126 * using it.
3127 */
3128 technology->suspended = 0;
3129}

References ast_bridge_technology::suspended.

Referenced by handle_bridge_technology_suspend(), and handle_manager_bridge_tech_suspend().

◆ ast_bridge_transfer_acquire_bridge()

struct ast_bridge * ast_bridge_transfer_acquire_bridge ( struct ast_channel chan)

Acquire the channel's bridge for transfer purposes.

Since
13.21.0
Parameters
chanChannel involved in a transfer.
Returns
The bridge the channel is in or NULL if it either isn't in a bridge or should not be considered to be in a bridge.

Definition at line 4477 of file bridge.c.

4478{
4479 struct ast_bridge *bridge;
4480
4481 ast_channel_lock(chan);
4482 bridge = ast_channel_get_bridge(chan);
4483 ast_channel_unlock(chan);
4484
4485 if (bridge && ast_test_flag(&bridge->feature_flags,
4487 ao2_ref(bridge, -1);
4488 bridge = NULL;
4489 }
4490
4491 return bridge;
4492}
@ AST_BRIDGE_FLAG_MASQUERADE_ONLY
@ AST_BRIDGE_FLAG_INVISIBLE
struct ast_flags feature_flags
Definition: bridge.h:373

References ao2_ref, AST_BRIDGE_FLAG_INVISIBLE, AST_BRIDGE_FLAG_MASQUERADE_ONLY, ast_channel_get_bridge(), ast_channel_lock, ast_channel_unlock, ast_test_flag, ast_bridge::feature_flags, and NULL.

Referenced by ast_bridge_transfer_attended(), ast_bridge_transfer_blind(), ast_refer_notify_transfer_request(), and invite_replaces().

◆ ast_bridge_transfer_attended()

enum ast_transfer_result ast_bridge_transfer_attended ( struct ast_channel to_transferee,
struct ast_channel to_transfer_target 
)

Attended transfer.

The two channels are both transferer channels. The first is the channel that is bridged to the transferee (or if unbridged, the 'first' call of the transfer). The second is the channel that is bridged to the transfer target (or if unbridged, the 'second' call of the transfer).

Note
Absolutely NO channel locks should be held before calling this function.
Parameters
to_transfereeTransferer channel on initial call (presumably bridged to transferee)
to_transfer_targetTransferer channel on consultation call (presumably bridged to transfer target)
Returns
The success or failure of the attended transfer

Definition at line 4746 of file bridge.c.

4748{
4749 RAII_VAR(struct ast_bridge *, to_transferee_bridge, NULL, ao2_cleanup);
4750 RAII_VAR(struct ast_bridge *, to_target_bridge, NULL, ao2_cleanup);
4751 RAII_VAR(struct ast_bridge_channel *, to_transferee_bridge_channel, NULL, ao2_cleanup);
4752 RAII_VAR(struct ast_bridge_channel *, to_target_bridge_channel, NULL, ao2_cleanup);
4754 RAII_VAR(struct ast_channel *, transferee, NULL, ao2_cleanup);
4755 RAII_VAR(struct ast_attended_transfer_message *, transfer_msg, NULL, ao2_cleanup);
4756 struct ast_bridge *the_bridge = NULL;
4757 struct ast_channel *chan_bridged;
4758 struct ast_channel *chan_unbridged;
4759 int transfer_prohibited;
4760 int do_bridge_transfer;
4761 enum ast_transfer_result res;
4762 const char *app = NULL;
4763 int hangup_target = 0;
4764
4765 to_transferee_bridge = ast_bridge_transfer_acquire_bridge(to_transferee);
4766 to_target_bridge = ast_bridge_transfer_acquire_bridge(to_transfer_target);
4767
4768 transfer_msg = ast_attended_transfer_message_create(1, to_transferee, to_transferee_bridge,
4769 to_transfer_target, to_target_bridge, NULL, NULL);
4770 if (!transfer_msg) {
4771 ast_log(LOG_ERROR, "Unable to create Stasis publication for attended transfer from %s\n",
4772 ast_channel_name(to_transferee));
4774 }
4775
4776 /* They can't both be unbridged, you silly goose! */
4777 if (!to_transferee_bridge && !to_target_bridge) {
4779 goto end;
4780 }
4781
4782 ast_channel_lock(to_transferee);
4783 to_transferee_bridge_channel = ast_channel_get_bridge_channel(to_transferee);
4784 ast_channel_unlock(to_transferee);
4785
4786 ast_channel_lock(to_transfer_target);
4787 to_target_bridge_channel = ast_channel_get_bridge_channel(to_transfer_target);
4788 ast_channel_unlock(to_transfer_target);
4789
4790 if (to_transferee_bridge_channel) {
4791 /* Take off hold if they are on hold. */
4792 if (ast_bridge_channel_write_unhold(to_transferee_bridge_channel)) {
4793 ast_log(LOG_ERROR, "Transferee channel disappeared during transfer!\n");
4795 goto end;
4796 }
4797 }
4798
4799 if (to_target_bridge_channel) {
4800 const char *target_complete_sound;
4801
4802 /* Take off hold if they are on hold. */
4803 if (ast_bridge_channel_write_unhold(to_target_bridge_channel)) {
4804 ast_log(LOG_ERROR, "Target channel disappeared during transfer!\n");
4806 goto end;
4807 }
4808
4809 /* Is there a courtesy sound to play to the target? */
4810 ast_channel_lock(to_transfer_target);
4811 target_complete_sound = pbx_builtin_getvar_helper(to_transfer_target,
4812 "ATTENDED_TRANSFER_COMPLETE_SOUND");
4813 if (!ast_strlen_zero(target_complete_sound)) {
4814 target_complete_sound = ast_strdupa(target_complete_sound);
4815 } else {
4816 target_complete_sound = NULL;
4817 }
4818 ast_channel_unlock(to_transfer_target);
4819 if (!target_complete_sound) {
4820 ast_channel_lock(to_transferee);
4821 target_complete_sound = pbx_builtin_getvar_helper(to_transferee,
4822 "ATTENDED_TRANSFER_COMPLETE_SOUND");
4823 if (!ast_strlen_zero(target_complete_sound)) {
4824 target_complete_sound = ast_strdupa(target_complete_sound);
4825 } else {
4826 target_complete_sound = NULL;
4827 }
4828 ast_channel_unlock(to_transferee);
4829 }
4830 if (target_complete_sound) {
4831 ast_bridge_channel_write_playfile(to_target_bridge_channel, NULL,
4832 target_complete_sound, NULL);
4833 }
4834 }
4835
4836 /* Let's get the easy one out of the way first */
4837 if (to_transferee_bridge && to_target_bridge) {
4838
4839 if (!to_transferee_bridge_channel || !to_target_bridge_channel) {
4841 goto end;
4842 }
4843
4844 ast_bridge_lock_both(to_transferee_bridge, to_target_bridge);
4845 res = two_bridge_attended_transfer(to_transferee, to_transferee_bridge_channel,
4846 to_transfer_target, to_target_bridge_channel,
4847 to_transferee_bridge, to_target_bridge, transfer_msg);
4848 ast_bridge_unlock(to_transferee_bridge);
4849 ast_bridge_unlock(to_target_bridge);
4850
4851 hangup_target = 1;
4852 goto end;
4853 }
4854
4855 the_bridge = to_transferee_bridge ?: to_target_bridge;
4856 chan_bridged = to_transferee_bridge ? to_transferee : to_transfer_target;
4857 chan_unbridged = to_transferee_bridge ? to_transfer_target : to_transferee;
4858
4859 /*
4860 * Race condition makes it possible for app to be NULL, so get the app prior to
4861 * transferring with a fallback of "unknown".
4862 */
4863 app = ast_strdupa(ast_channel_appl(chan_unbridged) ?: "unknown");
4864
4865 {
4866 int chan_count;
4868
4869 channels = ast_bridge_peers_nolock(the_bridge);
4870 if (!channels) {
4872 goto end;
4873 }
4874 chan_count = ao2_container_count(channels);
4875 if (chan_count <= 1) {
4877 goto end;
4878 }
4879 transfer_prohibited = ast_test_flag(&the_bridge->feature_flags,
4881 do_bridge_transfer = ast_test_flag(&the_bridge->feature_flags,
4883 chan_count > 2;
4884 }
4885
4886 if (transfer_prohibited) {
4888 goto end;
4889 }
4890
4891 set_transfer_variables_all(to_transferee, channels, 1);
4892
4893 if (do_bridge_transfer) {
4894 /*
4895 * Hang up the target if it was bridged. Note, if it is not bridged
4896 * it is hung up during the masquerade.
4897 */
4898 hangup_target = chan_bridged == to_transfer_target;
4899 ast_bridge_lock(the_bridge);
4900 res = attended_transfer_bridge(chan_bridged, chan_unbridged, the_bridge, NULL, transfer_msg);
4901 ast_bridge_unlock(the_bridge);
4902 goto end;
4903 }
4904
4905 transferee = get_transferee(channels, chan_bridged);
4906 if (!transferee) {
4908 goto end;
4909 }
4910
4911 if (bridge_channel_internal_queue_attended_transfer(transferee, chan_unbridged)) {
4913 goto end;
4914 }
4915
4916 ast_bridge_remove(the_bridge, chan_bridged);
4917
4920
4921end:
4922 if ((res == AST_BRIDGE_TRANSFER_SUCCESS && hangup_target) || res == AST_BRIDGE_TRANSFER_FAIL) {
4923 ast_softhangup(to_transfer_target, AST_SOFTHANGUP_DEV);
4924 }
4925
4926 transfer_msg->result = res;
4928 return res;
4929}
static const char app[]
Definition: app_adsiprog.c:56
ast_mutex_t lock
Definition: app_sla.c:337
#define ast_strdupa(s)
duplicate a string in memory from the stack
Definition: astmm.h:298
int ao2_container_count(struct ao2_container *c)
Returns the number of elements in a container.
static struct ast_channel * get_transferee(struct ao2_container *channels, struct ast_channel *transferer)
Definition: bridge.c:4251
static enum ast_transfer_result two_bridge_attended_transfer(struct ast_channel *to_transferee, struct ast_bridge_channel *to_transferee_bridge_channel, struct ast_channel *to_transfer_target, struct ast_bridge_channel *to_target_bridge_channel, struct ast_bridge *to_transferee_bridge, struct ast_bridge *to_target_bridge, struct ast_attended_transfer_message *transfer_msg)
Definition: bridge.c:4680
static enum ast_transfer_result attended_transfer_bridge(struct ast_channel *chan1, struct ast_channel *chan2, struct ast_bridge *bridge1, struct ast_bridge *bridge2, struct ast_attended_transfer_message *transfer_msg)
Perform an attended transfer of a bridge.
Definition: bridge.c:4290
struct ast_bridge * ast_bridge_transfer_acquire_bridge(struct ast_channel *chan)
Acquire the channel's bridge for transfer purposes.
Definition: bridge.c:4477
int ast_bridge_remove(struct ast_bridge *bridge, struct ast_channel *chan)
Remove a channel from a bridge.
Definition: bridge.c:2020
static void set_transfer_variables_all(struct ast_channel *transferer, struct ao2_container *channels, int is_attended)
Definition: bridge.c:4452
ast_transfer_result
Definition: bridge.h:1102
@ AST_BRIDGE_TRANSFER_NOT_PERMITTED
Definition: bridge.h:1106
@ AST_BRIDGE_TRANSFER_SUCCESS
Definition: bridge.h:1104
@ AST_BRIDGE_TRANSFER_INVALID
Definition: bridge.h:1108
@ AST_BRIDGE_TRANSFER_FAIL
Definition: bridge.h:1110
int ast_bridge_channel_write_unhold(struct ast_bridge_channel *bridge_channel)
Write an unhold frame into the bridge.
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)
Write a bridge action play file frame into the bridge.
int bridge_channel_internal_queue_attended_transfer(struct ast_channel *transferee, struct ast_channel *unbridged_chan)
@ AST_BRIDGE_FLAG_TRANSFER_BRIDGE_ONLY
@ AST_BRIDGE_FLAG_TRANSFER_PROHIBITED
const char * ast_channel_appl(const struct ast_channel *chan)
int ast_softhangup(struct ast_channel *chan, int cause)
Softly hangup up a channel.
Definition: channel.c:2500
@ AST_SOFTHANGUP_DEV
Definition: channel.h:1141
char * end
Definition: eagi_proxy.c:73
#define SCOPED_LOCK(varname, lock, lockfunc, unlockfunc)
Scoped Locks.
Definition: lock.h:587
const char * pbx_builtin_getvar_helper(struct ast_channel *chan, const char *name)
Return a pointer to the value of the corresponding channel variable.
void ast_bridge_publish_attended_transfer(struct ast_attended_transfer_message *transfer_msg)
Publish an attended transfer.
int ast_attended_transfer_message_add_app(struct ast_attended_transfer_message *transfer_msg, const char *app, struct ast_channel *replace_channel)
Add details for an attended transfer to an application.
struct ast_attended_transfer_message * ast_attended_transfer_message_create(int is_external, struct ast_channel *to_transferee, struct ast_bridge *transferee_bridge, struct ast_channel *to_transfer_target, struct ast_bridge *target_bridge, struct ast_channel *transferee, struct ast_channel *transfer_target)
Create an Attended transfer message to be published.
Message representing attended transfer.

References ao2_cleanup, ao2_container_count(), app, ast_attended_transfer_message_add_app(), ast_attended_transfer_message_create(), ast_bridge_channel_write_playfile(), ast_bridge_channel_write_unhold(), AST_BRIDGE_FLAG_TRANSFER_BRIDGE_ONLY, AST_BRIDGE_FLAG_TRANSFER_PROHIBITED, ast_bridge_lock, ast_bridge_lock_both, ast_bridge_peers_nolock(), ast_bridge_publish_attended_transfer(), ast_bridge_remove(), ast_bridge_transfer_acquire_bridge(), AST_BRIDGE_TRANSFER_FAIL, AST_BRIDGE_TRANSFER_INVALID, AST_BRIDGE_TRANSFER_NOT_PERMITTED, AST_BRIDGE_TRANSFER_SUCCESS, ast_bridge_unlock, ast_channel_appl(), ast_channel_get_bridge_channel(), ast_channel_lock, ast_channel_name(), ast_channel_unlock, ast_log, ast_softhangup(), AST_SOFTHANGUP_DEV, ast_strdupa, ast_strlen_zero(), ast_test_flag, attended_transfer_bridge(), bridge_channel_internal_queue_attended_transfer(), channels, end, ast_bridge::feature_flags, get_transferee(), lock, LOG_ERROR, NULL, pbx_builtin_getvar_helper(), RAII_VAR, SCOPED_LOCK, set_transfer_variables_all(), and two_bridge_attended_transfer().

Referenced by analog_attempt_transfer(), AST_TEST_DEFINE(), attempt_transfer(), and refer_attended_task().

◆ ast_bridge_transfer_blind()

enum ast_transfer_result ast_bridge_transfer_blind ( int  is_external,
struct ast_channel transferer,
const char *  exten,
const char *  context,
transfer_channel_cb  new_channel_cb,
void *  user_data 
)

Blind transfer target to the extension and context provided.

The channel given is bridged to one or multiple channels. Depending on the bridge and the number of participants, the entire bridge could be transferred to the given destination, or a single channel may be redirected.

Callers may also provide a callback to be called on the channel that will be running dialplan. The user data passed into ast_bridge_transfer_blind will be given as the argument to the callback to be interpreted as desired. This callback is guaranteed to be called in the same thread as ast_bridge_transfer_blind() and before ast_bridge_transfer_blind() returns.

Note
Absolutely NO channel locks should be held before calling this function.
Parameters
is_externalIndicates that transfer was initiated externally
transfererThe channel performing the blind transfer
extenThe dialplan extension to send the call to
contextThe dialplan context to send the call to
new_channel_cbA callback to be called on the channel that will be executing dialplan
user_dataArgument for new_channel_cb
Returns
The success or failure result of the blind transfer

Definition at line 4494 of file bridge.c.

4497{
4498 RAII_VAR(struct ast_bridge *, bridge, NULL, ao2_cleanup);
4499 RAII_VAR(struct ast_bridge_channel *, bridge_channel, NULL, ao2_cleanup);
4501 RAII_VAR(struct ast_channel *, transferee, NULL, ast_channel_cleanup);
4502 RAII_VAR(struct transfer_channel_data *, user_data_wrapper, NULL, ao2_cleanup);
4503 RAII_VAR(struct ast_blind_transfer_message *, transfer_message, NULL, ao2_cleanup);
4504 int do_bridge_transfer;
4505 int transfer_prohibited;
4506 enum ast_transfer_result transfer_result;
4507
4508 transfer_message = ast_blind_transfer_message_create(is_external, transferer, exten, context);
4509 if (!transfer_message) {
4510 /* Out of memory. Not even possible to publish a Stasis message about the
4511 * failure
4512 */
4513 ast_log(LOG_ERROR, "Unable to allocate memory for blind transfer publication from %s\n",
4514 ast_channel_name(transferer));
4516 }
4517
4518 bridge = ast_bridge_transfer_acquire_bridge(transferer);
4519 if (!bridge) {
4520 transfer_result = AST_BRIDGE_TRANSFER_INVALID;
4521 goto publish;
4522 }
4523
4524 ast_bridge_lock(bridge);
4525 transfer_message->bridge = ast_bridge_snapshot_create(bridge);
4526 ast_bridge_unlock(bridge);
4527 if (!transfer_message->bridge) {
4528 transfer_result = AST_BRIDGE_TRANSFER_FAIL;
4529 goto publish;
4530 }
4531
4532 transferee = ast_bridge_peer(bridge, transferer);
4533 if (transferee) {
4534 transfer_message->transferee = ast_channel_snapshot_get_latest(ast_channel_uniqueid(transferee));
4535 if (!transfer_message->transferee) {
4536 transfer_result = AST_BRIDGE_TRANSFER_FAIL;
4537 goto publish;
4538 }
4539 }
4540
4541 ast_channel_lock(transferer);
4542 bridge_channel = ast_channel_get_bridge_channel(transferer);
4543 ast_channel_unlock(transferer);
4544 if (!bridge_channel) {
4545 transfer_result = AST_BRIDGE_TRANSFER_INVALID;
4546 goto publish;
4547 }
4548
4549 user_data_wrapper = ao2_alloc(sizeof(*user_data_wrapper), NULL);
4550 if (!user_data_wrapper) {
4551 transfer_result = AST_BRIDGE_TRANSFER_FAIL;
4552 goto publish;
4553 }
4554
4555 user_data_wrapper->data = user_data;
4556
4557 /* Take off hold if they are on hold. */
4558 ast_bridge_channel_write_unhold(bridge_channel);
4559
4560 transfer_result = try_parking(transferer, context, exten, new_channel_cb, user_data_wrapper);
4561 if (transfer_result == AST_BRIDGE_TRANSFER_SUCCESS) {
4562 goto publish;
4563 }
4564
4565 /* Since parking didn't take control of the user_data_wrapper, we are just going to raise the completed flag now. */
4566 user_data_wrapper->completed = 1;
4567
4568 {
4570
4572 if (!channels) {
4573 transfer_result = AST_BRIDGE_TRANSFER_FAIL;
4574 goto publish;
4575 }
4576 if (ao2_container_count(channels) <= 1) {
4577 transfer_result = AST_BRIDGE_TRANSFER_INVALID;
4578 goto publish;
4579 }
4580 transfer_prohibited = ast_test_flag(&bridge->feature_flags,
4582 do_bridge_transfer = ast_test_flag(&bridge->feature_flags,
4585 }
4586
4587 if (transfer_prohibited) {
4588 transfer_result = AST_BRIDGE_TRANSFER_NOT_PERMITTED;
4589 goto publish;
4590 }
4591
4592 set_transfer_variables_all(transferer, channels, 0);
4593
4594 if (do_bridge_transfer) {
4595 transfer_result = blind_transfer_bridge(is_external, transferer, bridge,
4596 exten, context, transferee, new_channel_cb, user_data_wrapper, transfer_message);
4597 goto publish;
4598 }
4599
4600 /* Reaching this portion means that we're dealing with a two-party bridge */
4601
4602 if (!transferee) {
4603 transfer_result = AST_BRIDGE_TRANSFER_FAIL;
4604 goto publish;
4605 }
4606
4608 new_channel_cb, user_data_wrapper)) {
4609 transfer_result = AST_BRIDGE_TRANSFER_FAIL;
4610 goto publish;
4611 }
4612
4613 ast_bridge_remove(bridge, transferer);
4614 transfer_result = AST_BRIDGE_TRANSFER_SUCCESS;
4615
4616publish:
4617 transfer_message->result = transfer_result;
4618 ast_bridge_publish_blind_transfer(transfer_message);
4619 return transfer_result;
4620}
#define ao2_alloc(data_size, destructor_fn)
Definition: astobj2.h:409
struct ast_channel * ast_bridge_peer(struct ast_bridge *bridge, struct ast_channel *chan)
Get the channel's bridge peer only if the bridge is two-party.
Definition: bridge.c:4144
static enum ast_transfer_result try_parking(struct ast_channel *transferer, const char *context, const char *exten, transfer_channel_cb new_channel_cb, struct transfer_channel_data *user_data_wrapper)
Definition: bridge.c:4395
static enum ast_transfer_result blind_transfer_bridge(int is_external, struct ast_channel *transferer, struct ast_bridge *bridge, const char *exten, const char *context, struct ast_channel *transferee, transfer_channel_cb new_channel_cb, struct transfer_channel_data *user_data_wrapper, struct ast_blind_transfer_message *transfer_message)
Definition: bridge.c:4180
int bridge_channel_internal_queue_blind_transfer(struct ast_channel *transferee, const char *exten, const char *context, transfer_channel_cb new_channel_cb, void *user_data)
#define ast_channel_cleanup(c)
Cleanup a channel reference.
Definition: channel.h:3017
struct ast_channel_snapshot * ast_channel_snapshot_get_latest(const char *uniqueid)
Obtain the latest ast_channel_snapshot from the Stasis Message Bus API cache. This is an ao2 object,...
unsigned char publish
Definition: res_corosync.c:241
void ast_bridge_publish_blind_transfer(struct ast_blind_transfer_message *transfer_message)
Publish a blind transfer event.
struct ast_bridge_snapshot * ast_bridge_snapshot_create(struct ast_bridge *bridge)
Generate a snapshot of the bridge state. This is an ao2 object, so ao2_cleanup() to deallocate.
struct ast_blind_transfer_message * ast_blind_transfer_message_create(int is_external, struct ast_channel *transferer, const char *exten, const char *context)
Create a blind transfer message to be published.
Message published during a blind transfer.
AO2 object that wraps data for transfer_channel_cb.
Definition: bridge.h:1123

References ao2_alloc, ao2_cleanup, ao2_container_count(), ast_blind_transfer_message_create(), ast_bridge_channel_write_unhold(), AST_BRIDGE_FLAG_TRANSFER_BRIDGE_ONLY, AST_BRIDGE_FLAG_TRANSFER_PROHIBITED, ast_bridge_lock, ast_bridge_peer(), ast_bridge_peers_nolock(), ast_bridge_publish_blind_transfer(), ast_bridge_remove(), ast_bridge_snapshot_create(), ast_bridge_transfer_acquire_bridge(), AST_BRIDGE_TRANSFER_FAIL, AST_BRIDGE_TRANSFER_INVALID, AST_BRIDGE_TRANSFER_NOT_PERMITTED, AST_BRIDGE_TRANSFER_SUCCESS, ast_bridge_unlock, ast_channel_cleanup, ast_channel_get_bridge_channel(), ast_channel_lock, ast_channel_name(), ast_channel_snapshot_get_latest(), ast_channel_uniqueid(), ast_channel_unlock, ast_log, ast_test_flag, blind_transfer_bridge(), bridge_channel_internal_queue_blind_transfer(), channels, voicemailpwcheck::context, lock, LOG_ERROR, NULL, publish, RAII_VAR, SCOPED_LOCK, set_transfer_variables_all(), and try_parking().

Referenced by action_blind_transfer(), blind_transfer_exec(), feature_blind_transfer(), refer_incoming_attended_request(), refer_incoming_blind_request(), and socket_process_helper().

◆ ast_bridge_unreal_optimize_out()

int ast_bridge_unreal_optimize_out ( struct ast_channel chan,
struct ast_channel peer,
struct ast_unreal_pvt pvt 
)

Check and optimize out the unreal channels between bridges.

Since
12.0.0
Parameters
chanUnreal channel writing a frame into the channel driver.
peerOther unreal channel in the pair.
pvtPrivate data provided by an implementation of the unreal driver that contains the callbacks that should be called when optimization begins/ends
Note
It is assumed that chan is already locked.
Return values
0if unreal channels were not optimized out.
non-zeroif unreal channels were optimized out.

Definition at line 2989 of file bridge.c.

2990{
2991 struct ast_bridge *chan_bridge;
2992 struct ast_bridge *peer_bridge;
2993 struct ast_bridge_channel *chan_bridge_channel;
2994 struct ast_bridge_channel *peer_bridge_channel;
2995 int res = 0;
2996
2997 chan_bridge = optimize_lock_chan_stack(chan);
2998 if (!chan_bridge) {
2999 return res;
3000 }
3001 chan_bridge_channel = ast_channel_internal_bridge_channel(chan);
3002
3003 peer_bridge = optimize_lock_peer_stack(peer);
3004 if (peer_bridge) {
3005 peer_bridge_channel = ast_channel_internal_bridge_channel(peer);
3006
3007 res = try_swap_optimize_out(chan_bridge, chan_bridge_channel,
3008 peer_bridge, peer_bridge_channel, pvt);
3009 if (!res) {
3010 res = try_merge_optimize_out(chan_bridge, chan_bridge_channel,
3011 peer_bridge, peer_bridge_channel, pvt);
3012 } else if (0 < res) {
3013 res = 0;
3014 }
3015
3016 /* Release peer locks. */
3017 ast_bridge_unlock(peer_bridge);
3018 ast_bridge_channel_unlock(peer_bridge_channel);
3019 ast_channel_unlock(peer);
3020 }
3021
3022 /* Release chan locks. */
3023 ast_bridge_unlock(chan_bridge);
3024 ast_bridge_channel_unlock(chan_bridge_channel);
3025
3026 return res;
3027}
static int try_merge_optimize_out(struct ast_bridge *chan_bridge, struct ast_bridge_channel *chan_bridge_channel, struct ast_bridge *peer_bridge, struct ast_bridge_channel *peer_bridge_channel, struct ast_unreal_pvt *pvt)
Definition: bridge.c:2938
static struct ast_bridge * optimize_lock_chan_stack(struct ast_channel *chan)
Definition: bridge.c:2648
static struct ast_bridge * optimize_lock_peer_stack(struct ast_channel *peer)
Definition: bridge.c:2693
static int try_swap_optimize_out(struct ast_bridge *chan_bridge, struct ast_bridge_channel *chan_bridge_channel, struct ast_bridge *peer_bridge, struct ast_bridge_channel *peer_bridge_channel, struct ast_unreal_pvt *pvt)
Definition: bridge.c:2814
#define ast_bridge_channel_unlock(bridge_channel)
Unlock the bridge_channel.

References ast_bridge_channel_unlock, ast_bridge_unlock, ast_channel_internal_bridge_channel(), ast_channel_unlock, ast_bridge_channel::chan, optimize_lock_chan_stack(), optimize_lock_peer_stack(), try_merge_optimize_out(), and try_swap_optimize_out().

Referenced by got_optimized_out().

◆ ast_bridge_unsuspend()

int ast_bridge_unsuspend ( struct ast_bridge bridge,
struct ast_channel chan 
)

Unsuspend a channel from a bridge.

Parameters
bridgeBridge to unsuspend the channel from
chanChannel to unsuspend
Return values
0on success
-1on failure

Example usage:

ast_bridge_unsuspend(bridge, chan);
int ast_bridge_unsuspend(struct ast_bridge *bridge, struct ast_channel *chan)
Unsuspend a channel from a bridge.
Definition: bridge.c:3097

This unsuspends the channel pointed to by chan from the bridge pointed to by bridge. The bridge will go back to handling the channel once this function returns.

Note
You must not mess with the channel once this function returns. Doing so may result in bad things happening.

Definition at line 3097 of file bridge.c.

3098{
3099 struct ast_bridge_channel *bridge_channel;
3100/* XXX ASTERISK-21271 the case of a dissolved bridge while channel is suspended is not handled. */
3101
3103
3104 if (!(bridge_channel = bridge_find_channel(bridge, chan))) {
3106 return -1;
3107 }
3108
3110
3112
3113 return 0;
3114}
void bridge_channel_internal_unsuspend_nolock(struct ast_bridge_channel *bridge_channel)

References ast_bridge_lock, ast_bridge_unlock, ast_bridge_channel::bridge, bridge_channel_internal_unsuspend_nolock(), bridge_find_channel(), and ast_bridge_channel::chan.

Referenced by conf_moh_start(), and conf_moh_stop().

◆ ast_bridge_update_talker_src_video_mode()

void ast_bridge_update_talker_src_video_mode ( struct ast_bridge bridge,
struct ast_channel chan,
int  talker_energy,
int  is_keyframe 
)

Update information about talker energy for talker src video mode.

Definition at line 3885 of file bridge.c.

3886{
3888
3889 /* If the channel doesn't support video, we don't care about it */
3891 return;
3892 }
3893
3894 ast_bridge_lock(bridge);
3896
3897 if (data->chan_vsrc == chan) {
3898 data->average_talking_energy = talker_energy;
3899 } else if ((data->average_talking_energy < talker_energy) && is_keyframe) {
3900 if (data->chan_old_vsrc) {
3902 }
3903 if (data->chan_vsrc) {
3904 data->chan_old_vsrc = data->chan_vsrc;
3906 }
3907 data->chan_vsrc = ast_channel_ref(chan);
3908 data->average_talking_energy = talker_energy;
3909 ast_verb(5, "Video source in bridge '%s' (%s) is now '%s' (%s)\n",
3910 bridge->name, bridge->uniqueid,
3915 } else if ((data->average_talking_energy < talker_energy) && !is_keyframe) {
3917 } else if (!data->chan_vsrc && is_keyframe) {
3918 data->chan_vsrc = ast_channel_ref(chan);
3919 data->average_talking_energy = talker_energy;
3920 ast_verb(5, "Video source in bridge '%s' (%s) is now '%s' (%s)\n",
3921 bridge->name, bridge->uniqueid,
3926 } else if (!data->chan_old_vsrc && is_keyframe) {
3927 data->chan_old_vsrc = ast_channel_ref(chan);
3929 }
3930 ast_bridge_unlock(bridge);
3931}
struct ast_format_cap * ast_channel_nativeformats(const struct ast_channel *chan)
@ AST_MEDIA_TYPE_VIDEO
Definition: codec.h:33
int ast_format_cap_has_type(const struct ast_format_cap *cap, enum ast_media_type type)
Find out if the capabilities structure has any formats of a specific type.
Definition: format_cap.c:613
This is used for both SINGLE_SRC_TALKER mode to set what channel should be the current single video f...
Definition: bridge.h:125

References ast_bridge_lock, ast_bridge_publish_state(), ast_bridge_unlock, ast_channel_name(), ast_channel_nativeformats(), ast_channel_ref, ast_channel_uniqueid(), ast_channel_unref, AST_CONTROL_VIDUPDATE, ast_format_cap_has_type(), ast_indicate(), AST_MEDIA_TYPE_VIDEO, ast_verb, ast_bridge_video_talker_src_data::average_talking_energy, ast_bridge_video_talker_src_data::chan_old_vsrc, ast_bridge_video_talker_src_data::chan_vsrc, ast_bridge_video_mode::mode_data, ast_bridge::name, ast_bridge::softmix, ast_bridge_video_mode::talker_src_data, ast_bridge::uniqueid, and ast_bridge_softmix::video_mode.

Referenced by softmix_bridge_write_video().

◆ ast_bridge_vars_set()

void ast_bridge_vars_set ( struct ast_channel chan,
const char *  name,
const char *  pvtid 
)

Sets BRIDGECHANNEL and BRIDGEPVTCALLID for a channel.

Precondition
chan must be locked before calling
Parameters
chanchannel name of the bridged peer
name
pvtidPrivate CallID of the bridged peer

Definition at line 1281 of file bridge.c.

1282{
1284 pbx_builtin_setvar_helper(chan, "BRIDGEPEER", name);
1285 pbx_builtin_setvar_helper(chan, "BRIDGEPVTCALLID", pvtid);
1287}
void ast_channel_stage_snapshot_done(struct ast_channel *chan)
Clear flag to indicate channel snapshot is being staged, and publish snapshot.
void ast_channel_stage_snapshot(struct ast_channel *chan)
Set flag to indicate channel snapshot is being staged.

References ast_channel_stage_snapshot(), ast_channel_stage_snapshot_done(), ast_bridge_channel::chan, name, and pbx_builtin_setvar_helper().

Referenced by ast_bridge_channel_leave_bridge_nolock(), set_bridge_peer_vars_2party(), set_bridge_peer_vars_holding(), and set_bridge_peer_vars_multiparty().

◆ ast_bridge_video_mode_to_string()

const char * ast_bridge_video_mode_to_string ( enum ast_bridge_video_mode_type  video_mode)

Converts an enum representation of a bridge video mode to string.

Parameters
video_modeThe video mode
Returns
A string representation of video_mode

Definition at line 4020 of file bridge.c.

4021{
4022 switch (video_mode) {
4024 return "talker";
4026 return "single";
4028 return "sfu";
4030 default:
4031 return "none";
4032 }
4033}

References AST_BRIDGE_VIDEO_MODE_NONE, AST_BRIDGE_VIDEO_MODE_SFU, AST_BRIDGE_VIDEO_MODE_SINGLE_SRC, and AST_BRIDGE_VIDEO_MODE_TALKER_SRC.

Referenced by ast_bridge_snapshot_to_json(), ast_manager_build_bridge_state_string_prefix(), and handle_bridge_show_specific().

◆ ast_bridges()

struct ao2_container * ast_bridges ( void  )

Returns the global bridges container.

Since
17.0
Returns
a pointer to the bridges container success
Return values
NULLon failure
Note
You must use
ao2_ref(<container>, -1) 
when done with it
Warning
You must not attempt to modify the container returned.

Definition at line 185 of file bridge.c.

186{
187 return ao2_bump(bridges);
188}
#define ao2_bump(obj)
Bump refcount on an AO2 object by one, returning the object.
Definition: astobj2.h:480

References ao2_bump, and bridges.

Referenced by ast_ari_bridges_list(), bridges_scrape_cb(), and manager_bridges_list().

◆ ast_bridges_allow_optimization()

enum ast_bridge_optimization ast_bridges_allow_optimization ( struct ast_bridge chan_bridge,
struct ast_bridge peer_bridge 
)

Determine if bridges allow for optimization to occur betweem them.

Since
12.0.0
Parameters
chan_bridgeFirst bridge being tested
peer_bridgeSecond bridge being tested

This determines if two bridges allow for unreal channel optimization to occur between them. The function does not require for unreal channels to already be in the bridges when called.

Note
It is assumed that both bridges are locked prior to calling this function
A return other than AST_BRIDGE_OPTIMIZE_PROHIBITED does not guarantee that an optimization attempt will succeed. However, a return of AST_BRIDGE_OPTIMIZE_PROHIBITED guarantees that an optimization attempt will never succeed.
Returns
Optimization allowability for the bridges

Definition at line 3029 of file bridge.c.

3031{
3032 struct merge_direction merge;
3033
3034 if (!bridge_allows_optimization(chan_bridge) || !bridge_allows_optimization(peer_bridge)) {
3036 }
3037
3038 switch (bridges_allow_swap_optimization(chan_bridge, peer_bridge)) {
3043 case SWAP_PROHIBITED:
3044 default:
3045 break;
3046 }
3047
3048 /* Two channels will be kicked from the bridges, the unreal;1 and unreal;2 channels */
3049 if (bridges_allow_merge_optimization(chan_bridge, peer_bridge, 2, &merge) != MERGE_ALLOWED) {
3051 }
3052
3053 if (merge.dest == chan_bridge) {
3055 } else {
3057 }
3058}
static enum bridge_allow_merge bridges_allow_merge_optimization(struct ast_bridge *chan_bridge, struct ast_bridge *peer_bridge, int num_kick_channels, struct merge_direction *merge)
Definition: bridge.c:2904
static enum bridge_allow_swap bridges_allow_swap_optimization(struct ast_bridge *chan_bridge, struct ast_bridge *peer_bridge)
Definition: bridge.c:2758
static int bridge_allows_optimization(struct ast_bridge *bridge)
Definition: bridge.c:2629
@ AST_BRIDGE_OPTIMIZE_PROHIBITED
Definition: bridge.h:888
@ AST_BRIDGE_OPTIMIZE_MERGE_TO_CHAN_BRIDGE
Definition: bridge.h:884
@ AST_BRIDGE_OPTIMIZE_SWAP_TO_PEER_BRIDGE
Definition: bridge.h:882
@ AST_BRIDGE_OPTIMIZE_MERGE_TO_PEER_BRIDGE
Definition: bridge.h:886
@ AST_BRIDGE_OPTIMIZE_SWAP_TO_CHAN_BRIDGE
Definition: bridge.h:880

References AST_BRIDGE_OPTIMIZE_MERGE_TO_CHAN_BRIDGE, AST_BRIDGE_OPTIMIZE_MERGE_TO_PEER_BRIDGE, AST_BRIDGE_OPTIMIZE_PROHIBITED, AST_BRIDGE_OPTIMIZE_SWAP_TO_CHAN_BRIDGE, AST_BRIDGE_OPTIMIZE_SWAP_TO_PEER_BRIDGE, bridge_allows_optimization(), bridges_allow_merge_optimization(), bridges_allow_swap_optimization(), merge_direction::dest, MERGE_ALLOWED, SWAP_PROHIBITED, SWAP_TO_CHAN_BRIDGE, and SWAP_TO_PEER_BRIDGE.

Referenced by two_bridge_attended_transfer().

◆ ast_bridging_init()

int ast_bridging_init ( void  )

Initialize the bridging system.

Since
12.0.0
Return values
0on success.
-1on error.

Definition at line 5613 of file bridge.c.

5614{
5616
5618 return -1;
5619 }
5620
5622 if (!bridge_manager) {
5623 return -1;
5624 }
5625
5628 if (!bridges) {
5629 return -1;
5630 }
5632
5634
5636
5637 ast_manager_register_xml_core("BridgeTechnologyList", 0, manager_bridge_tech_list);
5638 ast_manager_register_xml_core("BridgeTechnologySuspend", 0, manager_bridge_tech_suspend);
5639 ast_manager_register_xml_core("BridgeTechnologyUnsuspend", 0, manager_bridge_tech_unsuspend);
5640
5641 return 0;
5642}
int ast_register_cleanup(void(*func)(void))
Register a function to be executed before Asterisk gracefully exits.
Definition: clicompat.c:19
#define ao2_container_alloc_rbtree(ao2_options, container_options, sort_fn, cmp_fn)
Allocate and initialize a red-black tree container.
Definition: astobj2.h:1349
int ao2_container_register(const char *name, struct ao2_container *self, ao2_prnt_obj_fn *prnt_obj)
Register a container for CLI stats and integrity check.
static struct bridge_manager_controller * bridge_manager
Definition: bridge.c:183
static int manager_bridge_tech_list(struct mansession *s, const struct message *m)
Definition: bridge.c:5530
static int manager_bridge_tech_suspend(struct mansession *s, const struct message *m)
Definition: bridge.c:5520
static int manager_bridge_tech_unsuspend(struct mansession *s, const struct message *m)
Definition: bridge.c:5525
static struct ast_cli_entry bridge_cli[]
Definition: bridge.c:5474
static int bridge_sort_cmp(const void *obj_left, const void *obj_right, int flags)
Definition: bridge.c:5059
static void bridge_prnt_obj(void *v_obj, void *where, ao2_prnt_fn *prnt)
Definition: bridge.c:5583
static void bridge_cleanup(void)
Definition: bridge.c:5599
static struct bridge_manager_controller * bridge_manager_create(void)
Definition: bridge.c:5020
void ast_bridging_init_basic(void)
#define ast_cli_register_multiple(e, len)
Register multiple commands.
Definition: cli.h:265
#define ast_manager_register_xml_core(action, authority, func)
Register a manager callback using XML documentation to describe the manager.
Definition: manager.h:203
int ast_stasis_bridging_init(void)

References AO2_ALLOC_OPT_LOCK_MUTEX, AO2_CONTAINER_ALLOC_OPT_DUPS_REPLACE, ao2_container_alloc_rbtree, ao2_container_register(), ARRAY_LEN, ast_bridging_init_basic(), ast_cli_register_multiple, ast_manager_register_xml_core, ast_register_cleanup(), ast_stasis_bridging_init(), bridge_cleanup(), bridge_cli, bridge_manager, bridge_manager_create(), bridge_prnt_obj(), bridge_sort_cmp(), bridges, manager_bridge_tech_list(), manager_bridge_tech_suspend(), manager_bridge_tech_unsuspend(), and NULL.

Referenced by asterisk_daemon().

◆ ast_brige_set_remb_behavior()

void ast_brige_set_remb_behavior ( struct ast_bridge bridge,
enum ast_bridge_video_sfu_remb_behavior  behavior 
)

Set the REMB report generation behavior on a bridge.

Parameters
bridgeBridge to set the REMB behavior on
behaviorHow REMB reports are generated
Note
This can only be called when the bridge has been set to the SFU video mode.

Definition at line 3867 of file bridge.c.

3868{
3870
3871 ast_bridge_lock(bridge);
3873 ast_bridge_unlock(bridge);
3874}
enum ast_bridge_video_sfu_remb_behavior remb_behavior
Definition: bridge.h:157

References ast_assert, ast_bridge_lock, ast_bridge_unlock, AST_BRIDGE_VIDEO_MODE_SFU, ast_bridge_video_mode::mode, ast_bridge_video_mode::mode_data, ast_bridge_video_sfu_data::remb_behavior, ast_bridge_video_mode::sfu_data, ast_bridge::softmix, and ast_bridge_softmix::video_mode.

Referenced by join_conference_bridge().

◆ attended_transfer_bridge()

static enum ast_transfer_result attended_transfer_bridge ( struct ast_channel chan1,
struct ast_channel chan2,
struct ast_bridge bridge1,
struct ast_bridge bridge2,
struct ast_attended_transfer_message transfer_msg 
)
static

Perform an attended transfer of a bridge.

This performs an attended transfer of an entire bridge to a target. The target varies, depending on what bridges exist during the transfer attempt.

If two bridges exist, then a local channel is created to link the two bridges together.

If only one bridge exists, then a local channel is created with one end placed into the existing bridge and the other end masquerading into the unbridged channel.

Parameters
chan1Transferer channel. Guaranteed to be bridged.
chan2Other transferer channel. May or may not be bridged.
bridge1Bridge that chan1 is in. Guaranteed to be non-NULL.
bridge2Bridge that chan2 is in. If NULL, then chan2 is not bridged.
transfer_msgData to publish for a stasis attended transfer message.
Return values
AST_BRIDGE_TRANSFER_FAILInternal error occurred
AST_BRIDGE_TRANSFER_SUCCESSSuccessfully transferred the bridge

Definition at line 4290 of file bridge.c.

4293{
4294#define BRIDGE_LOCK_ONE_OR_BOTH(b1, b2) \
4295 do { \
4296 if (b2) { \
4297 ast_bridge_lock_both(b1, b2); \
4298 } else { \
4299 ast_bridge_lock(b1); \
4300 } \
4301 } while (0)
4302
4303 static const char *dest = "_attended@transfer/m";
4304 struct ast_channel *local_chan;
4305 int cause;
4306 int res;
4307 const char *app = NULL;
4308 struct ast_format_cap *caps;
4309
4310 ast_channel_lock(chan1);
4311 caps = ao2_bump(ast_channel_nativeformats(chan1));
4312 ast_channel_unlock(chan1);
4313
4314 local_chan = ast_request("Local", caps, NULL, chan1, dest, &cause);
4315
4316 ao2_cleanup(caps);
4317
4318 if (!local_chan) {
4320 }
4321
4322 ast_channel_lock_both(local_chan, chan1);
4325 ast_channel_unlock(local_chan);
4326 ast_channel_unlock(chan1);
4327
4328 if (bridge2) {
4329 res = ast_local_setup_bridge(local_chan, bridge2, chan2, NULL);
4330 } else {
4332 res = ast_local_setup_masquerade(local_chan, chan2);
4333 }
4334
4335 if (res) {
4336 ast_hangup(local_chan);
4338 }
4339
4340 /*
4341 * Since bridges need to be unlocked before entering ast_bridge_impart and
4342 * core_local may call into it then the bridges need to be unlocked here.
4343 */
4344 ast_bridge_unlock(bridge1);
4345 if (bridge2) {
4346 ast_bridge_unlock(bridge2);
4347 }
4348
4349 if (ast_call(local_chan, dest, 0)) {
4350 ast_hangup(local_chan);
4351 BRIDGE_LOCK_ONE_OR_BOTH(bridge1, bridge2);
4353 }
4354
4355 /* Get a ref for use later since this one is being stolen */
4356 ao2_ref(local_chan, +1);
4357 if (ast_bridge_impart(bridge1, local_chan, chan1, NULL,
4359 ast_hangup(local_chan);
4360 ao2_cleanup(local_chan);
4361 BRIDGE_LOCK_ONE_OR_BOTH(bridge1, bridge2);
4363 }
4364 BRIDGE_LOCK_ONE_OR_BOTH(bridge1, bridge2);
4365
4366 if (bridge2) {
4367 void *tech;
4368 struct ast_channel *locals[2];
4369
4370 /* Have to lock everything just in case a hangup comes in early */
4371 ast_local_lock_all(local_chan, &tech, &locals[0], &locals[1]);
4372 if (!locals[0] || !locals[1]) {
4373 ast_log(LOG_ERROR, "Transfer failed probably due to an early hangup - "
4374 "missing other half of '%s'\n", ast_channel_name(local_chan));
4376 ao2_cleanup(local_chan);
4378 }
4379
4380 /* Make sure the peer is properly set */
4381 if (local_chan != locals[0]) {
4382 SWAP(locals[0], locals[1]);
4383 }
4384
4387 } else {
4388 ast_attended_transfer_message_add_app(transfer_msg, app, local_chan);
4389 }
4390
4391 ao2_cleanup(local_chan);
4393}
#define BRIDGE_LOCK_ONE_OR_BOTH(b1, b2)
int ast_call(struct ast_channel *chan, const char *addr, int timeout)
Make a call.
Definition: channel.c:6478
@ AST_CHANNEL_REQUESTOR_REPLACEMENT
Definition: channel.h:1525
#define ast_channel_lock_both(chan1, chan2)
Lock two channels.
Definition: channel.h:2977
void ast_channel_req_accountcodes(struct ast_channel *chan, const struct ast_channel *requestor, enum ast_channel_requestor_relationship relationship)
Setup new channel accountcodes from the requestor channel after ast_request().
Definition: channel.c:6451
struct ast_channel * ast_request(const char *type, struct ast_format_cap *request_cap, const struct ast_assigned_ids *assignedids, const struct ast_channel *requestor, const char *addr, int *cause)
Requests a channel.
Definition: channel.c:6371
static struct ao2_container * locals
Definition: core_local.c:150
void ast_local_unlock_all(void *tech_pvt, struct ast_channel *base_chan, struct ast_channel *base_owner)
Remove a reference to the given local channel's private tech, unlock the given local channel's privat...
Definition: core_local.c:268
int ast_local_setup_bridge(struct ast_channel *ast, struct ast_bridge *bridge, struct ast_channel *swap, struct ast_bridge_features *features)
Setup the outgoing local channel to join a bridge on ast_call().
Definition: core_local.c:613
void ast_local_lock_all(struct ast_channel *chan, void **tech_pvt, struct ast_channel **base_chan, struct ast_channel **base_owner)
Add a reference to the local channel's private tech, lock the local channel's private base,...
Definition: core_local.c:253
int ast_local_setup_masquerade(struct ast_channel *ast, struct ast_channel *masq)
Setup the outgoing local channel to masquerade into a channel on ast_call().
Definition: core_local.c:655
int ast_attended_transfer_message_add_link(struct ast_attended_transfer_message *transfer_msg, struct ast_channel *locals[2])
Add details for an attended transfer that has a link between bridges.
const struct ast_channel_tech * tech
Format capabilities structure, holds formats + preference order + etc.
Definition: format_cap.c:54
#define SWAP(a, b)
Definition: utils.h:235

References ao2_bump, ao2_cleanup, ao2_ref, app, ast_attended_transfer_message_add_app(), ast_attended_transfer_message_add_link(), ast_bridge_impart(), AST_BRIDGE_IMPART_CHAN_INDEPENDENT, AST_BRIDGE_TRANSFER_FAIL, AST_BRIDGE_TRANSFER_SUCCESS, ast_bridge_unlock, ast_call(), ast_channel_appl(), ast_channel_lock, ast_channel_lock_both, ast_channel_name(), ast_channel_nativeformats(), ast_channel_req_accountcodes(), AST_CHANNEL_REQUESTOR_REPLACEMENT, ast_channel_unlock, ast_hangup(), ast_local_lock_all(), ast_local_setup_bridge(), ast_local_setup_masquerade(), ast_local_unlock_all(), ast_log, ast_request(), ast_strdupa, ATTENDEDTRANSFER, BRIDGE_LOCK_ONE_OR_BOTH, locals, LOG_ERROR, NULL, pbx_builtin_setvar_helper(), SWAP, and ast_channel::tech.

Referenced by ast_bridge_transfer_attended(), and two_bridge_attended_transfer().

◆ blind_transfer_bridge()

static enum ast_transfer_result blind_transfer_bridge ( int  is_external,
struct ast_channel transferer,
struct ast_bridge bridge,
const char *  exten,
const char *  context,
struct ast_channel transferee,
transfer_channel_cb  new_channel_cb,
struct transfer_channel_data user_data_wrapper,
struct ast_blind_transfer_message transfer_message 
)
static

Definition at line 4180 of file bridge.c.

4186{
4187 struct ast_channel *local;
4188 char chan_name[AST_MAX_EXTENSION + AST_MAX_CONTEXT + 2];
4189 int cause;
4190 struct ast_format_cap *caps;
4191
4192 ast_channel_lock(transferer);
4193 caps = ao2_bump(ast_channel_nativeformats(transferer));
4194 ast_channel_unlock(transferer);
4195
4196 snprintf(chan_name, sizeof(chan_name), "%s@%s", exten, context);
4197 local = ast_request("Local", caps, NULL, transferer,
4198 chan_name, &cause);
4199
4200 ao2_cleanup(caps);
4201
4202 if (!local) {
4204 }
4205
4206 ast_channel_lock_both(local, transferer);
4208
4210 if (!transfer_message->replace_channel) {
4211 ast_hangup(local);
4213 }
4214
4216 ast_channel_unlock(local);
4217 ast_channel_unlock(transferer);
4218
4219 if (new_channel_cb) {
4220 new_channel_cb(local, user_data_wrapper, AST_BRIDGE_TRANSFER_MULTI_PARTY);
4221 }
4222
4223 if (ast_call(local, chan_name, 0)) {
4224 ast_hangup(local);
4226 }
4227
4228 if (ast_bridge_impart(bridge, local, transferer, NULL,
4230 ast_hangup(local);
4232 }
4233
4235}
@ AST_BRIDGE_TRANSFER_MULTI_PARTY
Definition: bridge.h:1117
#define AST_MAX_CONTEXT
Definition: channel.h:135
#define AST_MAX_EXTENSION
Definition: channel.h:134
struct ast_channel_snapshot * replace_channel

References ao2_bump, ao2_cleanup, ast_bridge_impart(), AST_BRIDGE_IMPART_CHAN_INDEPENDENT, AST_BRIDGE_TRANSFER_FAIL, AST_BRIDGE_TRANSFER_MULTI_PARTY, AST_BRIDGE_TRANSFER_SUCCESS, ast_call(), ast_channel_lock, ast_channel_lock_both, ast_channel_name(), ast_channel_nativeformats(), ast_channel_req_accountcodes(), AST_CHANNEL_REQUESTOR_REPLACEMENT, ast_channel_snapshot_get_latest(), ast_channel_uniqueid(), ast_channel_unlock, ast_hangup(), AST_MAX_CONTEXT, AST_MAX_EXTENSION, ast_request(), BLINDTRANSFER, voicemailpwcheck::context, NULL, pbx_builtin_setvar_helper(), and ast_blind_transfer_message::replace_channel.

Referenced by ast_bridge_transfer_blind().

◆ bridge_action_bridge()

static void bridge_action_bridge ( struct ast_bridge bridge,
struct ast_frame action 
)
static

Definition at line 607 of file bridge.c.

608{
609#if 0 /* In case we need to know when the destructor is calling us. */
610 int in_destructor = !ao2_ref(bridge, 0);
611#endif
612
613 switch (action->subclass.integer) {
615 ast_bridge_unlock(bridge);
616 bridge_tech_deferred_destroy(bridge, action);
617 ast_bridge_lock(bridge);
618 break;
620 ast_bridge_unlock(bridge);
621 bridge->v_table->dissolving(bridge);
622 ast_bridge_lock(bridge);
623 break;
624 default:
625 /* Unexpected deferred action type. Should never happen. */
626 ast_assert(0);
627 break;
628 }
629}
static void bridge_tech_deferred_destroy(struct ast_bridge *bridge, struct ast_frame *action)
Definition: bridge.c:579
@ BRIDGE_CHANNEL_ACTION_DEFERRED_TECH_DESTROY
@ BRIDGE_CHANNEL_ACTION_DEFERRED_DISSOLVING
ast_bridge_dissolving_fn dissolving
Definition: bridge.h:267
struct ast_frame_subclass subclass

References ao2_ref, ast_assert, ast_bridge_lock, ast_bridge_unlock, BRIDGE_CHANNEL_ACTION_DEFERRED_DISSOLVING, BRIDGE_CHANNEL_ACTION_DEFERRED_TECH_DESTROY, bridge_tech_deferred_destroy(), ast_bridge_methods::dissolving, ast_frame_subclass::integer, ast_frame::subclass, and ast_bridge::v_table.

Referenced by bridge_handle_actions().

◆ bridge_alloc()

struct ast_bridge * bridge_alloc ( size_t  size,
const struct ast_bridge_methods v_table 
)

Definition at line 747 of file bridge.c.

748{
749 struct ast_bridge *bridge;
750
751 /* Check v_table that all methods are present. */
752 if (!v_table
753 || !v_table->name
754 || !v_table->destroy
756 || !v_table->push
757 || !v_table->pull
760 ast_log(LOG_ERROR, "Virtual method table for bridge class %s not complete.\n",
761 v_table && v_table->name ? v_table->name : "<unknown>");
762 ast_assert(0);
763 return NULL;
764 }
765
766 bridge = ao2_alloc(size, destroy_bridge);
767 if (!bridge) {
768 return NULL;
769 }
770
771 if (ast_string_field_init(bridge, 80)) {
772 ao2_cleanup(bridge);
773 return NULL;
774 }
775
776 bridge->v_table = v_table;
777
779
780 return bridge;
781}
static void destroy_bridge(void *obj)
Definition: bridge.c:659
@ AST_MEDIA_TYPE_END
Definition: codec.h:36
ast_bridge_push_channel_fn push
Definition: bridge.h:269
const char * name
Definition: bridge.h:263
ast_bridge_destructor_fn destroy
Definition: bridge.h:265
ast_bridge_merge_priority_fn get_merge_priority
Definition: bridge.h:275
ast_bridge_pull_channel_fn pull
Definition: bridge.h:271
struct ast_vector_int media_types
Definition: bridge.h:408
#define AST_VECTOR_INIT(vec, size)
Initialize a vector.
Definition: vector.h:113

References ao2_alloc, ao2_cleanup, ast_assert, ast_log, AST_MEDIA_TYPE_END, ast_string_field_init, AST_VECTOR_INIT, ast_bridge_methods::destroy, destroy_bridge(), ast_bridge_methods::dissolving, ast_bridge_methods::get_merge_priority, LOG_ERROR, ast_bridge::media_types, ast_bridge_methods::name, ast_bridge_methods::notify_masquerade, NULL, ast_bridge_methods::pull, ast_bridge_methods::push, and ast_bridge::v_table.

Referenced by ast_bridge_base_new(), ast_bridge_basic_new(), bridge_agent_hold_new(), bridge_parking_new(), and bridge_stasis_new().

◆ bridge_allows_optimization()

static int bridge_allows_optimization ( struct ast_bridge bridge)
static

Definition at line 2629 of file bridge.c.

2630{
2631 return !(bridge->inhibit_merge
2632 || bridge->dissolved
2634}
unsigned int dissolved
Definition: bridge.h:394
unsigned int inhibit_merge
Count of the active temporary requests to inhibit bridge merges. Zero if merges are allowed.
Definition: bridge.h:388

References AST_BRIDGE_FLAG_MASQUERADE_ONLY, ast_test_flag, ast_channel::bridge, ast_bridge::dissolved, ast_bridge::feature_flags, and ast_bridge::inhibit_merge.

Referenced by ast_bridges_allow_optimization(), optimize_lock_chan_stack(), and optimize_lock_peer_stack().

◆ bridge_base_destroy()

static void bridge_base_destroy ( struct ast_bridge self)
static

Definition at line 880 of file bridge.c.

881{
882 ast_debug(1, "Bridge " BRIDGE_PRINTF_SPEC ": destroying bridge (noop)\n",
883 BRIDGE_PRINTF_VARS(self));
884}

References ast_debug, BRIDGE_PRINTF_SPEC, and BRIDGE_PRINTF_VARS.

◆ bridge_base_dissolving()

static void bridge_base_dissolving ( struct ast_bridge self)
static

Definition at line 893 of file bridge.c.

894{
895 ast_debug(1, "Bridge " BRIDGE_PRINTF_SPEC ": unlinking bridge. Refcount: %d\n",
896 BRIDGE_PRINTF_VARS(self), ao2_ref(self, 0));
897 ao2_unlink(bridges, self);
898 ast_debug(1, "Bridge " BRIDGE_PRINTF_SPEC ": unlinked bridge. Refcount: %d\n",
899 BRIDGE_PRINTF_VARS(self), ao2_ref(self, 0));
900}
#define ao2_unlink(container, obj)
Remove an object from a container.
Definition: astobj2.h:1578

References ao2_ref, ao2_unlink, ast_debug, BRIDGE_PRINTF_SPEC, BRIDGE_PRINTF_VARS, and bridges.

◆ bridge_base_get_merge_priority()

static int bridge_base_get_merge_priority ( struct ast_bridge self)
static

Definition at line 963 of file bridge.c.

964{
965 return 0;
966}

◆ bridge_base_init()

struct ast_bridge * bridge_base_init ( struct ast_bridge self,
uint32_t  capabilities,
unsigned int  flags,
const char *  creator,
const char *  name,
const char *  id 
)

Initialize the base class of the bridge.

Parameters
selfBridge to operate upon. (Tolerates a NULL pointer)
capabilitiesThe capabilities that we require to be used on the bridge
flagsFlags that will alter the behavior of the bridge
creatorEntity that created the bridge (optional)
nameName given to the bridge by its creator (optional, requires named creator)
idUnique ID given to the bridge by its creator (optional)
Returns
self on success
Return values
NULLon failure, self is already destroyed

Example usage:

struct ast_bridge *bridge;
bridge = bridge_alloc(sizeof(*bridge), &ast_bridge_base_v_table);
struct ast_bridge_methods ast_bridge_base_v_table
Bridge base class virtual method table.
Definition: bridge.c:988
struct ast_bridge * bridge_base_init(struct ast_bridge *self, uint32_t capabilities, unsigned int flags, const char *creator, const char *name, const char *id)
Initialize the base class of the bridge.
Definition: bridge.c:783
struct ast_bridge * bridge_alloc(size_t size, const struct ast_bridge_methods *v_table)
Definition: bridge.c:747

This creates a no frills two party bridge that will be destroyed once one of the channels hangs up.

Definition at line 783 of file bridge.c.

784{
785 char uuid_hold[AST_UUID_STR_LEN];
786
787 if (!self) {
788 return NULL;
789 }
790
791 {
792 /*
793 * We need to ensure that another bridge with the same uniqueid
794 * doesn't get created before the previous bridge's destructor
795 * has run and deleted the existing topic.
796 */
798 if (!ast_strlen_zero(id)) {
799 if (ast_bridge_topic_exists(id)) {
800 ast_log(LOG_WARNING, "Bridge " BRIDGE_PRINTF_SPEC ": already registered\n",
801 BRIDGE_PRINTF_VARS(self));
802 ast_bridge_destroy(self, 0);
803 return NULL;
804 }
805 ast_string_field_set(self, uniqueid, id);
806 } else {
808 ast_string_field_set(self, uniqueid, uuid_hold);
809 }
810 if (!(flags & AST_BRIDGE_FLAG_INVISIBLE)) {
811 if (bridge_topics_init(self) != 0) {
812 ast_log(LOG_WARNING, "Bridge " BRIDGE_PRINTF_SPEC ": Could not initialize topics\n",
813 BRIDGE_PRINTF_VARS(self));
814 ao2_ref(self, -1);
815 return NULL;
816 }
817 }
818 }
819
820 ast_string_field_set(self, creator, creator);
821 if (!ast_strlen_zero(creator)) {
823 }
824 ast_debug(1, "Bridge " BRIDGE_PRINTF_SPEC ": base_init\n",
825 BRIDGE_PRINTF_VARS(self));
826
827 ast_set_flag(&self->feature_flags, flags);
828 self->allowed_capabilities = capabilities;
829
830 /* Use our helper function to find the "best" bridge technology. */
831 self->technology = find_best_technology(capabilities, self);
832 if (!self->technology) {
833 ast_log(LOG_WARNING, "Bridge %s: Could not create class %s. No technology to support it.\n",
834 self->uniqueid, self->v_table->name);
835 ao2_ref(self, -1);
836 return NULL;
837 }
838
839 /* Pass off the bridge to the technology to manipulate if needed */
840 ast_debug(1, "Bridge %s: calling %s technology constructor\n",
841 self->uniqueid, self->technology->name);
842 if (self->technology->create && self->technology->create(self)) {
843 ast_log(LOG_WARNING, "Bridge %s: failed to setup bridge technology %s\n",
844 self->uniqueid, self->technology->name);
845 ao2_ref(self, -1);
846 return NULL;
847 }
848 ast_debug(1, "Bridge %s: calling %s technology start\n",
849 self->uniqueid, self->technology->name);
850 if (self->technology->start && self->technology->start(self)) {
851 ast_log(LOG_WARNING, "Bridge %s: failed to start bridge technology %s\n",
852 self->uniqueid, self->technology->name);
853 ao2_ref(self, -1);
854 return NULL;
855 }
856
857 if (!(flags & AST_BRIDGE_FLAG_INVISIBLE)) {
858 if (!ast_bridge_topic(self)) {
859 ao2_ref(self, -1);
860 return NULL;
861 }
862 }
863
864 self->creationtime = ast_tvnow();
865 ast_debug(1, "Bridge " BRIDGE_PRINTF_SPEC ": base_init complete\n",
866 BRIDGE_PRINTF_VARS(self));
867
868 return self;
869}
int ast_bridge_destroy(struct ast_bridge *bridge, int cause)
Destroy a bridge.
Definition: bridge.c:1009
static struct ast_bridge_technology * find_best_technology(uint32_t capabilities, struct ast_bridge *bridge)
Helper function used to find the "best" bridge technology given specified capabilities.
Definition: bridge.c:518
static ast_mutex_t bridge_init_lock
Definition: bridge.c:136
#define SCOPED_MUTEX(varname, lock)
scoped lock specialization for mutexes
Definition: lock.h:593
int ast_bridge_topic_exists(const char *uniqueid)
Check if a stasis topic exists for a bridge uniqueid.
int bridge_topics_init(struct ast_bridge *bridge)
struct stasis_topic * ast_bridge_topic(struct ast_bridge *bridge)
A topic which publishes the events for a particular bridge.
#define ast_string_field_set(x, field, data)
Set a field to a simple string value.
Definition: stringfields.h:521
int(* start)(struct ast_bridge *bridge)
Request a bridge technology instance start operations.
int(* create)(struct ast_bridge *bridge)
Create a bridge technology instance for a bridge.
struct timeval creationtime
Definition: bridge.h:412
uint32_t allowed_capabilities
Definition: bridge.h:375
#define AST_UUID_STR_LEN
Definition: uuid.h:27
char * ast_uuid_generate_str(char *buf, size_t size)
Generate a UUID string.
Definition: uuid.c:141

References ast_bridge::allowed_capabilities, ao2_ref, ast_bridge_destroy(), AST_BRIDGE_FLAG_INVISIBLE, ast_bridge_topic(), ast_bridge_topic_exists(), ast_debug, ast_log, ast_set_flag, ast_string_field_set, ast_strlen_zero(), ast_tvnow(), ast_uuid_generate_str(), AST_UUID_STR_LEN, bridge_init_lock, BRIDGE_PRINTF_SPEC, BRIDGE_PRINTF_VARS, bridge_topics_init(), ast_bridge_technology::create, ast_bridge::creationtime, ast_bridge::creator, ast_bridge::feature_flags, find_best_technology(), lock, LOG_WARNING, name, ast_bridge_methods::name, ast_bridge_technology::name, NULL, SCOPED_MUTEX, ast_bridge_technology::start, ast_bridge::technology, ast_bridge::uniqueid, and ast_bridge::v_table.

Referenced by ast_bridge_base_new(), ast_bridge_basic_new(), bridge_agent_hold_new(), bridge_parking_new(), and bridge_stasis_new().

◆ bridge_base_notify_masquerade()

static void bridge_base_notify_masquerade ( struct ast_bridge self,
struct ast_bridge_channel bridge_channel 
)
static

Definition at line 947 of file bridge.c.

948{
949 self->reconfigured = 1;
950}
unsigned int reconfigured
Definition: bridge.h:392

References ast_bridge::reconfigured.

◆ bridge_base_pull()

static void bridge_base_pull ( struct ast_bridge self,
struct ast_bridge_channel bridge_channel 
)
static

Definition at line 932 of file bridge.c.

933{
935}
void ast_bridge_features_remove(struct ast_bridge_features *features, enum ast_bridge_hook_remove_flags remove_flags)
Remove marked bridge channel feature hooks.
Definition: bridge.c:3570
@ AST_BRIDGE_HOOK_REMOVE_ON_PULL

References ast_bridge_features_remove(), AST_BRIDGE_HOOK_REMOVE_ON_PULL, and ast_bridge_channel::features.

◆ bridge_base_push()

static int bridge_base_push ( struct ast_bridge self,
struct ast_bridge_channel bridge_channel,
struct ast_bridge_channel swap 
)
static

Definition at line 917 of file bridge.c.

918{
919 return 0;
920}

◆ bridge_base_push_peek()

static int bridge_base_push_peek ( struct ast_bridge self,
struct ast_bridge_channel bridge_channel,
struct ast_bridge_channel swap 
)
static

Definition at line 983 of file bridge.c.

984{
985 return 0;
986}

◆ bridge_channel_change_bridge()

static void bridge_channel_change_bridge ( struct ast_bridge_channel bridge_channel,
struct ast_bridge new_bridge 
)
static

Definition at line 2076 of file bridge.c.

2077{
2078 struct ast_bridge *old_bridge;
2079
2080 ao2_ref(new_bridge, +1);
2081 ast_bridge_channel_lock(bridge_channel);
2082 ast_channel_lock(bridge_channel->chan);
2083 old_bridge = bridge_channel->bridge;
2084 bridge_channel->bridge = new_bridge;
2085 ast_channel_internal_bridge_set(bridge_channel->chan, new_bridge);
2086 ast_channel_unlock(bridge_channel->chan);
2087 ast_bridge_channel_unlock(bridge_channel);
2088 ao2_ref(old_bridge, -1);
2089}
#define ast_bridge_channel_lock(bridge_channel)
Lock the bridge_channel.
void ast_channel_internal_bridge_set(struct ast_channel *chan, struct ast_bridge *value)

References ao2_ref, ast_bridge_channel_lock, ast_bridge_channel_unlock, ast_channel_internal_bridge_set(), ast_channel_lock, ast_channel_unlock, ast_bridge_channel::bridge, and ast_bridge_channel::chan.

Referenced by bridge_do_merge(), and bridge_do_move().

◆ bridge_channel_complete_join()

static void bridge_channel_complete_join ( struct ast_bridge bridge,
struct ast_bridge_channel bridge_channel 
)
static

Definition at line 452 of file bridge.c.

453{
454 /* Tell the bridge technology we are joining so they set us up */
455 ast_debug(1, "Bridge %s: %p(%s) is joining %s technology\n",
456 bridge->uniqueid, bridge_channel, ast_channel_name(bridge_channel->chan),
457 bridge->technology->name);
458 if (bridge->technology->join
459 && bridge->technology->join(bridge, bridge_channel)) {
460 /* We cannot leave the channel partially in the bridge so we must kick it out */
461 ast_debug(1, "Bridge %s: %p(%s) failed to join %s technology (Kicking it out)\n",
462 bridge->uniqueid, bridge_channel, ast_channel_name(bridge_channel->chan),
463 bridge->technology->name);
464 bridge_channel->just_joined = 1;
466 return;
467 }
468
469 bridge_channel->just_joined = 0;
470
471 /*
472 * When a channel joins the bridge its streams need to be mapped to the bridge's
473 * media types vector. This way all streams map to the same media type index for
474 * a given channel.
475 */
476 if (bridge_channel->bridge->technology->stream_topology_changed) {
477 bridge_channel->bridge->technology->stream_topology_changed(
478 bridge_channel->bridge, bridge_channel);
479 } else {
480 ast_bridge_channel_stream_map(bridge_channel);
481 }
482}
void ast_bridge_channel_stream_map(struct ast_bridge_channel *bridge_channel)
Maps a channel's stream topology to and from the bridge.
@ BRIDGE_CHANNEL_STATE_END
unsigned int just_joined
void(* stream_topology_changed)(struct ast_bridge *bridge, struct ast_bridge_channel *bridge_channel)
Callback for when a stream topology changes on the channel.
int(* join)(struct ast_bridge *bridge, struct ast_bridge_channel *bridge_channel)
Add a channel to a bridging technology instance for a bridge.

References ast_bridge_channel_leave_bridge(), ast_bridge_channel_stream_map(), ast_channel_name(), ast_debug, ast_bridge_channel::bridge, BRIDGE_CHANNEL_STATE_END, ast_bridge_channel::chan, ast_bridge_technology::join, ast_bridge_channel::just_joined, ast_bridge_technology::name, ast_bridge_technology::stream_topology_changed, ast_bridge::technology, and ast_bridge::uniqueid.

Referenced by bridge_complete_join(), and smart_bridge_operation().

◆ bridge_channel_depart_thread()

static void * bridge_channel_depart_thread ( void *  data)
static

Thread responsible for imparted bridged channels to be departed.

Definition at line 1780 of file bridge.c.

1781{
1782 struct ast_bridge_channel *bridge_channel = data;
1783 int res = 0;
1784
1785 if (bridge_channel->callid) {
1786 ast_callid_threadassoc_add(bridge_channel->callid);
1787 }
1788
1789 res = bridge_channel_internal_join(bridge_channel);
1790
1791 /*
1792 * cleanup
1793 *
1794 * If bridge_channel->swap is not NULL then the join failed.
1795 */
1796 ao2_t_cleanup(bridge_channel->swap, "Bridge complete: Departable impart join failed");
1797 bridge_channel->swap = NULL;
1798 ast_bridge_features_destroy(bridge_channel->features);
1799 bridge_channel->features = NULL;
1800
1803 /* If join failed there will be impart threads waiting. */
1804 bridge_channel_impart_signal(bridge_channel->chan);
1805 ast_bridge_discard_after_goto(bridge_channel->chan);
1806
1807 return NULL;
1808}
@ AST_BRIDGE_AFTER_CB_REASON_DEPART
Definition: bridge_after.h:45
void ast_bridge_discard_after_goto(struct ast_channel *chan)
Discard channel after bridge goto location.
Definition: bridge_after.c:384
int ast_callid_threadassoc_add(ast_callid callid)
Adds a known callid to thread storage of the calling thread.
Definition: logger.c:2295

References ao2_t_cleanup, AST_BRIDGE_AFTER_CB_REASON_DEPART, AST_BRIDGE_AFTER_CB_REASON_IMPART_FAILED, ast_bridge_discard_after_callback(), ast_bridge_discard_after_goto(), ast_bridge_features_destroy(), ast_callid_threadassoc_add(), bridge_channel_impart_signal(), bridge_channel_internal_join(), ast_bridge_channel::callid, ast_bridge_channel::chan, ast_bridge_channel::features, NULL, and ast_bridge_channel::swap.

Referenced by bridge_impart_internal().

◆ bridge_channel_impart_add()

static int bridge_channel_impart_add ( struct ast_channel chan,
struct bridge_channel_impart_cond cond 
)
static

Definition at line 1618 of file bridge.c.

1619{
1620 struct ast_datastore *datastore;
1621 struct bridge_channel_impart_ds_head *ds_head;
1622
1623 ast_channel_lock(chan);
1624
1626 if (!datastore) {
1628 if (!datastore) {
1629 ast_channel_unlock(chan);
1630 return -1;
1631 }
1632 ds_head = ast_calloc(1, sizeof(*ds_head));
1633 if (!ds_head) {
1634 ast_channel_unlock(chan);
1635 ast_datastore_free(datastore);
1636 return -1;
1637 }
1638 datastore->data = ds_head;
1639 ast_channel_datastore_add(chan, datastore);
1640 } else {
1641 ds_head = datastore->data;
1642 ast_assert(ds_head != NULL);
1643 }
1644
1645 AST_LIST_INSERT_TAIL(ds_head, cond, node);
1646
1647 ast_channel_unlock(chan);
1648 return 0;
1649}
#define ast_calloc(num, len)
A wrapper for calloc()
Definition: astmm.h:202
static const struct ast_datastore_info bridge_channel_impart_ds_info
Definition: bridge.c:1601
int ast_channel_datastore_add(struct ast_channel *chan, struct ast_datastore *datastore)
Add a datastore to a channel.
Definition: channel.c:2414
struct ast_datastore * ast_channel_datastore_find(struct ast_channel *chan, const struct ast_datastore_info *info, const char *uid)
Find a datastore on a channel.
Definition: channel.c:2428
#define ast_datastore_alloc(info, uid)
Definition: datastore.h:85
int ast_datastore_free(struct ast_datastore *datastore)
Free a data store object.
Definition: datastore.c:68
#define AST_LIST_INSERT_TAIL(head, elm, field)
Appends a list entry to the tail of a list.
Definition: linkedlists.h:731
Structure for a data store object.
Definition: datastore.h:64
void * data
Definition: datastore.h:66
Definition: test_heap.c:38

References ast_assert, ast_calloc, ast_channel_datastore_add(), ast_channel_datastore_find(), ast_channel_lock, ast_channel_unlock, ast_datastore_alloc, ast_datastore_free(), AST_LIST_INSERT_TAIL, bridge_channel_impart_ds_info, cond, ast_datastore::data, and NULL.

Referenced by bridge_impart_internal().

◆ bridge_channel_impart_ds_head_dtor()

static void bridge_channel_impart_ds_head_dtor ( void *  doomed)
static

Definition at line 1577 of file bridge.c.

1578{
1580 ast_free(doomed);
1581}
static void bridge_channel_impart_ds_head_signal(struct bridge_channel_impart_ds_head *ds_head)
Definition: bridge.c:1563

References ast_free, and bridge_channel_impart_ds_head_signal().

◆ bridge_channel_impart_ds_head_fixup()

static void bridge_channel_impart_ds_head_fixup ( void *  data,
struct ast_channel old_chan,
struct ast_channel new_chan 
)
static

Definition at line 1592 of file bridge.c.

1593{
1594 /*
1595 * Signal any waiting impart threads. The masquerade is going to kill
1596 * old_chan and we don't need to be waiting on new_chan.
1597 */
1599}

References bridge_channel_impart_ds_head_signal().

◆ bridge_channel_impart_ds_head_signal()

static void bridge_channel_impart_ds_head_signal ( struct bridge_channel_impart_ds_head ds_head)
static

Definition at line 1563 of file bridge.c.

1564{
1565 if (ds_head) {
1567
1568 while ((cond = AST_LIST_REMOVE_HEAD(ds_head, node))) {
1569 ast_mutex_lock(&cond->lock);
1570 cond->done = 1;
1571 ast_cond_signal(&cond->cond);
1572 ast_mutex_unlock(&cond->lock);
1573 }
1574 }
1575}
#define AST_LIST_REMOVE_HEAD(head, field)
Removes and returns the head entry from a list.
Definition: linkedlists.h:833
#define ast_mutex_unlock(a)
Definition: lock.h:194
#define ast_mutex_lock(a)
Definition: lock.h:193
#define ast_cond_signal(cond)
Definition: lock.h:207

References ast_cond_signal, AST_LIST_REMOVE_HEAD, ast_mutex_lock, ast_mutex_unlock, and cond.

Referenced by bridge_channel_impart_ds_head_dtor(), bridge_channel_impart_ds_head_fixup(), and bridge_channel_impart_signal().

◆ bridge_channel_impart_signal()

void bridge_channel_impart_signal ( struct ast_channel chan)

◆ bridge_channel_impart_wait()

static void bridge_channel_impart_wait ( struct bridge_channel_impart_cond cond)
static

Definition at line 1670 of file bridge.c.

1671{
1672 ast_mutex_lock(&cond->lock);
1673 while (!cond->done) {
1674 ast_cond_wait(&cond->cond, &cond->lock);
1675 }
1676 ast_mutex_unlock(&cond->lock);
1677}
#define ast_cond_wait(cond, mutex)
Definition: lock.h:209

References ast_cond_wait, ast_mutex_lock, ast_mutex_unlock, and cond.

Referenced by bridge_impart_internal().

◆ bridge_channel_ind_thread()

static void * bridge_channel_ind_thread ( void *  data)
static

Thread responsible for independent imparted bridged channels.

Definition at line 1811 of file bridge.c.

1812{
1813 struct ast_bridge_channel *bridge_channel = data;
1814 struct ast_channel *chan;
1815
1816 if (bridge_channel->callid) {
1818 }
1819
1821 chan = bridge_channel->chan;
1822
1823 /* cleanup */
1824 ast_channel_lock(chan);
1826 ast_channel_unlock(chan);
1827 /* Lock here for ast_bridge_channel_get_chan */
1831 /* If bridge_channel->swap is not NULL then the join failed. */
1832 ao2_t_cleanup(bridge_channel->swap, "Bridge complete: Independent impart join failed");
1836
1838
1840 /* If join failed there will be impart threads waiting. */
1843 return NULL;
1844}
void ast_bridge_run_after_goto(struct ast_channel *chan)
Run a PBX on any after bridge goto location.
Definition: bridge_after.c:525
struct ast_bridge_channel * bridge_channel

References ao2_lock, ao2_ref, ao2_t_cleanup, ao2_unlock, ast_bridge_features_destroy(), ast_bridge_run_after_callback(), ast_bridge_run_after_goto(), ast_callid_threadassoc_add(), ast_channel_internal_bridge_channel_set(), ast_channel_lock, ast_channel_unlock, ast_channel::bridge_channel, bridge_channel_impart_signal(), bridge_channel_internal_join(), ast_bridge_channel::callid, ast_bridge_channel::chan, ast_bridge_channel::features, NULL, and ast_bridge_channel::swap.

Referenced by bridge_impart_internal().

◆ bridge_channel_moving()

static void bridge_channel_moving ( struct ast_bridge_channel bridge_channel,
struct ast_bridge src,
struct ast_bridge dst 
)
static

Definition at line 2091 of file bridge.c.

2092{
2093 struct ast_bridge_features *features = bridge_channel->features;
2094 struct ast_bridge_hook *hook;
2095 struct ao2_iterator iter;
2096
2097 /* Run any moving hooks. */
2098 iter = ao2_iterator_init(features->other_hooks, 0);
2099 for (; (hook = ao2_iterator_next(&iter)); ao2_ref(hook, -1)) {
2100 int remove_me;
2102
2103 if (hook->type != AST_BRIDGE_HOOK_TYPE_MOVE) {
2104 continue;
2105 }
2107 remove_me = move_cb(bridge_channel, hook->hook_pvt, src, dst);
2108 if (remove_me) {
2109 ast_debug(1, "Move detection hook %p is being removed from %p(%s)\n",
2110 hook, bridge_channel, ast_channel_name(bridge_channel->chan));
2111 ao2_unlink(features->other_hooks, hook);
2112 }
2113 }
2114 ao2_iterator_destroy(&iter);
2115}
#define ao2_iterator_next(iter)
Definition: astobj2.h:1911
struct ao2_iterator ao2_iterator_init(struct ao2_container *c, int flags) attribute_warn_unused_result
Create an iterator for a container.
void ao2_iterator_destroy(struct ao2_iterator *iter)
Destroy a container iterator.
int(* ast_bridge_move_indicate_callback)(struct ast_bridge_channel *bridge_channel, void *hook_pvt, struct ast_bridge *src, struct ast_bridge *dst)
Move indicator callback.
When we need to walk through a container, we use an ao2_iterator to keep track of the current positio...
Definition: astobj2.h:1821
Structure that is the essence of a feature hook.
ast_bridge_hook_callback callback

References ao2_iterator_destroy(), ao2_iterator_init(), ao2_iterator_next, ao2_ref, ao2_unlink, AST_BRIDGE_HOOK_TYPE_MOVE, ast_channel_name(), ast_debug, ast_bridge_hook::callback, ast_bridge_channel::chan, ast_bridge_channel::features, ast_bridge_hook::hook_pvt, ast_bridge_features::other_hooks, and ast_bridge_hook::type.

Referenced by bridge_do_merge(), and bridge_do_move().

◆ bridge_cleanup()

static void bridge_cleanup ( void  )
static

Definition at line 5599 of file bridge.c.

5600{
5601 ast_manager_unregister("BridgeTechnologyList");
5602 ast_manager_unregister("BridgeTechnologySuspend");
5603 ast_manager_unregister("BridgeTechnologyUnsuspend");
5605 ao2_container_unregister("bridges");
5606
5608 bridges = NULL;
5611}
void ao2_container_unregister(const char *name)
Unregister a container for CLI stats and integrity check.
int ast_cli_unregister_multiple(struct ast_cli_entry *e, int len)
Unregister multiple commands.
Definition: clicompat.c:30
int ast_manager_unregister(const char *action)
Unregister a registered manager command.
Definition: manager.c:7697

References ao2_cleanup, ao2_container_unregister(), ARRAY_LEN, ast_cli_unregister_multiple(), ast_manager_unregister(), bridge_cli, bridge_manager, bridges, and NULL.

Referenced by ast_bridging_init().

◆ bridge_complete_join()

static void bridge_complete_join ( struct ast_bridge bridge)
static

Definition at line 493 of file bridge.c.

494{
495 struct ast_bridge_channel *bridge_channel;
496
497 if (bridge->dissolved) {
498 /*
499 * No sense in completing the join on channels for a dissolved
500 * bridge. They are just going to be removed soon anyway.
501 * However, we do have reason to abort here because the bridge
502 * technology may not be able to handle the number of channels
503 * still in the bridge.
504 */
505 return;
506 }
507
508 AST_LIST_TRAVERSE(&bridge->channels, bridge_channel, entry) {
510 if (!bridge_channel->just_joined) {
511 continue;
512 }
513 bridge_channel_complete_join(bridge, bridge_channel);
514 }
515}
static void bridge_channel_complete_join(struct ast_bridge *bridge, struct ast_bridge_channel *bridge_channel)
Definition: bridge.c:452
void bridge_channel_queue_deferred_frames(struct ast_bridge_channel *bridge_channel)

References AST_LIST_TRAVERSE, ast_bridge_channel::bridge, bridge_channel_complete_join(), bridge_channel_queue_deferred_frames(), ast_bridge::channels, ast_bridge::dissolved, ast_bridge_channel::entry, and ast_bridge_channel::just_joined.

Referenced by bridge_reconfigured().

◆ bridge_dissolve()

void bridge_dissolve ( struct ast_bridge bridge,
int  cause 
)

Definition at line 326 of file bridge.c.

327{
328 struct ast_bridge_channel *bridge_channel;
329 struct ast_frame action = {
332 };
333
334 if (bridge->dissolved) {
335 ast_debug(1, "Bridge " BRIDGE_PRINTF_SPEC ": already dissolved\n",
336 BRIDGE_PRINTF_VARS(bridge));
337 return;
338 }
339 bridge->dissolved = 1;
340
341 if (cause <= 0) {
343 }
344 bridge->cause = cause;
345
346 ast_debug(1, "Bridge " BRIDGE_PRINTF_SPEC ": dissolving with cause %d(%s)\n",
347 BRIDGE_PRINTF_VARS(bridge), cause, ast_cause2str(cause));
348
349 AST_LIST_TRAVERSE(&bridge->channels, bridge_channel, entry) {
350 ast_debug(1, "Bridge " BRIDGE_PRINTF_SPEC ": kicking channel %s\n",
351 BRIDGE_PRINTF_VARS(bridge),
352 ast_channel_name(bridge_channel->chan));
353 ast_bridge_channel_leave_bridge(bridge_channel,
355 }
356
357 /* Must defer dissolving bridge because it is already locked. */
358 ast_bridge_queue_action(bridge, &action);
359 ast_debug(1, "Bridge " BRIDGE_PRINTF_SPEC ": DEFERRED_DISSOLVING queued. current refcound: %d\n",
360 BRIDGE_PRINTF_VARS(bridge), ao2_ref(bridge, 0));
361
362}
int ast_bridge_queue_action(struct ast_bridge *bridge, struct ast_frame *action)
Put an action onto the specified bridge.
Definition: bridge.c:314
const char * ast_cause2str(int cause) attribute_pure
Gives the string form of a given cause code.
Definition: channel.c:612
@ AST_FRAME_BRIDGE_ACTION
int cause
Definition: bridge.h:390
enum ast_frame_type frametype

References ao2_ref, ast_bridge_channel_leave_bridge(), ast_bridge_queue_action(), ast_cause2str(), AST_CAUSE_NORMAL_CLEARING, ast_channel_name(), ast_debug, AST_FRAME_BRIDGE_ACTION, AST_LIST_TRAVERSE, BRIDGE_CHANNEL_ACTION_DEFERRED_DISSOLVING, BRIDGE_CHANNEL_STATE_END_NO_DISSOLVE, BRIDGE_PRINTF_SPEC, BRIDGE_PRINTF_VARS, ast_bridge::cause, ast_bridge_channel::chan, ast_bridge::channels, ast_bridge::dissolved, and ast_frame::frametype.

Referenced by ast_bridge_destroy(), bridge_channel_dissolve_check(), bridge_dissolve_check_stolen(), and bridge_reconfigured().

◆ bridge_dissolve_check_stolen()

static void bridge_dissolve_check_stolen ( struct ast_bridge bridge,
struct ast_bridge_channel bridge_channel 
)
static

Definition at line 374 of file bridge.c.

375{
376 if (bridge->dissolved) {
377 return;
378 }
379
380 if (bridge_channel->features->usable
381 && ast_test_flag(&bridge_channel->features->feature_flags,
383 /* The stolen channel controlled the bridge it was stolen from. */
384 bridge_dissolve(bridge, 0);
385 return;
386 }
387 if (bridge->num_channels < 2
389 /*
390 * The stolen channel has not left enough channels to keep the
391 * bridge alive. Assume the stolen channel hung up.
392 */
393 bridge_dissolve(bridge, 0);
394 return;
395 }
396}

References AST_BRIDGE_CHANNEL_FLAG_DISSOLVE_HANGUP, AST_BRIDGE_FLAG_DISSOLVE_HANGUP, ast_test_flag, bridge_dissolve(), ast_bridge::dissolved, ast_bridge::feature_flags, ast_bridge_features::feature_flags, ast_bridge_channel::features, ast_bridge::num_channels, and ast_bridge_features::usable.

Referenced by ast_bridge_add_channel().

◆ bridge_do_merge()

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 
)

Definition at line 2117 of file bridge.c.

2119{
2120 struct ast_bridge_channel *bridge_channel;
2121 unsigned int idx;
2122
2123 ast_debug(1, "Merging bridge %s into bridge %s\n",
2124 src_bridge->uniqueid, dst_bridge->uniqueid);
2125
2126 ast_bridge_publish_merge(dst_bridge, src_bridge);
2127
2128 /*
2129 * Move channels from src_bridge over to dst_bridge.
2130 *
2131 * We must use AST_LIST_TRAVERSE_SAFE_BEGIN() because
2132 * bridge_channel_internal_pull() alters the list we are traversing.
2133 */
2134 AST_LIST_TRAVERSE_SAFE_BEGIN(&src_bridge->channels, bridge_channel, entry) {
2135 if (bridge_channel->state != BRIDGE_CHANNEL_STATE_WAIT) {
2136 /*
2137 * The channel is already leaving let it leave normally because
2138 * pulling it may delete hooks that should run for this channel.
2139 */
2140 continue;
2141 }
2142 if (ast_test_flag(&bridge_channel->features->feature_flags,
2144 continue;
2145 }
2146
2147 if (kick_me) {
2148 for (idx = 0; idx < num_kick; ++idx) {
2149 if (bridge_channel == kick_me[idx]) {
2150 ast_bridge_channel_leave_bridge(bridge_channel,
2152 break;
2153 }
2154 }
2155 }
2156 bridge_channel_internal_pull(bridge_channel);
2157 if (bridge_channel->state != BRIDGE_CHANNEL_STATE_WAIT) {
2158 /*
2159 * The channel died as a result of being pulled or it was
2160 * kicked. Leave it pointing to the original bridge.
2161 */
2162 continue;
2163 }
2164
2165 bridge_channel_moving(bridge_channel, bridge_channel->bridge, dst_bridge);
2166
2167 /* Point to new bridge.*/
2168 bridge_channel_change_bridge(bridge_channel, dst_bridge);
2169
2170 if (bridge_channel_internal_push(bridge_channel)) {
2171 ast_bridge_features_remove(bridge_channel->features,
2173 ast_bridge_channel_leave_bridge(bridge_channel,
2175 }
2176 }
2178
2179 if (kick_me) {
2180 /*
2181 * Now we can kick any channels in the dst_bridge without
2182 * potentially dissolving the bridge.
2183 */
2184 for (idx = 0; idx < num_kick; ++idx) {
2185 bridge_channel = kick_me[idx];
2186 ast_bridge_channel_lock(bridge_channel);
2187 if (bridge_channel->state == BRIDGE_CHANNEL_STATE_WAIT) {
2190 bridge_channel_internal_pull(bridge_channel);
2191 }
2192 ast_bridge_channel_unlock(bridge_channel);
2193 }
2194 }
2195
2196 bridge_reconfigured(dst_bridge, !optimized);
2197 bridge_reconfigured(src_bridge, !optimized);
2198
2199 ast_debug(1, "Merged bridge %s into bridge %s\n",
2200 src_bridge->uniqueid, dst_bridge->uniqueid);
2201}
static void bridge_channel_change_bridge(struct ast_bridge_channel *bridge_channel, struct ast_bridge *new_bridge)
Definition: bridge.c:2076
static void bridge_channel_moving(struct ast_bridge_channel *bridge_channel, struct ast_bridge *src, struct ast_bridge *dst)
Definition: bridge.c:2091
void ast_bridge_channel_leave_bridge_nolock(struct ast_bridge_channel *bridge_channel, enum bridge_channel_state new_state, int cause)
Set bridge channel state to leave bridge (if not leaving already).
@ BRIDGE_CHANNEL_STATE_WAIT
int bridge_channel_internal_push(struct ast_bridge_channel *bridge_channel)
void bridge_channel_internal_pull(struct ast_bridge_channel *bridge_channel)
@ AST_BRIDGE_CHANNEL_FLAG_IMMOVABLE
#define AST_LIST_TRAVERSE_SAFE_END
Closes a safe loop traversal block.
Definition: linkedlists.h:615
#define AST_LIST_TRAVERSE_SAFE_BEGIN(head, var, field)
Loops safely over (traverses) the entries in a list.
Definition: linkedlists.h:529
void ast_bridge_publish_merge(struct ast_bridge *to, struct ast_bridge *from)
Publish a bridge merge.
enum bridge_channel_state state

References AST_BRIDGE_CHANNEL_FLAG_IMMOVABLE, ast_bridge_channel_leave_bridge(), ast_bridge_channel_leave_bridge_nolock(), ast_bridge_channel_lock, ast_bridge_channel_unlock, ast_bridge_features_remove(), AST_BRIDGE_HOOK_REMOVE_ON_PULL, ast_bridge_publish_merge(), AST_CAUSE_NORMAL_CLEARING, ast_debug, AST_LIST_TRAVERSE_SAFE_BEGIN, AST_LIST_TRAVERSE_SAFE_END, ast_test_flag, ast_bridge_channel::bridge, bridge_channel_change_bridge(), bridge_channel_internal_pull(), bridge_channel_internal_push(), bridge_channel_moving(), BRIDGE_CHANNEL_STATE_END_NO_DISSOLVE, BRIDGE_CHANNEL_STATE_WAIT, bridge_reconfigured(), ast_bridge::cause, ast_bridge::channels, ast_bridge_channel::entry, ast_bridge_features::feature_flags, ast_bridge_channel::features, ast_bridge_channel::state, and ast_bridge::uniqueid.

Referenced by bridge_merge(), bridge_merge_locked(), try_merge_optimize_out(), and two_bridge_attended_transfer().

◆ bridge_do_move()

int bridge_do_move ( struct ast_bridge dst_bridge,
struct ast_bridge_channel bridge_channel,
int  attempt_recovery,
unsigned int  optimized 
)

Definition at line 2383 of file bridge.c.

2385{
2386 struct ast_bridge *orig_bridge;
2387 int was_in_bridge;
2388 int res = 0;
2389
2390 if (bridge_channel->swap) {
2391 ast_debug(1, "Moving %p(%s) into bridge %s swapping with %s\n",
2392 bridge_channel, ast_channel_name(bridge_channel->chan), dst_bridge->uniqueid,
2393 ast_channel_name(bridge_channel->swap));
2394 } else {
2395 ast_debug(1, "Moving %p(%s) into bridge %s\n",
2396 bridge_channel, ast_channel_name(bridge_channel->chan), dst_bridge->uniqueid);
2397 }
2398
2399 orig_bridge = bridge_channel->bridge;
2400 was_in_bridge = bridge_channel->in_bridge;
2401
2402 bridge_channel_internal_pull(bridge_channel);
2403 if (bridge_channel->state != BRIDGE_CHANNEL_STATE_WAIT) {
2404 /*
2405 * The channel died as a result of being pulled. Leave it
2406 * pointing to the original bridge.
2407 *
2408 * Clear out the swap channel pointer. A ref is not held
2409 * by bridge_channel->swap at this point.
2410 */
2411 bridge_channel->swap = NULL;
2412 bridge_reconfigured(orig_bridge, 0);
2413 return -1;
2414 }
2415
2416 /* Point to new bridge.*/
2417 ao2_ref(orig_bridge, +1);/* Keep a ref in case the push fails. */
2418 bridge_channel_change_bridge(bridge_channel, dst_bridge);
2419
2420 bridge_channel_moving(bridge_channel, orig_bridge, dst_bridge);
2421
2422 if (bridge_channel_internal_push_full(bridge_channel, optimized)) {
2423 /* Try to put the channel back into the original bridge. */
2424 ast_bridge_features_remove(bridge_channel->features,
2426 if (attempt_recovery && was_in_bridge) {
2427 /* Point back to original bridge. */
2428 bridge_channel_change_bridge(bridge_channel, orig_bridge);
2429
2430 if (bridge_channel_internal_push(bridge_channel)) {
2431 ast_bridge_features_remove(bridge_channel->features,
2433 ast_bridge_channel_leave_bridge(bridge_channel,
2435 }
2436 } else {
2437 ast_bridge_channel_leave_bridge(bridge_channel,
2439 bridge_channel_settle_owed_events(orig_bridge, bridge_channel);
2440 }
2441 res = -1;
2442 } else if (!optimized) {
2443 bridge_channel_settle_owed_events(orig_bridge, bridge_channel);
2444 }
2445
2446 bridge_reconfigured(dst_bridge, !optimized);
2447 bridge_reconfigured(orig_bridge, !optimized);
2448 ao2_ref(orig_bridge, -1);
2449 return res;
2450}
void bridge_channel_settle_owed_events(struct ast_bridge *orig_bridge, struct ast_bridge_channel *bridge_channel)
int bridge_channel_internal_push_full(struct ast_bridge_channel *bridge_channel, int optimized)

References ao2_ref, ast_bridge_channel_leave_bridge(), ast_bridge_features_remove(), AST_BRIDGE_HOOK_REMOVE_ON_PULL, ast_channel_name(), ast_debug, ast_bridge_channel::bridge, bridge_channel_change_bridge(), bridge_channel_internal_pull(), bridge_channel_internal_push(), bridge_channel_internal_push_full(), bridge_channel_moving(), bridge_channel_settle_owed_events(), BRIDGE_CHANNEL_STATE_END_NO_DISSOLVE, BRIDGE_CHANNEL_STATE_WAIT, bridge_reconfigured(), ast_bridge::cause, ast_bridge_channel::chan, ast_bridge_channel::features, ast_bridge_channel::in_bridge, NULL, ast_bridge_channel::state, ast_bridge_channel::swap, and ast_bridge::uniqueid.

Referenced by bridge_move(), bridge_move_locked(), bridge_swap_attended_transfer(), and try_swap_optimize_out().

◆ bridge_dtmf_hook_sort()

static int bridge_dtmf_hook_sort ( const void *  obj_left,
const void *  obj_right,
int  flags 
)
static

Definition at line 3608 of file bridge.c.

3609{
3610 const struct ast_bridge_hook_dtmf *hook_left = obj_left;
3611 const struct ast_bridge_hook_dtmf *hook_right = obj_right;
3612 const char *right_key = obj_right;
3613 int cmp;
3614
3615 switch (flags & (OBJ_POINTER | OBJ_KEY | OBJ_PARTIAL_KEY)) {
3616 default:
3617 case OBJ_POINTER:
3618 right_key = hook_right->dtmf.code;
3619 /* Fall through */
3620 case OBJ_KEY:
3621 cmp = strcasecmp(hook_left->dtmf.code, right_key);
3622 break;
3623 case OBJ_PARTIAL_KEY:
3624 cmp = strncasecmp(hook_left->dtmf.code, right_key, strlen(right_key));
3625 break;
3626 }
3627 return cmp;
3628}
#define OBJ_KEY
Definition: astobj2.h:1151
#define OBJ_POINTER
Definition: astobj2.h:1150
#define OBJ_PARTIAL_KEY
Definition: astobj2.h:1152

References ast_bridge_hook_dtmf_parms::code, ast_bridge_hook_dtmf::dtmf, OBJ_KEY, OBJ_PARTIAL_KEY, and OBJ_POINTER.

Referenced by ast_bridge_features_init().

◆ bridge_find_channel()

struct ast_bridge_channel * bridge_find_channel ( struct ast_bridge bridge,
struct ast_channel chan 
)

◆ bridge_handle_actions()

static void bridge_handle_actions ( struct ast_bridge bridge)
static

Definition at line 641 of file bridge.c.

642{
643 struct ast_frame *action;
644
645 while ((action = AST_LIST_REMOVE_HEAD(&bridge->action_queue, frame_list))) {
646 switch (action->frametype) {
648 bridge_action_bridge(bridge, action);
649 break;
650 default:
651 /* Unexpected deferred frame type. Should never happen. */
652 ast_assert(0);
653 break;
654 }
655 ast_frfree(action);
656 }
657}
static void bridge_action_bridge(struct ast_bridge *bridge, struct ast_frame *action)
Definition: bridge.c:607
#define ast_frfree(fr)
struct ast_bridge::@192 action_queue

References ast_bridge::action_queue, ast_assert, AST_FRAME_BRIDGE_ACTION, ast_frfree, AST_LIST_REMOVE_HEAD, bridge_action_bridge(), and ast_frame::frametype.

Referenced by bridge_manager_service(), and destroy_bridge().

◆ bridge_hook_destroy()

static void bridge_hook_destroy ( void *  vhook)
static

Definition at line 3208 of file bridge.c.

3209{
3210 struct ast_bridge_hook *hook = vhook;
3211
3212 if (hook->destructor) {
3213 hook->destructor(hook->hook_pvt);
3214 }
3215}

References ast_bridge_hook::destructor, and ast_bridge_hook::hook_pvt.

Referenced by bridge_hook_generic().

◆ bridge_hook_generic()

static struct ast_bridge_hook * bridge_hook_generic ( size_t  size,
ast_bridge_hook_callback  callback,
void *  hook_pvt,
ast_bridge_hook_pvt_destructor  destructor,
enum ast_bridge_hook_remove_flags  remove_flags 
)
static

Definition at line 3231 of file bridge.c.

3236{
3237 struct ast_bridge_hook *hook;
3238
3239 /* Allocate new hook and setup it's basic variables */
3241 if (hook) {
3242 hook->callback = callback;
3243 hook->destructor = destructor;
3244 hook->hook_pvt = hook_pvt;
3246 }
3247
3248 return hook;
3249}
#define ao2_alloc_options(data_size, destructor_fn, options)
Definition: astobj2.h:404
static void bridge_hook_destroy(void *vhook)
Definition: bridge.c:3208
struct ast_flags remove_flags

References AO2_ALLOC_OPT_LOCK_NOLOCK, ao2_alloc_options, ast_set_flag, bridge_hook_destroy(), ast_bridge_hook::callback, ast_bridge_hook::destructor, ast_bridge_hook::hook_pvt, and ast_bridge_hook::remove_flags.

Referenced by ast_bridge_dtmf_hook(), ast_bridge_interval_hook(), and bridge_other_hook().

◆ bridge_impart_internal()

static int bridge_impart_internal ( struct ast_bridge bridge,
struct ast_channel chan,
struct ast_channel swap,
struct ast_bridge_features features,
enum ast_bridge_impart_flags  flags,
struct bridge_channel_impart_cond cond 
)
static

Definition at line 1846 of file bridge.c.

1852{
1853 int res = 0;
1854 struct ast_bridge_channel *bridge_channel;
1855
1856 /* Imparted channels cannot have a PBX. */
1857 if (ast_channel_pbx(chan)) {
1858 ast_log(AST_LOG_WARNING, "Channel %s has a PBX thread and cannot be imparted into bridge %s\n",
1861 return -1;
1862 }
1863
1864 /* Supply an empty features structure if the caller did not. */
1865 if (!features) {
1867 if (!features) {
1868 return -1;
1869 }
1870 }
1871
1872 /* Try to allocate a structure for the bridge channel */
1873 bridge_channel = bridge_channel_internal_alloc(bridge);
1874 if (!bridge_channel) {
1876 return -1;
1877 }
1878
1881 ast_log(AST_LOG_NOTICE, "Channel %s is a zombie and cannot be imparted into bridge %s\n",
1883 res = -1;
1884 } else {
1886 }
1888 bridge_channel->chan = chan;
1889 bridge_channel->swap = ao2_t_bump(swap, "Setting up bridge impart");
1890 bridge_channel->features = features;
1891 bridge_channel->inhibit_colp = !!(flags & AST_BRIDGE_IMPART_INHIBIT_JOIN_COLP);
1892 bridge_channel->depart_wait =
1894 bridge_channel->callid = ast_read_threadstorage_callid();
1895
1896 /* allow subclass to peek at swap channel before it can hangup */
1897 if (bridge->v_table->push_peek && !res) {
1898 struct ast_bridge_channel *bcswap = NULL;
1899
1901 if (bridge_channel->swap) {
1902 bcswap = bridge_find_channel(bridge, bridge_channel->swap);
1903 }
1904 res = bridge->v_table->push_peek(bridge, bridge_channel, bcswap);
1906 }
1907
1908 /* Actually create the thread that will handle the channel */
1909 if (!res) {
1911 }
1912 if (!res) {
1914 res = ast_pthread_create_detached(&bridge_channel->thread, NULL,
1915 bridge_channel_ind_thread, bridge_channel);
1916 } else {
1917 res = ast_pthread_create(&bridge_channel->thread, NULL,
1918 bridge_channel_depart_thread, bridge_channel);
1919 }
1920
1921 if (!res) {
1923 }
1924 }
1925
1926 if (res) {
1927 /* cleanup */
1931 /* Lock here for ast_bridge_channel_get_chan */
1932 ao2_lock(bridge_channel);
1933 bridge_channel->chan = NULL;
1934 ao2_unlock(bridge_channel);
1935 ao2_t_cleanup(bridge_channel->swap, "Bridge complete: Impart failed");
1936 bridge_channel->swap = NULL;
1937 ast_bridge_features_destroy(bridge_channel->features);
1938 bridge_channel->features = NULL;
1939
1940 ao2_ref(bridge_channel, -1);
1941 return -1;
1942 }
1943
1944 return 0;
1945}
#define ao2_t_bump(obj, tag)
Definition: astobj2.h:483
static void bridge_channel_impart_wait(struct bridge_channel_impart_cond *cond)
Definition: bridge.c:1670
struct ast_bridge_features * ast_bridge_features_new(void)
Allocate a new bridge features struct.
Definition: bridge.c:3752
static void * bridge_channel_depart_thread(void *data)
Thread responsible for imparted bridged channels to be departed.
Definition: bridge.c:1780
static int bridge_channel_impart_add(struct ast_channel *chan, struct bridge_channel_impart_cond *cond)
Definition: bridge.c:1618
static void * bridge_channel_ind_thread(void *data)
Thread responsible for independent imparted bridged channels.
Definition: bridge.c:1811
@ AST_BRIDGE_IMPART_CHAN_DEPARTABLE
Definition: bridge.h:592
@ AST_BRIDGE_IMPART_CHAN_MASK
Definition: bridge.h:590
@ AST_BRIDGE_IMPART_INHIBIT_JOIN_COLP
Definition: bridge.h:596
#define AST_LOG_WARNING
ast_callid ast_read_threadstorage_callid(void)
extracts the callerid from the thread
Definition: logger.c:2273
#define AST_LOG_NOTICE
#define ast_pthread_create(a, b, c, d)
Definition: utils.h:584
#define ast_pthread_create_detached(a, b, c, d)
Definition: utils.h:588

References ao2_lock, ao2_ref, ao2_t_bump, ao2_t_cleanup, ao2_unlock, ast_bridge_features_destroy(), ast_bridge_features_new(), AST_BRIDGE_IMPART_CHAN_DEPARTABLE, AST_BRIDGE_IMPART_CHAN_INDEPENDENT, AST_BRIDGE_IMPART_CHAN_MASK, AST_BRIDGE_IMPART_INHIBIT_JOIN_COLP, ast_bridge_lock, ast_bridge_unlock, ast_channel_flags(), ast_channel_internal_bridge_channel_set(), ast_channel_lock, ast_channel_name(), ast_channel_pbx(), ast_channel_unlock, AST_FLAG_ZOMBIE, ast_log, AST_LOG_NOTICE, AST_LOG_WARNING, ast_pthread_create, ast_pthread_create_detached, ast_read_threadstorage_callid(), ast_test_flag, ast_bridge_channel::bridge, bridge_channel_depart_thread(), bridge_channel_impart_add(), bridge_channel_impart_wait(), bridge_channel_ind_thread(), bridge_channel_internal_alloc(), bridge_find_channel(), ast_bridge_channel::callid, ast_bridge_channel::chan, cond, ast_bridge_channel::depart_wait, ast_bridge_channel::features, ast_bridge_channel::inhibit_colp, NULL, ast_bridge_methods::push_peek, ast_bridge_channel::swap, ast_bridge_channel::thread, ast_bridge::uniqueid, and ast_bridge::v_table.

Referenced by ast_bridge_impart().

◆ bridge_manager_create()

static struct bridge_manager_controller * bridge_manager_create ( void  )
static

Definition at line 5020 of file bridge.c.

5021{
5022 struct bridge_manager_controller *manager;
5023
5024 manager = ao2_alloc(sizeof(*manager), bridge_manager_destroy);
5025 if (!manager) {
5026 /* Well. This isn't good. */
5027 return NULL;
5028 }
5029 ast_cond_init(&manager->cond, NULL);
5031
5032 /* Create the bridge manager thread. */
5033 if (ast_pthread_create(&manager->thread, NULL, bridge_manager_thread, manager)) {
5034 /* Well. This isn't good either. */
5035 manager->thread = AST_PTHREADT_NULL;
5036 ao2_ref(manager, -1);
5037 manager = NULL;
5038 }
5039
5040 return manager;
5041}
static void bridge_manager_destroy(void *obj)
Definition: bridge.c:4988
static void * bridge_manager_thread(void *data)
Definition: bridge.c:4955
#define AST_LIST_HEAD_INIT_NOLOCK(head)
Initializes a list head structure.
Definition: linkedlists.h:681
#define AST_PTHREADT_NULL
Definition: lock.h:70
struct bridge_manager_controller::@310 service_requests

References ao2_alloc, ao2_ref, ast_cond_init, AST_LIST_HEAD_INIT_NOLOCK, ast_pthread_create, AST_PTHREADT_NULL, bridge_manager_destroy(), bridge_manager_thread(), bridge_manager_controller::cond, NULL, bridge_manager_controller::service_requests, and bridge_manager_controller::thread.

Referenced by ast_bridging_init().

◆ bridge_manager_destroy()

static void bridge_manager_destroy ( void *  obj)
static

Definition at line 4988 of file bridge.c.

4989{
4990 struct bridge_manager_controller *manager = obj;
4992
4993 if (manager->thread != AST_PTHREADT_NULL) {
4994 /* Stop the manager thread. */
4995 ao2_lock(manager);
4996 manager->stop = 1;
4997 ast_cond_signal(&manager->cond);
4998 ao2_unlock(manager);
4999 ast_debug(1, "Waiting for bridge manager thread to die.\n");
5000 pthread_join(manager->thread, NULL);
5001 }
5002
5003 /* Destroy the service request queue. */
5004 while ((request = AST_LIST_REMOVE_HEAD(&manager->service_requests, node))) {
5005 ao2_ref(request->bridge, -1);
5007 }
5008
5009 ast_cond_destroy(&manager->cond);
5010}
unsigned int stop
Definition: bridge.c:179

References ao2_lock, ao2_ref, ao2_unlock, ast_cond_destroy, ast_cond_signal, ast_debug, ast_free, AST_LIST_REMOVE_HEAD, AST_PTHREADT_NULL, bridge_manager_controller::cond, NULL, request(), bridge_manager_controller::service_requests, bridge_manager_controller::stop, and bridge_manager_controller::thread.

Referenced by bridge_manager_create().

◆ bridge_manager_service()

static void bridge_manager_service ( struct ast_bridge bridge)
static

Definition at line 4938 of file bridge.c.

4939{
4940 ast_bridge_lock(bridge);
4941 if (bridge->callid) {
4943 }
4944
4945 /* Do any pending bridge actions. */
4946 bridge_handle_actions(bridge);
4947 ast_bridge_unlock(bridge);
4948}
static void bridge_handle_actions(struct ast_bridge *bridge)
Definition: bridge.c:641
int ast_callid_threadassoc_change(ast_callid callid)
Sets what is stored in the thread storage to the given callid if it does not match what is already th...
Definition: logger.c:2282
ast_callid callid
Definition: bridge.h:365

References ast_bridge_lock, ast_bridge_unlock, ast_callid_threadassoc_change(), ast_channel::bridge, bridge_handle_actions(), and ast_bridge::callid.

Referenced by bridge_manager_thread().

◆ bridge_manager_service_req()

static void bridge_manager_service_req ( struct ast_bridge bridge)
static

Definition at line 197 of file bridge.c.

198{
200
202 if (bridge_manager->stop) {
204 return;
205 }
206
207 /* Create the service request. */
208 request = ast_calloc(1, sizeof(*request));
209 if (!request) {
210 /* Well. This isn't good. */
212 return;
213 }
214 ao2_ref(bridge, +1);
215 request->bridge = bridge;
216
217 /* Put request into the queue and wake the bridge manager. */
221}
struct ast_bridge * bridge
Definition: bridge.c:168

References ao2_lock, ao2_ref, ao2_unlock, ast_calloc, ast_cond_signal, AST_LIST_INSERT_TAIL, bridge_manager_request::bridge, bridge_manager, bridge_manager_controller::cond, request(), bridge_manager_controller::service_requests, and bridge_manager_controller::stop.

Referenced by bridge_queue_action_nodup().

◆ bridge_manager_thread()

static void * bridge_manager_thread ( void *  data)
static

Definition at line 4955 of file bridge.c.

4956{
4957 struct bridge_manager_controller *manager = data;
4959
4960 ao2_lock(manager);
4961 while (!manager->stop) {
4963 if (!request) {
4964 ast_cond_wait(&manager->cond, ao2_object_get_lockaddr(manager));
4965 continue;
4966 }
4967 ao2_unlock(manager);
4968
4969 /* Service the bridge. */
4971 ao2_ref(request->bridge, -1);
4973
4974 ao2_lock(manager);
4975 }
4976 ao2_unlock(manager);
4977
4978 return NULL;
4979}
void * ao2_object_get_lockaddr(void *obj)
Return the mutex lock address of an object.
Definition: astobj2.c:476
static void bridge_manager_service(struct ast_bridge *bridge)
Definition: bridge.c:4938

References ao2_lock, ao2_object_get_lockaddr(), ao2_ref, ao2_unlock, ast_cond_wait, ast_free, AST_LIST_REMOVE_HEAD, bridge_manager_service(), bridge_manager_controller::cond, NULL, request(), bridge_manager_controller::service_requests, and bridge_manager_controller::stop.

Referenced by bridge_manager_create().

◆ bridge_merge_determine_direction()

static struct merge_direction bridge_merge_determine_direction ( struct ast_bridge bridge1,
struct ast_bridge bridge2 
)
static

Definition at line 2222 of file bridge.c.

2223{
2224 struct merge_direction merge = { NULL, NULL };
2225 int bridge1_priority;
2226 int bridge2_priority;
2227
2228 if (!ast_test_flag(&bridge1->feature_flags,
2230 && !ast_test_flag(&bridge2->feature_flags,
2232 /*
2233 * Can merge either way. Merge to the higher priority merge
2234 * bridge. Otherwise merge to the larger bridge.
2235 */
2236 bridge1_priority = bridge1->v_table->get_merge_priority(bridge1);
2237 bridge2_priority = bridge2->v_table->get_merge_priority(bridge2);
2238 if (bridge2_priority < bridge1_priority) {
2239 merge.dest = bridge1;
2240 merge.src = bridge2;
2241 } else if (bridge1_priority < bridge2_priority) {
2242 merge.dest = bridge2;
2243 merge.src = bridge1;
2244 } else {
2245 /* Merge to the larger bridge. */
2246 if (bridge2->num_channels <= bridge1->num_channels) {
2247 merge.dest = bridge1;
2248 merge.src = bridge2;
2249 } else {
2250 merge.dest = bridge2;
2251 merge.src = bridge1;
2252 }
2253 }
2256 /* Can merge only one way. */
2257 merge.dest = bridge1;
2258 merge.src = bridge2;
2261 /* Can merge only one way. */
2262 merge.dest = bridge2;
2263 merge.src = bridge1;
2264 }
2265
2266 return merge;
2267}
@ AST_BRIDGE_FLAG_MERGE_INHIBIT_TO
@ AST_BRIDGE_FLAG_MERGE_INHIBIT_FROM
struct ast_bridge * src
Definition: bridge.c:2207
struct ast_bridge * dest
Definition: bridge.c:2205

References AST_BRIDGE_FLAG_MERGE_INHIBIT_FROM, AST_BRIDGE_FLAG_MERGE_INHIBIT_TO, ast_test_flag, merge_direction::dest, NULL, and merge_direction::src.

Referenced by bridge_merge_locked(), and bridges_allow_merge_optimization().

◆ bridge_merge_inhibit_nolock()

void bridge_merge_inhibit_nolock ( struct ast_bridge bridge,
int  request 
)

Definition at line 3060 of file bridge.c.

3061{
3062 int new_request;
3063
3064 new_request = bridge->inhibit_merge + request;
3065 ast_assert(0 <= new_request);
3066 bridge->inhibit_merge = new_request;
3067}

References ast_assert, ast_bridge::inhibit_merge, and request().

Referenced by ast_bridge_channel_merge_inhibit(), and ast_bridge_merge_inhibit().

◆ bridge_merge_locked()

static int bridge_merge_locked ( struct ast_bridge dst_bridge,
struct ast_bridge src_bridge,
int  merge_best_direction,
struct ast_channel **  kick_me,
unsigned int  num_kick 
)
static

Definition at line 2285 of file bridge.c.

2286{
2287 struct merge_direction merge;
2288 struct ast_bridge_channel **kick_them = NULL;
2289
2290 /* Sanity check. */
2291 ast_assert(dst_bridge && src_bridge && dst_bridge != src_bridge && (!num_kick || kick_me));
2292
2293 if (dst_bridge->dissolved || src_bridge->dissolved) {
2294 ast_debug(1, "Can't merge bridges %s and %s, at least one bridge is dissolved.\n",
2295 src_bridge->uniqueid, dst_bridge->uniqueid);
2296 return -1;
2297 }
2300 ast_debug(1, "Can't merge bridges %s and %s, masquerade only.\n",
2301 src_bridge->uniqueid, dst_bridge->uniqueid);
2302 return -1;
2303 }
2304 if (dst_bridge->inhibit_merge || src_bridge->inhibit_merge) {
2305 ast_debug(1, "Can't merge bridges %s and %s, merging temporarily inhibited.\n",
2306 src_bridge->uniqueid, dst_bridge->uniqueid);
2307 return -1;
2308 }
2309
2310 if (merge_best_direction) {
2311 merge = bridge_merge_determine_direction(dst_bridge, src_bridge);
2312 } else {
2313 merge.dest = dst_bridge;
2314 merge.src = src_bridge;
2315 }
2316
2317 if (!merge.dest
2318 || ast_test_flag(&merge.dest->feature_flags, AST_BRIDGE_FLAG_MERGE_INHIBIT_TO)
2319 || ast_test_flag(&merge.src->feature_flags, AST_BRIDGE_FLAG_MERGE_INHIBIT_FROM)) {
2320 ast_debug(1, "Can't merge bridges %s and %s, merging inhibited.\n",
2321 src_bridge->uniqueid, dst_bridge->uniqueid);
2322 return -1;
2323 }
2324 if (merge.src->num_channels < 2) {
2325 /*
2326 * For a two party bridge, a channel may be temporarily removed
2327 * from the source bridge or the initial bridge members have not
2328 * joined yet.
2329 */
2330 ast_debug(1, "Can't merge bridge %s into bridge %s, not enough channels in source bridge.\n",
2331 merge.src->uniqueid, merge.dest->uniqueid);
2332 return -1;
2333 }
2334 if (2 + num_kick < merge.dest->num_channels + merge.src->num_channels
2335 && !(merge.dest->technology->capabilities & AST_BRIDGE_CAPABILITY_MULTIMIX)
2336 && (!ast_test_flag(&merge.dest->feature_flags, AST_BRIDGE_FLAG_SMART)
2337 || !(merge.dest->allowed_capabilities & AST_BRIDGE_CAPABILITY_MULTIMIX))) {
2338 ast_debug(1, "Can't merge bridge %s into bridge %s, multimix is needed and it cannot be acquired.\n",
2339 merge.src->uniqueid, merge.dest->uniqueid);
2340 return -1;
2341 }
2342
2343 if (num_kick) {
2344 unsigned int num_to_kick = 0;
2345 unsigned int idx;
2346
2347 kick_them = ast_alloca(num_kick * sizeof(*kick_them));
2348 for (idx = 0; idx < num_kick; ++idx) {
2349 kick_them[num_to_kick] = bridge_find_channel(merge.src, kick_me[idx]);
2350 if (!kick_them[num_to_kick]) {
2351 kick_them[num_to_kick] = bridge_find_channel(merge.dest, kick_me[idx]);
2352 }
2353 if (kick_them[num_to_kick]) {
2354 ++num_to_kick;
2355 }
2356 }
2357
2358 if (num_to_kick != num_kick) {
2359 ast_debug(1, "Can't merge bridge %s into bridge %s, at least one kicked channel is not in either bridge.\n",
2360 merge.src->uniqueid, merge.dest->uniqueid);
2361 return -1;
2362 }
2363 }
2364
2365 bridge_do_merge(merge.dest, merge.src, kick_them, num_kick, 0);
2366 return 0;
2367}
#define ast_alloca(size)
call __builtin_alloca to ensure we get gcc builtin semantics
Definition: astmm.h:288
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)
Definition: bridge.c:2117
static struct merge_direction bridge_merge_determine_direction(struct ast_bridge *bridge1, struct ast_bridge *bridge2)
Definition: bridge.c:2222
@ AST_BRIDGE_CAPABILITY_MULTIMIX
Definition: bridge.h:98
@ AST_BRIDGE_FLAG_SMART

References ast_bridge::allowed_capabilities, ast_alloca, ast_assert, AST_BRIDGE_CAPABILITY_MULTIMIX, AST_BRIDGE_FLAG_MASQUERADE_ONLY, AST_BRIDGE_FLAG_MERGE_INHIBIT_FROM, AST_BRIDGE_FLAG_MERGE_INHIBIT_TO, AST_BRIDGE_FLAG_SMART, ast_debug, ast_test_flag, bridge_do_merge(), bridge_find_channel(), bridge_merge_determine_direction(), ast_bridge_technology::capabilities, merge_direction::dest, ast_bridge::dissolved, ast_bridge::feature_flags, ast_bridge::inhibit_merge, NULL, ast_bridge::num_channels, merge_direction::src, ast_bridge::technology, and ast_bridge::uniqueid.

Referenced by ast_bridge_merge().

◆ bridge_move_locked()

static int bridge_move_locked ( struct ast_bridge dst_bridge,
struct ast_bridge src_bridge,
struct ast_channel chan,
struct ast_channel swap,
int  attempt_recovery 
)
static

Definition at line 2468 of file bridge.c.

2469{
2470 struct ast_bridge_channel *bridge_channel;
2471
2472 if (dst_bridge->dissolved || src_bridge->dissolved) {
2473 ast_debug(1, "Can't move channel %s from bridge %s into bridge %s, at least one bridge is dissolved.\n",
2474 ast_channel_name(chan), src_bridge->uniqueid, dst_bridge->uniqueid);
2475 return -1;
2476 }
2479 ast_debug(1, "Can't move channel %s from bridge %s into bridge %s, masquerade only.\n",
2480 ast_channel_name(chan), src_bridge->uniqueid, dst_bridge->uniqueid);
2481 return -1;
2482 }
2483 if (dst_bridge->inhibit_merge || src_bridge->inhibit_merge) {
2484 ast_debug(1, "Can't move channel %s from bridge %s into bridge %s, temporarily inhibited.\n",
2485 ast_channel_name(chan), src_bridge->uniqueid, dst_bridge->uniqueid);
2486 return -1;
2487 }
2488
2489 bridge_channel = bridge_find_channel(src_bridge, chan);
2490 if (!bridge_channel) {
2491 ast_debug(1, "Can't move channel %s from bridge %s into bridge %s, channel not in bridge.\n",
2492 ast_channel_name(chan), src_bridge->uniqueid, dst_bridge->uniqueid);
2493 return -1;
2494 }
2495 if (bridge_channel->state != BRIDGE_CHANNEL_STATE_WAIT) {
2496 ast_debug(1, "Can't move channel %s from bridge %s into bridge %s, channel leaving bridge.\n",
2497 ast_channel_name(chan), src_bridge->uniqueid, dst_bridge->uniqueid);
2498 return -1;
2499 }
2500 if (ast_test_flag(&bridge_channel->features->feature_flags,
2502 ast_debug(1, "Can't move channel %s from bridge %s into bridge %s, channel immovable.\n",
2503 ast_channel_name(chan), src_bridge->uniqueid, dst_bridge->uniqueid);
2504 return -1;
2505 }
2506
2507 if (swap) {
2508 struct ast_bridge_channel *bridge_channel_swap;
2509
2510 bridge_channel_swap = bridge_find_channel(dst_bridge, swap);
2511 if (!bridge_channel_swap) {
2512 ast_debug(1, "Can't move channel %s from bridge %s into bridge %s, swap channel %s not in bridge.\n",
2513 ast_channel_name(chan), src_bridge->uniqueid, dst_bridge->uniqueid,
2515 return -1;
2516 }
2517 if (bridge_channel_swap->state != BRIDGE_CHANNEL_STATE_WAIT) {
2518 ast_debug(1, "Can't move channel %s from bridge %s into bridge %s, swap channel %s leaving bridge.\n",
2519 ast_channel_name(chan), src_bridge->uniqueid, dst_bridge->uniqueid,
2521 return -1;
2522 }
2523 }
2524
2525 bridge_channel->swap = swap;
2526 return bridge_do_move(dst_bridge, bridge_channel, attempt_recovery, 0);
2527}
int bridge_do_move(struct ast_bridge *dst_bridge, struct ast_bridge_channel *bridge_channel, int attempt_recovery, unsigned int optimized)
Definition: bridge.c:2383

References AST_BRIDGE_CHANNEL_FLAG_IMMOVABLE, AST_BRIDGE_FLAG_MASQUERADE_ONLY, ast_channel_name(), ast_debug, ast_test_flag, BRIDGE_CHANNEL_STATE_WAIT, bridge_do_move(), bridge_find_channel(), ast_bridge_channel::chan, ast_bridge::dissolved, ast_bridge::feature_flags, ast_bridge_features::feature_flags, ast_bridge_channel::features, ast_bridge::inhibit_merge, ast_bridge_channel::state, ast_bridge_channel::swap, and ast_bridge::uniqueid.

Referenced by ast_bridge_add_channel(), and ast_bridge_move().

◆ bridge_other_hook()

static int bridge_other_hook ( struct ast_bridge_features features,
ast_bridge_hook_callback  callback,
void *  hook_pvt,
ast_bridge_hook_pvt_destructor  destructor,
enum ast_bridge_hook_remove_flags  remove_flags,
enum ast_bridge_hook_type  type 
)
static

Definition at line 3300 of file bridge.c.

3306{
3307 struct ast_bridge_hook *hook;
3308 int res;
3309
3310 /* Allocate new hook and setup it's various variables */
3311 hook = bridge_hook_generic(sizeof(*hook), callback, hook_pvt, destructor,
3312 remove_flags);
3313 if (!hook) {
3314 return -1;
3315 }
3316 hook->type = type;
3317
3318 /* Once done we put it in the container. */
3319 res = ao2_link(features->other_hooks, hook) ? 0 : -1;
3320 if (res) {
3321 /*
3322 * Could not link the hook into the container.
3323 *
3324 * Remove the hook_pvt destructor call from the hook since we
3325 * are returning failure to install the hook.
3326 */
3327 hook->destructor = NULL;
3328 }
3329 ao2_ref(hook, -1);
3330
3331 return res;
3332}
static const char type[]
Definition: chan_ooh323.c:109

References ao2_link, ao2_ref, bridge_hook_generic(), ast_bridge_hook::callback, ast_bridge_hook::destructor, ast_bridge_hook::hook_pvt, NULL, ast_bridge_features::other_hooks, ast_bridge_hook::remove_flags, type, and ast_bridge_hook::type.

Referenced by ast_bridge_hangup_hook(), ast_bridge_join_hook(), ast_bridge_leave_hook(), ast_bridge_move_hook(), and ast_bridge_talk_detector_hook().

◆ bridge_prnt_obj()

static void bridge_prnt_obj ( void *  v_obj,
void *  where,
ao2_prnt_fn prnt 
)
static

Definition at line 5583 of file bridge.c.

5584{
5585 struct ast_bridge *bridge = v_obj;
5586
5587 if (!bridge) {
5588 return;
5589 }
5590 prnt(where, "%s %s chans:%u",
5591 bridge->uniqueid, bridge->v_table->name, bridge->num_channels);
5592}

References ast_bridge_methods::name, ast_bridge::num_channels, ast_bridge::uniqueid, and ast_bridge::v_table.

Referenced by ast_bridging_init().

◆ bridge_queue_action_nodup()

static void bridge_queue_action_nodup ( struct ast_bridge bridge,
struct ast_frame action 
)
static

Definition at line 303 of file bridge.c.

304{
305 ast_debug(1, "Bridge %s: queueing action type:%u sub:%d\n",
306 bridge->uniqueid, action->frametype, action->subclass.integer);
307
308 ast_bridge_lock(bridge);
310 ast_bridge_unlock(bridge);
312}
static void bridge_manager_service_req(struct ast_bridge *bridge)
Definition: bridge.c:197

References ast_bridge::action_queue, ast_bridge_lock, ast_bridge_unlock, ast_debug, AST_LIST_INSERT_TAIL, bridge_manager_service_req(), ast_frame::frametype, ast_frame_subclass::integer, ast_frame::subclass, and ast_bridge::uniqueid.

Referenced by ast_bridge_queue_action(), and smart_bridge_operation().

◆ bridge_reconfigured()

void bridge_reconfigured ( struct ast_bridge bridge,
unsigned int  colp_update 
)

Definition at line 1472 of file bridge.c.

1473{
1474 if (!bridge->reconfigured) {
1475 return;
1476 }
1477 bridge->reconfigured = 0;
1479 && smart_bridge_operation(bridge)) {
1480 /* Smart bridge failed. */
1481 bridge_dissolve(bridge, 0);
1482 return;
1483 }
1484 bridge_complete_join(bridge);
1485
1486 if (bridge->dissolved) {
1487 return;
1488 }
1490 set_bridge_peer_vars(bridge);
1492
1493 if (colp_update) {
1495 }
1496}
static void check_bridge_play_sounds(struct ast_bridge *bridge)
Definition: bridge.c:1272
static int smart_bridge_operation(struct ast_bridge *bridge)
Definition: bridge.c:1041
static void bridge_reconfigured_connected_line_update(struct ast_bridge *bridge)
Definition: bridge.c:404
static void bridge_complete_join(struct ast_bridge *bridge)
Definition: bridge.c:493
static void set_bridge_peer_vars(struct ast_bridge *bridge)
Definition: bridge.c:1455

References AST_BRIDGE_FLAG_SMART, ast_bridge_publish_state(), ast_test_flag, ast_bridge_channel::bridge, bridge_complete_join(), bridge_dissolve(), bridge_reconfigured_connected_line_update(), check_bridge_play_sounds(), ast_bridge::dissolved, ast_bridge::feature_flags, ast_bridge::reconfigured, set_bridge_peer_vars(), and smart_bridge_operation().

Referenced by ast_bridge_notify_masquerade(), bridge_channel_handle_control(), bridge_channel_internal_join(), bridge_channel_wait(), bridge_do_merge(), and bridge_do_move().

◆ bridge_reconfigured_connected_line_update()

static void bridge_reconfigured_connected_line_update ( struct ast_bridge bridge)
static

Definition at line 404 of file bridge.c.

405{
407 struct ast_bridge_channel *bridge_channel = AST_LIST_FIRST(&bridge->channels), *peer;
408 unsigned char data[1024];
409 size_t datalen;
410
411 if (!bridge_channel ||
413 !(peer = ast_bridge_channel_peer(bridge_channel)) ||
416 ast_check_hangup_locked(bridge_channel->chan) ||
417 ast_check_hangup_locked(peer->chan)) {
418 return;
419 }
420
422
423 ast_channel_lock(bridge_channel->chan);
425 ast_channel_unlock(bridge_channel->chan);
426
427 if ((datalen = ast_connected_line_build_data(data, sizeof(data), &connected, NULL)) != (size_t) -1) {
429 }
430
431 ast_channel_lock(peer->chan);
433 ast_channel_unlock(peer->chan);
434
435 if ((datalen = ast_connected_line_build_data(data, sizeof(data), &connected, NULL)) != (size_t) -1) {
437 }
438
440}
struct ast_bridge_channel * ast_bridge_channel_peer(struct ast_bridge_channel *bridge_channel)
Get the peer bridge channel of a two party bridge.
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)
Queue a control frame onto the bridge channel with data.
void ast_party_connected_line_free(struct ast_party_connected_line *doomed)
Destroy the connected line information contents.
Definition: channel.c:2099
int ast_check_hangup_locked(struct ast_channel *chan)
Definition: channel.c:459
int ast_connected_line_build_data(unsigned char *data, size_t datalen, const struct ast_party_connected_line *connected, const struct ast_set_party_connected_line *update)
Build the connected line information data frame.
Definition: channel.c:8723
void ast_party_connected_line_init(struct ast_party_connected_line *init)
Initialize the given connected line structure.
Definition: channel.c:2049
void ast_connected_line_copy_from_caller(struct ast_party_connected_line *dest, const struct ast_party_caller *src)
Copy the caller information to the connected line information.
Definition: channel.c:8319
struct ast_party_caller * ast_channel_caller(struct ast_channel *chan)
char connected
Definition: eagi_proxy.c:82
@ AST_CONTROL_CONNECTED_LINE
#define AST_LIST_FIRST(head)
Returns the first entry contained in a list.
Definition: linkedlists.h:421
Connected Line/Party information.
Definition: channel.h:458

References AST_BRIDGE_CAPABILITY_1TO1MIX, AST_BRIDGE_CAPABILITY_NATIVE, ast_bridge_channel_peer(), ast_bridge_channel_queue_control_data(), ast_channel_caller(), ast_channel_flags(), ast_channel_lock, ast_channel_unlock, ast_check_hangup_locked(), ast_connected_line_build_data(), ast_connected_line_copy_from_caller(), AST_CONTROL_CONNECTED_LINE, AST_FLAG_ZOMBIE, AST_LIST_FIRST, ast_party_connected_line_free(), ast_party_connected_line_init(), ast_test_flag, ast_bridge_channel::bridge, ast_bridge_technology::capabilities, ast_bridge_channel::chan, ast_bridge::channels, connected, NULL, and ast_bridge::technology.

Referenced by bridge_reconfigured().

◆ bridge_register()

struct ast_bridge * bridge_register ( struct ast_bridge bridge)

Register the new bridge with the system.

Since
12.0.0
Parameters
bridgeWhat to register. (Tolerates a NULL pointer)
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;
}
struct ast_bridge_methods ast_bridge_basic_v_table
Bridge basic class virtual method table.
struct ast_bridge * ast_bridge_basic_new(void)
Create a new basic class bridge.
struct ast_bridge * bridge_register(struct ast_bridge *bridge)
Register the new bridge with the system.
Definition: bridge.c:713
Note
This must be done after a bridge constructor has completed setting up the new bridge but before it returns.
After a bridge is registered, ast_bridge_destroy() must eventually be called to get rid of the bridge.
Returns
bridge on success.
Return values
NULLon error.

Definition at line 713 of file bridge.c.

714{
715 if (bridge) {
717 /*
718 * Although bridge_base_init() should have already checked for
719 * an existing bridge with the same uniqueid, bridge_base_init()
720 * and bridge_register() are two separate public APIs so we need
721 * to check again here.
722 */
723 struct ast_bridge *existing = ast_bridge_find_by_id(bridge->uniqueid);
724 if (existing) {
725 ast_log(LOG_WARNING, "Bridge " BRIDGE_PRINTF_SPEC ": already registered\n",
726 BRIDGE_PRINTF_VARS(bridge));
727 ao2_ref(existing, -1);
728 ast_bridge_destroy(bridge, 0);
729 return NULL;
730 }
731 ast_debug(1, "Bridge " BRIDGE_PRINTF_SPEC ": registering\n",
732 BRIDGE_PRINTF_VARS(bridge));
733 bridge->construction_completed = 1;
734 ast_bridge_lock(bridge);
736 ast_bridge_unlock(bridge);
737 if (!ao2_link(bridges, bridge)) {
738 ast_log(LOG_WARNING, "Bridge " BRIDGE_PRINTF_SPEC ": failed to link\n",
739 BRIDGE_PRINTF_VARS(bridge));
740 ast_bridge_destroy(bridge, 0);
741 bridge = NULL;
742 }
743 }
744 return bridge;
745}
struct ast_bridge * ast_bridge_find_by_id(const char *bridge_id)
Find bridge by id.
Definition: bridge.c:5081
unsigned int construction_completed
Definition: bridge.h:396

References ao2_link, ao2_ref, ast_bridge_destroy(), ast_bridge_find_by_id(), ast_bridge_lock, ast_bridge_publish_state(), ast_bridge_unlock, ast_debug, ast_log, bridge_init_lock, BRIDGE_PRINTF_SPEC, BRIDGE_PRINTF_VARS, bridges, ast_bridge::construction_completed, lock, LOG_WARNING, NULL, SCOPED_MUTEX, and ast_bridge::uniqueid.

Referenced by ast_bridge_base_new(), ast_bridge_basic_new(), bridge_agent_hold_new(), bridge_parking_new(), and bridge_stasis_new().

◆ bridge_show_specific_print_channel()

static int bridge_show_specific_print_channel ( void *  obj,
void *  arg,
int  flags 
)
static

Internal callback function for sending channels in a bridge to the CLI.

Definition at line 5152 of file bridge.c.

5153{
5154 const char *uniqueid = obj;
5155 struct ast_cli_args *a = arg;
5156 struct ast_channel_snapshot *snapshot;
5157
5158 snapshot = ast_channel_snapshot_get_latest(uniqueid);
5159 if (!snapshot) {
5160 return 0;
5161 }
5162
5163 ast_cli(a->fd, "Channel: %s\n", snapshot->base->name);
5164 ao2_ref(snapshot, -1);
5165
5166 return 0;
5167}
void ast_cli(int fd, const char *fmt,...)
Definition: clicompat.c:6
const ast_string_field name
Structure representing a snapshot of channel state.
struct ast_channel_snapshot_base * base
static struct test_val a

References a, ao2_ref, ast_channel_snapshot_get_latest(), ast_cli(), ast_channel_snapshot::base, ast_channel_snapshot_base::name, and ast_bridge_snapshot::uniqueid.

Referenced by handle_bridge_show_specific().

◆ bridge_sort_cmp()

static int bridge_sort_cmp ( const void *  obj_left,
const void *  obj_right,
int  flags 
)
static

Definition at line 5059 of file bridge.c.

5060{
5061 const struct ast_bridge *bridge_left = obj_left;
5062 const struct ast_bridge *bridge_right = obj_right;
5063 const char *right_key = obj_right;
5064 int cmp;
5065
5066 switch (flags & (OBJ_POINTER | OBJ_KEY | OBJ_PARTIAL_KEY)) {
5067 default:
5068 case OBJ_POINTER:
5069 right_key = bridge_right->uniqueid;
5070 /* Fall through */
5071 case OBJ_KEY:
5072 cmp = strcmp(bridge_left->uniqueid, right_key);
5073 break;
5074 case OBJ_PARTIAL_KEY:
5075 cmp = strncmp(bridge_left->uniqueid, right_key, strlen(right_key));
5076 break;
5077 }
5078 return cmp;
5079}

References OBJ_KEY, OBJ_PARTIAL_KEY, OBJ_POINTER, and ast_bridge::uniqueid.

Referenced by ast_bridging_init().

◆ bridge_swap_attended_transfer()

static enum ast_transfer_result bridge_swap_attended_transfer ( struct ast_bridge dest_bridge,
struct ast_bridge_channel source_bridge_channel,
struct ast_channel swap_channel 
)
static

Definition at line 4637 of file bridge.c.

4639{
4640 struct ast_bridge_channel *bridged_to_source;
4641
4642 bridged_to_source = ast_bridge_channel_peer(source_bridge_channel);
4643 if (bridged_to_source
4644 && bridged_to_source->state == BRIDGE_CHANNEL_STATE_WAIT
4645 && !ast_test_flag(&bridged_to_source->features->feature_flags,
4647 bridged_to_source->swap = swap_channel;
4648 if (bridge_do_move(dest_bridge, bridged_to_source, 1, 0)) {
4650 }
4651 /* Must kick the source channel out of its bridge. */
4652 ast_bridge_channel_leave_bridge(source_bridge_channel,
4655 } else {
4657 }
4658}

References AST_BRIDGE_CHANNEL_FLAG_IMMOVABLE, ast_bridge_channel_leave_bridge(), ast_bridge_channel_peer(), AST_BRIDGE_TRANSFER_FAIL, AST_BRIDGE_TRANSFER_INVALID, AST_BRIDGE_TRANSFER_SUCCESS, AST_CAUSE_NORMAL_CLEARING, ast_test_flag, BRIDGE_CHANNEL_STATE_END_NO_DISSOLVE, BRIDGE_CHANNEL_STATE_WAIT, bridge_do_move(), ast_bridge_features::feature_flags, ast_bridge_channel::features, ast_bridge_channel::state, and ast_bridge_channel::swap.

Referenced by two_bridge_attended_transfer().

◆ bridge_tech_deferred_destroy()

static void bridge_tech_deferred_destroy ( struct ast_bridge bridge,
struct ast_frame action 
)
static

Definition at line 579 of file bridge.c.

580{
581 struct tech_deferred_destroy *deferred = action->data.ptr;
582 struct ast_bridge dummy_bridge = {
583 .technology = deferred->tech,
584 .tech_pvt = deferred->tech_pvt,
585 .creator = bridge->creator,
586 .name = bridge->name,
587 .uniqueid = bridge->uniqueid,
588 };
589
590 ast_debug(1, "Bridge %s: calling %s technology destructor (deferred, dummy)\n",
591 dummy_bridge.uniqueid, dummy_bridge.technology->name);
592 dummy_bridge.technology->destroy(&dummy_bridge);
593 ast_module_unref(dummy_bridge.technology->mod);
594}
#define ast_module_unref(mod)
Release a reference to the module.
Definition: module.h:483
void(* destroy)(struct ast_bridge *bridge)
Destroy a bridging technology instance for a bridge.
const ast_string_field creator
Definition: bridge.h:405
union ast_frame::@228 data
struct ast_bridge_technology * tech
Definition: bridge.c:565

References ast_debug, ast_module_unref, ast_bridge::creator, ast_frame::data, ast_bridge_technology::destroy, ast_bridge_technology::mod, ast_bridge::name, ast_bridge_technology::name, ast_frame::ptr, tech_deferred_destroy::tech, tech_deferred_destroy::tech_pvt, ast_bridge::technology, and ast_bridge::uniqueid.

Referenced by bridge_action_bridge().

◆ bridges_allow_merge_optimization()

static enum bridge_allow_merge bridges_allow_merge_optimization ( struct ast_bridge chan_bridge,
struct ast_bridge peer_bridge,
int  num_kick_channels,
struct merge_direction merge 
)
static

◆ bridges_allow_swap_optimization()

static enum bridge_allow_swap bridges_allow_swap_optimization ( struct ast_bridge chan_bridge,
struct ast_bridge peer_bridge 
)
static

Definition at line 2758 of file bridge.c.

2760{
2761 int chan_priority;
2762 int peer_priority;
2763
2764 if (!ast_test_flag(&chan_bridge->feature_flags,
2767 && !ast_test_flag(&peer_bridge->feature_flags,
2770 /*
2771 * Can swap either way. Swap to the higher priority merge
2772 * bridge.
2773 */
2774 chan_priority = chan_bridge->v_table->get_merge_priority(chan_bridge);
2775 peer_priority = peer_bridge->v_table->get_merge_priority(peer_bridge);
2776 if (chan_bridge->num_channels == 2
2777 && chan_priority <= peer_priority) {
2778 return SWAP_TO_PEER_BRIDGE;
2779 } else if (peer_bridge->num_channels == 2
2780 && peer_priority <= chan_priority) {
2781 return SWAP_TO_CHAN_BRIDGE;
2782 }
2783 } else if (chan_bridge->num_channels == 2
2786 /* Can swap optimize only one way. */
2787 return SWAP_TO_PEER_BRIDGE;
2788 } else if (peer_bridge->num_channels == 2
2791 /* Can swap optimize only one way. */
2792 return SWAP_TO_CHAN_BRIDGE;
2793 }
2794
2795 return SWAP_PROHIBITED;
2796}
@ AST_BRIDGE_FLAG_SWAP_INHIBIT_TO
@ AST_BRIDGE_FLAG_SWAP_INHIBIT_FROM

References AST_BRIDGE_FLAG_SWAP_INHIBIT_FROM, AST_BRIDGE_FLAG_SWAP_INHIBIT_TO, AST_BRIDGE_FLAG_TRANSFER_BRIDGE_ONLY, ast_test_flag, ast_bridge::feature_flags, ast_bridge_methods::get_merge_priority, ast_bridge::num_channels, SWAP_PROHIBITED, SWAP_TO_CHAN_BRIDGE, SWAP_TO_PEER_BRIDGE, and ast_bridge::v_table.

Referenced by ast_bridges_allow_optimization(), and try_swap_optimize_out().

◆ channel_cmp()

static int channel_cmp ( void *  obj,
void *  arg,
int  flags 
)
static

Definition at line 4065 of file bridge.c.

4066{
4067 const struct ast_channel *left = obj;
4068 const struct ast_channel *right = arg;
4069 const char *right_name = arg;
4070 int cmp;
4071
4072 switch (flags & (OBJ_POINTER | OBJ_KEY | OBJ_PARTIAL_KEY)) {
4073 default:
4074 case OBJ_POINTER:
4075 right_name = ast_channel_name(right);
4076 /* Fall through */
4077 case OBJ_KEY:
4078 cmp = strcmp(ast_channel_name(left), right_name);
4079 break;
4080 case OBJ_PARTIAL_KEY:
4081 cmp = strncmp(ast_channel_name(left), right_name, strlen(right_name));
4082 break;
4083 }
4084 return cmp ? 0 : CMP_MATCH;
4085}
@ CMP_MATCH
Definition: astobj2.h:1027
struct ast_flags flags

References ast_channel_name(), CMP_MATCH, ast_channel::flags, OBJ_KEY, OBJ_PARTIAL_KEY, and OBJ_POINTER.

Referenced by ast_bridge_peers_nolock().

◆ channel_hash()

static int channel_hash ( const void *  obj,
int  flags 
)
static

Definition at line 4042 of file bridge.c.

4043{
4044 const struct ast_channel *chan = obj;
4045 const char *name = obj;
4046 int hash;
4047
4048 switch (flags & (OBJ_POINTER | OBJ_KEY | OBJ_PARTIAL_KEY)) {
4049 default:
4050 case OBJ_POINTER:
4051 name = ast_channel_name(chan);
4052 /* Fall through */
4053 case OBJ_KEY:
4054 hash = ast_str_hash(name);
4055 break;
4056 case OBJ_PARTIAL_KEY:
4057 /* Should never happen in hash callback. */
4058 ast_assert(0);
4059 hash = 0;
4060 break;
4061 }
4062 return hash;
4063}
static force_inline int attribute_pure ast_str_hash(const char *str)
Compute a hash value on a string.
Definition: strings.h:1259

References ast_assert, ast_channel_name(), ast_str_hash(), ast_channel::flags, name, OBJ_KEY, OBJ_PARTIAL_KEY, and OBJ_POINTER.

Referenced by ast_bridge_peers_nolock().

◆ check_bridge_play_sound()

static void check_bridge_play_sound ( struct ast_bridge_channel bridge_channel)
static

Definition at line 1244 of file bridge.c.

1245{
1246 const char *play_file;
1247
1248 ast_channel_lock(bridge_channel->chan);
1249 play_file = pbx_builtin_getvar_helper(bridge_channel->chan, "BRIDGE_PLAY_SOUND");
1250 if (!ast_strlen_zero(play_file)) {
1252 pbx_builtin_setvar_helper(bridge_channel->chan, "BRIDGE_PLAY_SOUND", NULL);
1253 } else {
1254 play_file = NULL;
1255 }
1256 ast_channel_unlock(bridge_channel->chan);
1257
1258 if (play_file) {
1260 }
1261}
static int play_file(struct ast_bridge_channel *bridge_channel, struct ast_channel *channel, const char *filename)
Playback the given filename and monitor for any dtmf interrupts.

References ast_bridge_channel_queue_playfile(), ast_channel_lock, ast_channel_unlock, ast_strdupa, ast_strlen_zero(), ast_bridge_channel::chan, NULL, pbx_builtin_getvar_helper(), pbx_builtin_setvar_helper(), and play_file().

Referenced by check_bridge_play_sounds().

◆ check_bridge_play_sounds()

static void check_bridge_play_sounds ( struct ast_bridge bridge)
static

Definition at line 1272 of file bridge.c.

1273{
1274 struct ast_bridge_channel *bridge_channel;
1275
1276 AST_LIST_TRAVERSE(&bridge->channels, bridge_channel, entry) {
1277 check_bridge_play_sound(bridge_channel);
1278 }
1279}
static void check_bridge_play_sound(struct ast_bridge_channel *bridge_channel)
Definition: bridge.c:1244

References AST_LIST_TRAVERSE, ast_bridge_channel::bridge, ast_bridge::channels, check_bridge_play_sound(), and ast_bridge_channel::entry.

Referenced by bridge_reconfigured().

◆ cleanup_video_mode()

static void cleanup_video_mode ( struct ast_bridge bridge)
static

Definition at line 3795 of file bridge.c.

References AST_BRIDGE_VIDEO_MODE_NONE, AST_BRIDGE_VIDEO_MODE_SFU, AST_BRIDGE_VIDEO_MODE_SINGLE_SRC, AST_BRIDGE_VIDEO_MODE_TALKER_SRC, ast_channel_unref, ast_bridge_video_talker_src_data::chan_old_vsrc, ast_bridge_video_single_src_data::chan_vsrc, ast_bridge_video_talker_src_data::chan_vsrc, ast_bridge_video_mode::mode, ast_bridge_video_mode::mode_data, ast_bridge_video_mode::single_src_data, ast_bridge::softmix, ast_bridge_video_mode::talker_src_data, and ast_bridge_softmix::video_mode.

Referenced by ast_bridge_set_sfu_video_mode(), ast_bridge_set_single_src_video_mode(), ast_bridge_set_talker_src_video_mode(), and destroy_bridge().

◆ complete_bridge_live()

static char * complete_bridge_live ( const char *  word)
static

Definition at line 5097 of file bridge.c.

5098{
5101
5102 return NULL;
5103}
static int complete_bridge_live_search(void *obj, void *arg, int flags)
Definition: bridge.c:5086
short word

References ao2_callback, ast_strlen_zero(), bridges, complete_bridge_live_search(), NULL, and OBJ_PARTIAL_KEY.

Referenced by handle_bridge_kick_channel(), and handle_bridge_show_specific().

◆ complete_bridge_live_search()

static int complete_bridge_live_search ( void *  obj,
void *  arg,
int  flags 
)
static

Definition at line 5086 of file bridge.c.

5087{
5088 struct ast_bridge *bridge = obj;
5089
5091 return CMP_STOP;
5092 }
5093
5094 return 0;
5095}
#define ast_strdup(str)
A wrapper for strdup()
Definition: astmm.h:241
@ CMP_STOP
Definition: astobj2.h:1028
int ast_cli_completion_add(char *value)
Add a result to a request for completion options.
Definition: main/cli.c:2768

References ast_cli_completion_add(), ast_strdup, CMP_STOP, and ast_bridge::uniqueid.

Referenced by complete_bridge_live().

◆ complete_bridge_participant()

static char * complete_bridge_participant ( const char *  bridge_name,
const char *  word 
)
static

Definition at line 5253 of file bridge.c.

5254{
5255 struct ast_bridge *bridge;
5256 struct ast_bridge_channel *bridge_channel;
5257 int wordlen;
5258
5259 bridge = ast_bridge_find_by_id(bridge_name);
5260 if (!bridge) {
5261 return NULL;
5262 }
5263
5264 wordlen = strlen(word);
5265
5267 AST_LIST_TRAVERSE(&bridge->channels, bridge_channel, entry) {
5268 if (!strncasecmp(ast_channel_name(bridge_channel->chan), word, wordlen)) {
5269 if (ast_cli_completion_add(ast_strdup(ast_channel_name(bridge_channel->chan)))) {
5270 break;
5271 }
5272 }
5273 }
5275
5276 ao2_ref(bridge, -1);
5277
5278 return NULL;
5279}

References ao2_ref, ast_bridge_find_by_id(), ast_bridge_lock, ast_bridge_unlock, ast_channel_name(), ast_cli_completion_add(), AST_LIST_TRAVERSE, ast_strdup, ast_bridge_channel::bridge, ast_bridge_channel::chan, ast_bridge::channels, ast_bridge_channel::entry, and NULL.

Referenced by handle_bridge_kick_channel().

◆ complete_bridge_technology()

static char * complete_bridge_technology ( const char *  word)
static

Definition at line 5402 of file bridge.c.

5403{
5404 struct ast_bridge_technology *cur;
5405 int wordlen;
5406
5407 wordlen = strlen(word);
5410 if (!strncasecmp(cur->name, word, wordlen)) {
5412 break;
5413 }
5414 }
5415 }
5417
5418 return NULL;
5419}
#define AST_RWLIST_RDLOCK(head)
Read locks a list.
Definition: linkedlists.h:78

References ast_cli_completion_add(), AST_RWLIST_RDLOCK, AST_RWLIST_TRAVERSE, AST_RWLIST_UNLOCK, ast_strdup, ast_bridge_technology::name, and NULL.

Referenced by handle_bridge_technology_suspend().

◆ destroy_bridge()

static void destroy_bridge ( void *  obj)
static

Definition at line 659 of file bridge.c.

660{
661 struct ast_bridge *bridge = obj;
662
663 ast_debug(1, "Bridge " BRIDGE_PRINTF_SPEC ": actually destroying %s bridge, nobody wants it anymore\n",
664 BRIDGE_PRINTF_VARS(bridge), bridge->v_table->name);
665
666 if (bridge->construction_completed) {
667 bridge_topics_destroy(bridge);
668 }
669
670 /* Do any pending actions in the context of destruction. */
671 ast_bridge_lock(bridge);
672 bridge_handle_actions(bridge);
673 ast_bridge_unlock(bridge);
674
675 /* There should not be any channels left in the bridge. */
677
678 ast_debug(1, "Bridge %s: calling %s bridge destructor\n",
679 bridge->uniqueid, bridge->v_table->name);
680 bridge->v_table->destroy(bridge);
681
682 /* Pass off the bridge to the technology to destroy if needed */
683 if (bridge->technology) {
684 ast_debug(1, "Bridge %s: calling %s technology stop\n",
685 bridge->uniqueid, bridge->technology->name);
686 if (bridge->technology->stop) {
687 ast_bridge_lock(bridge);
688 bridge->technology->stop(bridge);
689 ast_bridge_unlock(bridge);
690 }
691 ast_debug(1, "Bridge %s: calling %s technology destructor\n",
692 bridge->uniqueid, bridge->technology->name);
693 if (bridge->technology->destroy) {
694 bridge->technology->destroy(bridge);
695 }
697 bridge->technology = NULL;
698 }
699
701
702 bridge->callid = 0;
703
704 cleanup_video_mode(bridge);
705
706 ast_debug(1, "Bridge " BRIDGE_PRINTF_SPEC ": destroyed\n",
707 BRIDGE_PRINTF_VARS(bridge));
710 bridge->current_snapshot = NULL;
711}
#define AST_LIST_EMPTY(head)
Checks whether the specified list contains any entries.
Definition: linkedlists.h:450
void bridge_topics_destroy(struct ast_bridge *bridge)
void(* stop)(struct ast_bridge *bridge)
Request a bridge technology instance stop in preparation for being destroyed.
struct ast_bridge_snapshot * current_snapshot
Definition: bridge.h:410
#define AST_VECTOR_FREE(vec)
Deallocates this vector.
Definition: vector.h:174

References ao2_cleanup, ast_assert, ast_bridge_lock, ast_bridge_unlock, ast_debug, AST_LIST_EMPTY, ast_module_unref, ast_string_field_free_memory, AST_VECTOR_FREE, bridge_handle_actions(), BRIDGE_PRINTF_SPEC, BRIDGE_PRINTF_VARS, bridge_topics_destroy(), ast_bridge::callid, ast_bridge::channels, cleanup_video_mode(), ast_bridge::construction_completed, ast_bridge::current_snapshot, ast_bridge_methods::destroy, ast_bridge_technology::destroy, ast_bridge::media_types, ast_bridge_technology::mod, ast_bridge_methods::name, ast_bridge_technology::name, NULL, ast_bridge_technology::stop, ast_bridge::technology, ast_bridge::uniqueid, and ast_bridge::v_table.

Referenced by bridge_alloc().

◆ fill_bridgepeer_buf()

static void fill_bridgepeer_buf ( char *  buf,
unsigned int  cur_idx,
const char *  names[],
unsigned int  num_names 
)
static

Definition at line 1338 of file bridge.c.

1339{
1340 int need_separator = 0;
1341 unsigned int idx;
1342 const char *src;
1343 char *pos;
1344
1345 pos = buf;
1346 for (idx = 0; idx < num_names; ++idx) {
1347 if (idx == cur_idx) {
1348 continue;
1349 }
1350
1351 if (need_separator) {
1352 *pos++ = ',';
1353 }
1354 need_separator = 1;
1355
1356 /* Copy name into buffer. */
1357 src = names[idx];
1358 while (*src) {
1359 *pos++ = *src++;
1360 }
1361 }
1362 *pos = '\0';
1363}
char buf[BUFSIZE]
Definition: eagi_proxy.c:66

References buf.

Referenced by set_bridge_peer_vars_multiparty().

◆ find_best_technology()

static struct ast_bridge_technology * find_best_technology ( uint32_t  capabilities,
struct ast_bridge bridge 
)
static

Helper function used to find the "best" bridge technology given specified capabilities.

Definition at line 518 of file bridge.c.

519{
521 struct ast_bridge_technology *best = NULL;
522
525 if (current->suspended) {
526 ast_debug(2, "Bridge technology %s is suspended. Skipping.\n",
527 current->name);
528 continue;
529 }
530 if (!(current->capabilities & capabilities)) {
531 ast_debug(2, "Bridge technology %s does not have any capabilities we want.\n",
532 current->name);
533 continue;
534 }
535 if (best && current->preference <= best->preference) {
536 ast_debug(2, "Bridge technology %s has less preference than %s (%u <= %u). Skipping.\n",
537 current->name, best->name, current->preference, best->preference);
538 continue;
539 }
540 if (current->compatible && !current->compatible(bridge)) {
541 ast_debug(2, "Bridge technology %s is not compatible with properties of existing bridge.\n",
542 current->name);
543 continue;
544 }
545 if (!ast_module_running_ref(current->mod)) {
546 ast_debug(2, "Bridge technology %s is not running, skipping.\n", current->name);
547 continue;
548 }
549 if (best) {
550 ast_module_unref(best->mod);
551 }
552 best = current;
553 }
554
555 if (best) {
556 ast_debug(1, "Chose bridge technology %s\n", best->name);
557 }
558
560
561 return best;
562}
#define ast_module_running_ref(mod)
Hold a reference to the module if it is running.
Definition: module.h:469

References ast_debug, ast_module_running_ref, ast_module_unref, AST_RWLIST_RDLOCK, AST_RWLIST_TRAVERSE, AST_RWLIST_UNLOCK, ast_bridge_technology::capabilities, current, ast_bridge_technology::mod, ast_bridge_technology::name, NULL, and ast_bridge_technology::preference.

Referenced by bridge_base_init(), and smart_bridge_operation().

◆ get_transferee()

static struct ast_channel * get_transferee ( struct ao2_container channels,
struct ast_channel transferer 
)
static

Definition at line 4251 of file bridge.c.

4252{
4253 struct ao2_iterator channel_iter;
4254 struct ast_channel *transferee;
4255
4256 for (channel_iter = ao2_iterator_init(channels, 0);
4257 (transferee = ao2_iterator_next(&channel_iter));
4258 ao2_cleanup(transferee)) {
4259 if (transferee != transferer) {
4260 break;
4261 }
4262 }
4263
4264 ao2_iterator_destroy(&channel_iter);
4265 return transferee;
4266}

References ao2_cleanup, ao2_iterator_destroy(), ao2_iterator_init(), ao2_iterator_next, and channels.

Referenced by ast_bridge_transfer_attended().

◆ handle_bridge_kick_channel()

static char * handle_bridge_kick_channel ( struct ast_cli_entry e,
int  cmd,
struct ast_cli_args a 
)
static

Definition at line 5281 of file bridge.c.

5282{
5283 static const char * const completions[] = { "all", NULL };
5284 struct ast_bridge *bridge;
5285
5286 switch (cmd) {
5287 case CLI_INIT:
5288 e->command = "bridge kick";
5289 e->usage =
5290 "Usage: bridge kick <bridge-id> <channel-name | all>\n"
5291 " Kick the <channel-name> channel out of the <bridge-id> bridge\n"
5292 " If all is specified as the channel name then all channels will be\n"
5293 " kicked out of the bridge.\n";
5294 return NULL;
5295 case CLI_GENERATE:
5296 if (a->pos == 2) {
5297 return complete_bridge_live(a->word);
5298 }
5299 if (a->pos == 3) {
5300 ast_cli_complete(a->word, completions, -1);
5301 return complete_bridge_participant(a->argv[2], a->word);
5302 }
5303 return NULL;
5304 }
5305
5306 if (a->argc != 4) {
5307 return CLI_SHOWUSAGE;
5308 }
5309
5310 bridge = ast_bridge_find_by_id(a->argv[2]);
5311 if (!bridge) {
5312 ast_cli(a->fd, "Bridge '%s' not found\n", a->argv[2]);
5313 return CLI_SUCCESS;
5314 }
5315
5316 if (!strcasecmp(a->argv[3], "all")) {
5317 struct ast_bridge_channel *bridge_channel;
5318
5319 ast_cli(a->fd, "Kicking all channels from bridge '%s'\n", a->argv[2]);
5320
5322 AST_LIST_TRAVERSE(&bridge->channels, bridge_channel, entry) {
5323 ast_bridge_channel_queue_callback(bridge_channel, 0, kick_it, NULL, 0);
5324 }
5326 } else {
5327 struct ast_channel *chan;
5328
5329 chan = ast_channel_get_by_name_prefix(a->argv[3], strlen(a->argv[3]));
5330 if (!chan) {
5331 ast_cli(a->fd, "Channel '%s' not found\n", a->argv[3]);
5332 ao2_ref(bridge, -1);
5333 return CLI_SUCCESS;
5334 }
5335
5336 ast_cli(a->fd, "Kicking channel '%s' from bridge '%s'\n",
5337 ast_channel_name(chan), a->argv[2]);
5338 ast_bridge_kick(bridge, chan);
5339 ast_channel_unref(chan);
5340 }
5341
5342 ao2_ref(bridge, -1);
5343 return CLI_SUCCESS;
5344}
int ast_bridge_kick(struct ast_bridge *bridge, struct ast_channel *chan)
Kick a channel from a bridge.
Definition: bridge.c:2048
static char * complete_bridge_live(const char *word)
Definition: bridge.c:5097
static char * complete_bridge_participant(const char *bridge_name, const char *word)
Definition: bridge.c:5253
struct ast_channel * ast_channel_get_by_name_prefix(const char *name, size_t name_len)
Find a channel by a name prefix.
Definition: channel.c:1461
#define CLI_SHOWUSAGE
Definition: cli.h:45
#define CLI_SUCCESS
Definition: cli.h:44
char * ast_cli_complete(const char *word, const char *const choices[], int pos)
Definition: main/cli.c:1853
@ CLI_INIT
Definition: cli.h:152
@ CLI_GENERATE
Definition: cli.h:153
char * command
Definition: cli.h:186
const char * usage
Definition: cli.h:177

References a, ao2_ref, ast_bridge_channel_queue_callback(), ast_bridge_find_by_id(), ast_bridge_kick(), ast_bridge_lock, ast_bridge_unlock, ast_channel_get_by_name_prefix(), ast_channel_name(), ast_channel_unref, ast_cli(), ast_cli_complete(), AST_LIST_TRAVERSE, ast_bridge_channel::bridge, ast_channel::bridge, ast_bridge::channels, CLI_GENERATE, CLI_INIT, CLI_SHOWUSAGE, CLI_SUCCESS, ast_cli_entry::command, complete_bridge_live(), complete_bridge_participant(), ast_bridge_channel::entry, kick_it(), NULL, and ast_cli_entry::usage.

◆ handle_bridge_show_all()

static char * handle_bridge_show_all ( struct ast_cli_entry e,
int  cmd,
struct ast_cli_args a 
)
static

Definition at line 5105 of file bridge.c.

5106{
5107#define FORMAT_HDR "%-36s %-36s %5s %-15s %-15s %s\n"
5108#define FORMAT_ROW "%-36s %-36s %5u %-15s %-15s %s\n"
5109
5110 struct ao2_iterator iter;
5111 struct ast_bridge *bridge;
5112
5113 switch (cmd) {
5114 case CLI_INIT:
5115 e->command = "bridge show all";
5116 e->usage =
5117 "Usage: bridge show all\n"
5118 " List all bridges\n";
5119 return NULL;
5120 case CLI_GENERATE:
5121 return NULL;
5122 }
5123
5124 ast_cli(a->fd, FORMAT_HDR, "Bridge-ID", "Name", "Chans", "Type", "Technology", "Duration");
5125
5126 iter = ao2_iterator_init(bridges, 0);
5127 for (; (bridge = ao2_iterator_next(&iter)); ao2_ref(bridge, -1)) {
5128 struct ast_bridge_snapshot *snapshot = ast_bridge_get_snapshot(bridge);
5129 char print_time[32];
5130
5131 if (snapshot) {
5132 ast_format_duration_hh_mm_ss(ast_tvnow().tv_sec - snapshot->creationtime.tv_sec, print_time, sizeof(print_time));
5133 ast_cli(a->fd, FORMAT_ROW,
5134 bridge->uniqueid,
5135 S_OR(bridge->name, "<unknown>"),
5136 snapshot->num_channels,
5137 S_OR(snapshot->subclass, "<unknown>"),
5138 S_OR(snapshot->technology, "<unknown>"),
5139 print_time);
5140 ao2_ref(snapshot, -1);
5141 }
5142 }
5143 ao2_iterator_destroy(&iter);
5144
5145 return CLI_SUCCESS;
5146
5147#undef FORMAT_HDR
5148#undef FORMAT_ROW
5149}
#define FORMAT_ROW
#define FORMAT_HDR
struct ast_bridge_snapshot * ast_bridge_get_snapshot(struct ast_bridge *bridge)
Returns the current snapshot for the bridge.
#define S_OR(a, b)
returns the equivalent of logic or for strings: first one if not empty, otherwise second one.
Definition: strings.h:80
Structure that contains a snapshot of information about a bridge.
Definition: bridge.h:318
struct timeval creationtime
Definition: bridge.h:347
unsigned int num_channels
Definition: bridge.h:341
const ast_string_field technology
Definition: bridge.h:332
const ast_string_field subclass
Definition: bridge.h:332
void ast_format_duration_hh_mm_ss(int duration, char *buf, size_t length)
Formats a duration into HH:MM:SS.
Definition: utils.c:2297

References a, ao2_iterator_destroy(), ao2_iterator_init(), ao2_iterator_next, ao2_ref, ast_bridge_get_snapshot(), ast_cli(), ast_format_duration_hh_mm_ss(), ast_tvnow(), bridges, CLI_GENERATE, CLI_INIT, CLI_SUCCESS, ast_cli_entry::command, ast_bridge_snapshot::creationtime, FORMAT_HDR, FORMAT_ROW, ast_bridge::name, NULL, ast_bridge_snapshot::num_channels, S_OR, ast_bridge_snapshot::subclass, ast_bridge_snapshot::technology, ast_bridge::uniqueid, and ast_cli_entry::usage.

◆ handle_bridge_show_specific()

static char * handle_bridge_show_specific ( struct ast_cli_entry e,
int  cmd,
struct ast_cli_args a 
)
static

Definition at line 5169 of file bridge.c.

5170{
5171 struct ast_bridge_snapshot *snapshot;
5172 char print_time[32];
5173
5174 switch (cmd) {
5175 case CLI_INIT:
5176 e->command = "bridge show";
5177 e->usage =
5178 "Usage: bridge show <bridge-id>\n"
5179 " Show information about the <bridge-id> bridge\n";
5180 return NULL;
5181 case CLI_GENERATE:
5182 if (a->pos == 2) {
5183 return complete_bridge_live(a->word);
5184 }
5185 return NULL;
5186 }
5187
5188 if (a->argc != 3) {
5189 return CLI_SHOWUSAGE;
5190 }
5191
5192 snapshot = ast_bridge_get_snapshot_by_uniqueid(a->argv[2]);
5193 if (!snapshot) {
5194 ast_cli(a->fd, "Bridge '%s' not found\n", a->argv[2]);
5195 return CLI_SUCCESS;
5196 }
5197
5198 ast_format_duration_hh_mm_ss(ast_tvnow().tv_sec - snapshot->creationtime.tv_sec, print_time, sizeof(print_time));
5199
5200 ast_cli(a->fd, "Id: %s\n", snapshot->uniqueid);
5201 ast_cli(a->fd, "Type: %s\n", S_OR(snapshot->subclass, "<unknown>"));
5202 ast_cli(a->fd, "Technology: %s\n", S_OR(snapshot->technology, "<unknown>"));
5203 ast_cli(a->fd, "Subclass: %s\n", snapshot->subclass);
5204 ast_cli(a->fd, "Creator: %s\n", snapshot->creator);
5205 ast_cli(a->fd, "Name: %s\n", snapshot->name);
5206 ast_cli(a->fd, "Video-Mode: %s\n", ast_bridge_video_mode_to_string(snapshot->video_mode));
5207 ast_cli(a->fd, "Video-Source-Id: %s\n", snapshot->video_source_id);
5208 ast_cli(a->fd, "Num-Channels: %u\n", snapshot->num_channels);
5209 ast_cli(a->fd, "Num-Active: %u\n", snapshot->num_active);
5210 ast_cli(a->fd, "Duration: %s\n", print_time);
5212 ao2_ref(snapshot, -1);
5213
5214 return CLI_SUCCESS;
5215}
@ OBJ_NODATA
Definition: astobj2.h:1044
const char * ast_bridge_video_mode_to_string(enum ast_bridge_video_mode_type video_mode)
Converts an enum representation of a bridge video mode to string.
Definition: bridge.c:4020
static int bridge_show_specific_print_channel(void *obj, void *arg, int flags)
Internal callback function for sending channels in a bridge to the CLI.
Definition: bridge.c:5152
struct ast_bridge_snapshot * ast_bridge_get_snapshot_by_uniqueid(const char *bridge_id)
Returns the current snapshot for the bridge.
enum ast_bridge_video_mode_type video_mode
Definition: bridge.h:345
unsigned int num_active
Definition: bridge.h:343
const ast_string_field video_source_id
Definition: bridge.h:332
const ast_string_field creator
Definition: bridge.h:332
const ast_string_field uniqueid
Definition: bridge.h:332
const ast_string_field name
Definition: bridge.h:332
struct ao2_container * channels
Definition: bridge.h:335

References a, ao2_callback, ao2_ref, ast_bridge_get_snapshot_by_uniqueid(), ast_bridge_video_mode_to_string(), ast_cli(), ast_format_duration_hh_mm_ss(), ast_tvnow(), bridge_show_specific_print_channel(), ast_bridge_snapshot::channels, CLI_GENERATE, CLI_INIT, CLI_SHOWUSAGE, CLI_SUCCESS, ast_cli_entry::command, complete_bridge_live(), ast_bridge_snapshot::creationtime, ast_bridge_snapshot::creator, ast_bridge_snapshot::name, NULL, ast_bridge_snapshot::num_active, ast_bridge_snapshot::num_channels, OBJ_NODATA, S_OR, ast_bridge_snapshot::subclass, ast_bridge_snapshot::technology, ast_bridge_snapshot::uniqueid, ast_cli_entry::usage, ast_bridge_snapshot::video_mode, and ast_bridge_snapshot::video_source_id.

◆ handle_bridge_technology_show()

static char * handle_bridge_technology_show ( struct ast_cli_entry e,
int  cmd,
struct ast_cli_args a 
)
static

Definition at line 5367 of file bridge.c.

5368{
5369#define FORMAT_HDR "%-20s %-20s %8s %s\n"
5370#define FORMAT_ROW "%-20s %-20s %8u %s\n"
5371
5372 struct ast_bridge_technology *cur;
5373
5374 switch (cmd) {
5375 case CLI_INIT:
5376 e->command = "bridge technology show";
5377 e->usage =
5378 "Usage: bridge technology show\n"
5379 " List registered bridge technologies\n";
5380 return NULL;
5381 case CLI_GENERATE:
5382 return NULL;
5383 }
5384
5385 ast_cli(a->fd, FORMAT_HDR, "Name", "Type", "Priority", "Suspended");
5388 const char *type;
5389
5390 /* Decode type for display */
5392
5393 ast_cli(a->fd, FORMAT_ROW, cur->name, type, cur->preference,
5394 AST_CLI_YESNO(cur->suspended));
5395 }
5397 return CLI_SUCCESS;
5398
5399#undef FORMAT
5400}
static const char * tech_capability2str(uint32_t capabilities)
Definition: bridge.c:5347
#define AST_CLI_YESNO(x)
Return Yes or No depending on the argument.
Definition: cli.h:71

References a, ast_cli(), AST_CLI_YESNO, AST_RWLIST_RDLOCK, AST_RWLIST_TRAVERSE, AST_RWLIST_UNLOCK, ast_bridge_technology::capabilities, CLI_GENERATE, CLI_INIT, CLI_SUCCESS, ast_cli_entry::command, FORMAT_HDR, FORMAT_ROW, ast_bridge_technology::name, NULL, ast_bridge_technology::preference, ast_bridge_technology::suspended, tech_capability2str(), type, and ast_cli_entry::usage.

◆ handle_bridge_technology_suspend()

static char * handle_bridge_technology_suspend ( struct ast_cli_entry e,
int  cmd,
struct ast_cli_args a 
)
static

Definition at line 5421 of file bridge.c.

5422{
5423 struct ast_bridge_technology *cur;
5424 int suspend;
5425 int successful;
5426
5427 switch (cmd) {
5428 case CLI_INIT:
5429 e->command = "bridge technology {suspend|unsuspend}";
5430 e->usage =
5431 "Usage: bridge technology {suspend|unsuspend} <technology-name>\n"
5432 " Suspend or unsuspend a bridge technology.\n";
5433 return NULL;
5434 case CLI_GENERATE:
5435 if (a->pos == 3) {
5436 return complete_bridge_technology(a->word);
5437 }
5438 return NULL;
5439 }
5440
5441 if (a->argc != 4) {
5442 return CLI_SHOWUSAGE;
5443 }
5444
5445 suspend = !strcasecmp(a->argv[2], "suspend");
5446 successful = 0;
5449 if (!strcasecmp(cur->name, a->argv[3])) {
5450 successful = 1;
5451 if (suspend) {
5453 } else {
5455 }
5456 break;
5457 }
5458 }
5460
5461 if (successful) {
5462 if (suspend) {
5463 ast_cli(a->fd, "Suspended bridge technology '%s'\n", a->argv[3]);
5464 } else {
5465 ast_cli(a->fd, "Unsuspended bridge technology '%s'\n", a->argv[3]);
5466 }
5467 } else {
5468 ast_cli(a->fd, "Bridge technology '%s' not found\n", a->argv[3]);
5469 }
5470
5471 return CLI_SUCCESS;
5472}
void ast_bridge_technology_unsuspend(struct ast_bridge_technology *technology)
Unsuspend a bridge technology.
Definition: bridge.c:3121
void ast_bridge_technology_suspend(struct ast_bridge_technology *technology)
Suspend a bridge technology from consideration.
Definition: bridge.c:3116
static char * complete_bridge_technology(const char *word)
Definition: bridge.c:5402
static void suspend(struct cc_core_instance *core_instance)
Definition: ccss.c:3166

References a, ast_bridge_technology_suspend(), ast_bridge_technology_unsuspend(), ast_cli(), AST_RWLIST_TRAVERSE, AST_RWLIST_UNLOCK, AST_RWLIST_WRLOCK, CLI_GENERATE, CLI_INIT, CLI_SHOWUSAGE, CLI_SUCCESS, ast_cli_entry::command, complete_bridge_technology(), ast_bridge_technology::name, NULL, suspend(), and ast_cli_entry::usage.

◆ handle_manager_bridge_tech_suspend()

static int handle_manager_bridge_tech_suspend ( struct mansession s,
const struct message m,
int  suspend 
)
static

Definition at line 5486 of file bridge.c.

5487{
5488 const char *name = astman_get_header(m, "BridgeTechnology");
5489 struct ast_bridge_technology *cur;
5490 int successful = 0;
5491
5492 if (ast_strlen_zero(name)) {
5493 astman_send_error(s, m, "BridgeTechnology must be provided");
5494 return 0;
5495 }
5496
5499
5500 if (!strcasecmp(cur->name, name)) {
5501 successful = 1;
5502 if (suspend) {
5504 } else {
5506 }
5507 break;
5508 }
5509 }
5511 if (!successful) {
5512 astman_send_error(s, m, "BridgeTechnology not found");
5513 return 0;
5514 }
5515
5516 astman_send_ack(s, m, (suspend ? "Suspended bridge technology" : "Unsuspended bridge technology"));
5517 return 0;
5518}
void astman_send_error(struct mansession *s, const struct message *m, char *error)
Send error in manager transaction.
Definition: manager.c:1986
void astman_send_ack(struct mansession *s, const struct message *m, char *msg)
Send ack in manager transaction.
Definition: manager.c:2018
const char * astman_get_header(const struct message *m, char *var)
Get header from manager transaction.
Definition: manager.c:1647

References ast_bridge_technology_suspend(), ast_bridge_technology_unsuspend(), AST_RWLIST_RDLOCK, AST_RWLIST_TRAVERSE, AST_RWLIST_UNLOCK, ast_strlen_zero(), astman_get_header(), astman_send_ack(), astman_send_error(), name, ast_bridge_technology::name, and suspend().

Referenced by manager_bridge_tech_suspend(), and manager_bridge_tech_unsuspend().

◆ hook_remove_match()

static int hook_remove_match ( void *  obj,
void *  arg,
int  flags 
)
static

Definition at line 3514 of file bridge.c.

3515{
3516 struct ast_bridge_hook *hook = obj;
3518
3519 if (ast_test_flag(&hook->remove_flags, *remove_flags)) {
3520 return CMP_MATCH;
3521 } else {
3522 return 0;
3523 }
3524}
ast_bridge_hook_remove_flags

References ast_test_flag, CMP_MATCH, and ast_bridge_hook::remove_flags.

Referenced by hooks_remove_container().

◆ hooks_remove_container()

static void hooks_remove_container ( struct ao2_container hooks,
enum ast_bridge_hook_remove_flags  remove_flags 
)
static

Definition at line 3534 of file bridge.c.

3535{
3537 hook_remove_match, &remove_flags);
3538}
@ OBJ_MULTIPLE
Definition: astobj2.h:1049
@ OBJ_UNLINK
Definition: astobj2.h:1039
static int hook_remove_match(void *obj, void *arg, int flags)
Definition: bridge.c:3514

References ao2_callback, hook_remove_match(), OBJ_MULTIPLE, OBJ_NODATA, OBJ_UNLINK, and ast_bridge_hook::remove_flags.

Referenced by ast_bridge_features_remove().

◆ hooks_remove_heap()

static void hooks_remove_heap ( struct ast_heap hooks,
enum ast_bridge_hook_remove_flags  remove_flags 
)
static

Definition at line 3548 of file bridge.c.

3549{
3550 struct ast_bridge_hook *hook;
3551 int changed;
3552
3553 ast_heap_wrlock(hooks);
3554 do {
3555 int idx;
3556
3557 changed = 0;
3558 for (idx = ast_heap_size(hooks); idx; --idx) {
3559 hook = ast_heap_peek(hooks, idx);
3561 ast_heap_remove(hooks, hook);
3562 ao2_ref(hook, -1);
3563 changed = 1;
3564 }
3565 }
3566 } while (changed);
3567 ast_heap_unlock(hooks);
3568}
void * ast_heap_remove(struct ast_heap *h, void *elm)
Remove a specific element from a heap.
Definition: heap.c:251
size_t ast_heap_size(struct ast_heap *h)
Get the current size of a heap.
Definition: heap.c:276

References ao2_ref, ast_heap_peek(), ast_heap_remove(), ast_heap_size(), ast_heap_unlock, ast_heap_wrlock, ast_test_flag, and ast_bridge_hook::remove_flags.

Referenced by ast_bridge_features_remove().

◆ interval_hook_time_cmp()

static int interval_hook_time_cmp ( void *  a,
void *  b 
)
static

Definition at line 3577 of file bridge.c.

3578{
3579 struct ast_bridge_hook_timer *hook_a = a;
3580 struct ast_bridge_hook_timer *hook_b = b;
3581 int cmp;
3582
3583 cmp = ast_tvcmp(hook_b->timer.trip_time, hook_a->timer.trip_time);
3584 if (cmp) {
3585 return cmp;
3586 }
3587
3588 cmp = hook_b->timer.seqno - hook_a->timer.seqno;
3589 return cmp;
3590}
static struct test_val b
int ast_tvcmp(struct timeval _a, struct timeval _b)
Compress two struct timeval instances returning -1, 0, 1 if the first arg is smaller,...
Definition: time.h:137

References a, ast_tvcmp(), b, ast_bridge_hook_timer_parms::seqno, ast_bridge_hook_timer::timer, and ast_bridge_hook_timer_parms::trip_time.

Referenced by ast_bridge_features_init().

◆ interval_wrapper_cb()

static int interval_wrapper_cb ( struct ast_bridge_channel bridge_channel,
void *  obj 
)
static

Wrapper for interval hooks that calls into the wrapped hook.

Definition at line 3638 of file bridge.c.

3639{
3640 struct ast_bridge_hook_timer *hook = obj;
3641
3642 return hook->generic.callback(bridge_channel, hook->generic.hook_pvt);
3643}

References ast_bridge_hook::callback, ast_bridge_hook_timer::generic, and ast_bridge_hook::hook_pvt.

Referenced by wrap_hook().

◆ interval_wrapper_pvt_dtor()

static void interval_wrapper_pvt_dtor ( void *  obj)
static

Destructor for the hook wrapper.

Definition at line 3646 of file bridge.c.

3647{
3648 ao2_cleanup(obj);
3649}

References ao2_cleanup.

Referenced by wrap_hook().

◆ kick_it()

static void kick_it ( struct ast_bridge_channel bridge_channel,
const void *  payload,
size_t  payload_size 
)
static

Definition at line 2043 of file bridge.c.

2044{
2046}
void ast_bridge_channel_kick(struct ast_bridge_channel *bridge_channel, int cause)
Kick the channel out of the bridge.

References ast_bridge_channel_kick(), and AST_CAUSE_NORMAL_CLEARING.

Referenced by ast_bridge_kick(), and handle_bridge_kick_channel().

◆ manager_bridge_tech_list()

static int manager_bridge_tech_list ( struct mansession s,
const struct message m 
)
static

Definition at line 5530 of file bridge.c.

5531{
5532 const char *id = astman_get_header(m, "ActionID");
5533 RAII_VAR(struct ast_str *, id_text, ast_str_create(128), ast_free);
5534 struct ast_bridge_technology *cur;
5535 int num_items = 0;
5536
5537 if (!id_text) {
5538 astman_send_error(s, m, "Internal error");
5539 return -1;
5540 }
5541
5542 if (!ast_strlen_zero(id)) {
5543 ast_str_set(&id_text, 0, "ActionID: %s\r\n", id);
5544 }
5545
5546 astman_send_listack(s, m, "Bridge technology listing will follow", "start");
5547
5550 const char *type;
5551
5553
5554 astman_append(s,
5555 "Event: BridgeTechnologyListItem\r\n"
5556 "BridgeTechnology: %s\r\n"
5557 "BridgeType: %s\r\n"
5558 "BridgePriority: %u\r\n"
5559 "BridgeSuspended: %s\r\n"
5560 "%s"
5561 "\r\n",
5562 cur->name, type, cur->preference, AST_YESNO(cur->suspended),
5563 ast_str_buffer(id_text));
5564 ++num_items;
5565 }
5567
5568 astman_send_list_complete_start(s, m, "BridgeTechnologyListComplete", num_items);
5570
5571 return 0;
5572}
void astman_send_listack(struct mansession *s, const struct message *m, char *msg, char *listflag)
Send ack in manager transaction to begin a list.
Definition: manager.c:2028
void astman_send_list_complete_start(struct mansession *s, const struct message *m, const char *event_name, int count)
Start the list complete event.
Definition: manager.c:2064
void astman_send_list_complete_end(struct mansession *s)
End the list complete event.
Definition: manager.c:2072
void astman_append(struct mansession *s, const char *fmt,...)
Definition: manager.c:1907
char * ast_str_buffer(const struct ast_str *buf)
Returns the string buffer within the ast_str buf.
Definition: strings.h:761
#define ast_str_create(init_len)
Create a malloc'ed dynamic length string.
Definition: strings.h:659
int ast_str_set(struct ast_str **buf, ssize_t max_len, const char *fmt,...)
Set a dynamic string using variable arguments.
Definition: strings.h:1113
#define AST_YESNO(x)
return Yes or No depending on the argument.
Definition: strings.h:143
Support for dynamic strings.
Definition: strings.h:623

References ast_free, AST_RWLIST_RDLOCK, AST_RWLIST_TRAVERSE, AST_RWLIST_UNLOCK, ast_str_buffer(), ast_str_create, ast_str_set(), ast_strlen_zero(), AST_YESNO, astman_append(), astman_get_header(), astman_send_error(), astman_send_list_complete_end(), astman_send_list_complete_start(), astman_send_listack(), ast_bridge_technology::capabilities, ast_bridge_technology::name, ast_bridge_technology::preference, RAII_VAR, ast_bridge_technology::suspended, tech_capability2str(), and type.

Referenced by ast_bridging_init().

◆ manager_bridge_tech_suspend()

static int manager_bridge_tech_suspend ( struct mansession s,
const struct message m 
)
static

Definition at line 5520 of file bridge.c.

5521{
5522 return handle_manager_bridge_tech_suspend(s, m, 1);
5523}
static int handle_manager_bridge_tech_suspend(struct mansession *s, const struct message *m, int suspend)
Definition: bridge.c:5486

References handle_manager_bridge_tech_suspend().

Referenced by ast_bridging_init().

◆ manager_bridge_tech_unsuspend()

static int manager_bridge_tech_unsuspend ( struct mansession s,
const struct message m 
)
static

Definition at line 5525 of file bridge.c.

5526{
5527 return handle_manager_bridge_tech_suspend(s, m, 0);
5528}

References handle_manager_bridge_tech_suspend().

Referenced by ast_bridging_init().

◆ merge_container_cb()

static int merge_container_cb ( void *  obj,
void *  data,
int  flags 
)
static

Callback for merging hook ao2_containers.

Definition at line 3631 of file bridge.c.

3632{
3633 ao2_link(data, obj);
3634 return 0;
3635}

References ao2_link.

Referenced by ast_bridge_features_merge().

◆ optimize_lock_chan_stack()

static struct ast_bridge * optimize_lock_chan_stack ( struct ast_channel chan)
static

Definition at line 2648 of file bridge.c.

2649{
2650 struct ast_bridge *bridge;
2651 struct ast_bridge_channel *bridge_channel;
2652
2654 return NULL;
2655 }
2657 return NULL;
2658 }
2660 /* Channel has an active monitor, audiohook, or framehook. */
2661 return NULL;
2662 }
2663 bridge_channel = ast_channel_internal_bridge_channel(chan);
2664 if (!bridge_channel || ast_bridge_channel_trylock(bridge_channel)) {
2665 return NULL;
2666 }
2667 bridge = bridge_channel->bridge;
2668 if (bridge_channel->activity != BRIDGE_CHANNEL_THREAD_SIMPLE
2669 || bridge_channel->state != BRIDGE_CHANNEL_STATE_WAIT
2671 ast_bridge_channel_unlock(bridge_channel);
2672 return NULL;
2673 }
2674 if (!bridge_channel_internal_allows_optimization(bridge_channel) ||
2677 ast_bridge_channel_unlock(bridge_channel);
2678 return NULL;
2679 }
2680 return bridge;
2681}
#define ast_bridge_trylock(bridge)
Try locking the bridge.
Definition: bridge.h:463
#define ast_bridge_channel_trylock(bridge_channel)
Try locking the bridge_channel.
@ BRIDGE_CHANNEL_THREAD_SIMPLE
int bridge_channel_internal_allows_optimization(struct ast_bridge_channel *bridge_channel)
struct ast_readq_list * ast_channel_readq(struct ast_channel *chan)
@ AST_FLAG_EMULATE_DTMF
Definition: channel.h:1024
int ast_channel_has_audio_frame_or_monitor(struct ast_channel *chan)
Check if the channel has active audiohooks, active framehooks, or a monitor.
Definition: channel.c:2547
enum bridge_channel_thread_state activity
The bridge channel thread activity.

References ast_bridge_channel::activity, ast_bridge_channel_trylock, ast_bridge_channel_unlock, ast_bridge_trylock, ast_bridge_unlock, ast_channel_flags(), ast_channel_has_audio_frame_or_monitor(), ast_channel_internal_bridge_channel(), ast_channel_readq(), AST_FLAG_EMULATE_DTMF, AST_LIST_EMPTY, ast_test_flag, ast_bridge_channel::bridge, bridge_allows_optimization(), bridge_channel_internal_allows_optimization(), BRIDGE_CHANNEL_STATE_WAIT, BRIDGE_CHANNEL_THREAD_SIMPLE, ast_bridge_channel::chan, NULL, and ast_bridge_channel::state.

Referenced by ast_bridge_unreal_optimize_out().

◆ optimize_lock_peer_stack()

static struct ast_bridge * optimize_lock_peer_stack ( struct ast_channel peer)
static

Definition at line 2693 of file bridge.c.

2694{
2695 struct ast_bridge *bridge;
2696 struct ast_bridge_channel *bridge_channel;
2697
2698 if (ast_channel_trylock(peer)) {
2699 return NULL;
2700 }
2701 if (!AST_LIST_EMPTY(ast_channel_readq(peer))) {
2702 ast_channel_unlock(peer);
2703 return NULL;
2704 }
2706 ast_channel_unlock(peer);
2707 return NULL;
2708 }
2710 /* Peer has an active monitor, audiohook, or framehook. */
2711 ast_channel_unlock(peer);
2712 return NULL;
2713 }
2714 bridge_channel = ast_channel_internal_bridge_channel(peer);
2715 if (!bridge_channel || ast_bridge_channel_trylock(bridge_channel)) {
2716 ast_channel_unlock(peer);
2717 return NULL;
2718 }
2719 bridge = bridge_channel->bridge;
2720 if (bridge_channel->activity != BRIDGE_CHANNEL_THREAD_IDLE
2721 || bridge_channel->state != BRIDGE_CHANNEL_STATE_WAIT
2723 ast_bridge_channel_unlock(bridge_channel);
2724 ast_channel_unlock(peer);
2725 return NULL;
2726 }
2730 ast_bridge_channel_unlock(bridge_channel);
2731 ast_channel_unlock(peer);
2732 return NULL;
2733 }
2734 return bridge;
2735}
@ BRIDGE_CHANNEL_THREAD_IDLE
#define ast_channel_trylock(chan)
Definition: channel.h:2972

References ast_bridge_channel::activity, ast_bridge_channel_trylock, ast_bridge_channel_unlock, ast_bridge_trylock, ast_bridge_unlock, ast_channel_flags(), ast_channel_has_audio_frame_or_monitor(), ast_channel_internal_bridge_channel(), ast_channel_readq(), ast_channel_trylock, ast_channel_unlock, AST_FLAG_EMULATE_DTMF, AST_LIST_EMPTY, ast_test_flag, ast_bridge_channel::bridge, bridge_allows_optimization(), bridge_channel_internal_allows_optimization(), BRIDGE_CHANNEL_STATE_WAIT, BRIDGE_CHANNEL_THREAD_IDLE, NULL, and ast_bridge_channel::state.

Referenced by ast_bridge_unreal_optimize_out().

◆ set_bridge_peer_vars()

static void set_bridge_peer_vars ( struct ast_bridge bridge)
static

Definition at line 1455 of file bridge.c.

1456{
1459 return;
1460 }
1461 if (bridge->num_channels < 2) {
1462 return;
1463 }
1464 if (bridge->num_channels == 2) {
1466 AST_LIST_LAST(&bridge->channels)->chan);
1467 } else {
1469 }
1470}
static void set_bridge_peer_vars_2party(struct ast_channel *c0, struct ast_channel *c1)
Definition: bridge.c:1300
static void set_bridge_peer_vars_multiparty(struct ast_bridge *bridge)
Definition: bridge.c:1375
static void set_bridge_peer_vars_holding(struct ast_bridge *bridge)
Definition: bridge.c:1435
@ AST_BRIDGE_CAPABILITY_HOLDING
Definition: bridge.h:90
#define AST_LIST_LAST(head)
Returns the last entry contained in a list.
Definition: linkedlists.h:429

References AST_BRIDGE_CAPABILITY_HOLDING, AST_LIST_FIRST, AST_LIST_LAST, ast_bridge_channel::bridge, ast_bridge_technology::capabilities, ast_bridge::channels, ast_bridge::num_channels, set_bridge_peer_vars_2party(), set_bridge_peer_vars_holding(), set_bridge_peer_vars_multiparty(), and ast_bridge::technology.

Referenced by bridge_reconfigured().

◆ set_bridge_peer_vars_2party()

static void set_bridge_peer_vars_2party ( struct ast_channel c0,
struct ast_channel c1 
)
static

Definition at line 1300 of file bridge.c.

1301{
1302 const char *c0_name;
1303 const char *c1_name;
1304 const char *c0_pvtid = NULL;
1305 const char *c1_pvtid = NULL;
1306#define UPDATE_BRIDGE_VARS_GET(chan, name, pvtid) \
1307 do { \
1308 name = ast_strdupa(ast_channel_name(chan)); \
1309 if (ast_channel_tech(chan)->get_pvt_uniqueid) { \
1310 pvtid = ast_strdupa(ast_channel_tech(chan)->get_pvt_uniqueid(chan)); \
1311 } \
1312 } while (0)
1313
1314 ast_channel_lock(c1);
1315 UPDATE_BRIDGE_VARS_GET(c1, c1_name, c1_pvtid);
1317
1318 ast_channel_lock(c0);
1319 ast_bridge_vars_set(c0, c1_name, c1_pvtid);
1320 UPDATE_BRIDGE_VARS_GET(c0, c0_name, c0_pvtid);
1322
1323 ast_channel_lock(c1);
1324 ast_bridge_vars_set(c1, c0_name, c0_pvtid);
1326}
#define UPDATE_BRIDGE_VARS_GET(chan, name, pvtid)
void ast_bridge_vars_set(struct ast_channel *chan, const char *name, const char *pvtid)
Sets BRIDGECHANNEL and BRIDGEPVTCALLID for a channel.
Definition: bridge.c:1281

References ast_bridge_vars_set(), ast_channel_lock, ast_channel_unlock, NULL, and UPDATE_BRIDGE_VARS_GET.

Referenced by set_bridge_peer_vars().

◆ set_bridge_peer_vars_holding()

static void set_bridge_peer_vars_holding ( struct ast_bridge bridge)
static

Definition at line 1435 of file bridge.c.

1436{
1437 struct ast_bridge_channel *bridge_channel;
1438
1439 AST_LIST_TRAVERSE(&bridge->channels, bridge_channel, entry) {
1440 ast_channel_lock(bridge_channel->chan);
1441 ast_bridge_vars_set(bridge_channel->chan, NULL, NULL);
1442 ast_channel_unlock(bridge_channel->chan);
1443 }
1444}

References ast_bridge_vars_set(), ast_channel_lock, ast_channel_unlock, AST_LIST_TRAVERSE, ast_bridge_channel::bridge, ast_bridge_channel::chan, ast_bridge::channels, ast_bridge_channel::entry, and NULL.

Referenced by set_bridge_peer_vars().

◆ set_bridge_peer_vars_multiparty()

static void set_bridge_peer_vars_multiparty ( struct ast_bridge bridge)
static

Definition at line 1375 of file bridge.c.

1376{
1377/*
1378 * Set a maximum number of channel names for the BRIDGEPEER
1379 * list. The plus one is for the current channel which is not
1380 * put in the list.
1381 */
1382#define MAX_BRIDGEPEER_CHANS (10 + 1)
1383
1384 unsigned int idx;
1385 unsigned int num_names;
1386 unsigned int len;
1387 const char **names;
1388 char *buf;
1389 struct ast_bridge_channel *bridge_channel;
1390
1391 /* Get first MAX_BRIDGEPEER_CHANS channel names. */
1393 names = ast_alloca(num_names * sizeof(*names));
1394 idx = 0;
1395 AST_LIST_TRAVERSE(&bridge->channels, bridge_channel, entry) {
1396 if (num_names <= idx) {
1397 break;
1398 }
1399 ast_channel_lock(bridge_channel->chan);
1400 names[idx++] = ast_strdupa(ast_channel_name(bridge_channel->chan));
1401 ast_channel_unlock(bridge_channel->chan);
1402 }
1403
1404 /* Determine maximum buf size needed. */
1405 len = num_names;
1406 for (idx = 0; idx < num_names; ++idx) {
1407 len += strlen(names[idx]);
1408 }
1409 buf = ast_alloca(len);
1410
1411 /* Set the bridge channel variables. */
1412 idx = 0;
1413 buf[0] = '\0';
1414 AST_LIST_TRAVERSE(&bridge->channels, bridge_channel, entry) {
1415 if (idx < num_names) {
1416 fill_bridgepeer_buf(buf, idx, names, num_names);
1417 }
1418 ++idx;
1419
1420 ast_channel_lock(bridge_channel->chan);
1421 ast_bridge_vars_set(bridge_channel->chan, buf, NULL);
1422 ast_channel_unlock(bridge_channel->chan);
1423 }
1424}
static void fill_bridgepeer_buf(char *buf, unsigned int cur_idx, const char *names[], unsigned int num_names)
Definition: bridge.c:1338
#define MAX_BRIDGEPEER_CHANS
static int len(struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t buflen)
#define MIN(a, b)
Definition: utils.h:231

References ast_alloca, ast_bridge_vars_set(), ast_channel_lock, ast_channel_name(), ast_channel_unlock, AST_LIST_TRAVERSE, ast_strdupa, ast_bridge_channel::bridge, buf, ast_bridge_channel::chan, ast_bridge::channels, ast_bridge_channel::entry, fill_bridgepeer_buf(), len(), MAX_BRIDGEPEER_CHANS, MIN, NULL, and ast_bridge::num_channels.

Referenced by set_bridge_peer_vars().

◆ set_transfer_variables_all()

static void set_transfer_variables_all ( struct ast_channel transferer,
struct ao2_container channels,
int  is_attended 
)
static

Definition at line 4452 of file bridge.c.

4453{
4454 struct ao2_iterator iter;
4455 struct ast_channel *chan;
4456 const char *transferer_name;
4457 const char *transferer_bridgepeer;
4458
4459 ast_channel_lock(transferer);
4460 transferer_name = ast_strdupa(ast_channel_name(transferer));
4461 transferer_bridgepeer = ast_strdupa(S_OR(pbx_builtin_getvar_helper(transferer, "BRIDGEPEER"), ""));
4462 ast_channel_unlock(transferer);
4463
4464 for (iter = ao2_iterator_init(channels, 0);
4465 (chan = ao2_iterator_next(&iter));
4466 ao2_cleanup(chan)) {
4467 if (chan == transferer) {
4468 ast_bridge_set_transfer_variables(chan, transferer_bridgepeer, is_attended);
4469 } else {
4470 ast_bridge_set_transfer_variables(chan, transferer_name, is_attended);
4471 }
4472 }
4473
4474 ao2_iterator_destroy(&iter);
4475}
void ast_bridge_set_transfer_variables(struct ast_channel *chan, const char *value, int attended)
Set the relevant transfer variables for a single channel.
Definition: bridge.c:4421

References ao2_cleanup, ao2_iterator_destroy(), ao2_iterator_init(), ao2_iterator_next, ast_bridge_set_transfer_variables(), ast_channel_lock, ast_channel_name(), ast_channel_unlock, ast_strdupa, channels, pbx_builtin_getvar_helper(), and S_OR.

Referenced by ast_bridge_transfer_attended(), ast_bridge_transfer_blind(), and two_bridge_attended_transfer().

◆ smart_bridge_operation()

static int smart_bridge_operation ( struct ast_bridge bridge)
static

Definition at line 1041 of file bridge.c.

1042{
1043 uint32_t new_capabilities;
1044 struct ast_bridge_technology *new_technology;
1045 struct ast_bridge_technology *old_technology = bridge->technology;
1046 struct ast_bridge_channel *bridge_channel;
1047 struct ast_frame *deferred_action;
1048 struct ast_bridge dummy_bridge = {
1049 .technology = bridge->technology,
1050 .tech_pvt = bridge->tech_pvt,
1051 .creator = bridge->creator,
1052 .name = bridge->name,
1053 .uniqueid = bridge->uniqueid,
1054 };
1055
1056 if (bridge->dissolved) {
1057 ast_debug(1, "Bridge %s is dissolved, not performing smart bridge operation.\n",
1058 bridge->uniqueid);
1059 return 0;
1060 }
1061
1062 /* Determine new bridge technology capabilities needed. */
1063 if (2 < bridge->num_channels) {
1064 new_capabilities = AST_BRIDGE_CAPABILITY_MULTIMIX;
1065 new_capabilities &= bridge->allowed_capabilities;
1066 } else {
1068 new_capabilities &= bridge->allowed_capabilities;
1069 if (!new_capabilities
1071 /* Allow switching between different multimix bridge technologies. */
1072 new_capabilities = AST_BRIDGE_CAPABILITY_MULTIMIX;
1073 }
1074 }
1075
1076 /* Find a bridge technology to satisfy the new capabilities. */
1077 new_technology = find_best_technology(new_capabilities, bridge);
1078 if (!new_technology) {
1079 int is_compatible = 0;
1080
1081 if (old_technology->compatible) {
1082 is_compatible = old_technology->compatible(bridge);
1083 } else if (old_technology->capabilities & AST_BRIDGE_CAPABILITY_MULTIMIX) {
1084 is_compatible = 1;
1085 } else if (bridge->num_channels <= 2
1086 && (old_technology->capabilities & AST_BRIDGE_CAPABILITY_1TO1MIX)) {
1087 is_compatible = 1;
1088 }
1089
1090 if (is_compatible) {
1091 ast_debug(1, "Bridge %s could not get a new technology, staying with old technology.\n",
1092 bridge->uniqueid);
1093 return 0;
1094 }
1095 ast_log(LOG_WARNING, "Bridge %s has no technology available to support it.\n",
1096 bridge->uniqueid);
1097 return -1;
1098 }
1099 if (new_technology == old_technology) {
1100 ast_debug(1, "Bridge %s is already using the new technology.\n",
1101 bridge->uniqueid);
1102 ast_module_unref(old_technology->mod);
1103 return 0;
1104 }
1105
1106 if (old_technology->destroy) {
1107 struct tech_deferred_destroy deferred_tech_destroy = {
1108 .tech = dummy_bridge.technology,
1109 .tech_pvt = dummy_bridge.tech_pvt,
1110 };
1111 struct ast_frame action = {
1114 .data.ptr = &deferred_tech_destroy,
1115 .datalen = sizeof(deferred_tech_destroy),
1116 };
1117
1118 /*
1119 * We need to defer the bridge technology destroy callback
1120 * because we have the bridge locked.
1121 */
1122 deferred_action = ast_frdup(&action);
1123 if (!deferred_action) {
1124 ast_module_unref(new_technology->mod);
1125 return -1;
1126 }
1127 } else {
1129 }
1130
1131 /*
1132 * We are now committed to changing the bridge technology. We
1133 * must not release the bridge lock until we have installed the
1134 * new bridge technology.
1135 */
1136 ast_verb(4, "Bridge %s: switching from %s technology to %s\n",
1137 bridge->uniqueid, old_technology->name, new_technology->name);
1138
1139 /*
1140 * Since we are soon going to pass this bridge to a new
1141 * technology we need to NULL out the tech_pvt pointer but
1142 * don't worry as it still exists in dummy_bridge, ditto for the
1143 * old technology.
1144 */
1145 bridge->tech_pvt = NULL;
1146 bridge->technology = new_technology;
1147
1148 /* Setup the new bridge technology. */
1149 ast_debug(1, "Bridge %s: calling %s technology constructor\n",
1150 bridge->uniqueid, new_technology->name);
1151 if (new_technology->create && new_technology->create(bridge)) {
1152 ast_log(LOG_WARNING, "Bridge %s: failed to setup bridge technology %s\n",
1153 bridge->uniqueid, new_technology->name);
1154 bridge->tech_pvt = dummy_bridge.tech_pvt;
1155 bridge->technology = dummy_bridge.technology;
1156 ast_module_unref(new_technology->mod);
1157 return -1;
1158 }
1159
1160 /* To ensure that things are sane for the old technology move the channels it
1161 * expects to the dummy bridge
1162 */
1163 AST_LIST_TRAVERSE_SAFE_BEGIN(&bridge->channels, bridge_channel, entry) {
1164 if (bridge_channel->just_joined) {
1165 continue;
1166 }
1167 ast_debug(1, "Bridge %s: moving %p(%s) to dummy bridge temporarily\n",
1168 bridge->uniqueid, bridge_channel, ast_channel_name(bridge_channel->chan));
1170 AST_LIST_INSERT_TAIL(&dummy_bridge.channels, bridge_channel, entry);
1171 dummy_bridge.num_channels++;
1173 dummy_bridge.num_lonely++;
1174 }
1175 if (!bridge_channel->suspended) {
1176 dummy_bridge.num_active++;
1177 }
1178 }
1180
1181 /* Take all the channels out of the old technology */
1182 AST_LIST_TRAVERSE_SAFE_BEGIN(&dummy_bridge.channels, bridge_channel, entry) {
1183 ast_debug(1, "Bridge %s: %p(%s) is leaving %s technology (dummy)\n",
1184 dummy_bridge.uniqueid, bridge_channel, ast_channel_name(bridge_channel->chan),
1185 old_technology->name);
1186 if (old_technology->leave) {
1187 old_technology->leave(&dummy_bridge, bridge_channel);
1188 }
1190 AST_LIST_INSERT_TAIL(&bridge->channels, bridge_channel, entry);
1191 dummy_bridge.num_channels--;
1193 dummy_bridge.num_lonely--;
1194 }
1195 if (!bridge_channel->suspended) {
1196 dummy_bridge.num_active--;
1197 }
1198 }
1200
1201 ast_debug(1, "Bridge %s: calling %s technology stop\n",
1202 dummy_bridge.uniqueid, old_technology->name);
1203 if (old_technology->stop) {
1204 old_technology->stop(&dummy_bridge);
1205 }
1206
1207 /* Add any new channels or re-add existing channels to the bridge. */
1208 AST_LIST_TRAVERSE(&bridge->channels, bridge_channel, entry) {
1209 bridge_channel_complete_join(bridge, bridge_channel);
1210 }
1211
1212 ast_debug(1, "Bridge %s: calling %s technology start\n",
1213 bridge->uniqueid, new_technology->name);
1214 if (new_technology->start && new_technology->start(bridge)) {
1215 ast_log(LOG_WARNING, "Bridge %s: failed to start bridge technology %s\n",
1216 bridge->uniqueid, new_technology->name);
1217 }
1218
1219 /*
1220 * Now that all the channels have been moved over we need to get
1221 * rid of all the information the old technology may have left
1222 * around.
1223 */
1224 if (old_technology->destroy) {
1225 ast_debug(1, "Bridge %s: deferring %s technology destructor\n",
1226 dummy_bridge.uniqueid, old_technology->name);
1228 } else {
1229 ast_debug(1, "Bridge %s: calling %s technology destructor\n",
1230 dummy_bridge.uniqueid, old_technology->name);
1231 ast_module_unref(old_technology->mod);
1232 }
1233
1234 return 0;
1235}
@ AST_BRIDGE_CHANNEL_FLAG_LONELY
static void deferred_action(struct ast_bridge_channel *bridge_channel, const void *payload, size_t payload_size)
#define AST_LIST_REMOVE_CURRENT(field)
Removes the current entry from a list during a traversal.
Definition: linkedlists.h:557
unsigned int suspended
int(* compatible)(struct ast_bridge *bridge)
Check if a bridge is compatible with the bridging technology.
void(* leave)(struct ast_bridge *bridge, struct ast_bridge_channel *bridge_channel)
Remove a channel from a bridging technology instance for a bridge.
void * tech_pvt
Definition: bridge.h:361
unsigned int num_active
Definition: bridge.h:379
unsigned int num_lonely
Definition: bridge.h:381

References ast_bridge::allowed_capabilities, AST_BRIDGE_CAPABILITY_1TO1MIX, AST_BRIDGE_CAPABILITY_MULTIMIX, AST_BRIDGE_CAPABILITY_NATIVE, AST_BRIDGE_CHANNEL_FLAG_LONELY, ast_channel_name(), ast_debug, AST_FRAME_BRIDGE_ACTION, ast_frdup, AST_LIST_INSERT_TAIL, AST_LIST_REMOVE_CURRENT, AST_LIST_TRAVERSE, AST_LIST_TRAVERSE_SAFE_BEGIN, AST_LIST_TRAVERSE_SAFE_END, ast_log, ast_module_unref, ast_test_flag, ast_verb, BRIDGE_CHANNEL_ACTION_DEFERRED_TECH_DESTROY, bridge_channel_complete_join(), bridge_queue_action_nodup(), ast_bridge_technology::capabilities, ast_bridge_channel::chan, ast_bridge::channels, ast_bridge_technology::compatible, ast_bridge_technology::create, ast_bridge::creator, deferred_action(), ast_bridge_technology::destroy, ast_bridge::dissolved, ast_bridge_features::feature_flags, ast_bridge_channel::features, find_best_technology(), ast_frame::frametype, ast_bridge_channel::just_joined, ast_bridge_technology::leave, LOG_WARNING, ast_bridge_technology::mod, ast_bridge::name, ast_bridge_technology::name, NULL, ast_bridge::num_active, ast_bridge::num_channels, ast_bridge::num_lonely, ast_bridge_technology::start, ast_bridge_technology::stop, ast_bridge_channel::suspended, tech_deferred_destroy::tech, ast_bridge::tech_pvt, ast_bridge::technology, and ast_bridge::uniqueid.

Referenced by bridge_reconfigured().

◆ tech_capability2str()

static const char * tech_capability2str ( uint32_t  capabilities)
static

Bridge technology capabilities to string.

Definition at line 5347 of file bridge.c.

5348{
5349 const char *type;
5350
5351 if (capabilities & AST_BRIDGE_CAPABILITY_HOLDING) {
5352 type = "Holding";
5353 } else if (capabilities & AST_BRIDGE_CAPABILITY_EARLY) {
5354 type = "Early";
5355 } else if (capabilities & AST_BRIDGE_CAPABILITY_NATIVE) {
5356 type = "Native";
5357 } else if (capabilities & AST_BRIDGE_CAPABILITY_1TO1MIX) {
5358 type = "1to1Mix";
5359 } else if (capabilities & AST_BRIDGE_CAPABILITY_MULTIMIX) {
5360 type = "MultiMix";
5361 } else {
5362 type = "<Unknown>";
5363 }
5364 return type;
5365}
@ AST_BRIDGE_CAPABILITY_EARLY
Definition: bridge.h:92

References AST_BRIDGE_CAPABILITY_1TO1MIX, AST_BRIDGE_CAPABILITY_EARLY, AST_BRIDGE_CAPABILITY_HOLDING, AST_BRIDGE_CAPABILITY_MULTIMIX, AST_BRIDGE_CAPABILITY_NATIVE, and type.

Referenced by handle_bridge_technology_show(), and manager_bridge_tech_list().

◆ try_merge_optimize_out()

static int try_merge_optimize_out ( struct ast_bridge chan_bridge,
struct ast_bridge_channel chan_bridge_channel,
struct ast_bridge peer_bridge,
struct ast_bridge_channel peer_bridge_channel,
struct ast_unreal_pvt pvt 
)
static

Definition at line 2938 of file bridge.c.

2942{
2943 struct merge_direction merge;
2944 struct ast_bridge_channel *kick_me[] = {
2945 chan_bridge_channel,
2946 peer_bridge_channel,
2947 };
2948 unsigned int id;
2949
2950 switch (bridges_allow_merge_optimization(chan_bridge, peer_bridge, ARRAY_LEN(kick_me), &merge)) {
2951 case MERGE_ALLOWED:
2952 break;
2953 case MERGE_PROHIBITED:
2954 return 0;
2956 ast_debug(4, "Can't optimize %s -- %s out, not enough channels in bridge %s.\n",
2957 ast_channel_name(chan_bridge_channel->chan),
2958 ast_channel_name(peer_bridge_channel->chan),
2959 merge.src->uniqueid);
2960 return 0;
2961 case MERGE_NO_MULTIMIX:
2962 ast_debug(4, "Can't optimize %s -- %s out, multimix is needed and it cannot be acquired.\n",
2963 ast_channel_name(chan_bridge_channel->chan),
2964 ast_channel_name(peer_bridge_channel->chan));
2965 return 0;
2966 }
2967
2968 ast_verb(4, "Merge optimizing %s -- %s out.\n",
2969 ast_channel_name(chan_bridge_channel->chan),
2970 ast_channel_name(peer_bridge_channel->chan));
2971
2972 id = ast_atomic_fetchadd_int((int *) &optimization_id, +1);
2973
2974 if (pvt && !ast_test_flag(pvt, AST_UNREAL_OPTIMIZE_BEGUN) && pvt->callbacks
2978 id);
2980 }
2981 bridge_do_merge(merge.dest, merge.src, kick_me, ARRAY_LEN(kick_me), 1);
2982 if (pvt && pvt->callbacks && pvt->callbacks->optimization_finished) {
2983 pvt->callbacks->optimization_finished(pvt, 1, id);
2984 }
2985
2986 return -1;
2987}
enum queue_result id
Definition: app_queue.c:1808
static unsigned int optimization_id
Definition: bridge.c:138
struct ast_bridge * ast_channel_internal_bridge(const struct ast_channel *chan)
@ AST_UNREAL_CHAN
Definition: core_unreal.h:51
@ AST_UNREAL_OWNER
Definition: core_unreal.h:50
#define AST_UNREAL_OPTIMIZE_BEGUN
Definition: core_unreal.h:110
void(*const optimization_started)(struct ast_unreal_pvt *p, struct ast_channel *source, enum ast_unreal_channel_indicator dest, unsigned int id)
Called when an optimization attempt has started.
Definition: core_unreal.h:69
void(*const optimization_finished)(struct ast_unreal_pvt *p, int success, unsigned int id)
Called when an optimization attempt completed successfully.
Definition: core_unreal.h:81
struct ast_unreal_pvt_callbacks * callbacks
Definition: core_unreal.h:92
struct ast_channel * owner
Definition: core_unreal.h:93

References ARRAY_LEN, ast_atomic_fetchadd_int(), ast_channel_internal_bridge(), ast_channel_name(), ast_debug, ast_set_flag, ast_test_flag, AST_UNREAL_CHAN, AST_UNREAL_OPTIMIZE_BEGUN, AST_UNREAL_OWNER, ast_verb, bridge_do_merge(), bridges_allow_merge_optimization(), ast_unreal_pvt::callbacks, ast_bridge_channel::chan, merge_direction::dest, id, MERGE_ALLOWED, MERGE_NO_MULTIMIX, MERGE_NOT_ENOUGH_CHANNELS, MERGE_PROHIBITED, NULL, ast_unreal_pvt_callbacks::optimization_finished, optimization_id, ast_unreal_pvt_callbacks::optimization_started, ast_unreal_pvt::owner, merge_direction::src, and ast_bridge::uniqueid.

Referenced by ast_bridge_unreal_optimize_out().

◆ try_parking()

static enum ast_transfer_result try_parking ( struct ast_channel transferer,
const char *  context,
const char *  exten,
transfer_channel_cb  new_channel_cb,
struct transfer_channel_data user_data_wrapper 
)
static

Definition at line 4395 of file bridge.c.

4398{
4399 RAII_VAR(struct ast_bridge_channel *, transferer_bridge_channel, NULL, ao2_cleanup);
4400
4403 }
4404
4405 ast_channel_lock(transferer);
4406 transferer_bridge_channel = ast_channel_get_bridge_channel(transferer);
4407 ast_channel_unlock(transferer);
4408
4409 if (!transferer_bridge_channel) {
4411 }
4412
4413 if (ast_parking_blind_transfer_park(transferer_bridge_channel,
4414 context, exten, new_channel_cb, user_data_wrapper)) {
4416 }
4417
4419}
int ast_parking_blind_transfer_park(struct ast_bridge_channel *parker, const char *context, const char *exten, transfer_channel_cb parked_channel_cb, struct transfer_channel_data *parked_channel_data)
Perform a blind transfer to a parking extension.
Definition: parking.c:143
int ast_parking_provider_registered(void)
Check whether a parking provider is registered.
Definition: parking.c:241

References ao2_cleanup, AST_BRIDGE_TRANSFER_FAIL, AST_BRIDGE_TRANSFER_SUCCESS, ast_channel_get_bridge_channel(), ast_channel_lock, ast_channel_unlock, ast_parking_blind_transfer_park(), ast_parking_provider_registered(), voicemailpwcheck::context, ast_channel::exten, NULL, and RAII_VAR.

Referenced by ast_bridge_transfer_blind().

◆ try_swap_optimize_out()

static int try_swap_optimize_out ( struct ast_bridge chan_bridge,
struct ast_bridge_channel chan_bridge_channel,
struct ast_bridge peer_bridge,
struct ast_bridge_channel peer_bridge_channel,
struct ast_unreal_pvt pvt 
)
static

Definition at line 2814 of file bridge.c.

2818{
2819 struct ast_bridge *dst_bridge;
2820 struct ast_bridge_channel *dst_bridge_channel;
2821 struct ast_bridge_channel *src_bridge_channel;
2822 struct ast_bridge_channel *other;
2823 int res = 1;
2824
2825 switch (bridges_allow_swap_optimization(chan_bridge, peer_bridge)) {
2827 dst_bridge = chan_bridge;
2828 dst_bridge_channel = chan_bridge_channel;
2829 src_bridge_channel = peer_bridge_channel;
2830 break;
2832 dst_bridge = peer_bridge;
2833 dst_bridge_channel = peer_bridge_channel;
2834 src_bridge_channel = chan_bridge_channel;
2835 break;
2836 case SWAP_PROHIBITED:
2837 default:
2838 return 0;
2839 }
2840
2841 other = ast_bridge_channel_peer(src_bridge_channel);
2842 if (other && other->state == BRIDGE_CHANNEL_STATE_WAIT) {
2843 unsigned int id;
2844
2845 if (ast_channel_trylock(other->chan)) {
2846 return 1;
2847 }
2848
2849 id = ast_atomic_fetchadd_int((int *) &optimization_id, +1);
2850
2851 ast_verb(4, "Move-swap optimizing %s <-- %s.\n",
2852 ast_channel_name(dst_bridge_channel->chan),
2853 ast_channel_name(other->chan));
2854
2855 if (pvt && !ast_test_flag(pvt, AST_UNREAL_OPTIMIZE_BEGUN) && pvt->callbacks
2857 pvt->callbacks->optimization_started(pvt, other->chan,
2858 dst_bridge_channel->chan == pvt->owner ? AST_UNREAL_OWNER : AST_UNREAL_CHAN,
2859 id);
2861 }
2862 other->swap = dst_bridge_channel->chan;
2863 if (!bridge_do_move(dst_bridge, other, 1, 1)) {
2864 ast_bridge_channel_leave_bridge(src_bridge_channel,
2866 res = -1;
2867 }
2868 if (pvt && pvt->callbacks && pvt->callbacks->optimization_finished) {
2869 pvt->callbacks->optimization_finished(pvt, res == 1, id);
2870 }
2871 ast_channel_unlock(other->chan);
2872 }
2873 return res;
2874}

References ast_atomic_fetchadd_int(), ast_bridge_channel_leave_bridge(), ast_bridge_channel_peer(), AST_CAUSE_NORMAL_CLEARING, ast_channel_name(), ast_channel_trylock, ast_channel_unlock, ast_set_flag, ast_test_flag, AST_UNREAL_CHAN, AST_UNREAL_OPTIMIZE_BEGUN, AST_UNREAL_OWNER, ast_verb, BRIDGE_CHANNEL_STATE_END_NO_DISSOLVE, BRIDGE_CHANNEL_STATE_WAIT, bridge_do_move(), bridges_allow_swap_optimization(), ast_unreal_pvt::callbacks, ast_bridge_channel::chan, id, ast_unreal_pvt_callbacks::optimization_finished, optimization_id, ast_unreal_pvt_callbacks::optimization_started, ast_unreal_pvt::owner, ast_bridge_channel::state, ast_bridge_channel::swap, SWAP_PROHIBITED, SWAP_TO_CHAN_BRIDGE, and SWAP_TO_PEER_BRIDGE.

Referenced by ast_bridge_unreal_optimize_out().

◆ two_bridge_attended_transfer()

static enum ast_transfer_result two_bridge_attended_transfer ( struct ast_channel to_transferee,
struct ast_bridge_channel to_transferee_bridge_channel,
struct ast_channel to_transfer_target,
struct ast_bridge_channel to_target_bridge_channel,
struct ast_bridge to_transferee_bridge,
struct ast_bridge to_target_bridge,
struct ast_attended_transfer_message transfer_msg 
)
static

Definition at line 4680 of file bridge.c.

4686{
4687 struct ast_bridge_channel *kick_me[] = {
4688 to_transferee_bridge_channel,
4689 to_target_bridge_channel,
4690 };
4691 enum ast_transfer_result res;
4692 struct ast_bridge *final_bridge = NULL;
4694
4695 channels = ast_bridge_peers_nolock(to_transferee_bridge);
4696
4697 if (!channels) {
4699 goto end;
4700 }
4701
4702 set_transfer_variables_all(to_transferee, channels, 1);
4703
4704 switch (ast_bridges_allow_optimization(to_transferee_bridge, to_target_bridge)) {
4706 final_bridge = to_transferee_bridge;
4707 res = bridge_swap_attended_transfer(to_transferee_bridge, to_target_bridge_channel, to_transferee);
4708 goto end;
4710 final_bridge = to_target_bridge;
4711 res = bridge_swap_attended_transfer(to_target_bridge, to_transferee_bridge_channel, to_transfer_target);
4712 goto end;
4714 final_bridge = to_transferee_bridge;
4715 bridge_do_merge(to_transferee_bridge, to_target_bridge, kick_me, ARRAY_LEN(kick_me), 0);
4717 goto end;
4719 final_bridge = to_target_bridge;
4720 bridge_do_merge(to_target_bridge, to_transferee_bridge, kick_me, ARRAY_LEN(kick_me), 0);
4722 goto end;
4724 default:
4725 /* Just because optimization wasn't doable doesn't necessarily mean
4726 * that we can actually perform the transfer. Some reasons for non-optimization
4727 * indicate bridge invalidity, so let's check those before proceeding.
4728 */
4729 if (to_transferee_bridge->inhibit_merge || to_transferee_bridge->dissolved ||
4730 to_target_bridge->inhibit_merge || to_target_bridge->dissolved) {
4732 }
4733
4734 return attended_transfer_bridge(to_transferee, to_transfer_target,
4735 to_transferee_bridge, to_target_bridge, transfer_msg);
4736 }
4737
4738end:
4739 if (res == AST_BRIDGE_TRANSFER_SUCCESS) {
4740 ast_attended_transfer_message_add_merge(transfer_msg, final_bridge);
4741 }
4742
4743 return res;
4744}
static enum ast_transfer_result bridge_swap_attended_transfer(struct ast_bridge *dest_bridge, struct ast_bridge_channel *source_bridge_channel, struct ast_channel *swap_channel)
Definition: bridge.c:4637
enum ast_bridge_optimization ast_bridges_allow_optimization(struct ast_bridge *chan_bridge, struct ast_bridge *peer_bridge)
Determine if bridges allow for optimization to occur betweem them.
Definition: bridge.c:3029
int ast_attended_transfer_message_add_merge(struct ast_attended_transfer_message *transfer_msg, struct ast_bridge *final_bridge)
Add details for a bridge merge to an attended transfer message.

References ao2_cleanup, ARRAY_LEN, ast_attended_transfer_message_add_merge(), AST_BRIDGE_OPTIMIZE_MERGE_TO_CHAN_BRIDGE, AST_BRIDGE_OPTIMIZE_MERGE_TO_PEER_BRIDGE, AST_BRIDGE_OPTIMIZE_PROHIBITED, AST_BRIDGE_OPTIMIZE_SWAP_TO_CHAN_BRIDGE, AST_BRIDGE_OPTIMIZE_SWAP_TO_PEER_BRIDGE, ast_bridge_peers_nolock(), AST_BRIDGE_TRANSFER_FAIL, AST_BRIDGE_TRANSFER_INVALID, AST_BRIDGE_TRANSFER_SUCCESS, ast_bridges_allow_optimization(), attended_transfer_bridge(), bridge_do_merge(), bridge_swap_attended_transfer(), channels, ast_bridge::dissolved, end, ast_bridge::inhibit_merge, NULL, RAII_VAR, and set_transfer_variables_all().

Referenced by ast_bridge_transfer_attended().

◆ wrap_hook()

static void wrap_hook ( struct ast_bridge_features features,
struct ast_bridge_hook_timer hook 
)
static

Wrap the provided interval hook and add it to features.

Definition at line 3652 of file bridge.c.

3653{
3654 /* Break out of the current wrapper if it exists to avoid multiple layers */
3655 if (hook->generic.callback == interval_wrapper_cb) {
3656 hook = hook->generic.hook_pvt;
3657 }
3658
3659 ast_bridge_interval_hook(features, hook->timer.flags, hook->timer.interval,
3661 hook->generic.remove_flags.flags);
3662}
int ast_bridge_interval_hook(struct ast_bridge_features *features, enum ast_bridge_hook_timer_option flags, unsigned int interval, ast_bridge_hook_callback callback, void *hook_pvt, ast_bridge_hook_pvt_destructor destructor, enum ast_bridge_hook_remove_flags remove_flags)
Attach an interval hook to a bridge features structure.
Definition: bridge.c:3388
static int interval_wrapper_cb(struct ast_bridge_channel *bridge_channel, void *obj)
Wrapper for interval hooks that calls into the wrapped hook.
Definition: bridge.c:3638
static void interval_wrapper_pvt_dtor(void *obj)
Destructor for the hook wrapper.
Definition: bridge.c:3646

References ao2_bump, ast_bridge_interval_hook(), ast_bridge_hook::callback, ast_bridge_hook_timer_parms::flags, ast_flags::flags, ast_bridge_hook_timer::generic, ast_bridge_hook::hook_pvt, ast_bridge_hook_timer_parms::interval, interval_wrapper_cb(), interval_wrapper_pvt_dtor(), ast_bridge_hook::remove_flags, and ast_bridge_hook_timer::timer.

Referenced by ast_bridge_features_merge().

Variable Documentation

◆ ast_bridge_base_v_table

struct ast_bridge_methods ast_bridge_base_v_table

◆ bridge_channel_impart_ds_info

const struct ast_datastore_info bridge_channel_impart_ds_info
static
Initial value:
= {
.type = "bridge-impart-ds",
}
static void bridge_channel_impart_ds_head_fixup(void *data, struct ast_channel *old_chan, struct ast_channel *new_chan)
Definition: bridge.c:1592
static void bridge_channel_impart_ds_head_dtor(void *doomed)
Definition: bridge.c:1577

Definition at line 1601 of file bridge.c.

Referenced by bridge_channel_impart_add(), and bridge_channel_impart_signal().

◆ bridge_cli

struct ast_cli_entry bridge_cli[]
static

Definition at line 5474 of file bridge.c.

Referenced by ast_bridging_init(), and bridge_cleanup().

◆ bridge_init_lock

ast_mutex_t bridge_init_lock = { PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP , NULL, {1, 0} }
static

Definition at line 136 of file bridge.c.

Referenced by bridge_base_init(), and bridge_register().

◆ bridge_manager

struct bridge_manager_controller* bridge_manager
static

Bridge manager controller.

Definition at line 183 of file bridge.c.

Referenced by ast_bridging_init(), bridge_cleanup(), and bridge_manager_service_req().

◆ bridge_technologies

struct bridge_technologies bridge_technologies = { .first = NULL, .last = NULL, .lock = { PTHREAD_RWLOCK_INITIALIZER , NULL, {1, 0} } , }
static

◆ bridges

struct ao2_container* bridges
static

◆ builtin_features_dtmf

char builtin_features_dtmf[AST_BRIDGE_BUILTIN_END][MAXIMUM_DTMF_FEATURE_STRING]
static

Default DTMF keys for built in features

Definition at line 155 of file bridge.c.

Referenced by ast_bridge_features_enable(), and ast_bridge_features_register().

◆ builtin_features_handlers

ast_bridge_hook_callback builtin_features_handlers[AST_BRIDGE_BUILTIN_END]
static

Function handlers for the built in features

Definition at line 158 of file bridge.c.

Referenced by ast_bridge_features_do(), ast_bridge_features_enable(), ast_bridge_features_register(), and ast_bridge_features_unregister().

◆ builtin_interval_handlers

Function handlers for built in interval features

Definition at line 161 of file bridge.c.

Referenced by ast_bridge_features_set_limits(), ast_bridge_interval_register(), and ast_bridge_interval_unregister().

◆ optimization_id

unsigned int optimization_id
static

Definition at line 138 of file bridge.c.

Referenced by try_merge_optimize_out(), and try_swap_optimize_out().