Asterisk - The Open Source Telephony Project GIT-master-7e7a603
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 %5s %-15s %-15s %s\n"
 
#define FORMAT_HDR   "%-20s %-20s %8s %s\n"
 
#define FORMAT_ROW   "%-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 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 139 of file bridge.c.

◆ BLINDTRANSFER

#define BLINDTRANSFER   "BLINDTRANSFER"

Definition at line 136 of file bridge.c.

◆ BRIDGE_ARRAY_GROW

#define BRIDGE_ARRAY_GROW   32

Definition at line 133 of file bridge.c.

◆ BRIDGE_ARRAY_START

#define BRIDGE_ARRAY_START   128

Definition at line 130 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 %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 %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 2811 of file bridge.c.

2811 {
2812 /*! Bridge properties prohibit merge optimization */
2814 /*! Merge optimization cannot occur because the source bridge has too few channels */
2816 /*! Merge optimization cannot occur because multimix capability could not be requested */
2818 /*! Merge optimization allowed between bridges */
2820};
@ MERGE_ALLOWED
Definition: bridge.c:2819
@ MERGE_NOT_ENOUGH_CHANNELS
Definition: bridge.c:2815
@ MERGE_NO_MULTIMIX
Definition: bridge.c:2817
@ MERGE_PROHIBITED
Definition: bridge.c:2813

◆ 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 2672 of file bridge.c.

2672 {
2673 /*! Bridges cannot allow for a swap optimization to occur */
2675 /*! Bridge swap optimization can occur into the chan_bridge */
2677 /*! Bridge swap optimization can occur into the peer_bridge */
2679};
@ SWAP_PROHIBITED
Definition: bridge.c:2674
@ SWAP_TO_PEER_BRIDGE
Definition: bridge.c:2678
@ SWAP_TO_CHAN_BRIDGE
Definition: bridge.c:2676

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 212 of file bridge.c.

213{
215
216 /* Perform a sanity check to make sure the bridge technology conforms to our needed requirements */
217 if (ast_strlen_zero(technology->name)
218 || !technology->capabilities
219 || !technology->write) {
220 ast_log(LOG_WARNING, "Bridge technology %s failed registration sanity check.\n",
221 technology->name);
222 return -1;
223 }
224
226
227 /* Look for duplicate bridge technology already using this name, or already registered */
229 if ((!strcasecmp(current->name, technology->name)) || (current == technology)) {
230 ast_log(LOG_WARNING, "A bridge technology of %s already claims to exist in our world.\n",
231 technology->name);
233 return -1;
234 }
235 }
236
237 /* Copy module pointer so reference counting can keep the module from unloading */
238 technology->mod = module;
239
240 /* Find the correct position to insert the technology. */
242 /* Put the highest preference tech's first in the list. */
243 if (technology->preference >= current->preference) {
245
246 break;
247 }
248 }
250
251 if (!current) {
252 /* Insert our new bridge technology to the end of the list. */
254 }
255
257
258 ast_verb(5, "Registered bridge technology %s\n", technology->name);
259
260 return 0;
261}
#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
Definition: search.h:40

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 2471 of file bridge.c.

2473{
2474 RAII_VAR(struct ast_bridge *, chan_bridge, NULL, ao2_cleanup);
2475 RAII_VAR(struct ast_channel *, yanked_chan, NULL, ao2_cleanup);
2476
2477 ast_moh_stop(chan);
2478
2479 ast_channel_lock(chan);
2480 chan_bridge = ast_channel_get_bridge(chan);
2481 ast_channel_unlock(chan);
2482
2483 if (chan_bridge) {
2484 struct ast_bridge_channel *bridge_channel;
2485
2486 /* The channel is in a bridge so it is not getting any new features. */
2488
2489 ast_bridge_lock_both(bridge, chan_bridge);
2490 bridge_channel = bridge_find_channel(chan_bridge, chan);
2491
2492 if (bridge_move_locked(bridge, chan_bridge, chan, NULL, 1)) {
2493 ast_bridge_unlock(chan_bridge);
2495 return -1;
2496 }
2497
2498 /*
2499 * bridge_move_locked() will implicitly ensure that
2500 * bridge_channel is not NULL.
2501 */
2502 ast_assert(bridge_channel != NULL);
2503
2504 /*
2505 * Additional checks if the channel we just stole dissolves the
2506 * original bridge.
2507 */
2508 bridge_dissolve_check_stolen(chan_bridge, bridge_channel);
2509 ast_bridge_unlock(chan_bridge);
2511 } else {
2512 /* Slightly less easy case. We need to yank channel A from
2513 * where he currently is and impart him into our bridge.
2514 */
2515 yanked_chan = ast_channel_yank(chan);
2516 if (!yanked_chan) {
2517 ast_log(LOG_WARNING, "Could not gain control of channel %s\n", ast_channel_name(chan));
2519 return -1;
2520 }
2521 if (ast_channel_state(yanked_chan) != AST_STATE_UP) {
2522 ast_answer(yanked_chan);
2523 }
2524 ast_channel_ref(yanked_chan);
2525 if (ast_bridge_impart(bridge, yanked_chan, NULL, features,
2527 /* It is possible for us to yank a channel and have some other
2528 * thread start a PBX on the channel after we yanked it. In particular,
2529 * this can theoretically happen on the ;2 of a Local channel if we
2530 * yank it prior to the ;1 being answered. Make sure that it isn't
2531 * executing a PBX before hanging it up.
2532 */
2533 if (ast_channel_pbx(yanked_chan)) {
2534 ast_channel_unref(yanked_chan);
2535 } else {
2536 ast_hangup(yanked_chan);
2537 }
2538 return -1;
2539 }
2540 }
2541
2542 if (play_tone && !ast_strlen_zero(xfersound)) {
2543 struct ast_channel *play_chan = yanked_chan ?: chan;
2544 RAII_VAR(struct ast_bridge_channel *, play_bridge_channel, NULL, ao2_cleanup);
2545
2546 ast_channel_lock(play_chan);
2547 play_bridge_channel = ast_channel_get_bridge_channel(play_chan);
2548 ast_channel_unlock(play_chan);
2549
2550 if (!play_bridge_channel) {
2551 ast_log(LOG_WARNING, "Unable to play tone for channel %s. No longer in a bridge.\n",
2552 ast_channel_name(play_chan));
2553 } else {
2554 ast_bridge_channel_queue_playfile(play_bridge_channel, NULL, xfersound, NULL);
2555 }
2556 }
2557 return 0;
2558}
#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:1878
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:2399
struct ast_bridge_channel * bridge_find_channel(struct ast_bridge *bridge, struct ast_channel *chan)
Definition: bridge.c:1429
void ast_bridge_features_destroy(struct ast_bridge_features *features)
Destroy an allocated bridge features struct.
Definition: bridge.c:3674
static void bridge_dissolve_check_stolen(struct ast_bridge *bridge, struct ast_bridge_channel *bridge_channel)
Definition: bridge.c:355
#define ast_bridge_lock_both(bridge1, bridge2)
Lock two bridges.
Definition: bridge.h:488
#define ast_bridge_unlock(bridge)
Unlock the bridge.
Definition: bridge.h:481
@ AST_BRIDGE_IMPART_CHAN_INDEPENDENT
Definition: bridge.h:590
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:2541
#define ast_channel_lock(chan)
Definition: channel.h:2922
struct ast_channel * ast_channel_yank(struct ast_channel *yankee)
Gain control of a channel in the system.
Definition: channel.c:10593
#define ast_channel_ref(c)
Increase channel reference count.
Definition: channel.h:2947
struct ast_bridge * ast_channel_get_bridge(const struct ast_channel *chan)
Get the bridge associated with a channel.
Definition: channel.c:10534
#define ast_channel_unref(c)
Decrease channel reference count.
Definition: channel.h:2958
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:10582
struct ast_pbx * ast_channel_pbx(const struct ast_channel *chan)
int ast_answer(struct ast_channel *chan)
Answer a channel.
Definition: channel.c:2805
#define ast_channel_unlock(chan)
Definition: channel.h:2923
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:7776
#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:349
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:934
@ AST_BRIDGE_CAPABILITY_1TO1MIX
Definition: bridge.h:92
@ 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 934 of file bridge.c.

935{
936 void *bridge;
937
938 bridge = bridge_alloc(sizeof(struct ast_bridge), &ast_bridge_base_v_table);
939 bridge = bridge_base_init(bridge, capabilities, flags, creator, name, id);
940 bridge = bridge_register(bridge);
941 return bridge;
942}
struct ast_bridge_methods ast_bridge_base_v_table
Bridge base class virtual method table.
Definition: bridge.c:923
struct ast_bridge * bridge_register(struct ast_bridge *bridge)
Register the new bridge with the system.
Definition: bridge.c:691
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:742
struct ast_bridge * bridge_alloc(size_t size, const struct ast_bridge_methods *v_table)
Definition: bridge.c:706
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:1906

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 1906 of file bridge.c.

1907{
1908 struct ast_bridge_channel *bridge_channel;
1909 int departable;
1910 SCOPE_TRACE(1, "%s\n", ast_channel_name(chan));
1911
1913 bridge_channel = ast_channel_internal_bridge_channel(chan);
1914 departable = bridge_channel && bridge_channel->depart_wait;
1916 if (!departable) {
1917 ast_log(LOG_ERROR, "Channel %s cannot be departed.\n",
1919 /*
1920 * Should never happen. It likely means that
1921 * ast_bridge_depart() is called by two threads for the same
1922 * channel, the channel was never imparted to be departed, or it
1923 * has already been departed.
1924 */
1925 ast_assert(0);
1926 return -1;
1927 }
1928
1929 /*
1930 * We are claiming the bridge_channel reference held by
1931 * bridge_channel_depart_thread().
1932 */
1933
1934 ast_bridge_channel_leave_bridge(bridge_channel,
1936
1937 /* Wait for the depart thread to die */
1938 ast_debug(1, "Waiting for %p(%s) bridge thread to die.\n",
1939 bridge_channel, ast_channel_name(bridge_channel->chan));
1940 pthread_join(bridge_channel->thread, NULL);
1941
1945
1946 /* We can get rid of the bridge_channel after the depart thread has died. */
1947 ao2_ref(bridge_channel, -1);
1948 return 0;
1949}
#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:944

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 944 of file bridge.c.

945{
946 ast_debug(1, "Bridge %s: telling all channels to leave the party\n", bridge->uniqueid);
947 ast_bridge_lock(bridge);
948 bridge_dissolve(bridge, cause);
949 ast_bridge_unlock(bridge);
950
951 ao2_ref(bridge, -1);
952
953 return 0;
954}
void bridge_dissolve(struct ast_bridge *bridge, int cause)
Definition: bridge.c:315
#define ast_bridge_lock(bridge)
Lock the bridge.
Definition: bridge.h:470
const ast_string_field uniqueid
Definition: bridge.h:401

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

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_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:3620
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:3182
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 3182 of file bridge.c.

3188{
3189 struct ast_bridge_hook_dtmf *hook;
3190 int res;
3191
3192 /* Allocate new hook and setup it's various variables */
3193 hook = (struct ast_bridge_hook_dtmf *) bridge_hook_generic(sizeof(*hook), callback,
3194 hook_pvt, destructor, remove_flags);
3195 if (!hook) {
3196 return -1;
3197 }
3199 ast_copy_string(hook->dtmf.code, dtmf, sizeof(hook->dtmf.code));
3200
3201 /* Once done we put it in the container. */
3202 res = ao2_link(features->dtmf_hooks, hook) ? 0 : -1;
3203 if (res) {
3204 /*
3205 * Could not link the hook into the container.
3206 *
3207 * Remove the hook_pvt destructor call from the hook since we
3208 * are returning failure to install the hook.
3209 */
3210 hook->generic.destructor = NULL;
3211 }
3212 ao2_ref(hook, -1);
3213
3214 return res;
3215}
#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:3162
@ 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:3653

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 3653 of file bridge.c.

3654{
3655 struct ast_bridge_hook_timer *hook;
3656
3657 /* Destroy the interval hooks heap. */
3658 if (features->interval_hooks) {
3659 while ((hook = ast_heap_pop(features->interval_hooks))) {
3660 ao2_ref(hook, -1);
3661 }
3662 features->interval_hooks = ast_heap_destroy(features->interval_hooks);
3663 }
3664
3665 /* Destroy the miscellaneous other hooks container. */
3666 ao2_cleanup(features->other_hooks);
3667 features->other_hooks = NULL;
3668
3669 /* Destroy the DTMF hooks container. */
3670 ao2_cleanup(features->dtmf_hooks);
3671 features->dtmf_hooks = NULL;
3672}
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:3683
void ast_bridge_features_destroy(struct ast_bridge_features *features)
Destroy an allocated bridge features struct.
Definition: bridge.c:3674

Definition at line 3674 of file bridge.c.

3675{
3676 if (!features) {
3677 return;
3678 }
3680 ast_free(features);
3681}
#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:3653

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:3090

Definition at line 3090 of file bridge.c.

3091{
3092 ast_bridge_hook_callback callback;
3093
3094 if (ARRAY_LEN(builtin_features_handlers) <= feature) {
3095 return -1;
3096 }
3097
3098 callback = builtin_features_handlers[feature];
3099 if (!callback) {
3100 return -1;
3101 }
3102 callback(bridge_channel, hook_pvt);
3103
3104 return 0;
3105}
static ast_bridge_hook_callback builtin_features_handlers[AST_BRIDGE_BUILTIN_END]
Definition: bridge.c:147
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:3365

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 3365 of file bridge.c.

3371{
3372 if (ARRAY_LEN(builtin_features_handlers) <= feature
3373 || !builtin_features_handlers[feature]) {
3374 return -1;
3375 }
3376
3377 /* If no alternate DTMF stream was provided use the default one */
3378 if (ast_strlen_zero(dtmf)) {
3379 dtmf = builtin_features_dtmf[feature];
3380 /* If no DTMF is still available (ie: it has been disabled) then error out now */
3381 if (ast_strlen_zero(dtmf)) {
3382 ast_debug(1, "Failed to enable built in feature %u on %p, no DTMF string is available for it.\n",
3383 feature, features);
3384 return -1;
3385 }
3386 }
3387
3388 /*
3389 * The rest is basically pretty easy. We create another hook
3390 * using the built in feature's DTMF callback. Easy as pie.
3391 */
3392 return ast_bridge_dtmf_hook(features, dtmf, builtin_features_handlers[feature],
3393 config, destructor, remove_flags);
3394}
static char builtin_features_dtmf[AST_BRIDGE_BUILTIN_END][MAXIMUM_DTMF_FEATURE_STRING]
Definition: bridge.c:144
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:3182
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 3620 of file bridge.c.

3621{
3622 /* Zero out the structure */
3623 memset(features, 0, sizeof(*features));
3624
3625 /* Initialize the DTMF hooks container */
3628 if (!features->dtmf_hooks) {
3629 return -1;
3630 }
3631
3632 /* Initialize the miscellaneous other hooks container */
3634 NULL);
3635 if (!features->other_hooks) {
3636 return -1;
3637 }
3638
3639 /* Initialize the interval hooks heap */
3641 offsetof(struct ast_bridge_hook_timer, timer.heap_index));
3642 if (!features->interval_hooks) {
3643 return -1;
3644 }
3645
3646 features->dtmf_passthrough = 1;
3647 features->text_messaging = 1;
3648
3649 return 0;
3650}
@ 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:3508
static int bridge_dtmf_hook_sort(const void *obj_left, const void *obj_right, int flags)
Definition: bridge.c:3539
static struct ast_timer * timer
Definition: chan_iax2.c:364
#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 3396 of file bridge.c.

3397{
3398 memset(limits, 0, sizeof(*limits));
3399
3400 if (ast_string_field_init(limits, 256)) {
3401 return -1;
3402 }
3403
3404 return 0;
3405}
#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 3407 of file bridge.c.

3408{
3410}
#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 3595 of file bridge.c.

3596{
3597 struct ast_bridge_hook_timer *hook;
3598 int idx;
3599
3600 /* Merge hook containers */
3603
3604 /* Merge hook heaps */
3606 for (idx = 1; (hook = ast_heap_peek(from->interval_hooks, idx)); idx++) {
3607 wrap_hook(into, hook);
3608 }
3610
3611 /* Merge feature flags */
3612 into->feature_flags.flags |= from->feature_flags.flags;
3613 into->usable |= from->usable;
3614
3615 into->mute |= from->mute;
3616 into->dtmf_passthrough |= from->dtmf_passthrough;
3617}
#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:3562
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:3583
#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 3683 of file bridge.c.

3684{
3685 struct ast_bridge_features *features;
3686
3687 features = ast_malloc(sizeof(*features));
3688 if (features) {
3689 if (ast_bridge_features_init(features)) {
3691 features = NULL;
3692 }
3693 }
3694
3695 return features;
3696}
#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:3620

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:3062

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

Definition at line 3062 of file bridge.c.

3063{
3064 if (ARRAY_LEN(builtin_features_handlers) <= feature
3065 || builtin_features_handlers[feature]) {
3066 return -1;
3067 }
3068
3069 if (!ast_strlen_zero(dtmf)) {
3070 ast_copy_string(builtin_features_dtmf[feature], dtmf, sizeof(builtin_features_dtmf[feature]));
3071 }
3072
3073 builtin_features_handlers[feature] = callback;
3074
3075 return 0;
3076}

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 3501 of file bridge.c.

3502{
3503 hooks_remove_container(features->dtmf_hooks, remove_flags);
3504 hooks_remove_container(features->other_hooks, remove_flags);
3505 hooks_remove_heap(features->interval_hooks, remove_flags);
3506}
static void hooks_remove_heap(struct ast_heap *hooks, enum ast_bridge_hook_remove_flags remove_flags)
Definition: bridge.c:3479
static void hooks_remove_container(struct ao2_container *hooks, enum ast_bridge_hook_remove_flags remove_flags)
Definition: bridge.c:3465

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:3427
@ 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 3427 of file bridge.c.

3428{
3429 ast_set_flag(&features->feature_flags, flag);
3430 features->usable = 1;
3431}
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:3412
int ast_bridge_features_limits_construct(struct ast_bridge_features_limits *limits)
Constructor function for ast_bridge_features_limits.
Definition: bridge.c:3396
void ast_bridge_features_limits_destroy(struct ast_bridge_features_limits *limits)
Destructor function for ast_bridge_features_limits.
Definition: bridge.c:3407
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 3412 of file bridge.c.

3415{
3418
3420 return callback(features, limits, remove_flags);
3421 }
3422
3423 ast_log(LOG_ERROR, "Attempted to set limits without an AST_BRIDGE_BUILTIN_INTERVAL_LIMITS callback registered.\n");
3424 return -1;
3425}
static ast_bridge_builtin_set_limits_fn builtin_interval_handlers[AST_BRIDGE_BUILTIN_INTERVAL_END]
Definition: bridge.c:150
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:3078

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

Definition at line 3078 of file bridge.c.

3079{
3080 if (ARRAY_LEN(builtin_features_handlers) <= feature
3081 || !builtin_features_handlers[feature]) {
3082 return -1;
3083 }
3084
3086
3087 return 0;
3088}

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 5012 of file bridge.c.

5013{
5014 return ao2_find(bridges, bridge_id, OBJ_SEARCH_KEY);
5015}
#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:123

References ao2_find, bridges, and OBJ_SEARCH_KEY.

Referenced by ast_bridge_get_snapshot_by_uniqueid(), 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:3265

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 3265 of file bridge.c.

3270{
3271 return bridge_other_hook(features, callback, hook_pvt, destructor, remove_flags,
3273}
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:3231
@ 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:1878

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 1878 of file bridge.c.

1883{
1885 .done = 0,
1886 };
1887 int res;
1888 SCOPE_TRACE(1, "%s Bridge: %s\n", ast_channel_name(chan), bridge->uniqueid);
1889
1890 ast_mutex_init(&cond.lock);
1891 ast_cond_init(&cond.cond, NULL);
1892
1893 res = bridge_impart_internal(bridge, chan, swap, features, flags, &cond);
1894 if (res) {
1895 /* Impart failed. Signal any other waiting impart threads */
1898 }
1899
1900 ast_cond_destroy(&cond.cond);
1901 ast_mutex_destroy(&cond.lock);
1902
1903 return res;
1904}
ast_cond_t cond
Definition: app_sla.c:330
void bridge_channel_impart_signal(struct ast_channel *chan)
Definition: bridge.c:1582
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:1777
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:202
#define ast_cond_init(cond, attr)
Definition: lock.h:201
#define ast_mutex_init(pmutex)
Definition: lock.h:186
#define ast_mutex_destroy(a)
Definition: lock.h:188
Internal bridge impart wait condition and associated conditional.
Definition: bridge.c:1475

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:3319

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 3319 of file bridge.c.

3326{
3327 struct ast_bridge_hook_timer *hook;
3328 int res;
3329
3330 if (!features ||!interval || !callback) {
3331 return -1;
3332 }
3333
3334 /* Allocate new hook and setup it's various variables */
3335 hook = (struct ast_bridge_hook_timer *) bridge_hook_generic(sizeof(*hook), callback,
3336 hook_pvt, destructor, remove_flags);
3337 if (!hook) {
3338 return -1;
3339 }
3341 hook->timer.interval = interval;
3342 hook->timer.trip_time = ast_tvadd(ast_tvnow(), ast_samp2tv(interval, 1000));
3343 hook->timer.seqno = ast_atomic_fetchadd_int((int *) &features->interval_sequence, +1);
3344 hook->timer.flags = flags;
3345
3346 ast_debug(1, "Putting interval hook %p with interval %u in the heap on features %p\n",
3347 hook, hook->timer.interval, features);
3349 res = ast_heap_push(features->interval_hooks, hook);
3351 if (res) {
3352 /*
3353 * Could not push the hook into the heap
3354 *
3355 * Remove the hook_pvt destructor call from the hook since we
3356 * are returning failure to install the hook.
3357 */
3358 hook->generic.destructor = NULL;
3359 ao2_ref(hook, -1);
3360 }
3361
3362 return res ? -1 : 0;
3363}
@ 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:757
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:3107

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

Definition at line 3107 of file bridge.c.

3108{
3109 if (ARRAY_LEN(builtin_interval_handlers) <= interval
3110 || builtin_interval_handlers[interval]) {
3111 return -1;
3112 }
3113
3114 builtin_interval_handlers[interval] = callback;
3115
3116 return 0;
3117}

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:3119

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

Definition at line 3119 of file bridge.c.

3120{
3121 if (ARRAY_LEN(builtin_interval_handlers) <= interval
3122 || !builtin_interval_handlers[interval]) {
3123 return -1;
3124 }
3125
3126 builtin_interval_handlers[interval] = NULL;
3127
3128 return 0;
3129
3130}

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 3891 of file bridge.c.

3892{
3893 int res = 0;
3894
3895 ast_bridge_lock(bridge);
3896 switch (bridge->softmix.video_mode.mode) {
3898 break;
3901 res = 1;
3902 }
3903 break;
3906 res = 1;
3907 } else if (bridge->softmix.video_mode.mode_data.talker_src_data.chan_old_vsrc == chan) {
3908 res = 2;
3909 }
3911 break;
3912 }
3913 ast_bridge_unlock(bridge);
3914 return res;
3915}
@ AST_BRIDGE_VIDEO_MODE_SINGLE_SRC
Definition: bridge.h:102
@ AST_BRIDGE_VIDEO_MODE_TALKER_SRC
Definition: bridge.h:105
@ AST_BRIDGE_VIDEO_MODE_NONE
Definition: bridge.h:100
@ AST_BRIDGE_VIDEO_MODE_SFU
Definition: bridge.h:109
struct ast_bridge_video_mode video_mode
Definition: bridge.h:279
struct ast_bridge_video_single_src_data single_src_data
Definition: bridge.h:163
struct ast_bridge_video_talker_src_data talker_src_data
Definition: bridge.h:164
union ast_bridge_video_mode::@189 mode_data
enum ast_bridge_video_mode_type mode
Definition: bridge.h:160
struct ast_channel * chan_vsrc
Definition: bridge.h:116
struct ast_channel * chan_old_vsrc
Definition: bridge.h:127
struct ast_channel * chan_vsrc
Definition: bridge.h:123
struct ast_bridge_softmix softmix
Definition: bridge.h:367

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:1621
@ AST_BRIDGE_JOIN_PASS_REFERENCE
Definition: bridge.h:535

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 1621 of file bridge.c.

1627{
1628 struct ast_bridge_channel *bridge_channel;
1629 int res = 0;
1630 SCOPE_TRACE(1, "%s Bridge: %s\n", ast_channel_name(chan), bridge->uniqueid);
1631
1632 bridge_channel = bridge_channel_internal_alloc(bridge);
1633 if (flags & AST_BRIDGE_JOIN_PASS_REFERENCE) {
1634 ao2_ref(bridge, -1);
1635 }
1636 if (!bridge_channel) {
1637 ao2_t_cleanup(swap, "Error exit: bridge_channel alloc failed");
1638 res = -1;
1639 goto join_exit;
1640 }
1641/* 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. */
1643 if (!features) {
1644 ao2_ref(bridge_channel, -1);
1645 ao2_t_cleanup(swap, "Error exit: features is NULL");
1646 res = -1;
1647 goto join_exit;
1648 }
1649 if (tech_args) {
1650 bridge_channel->tech_args = *tech_args;
1651 }
1652
1655 res = -1;
1656 } else {
1658 }
1660 bridge_channel->thread = pthread_self();
1661 bridge_channel->chan = chan;
1662 bridge_channel->swap = swap;
1663 bridge_channel->features = features;
1664 bridge_channel->inhibit_colp = !!(flags & AST_BRIDGE_JOIN_INHIBIT_JOIN_COLP);
1665
1666 /* allow subclass to peek at upcoming push operation */
1667 if (bridge->v_table->push_peek && !res) {
1668 struct ast_bridge_channel *bcswap = NULL;
1669
1671 if (bridge_channel->swap) {
1672 bcswap = bridge_find_channel(bridge, bridge_channel->swap);
1673 }
1674 res = bridge->v_table->push_peek(bridge, bridge_channel, bcswap);
1676 }
1677
1678 if (!res) {
1679 res = bridge_channel_internal_join(bridge_channel);
1680 }
1681
1682 /* Cleanup all the data in the bridge channel after it leaves the bridge. */
1686 /* Due to a race condition, we lock the bridge channel here for ast_bridge_channel_get_chan */
1687 ao2_lock(bridge_channel);
1688 bridge_channel->chan = NULL;
1689 ao2_unlock(bridge_channel);
1690 /* If bridge_channel->swap is not NULL then the join failed. */
1691 ao2_t_cleanup(bridge_channel->swap, "Bridge complete: join failed");
1692 bridge_channel->swap = NULL;
1693 bridge_channel->features = NULL;
1694
1695 ao2_ref(bridge_channel, -1);
1696
1697join_exit:
1702 /* Claim the after bridge goto is an async goto destination. */
1706 }
1707 return res;
1708}
#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:537
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_SOFTHANGUP_ASYNCGOTO
Definition: channel.h:1126
int ast_softhangup_nolock(struct ast_channel *chan, int cause)
Softly hangup up a channel (no channel lock)
Definition: channel.c:2458
@ AST_FLAG_ZOMBIE
Definition: channel.h:987
int ast_channel_softhangup_internal_flag(struct ast_channel *chan)
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:273
const struct ast_bridge_methods * v_table
Definition: bridge.h:351
#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:3275

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 3275 of file bridge.c.

3280{
3281 return bridge_other_hook(features, callback, hook_pvt, destructor, remove_flags,
3283}
@ 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:1979

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 1979 of file bridge.c.

1980{
1981 struct ast_bridge_channel *bridge_channel;
1982 int res;
1983
1985
1986 /* Try to find the channel that we want to kick. */
1987 if (!(bridge_channel = bridge_find_channel(bridge, chan))) {
1989 return -1;
1990 }
1991
1992 res = ast_bridge_channel_queue_callback(bridge_channel, 0, kick_it, NULL, 0);
1993
1995
1996 return res;
1997}
static void kick_it(struct ast_bridge_channel *bridge_channel, const void *payload, size_t payload_size)
Definition: bridge.c:1974
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:3285

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 3285 of file bridge.c.

3290{
3291 return bridge_other_hook(features, callback, hook_pvt, destructor, remove_flags,
3293}
@ 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:2300

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

Definition at line 2300 of file bridge.c.

2301{
2302 int res;
2303
2304 /* Sanity check. */
2305 ast_assert(dst_bridge && src_bridge);
2306
2307 ast_bridge_lock_both(dst_bridge, src_bridge);
2308 res = bridge_merge_locked(dst_bridge, src_bridge, merge_best_direction, kick_me, num_kick);
2309 ast_bridge_unlock(src_bridge);
2310 ast_bridge_unlock(dst_bridge);
2311 return res;
2312}
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:2216

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 3000 of file bridge.c.

3001{
3002 ast_bridge_lock(bridge);
3004 ast_bridge_unlock(bridge);
3005}
void bridge_merge_inhibit_nolock(struct ast_bridge *bridge, int request)
Definition: bridge.c:2991
static int request(void *obj)
Definition: chan_pjsip.c:2601

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 2460 of file bridge.c.

2461{
2462 int res;
2463
2464 ast_bridge_lock_both(dst_bridge, src_bridge);
2465 res = bridge_move_locked(dst_bridge, src_bridge, chan, swap, attempt_recovery);
2466 ast_bridge_unlock(src_bridge);
2467 ast_bridge_unlock(dst_bridge);
2468 return res;
2469}

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:3307

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 3307 of file bridge.c.

3312{
3314
3315 return bridge_other_hook(features, hook_cb, hook_pvt, destructor, remove_flags,
3317}
@ 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 1442 of file bridge.c.

1443{
1444 struct ast_bridge_channel *bridge_channel;
1445 struct ast_bridge *bridge;
1446
1447 /* Safely get the bridge_channel pointer for the chan. */
1448 ast_channel_lock(chan);
1449 bridge_channel = ast_channel_get_bridge_channel(chan);
1450 ast_channel_unlock(chan);
1451 if (!bridge_channel) {
1452 /* Not in a bridge */
1453 return;
1454 }
1455
1456 ast_bridge_channel_lock_bridge(bridge_channel);
1457 bridge = bridge_channel->bridge;
1458 if (bridge_channel == bridge_find_channel(bridge, chan)) {
1459/*
1460 * XXX ASTERISK-22366 this needs more work. The channels need
1461 * to be made compatible again if the formats change. The
1462 * bridge_channel thread needs to monitor for this case.
1463 */
1464 /* The channel we want to notify is still in a bridge. */
1465 bridge->v_table->notify_masquerade(bridge, bridge_channel);
1466 bridge_reconfigured(bridge, 1);
1467 }
1468 ast_bridge_unlock(bridge);
1469 ao2_ref(bridge_channel, -1);
1470}
void bridge_reconfigured(struct ast_bridge *bridge, unsigned int colp_update)
Definition: bridge.c:1403
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:269

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 4075 of file bridge.c.

4076{
4077 struct ast_channel *peer;
4078
4080 peer = ast_bridge_peer_nolock(bridge, chan);
4082
4083 return peer;
4084}
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:4047
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 4047 of file bridge.c.

4048{
4049 struct ast_channel *peer = NULL;
4050 struct ast_bridge_channel *iter;
4051
4052 /* Asking for the peer channel only makes sense on a two-party bridge. */
4053 if (bridge->num_channels == 2
4056 int in_bridge = 0;
4057
4059 if (iter->chan != chan) {
4060 peer = iter->chan;
4061 } else {
4062 in_bridge = 1;
4063 }
4064 }
4065 if (in_bridge && peer) {
4066 ast_channel_ref(peer);
4067 } else {
4068 peer = NULL;
4069 }
4070 }
4071
4072 return peer;
4073}
@ AST_BRIDGE_CAPABILITY_NATIVE
Definition: bridge.h:90
#define AST_LIST_TRAVERSE(head, var, field)
Loops over (traverses) the entries in a list.
Definition: linkedlists.h:491
unsigned int in_bridge
struct ast_bridge_channels_list channels
Definition: bridge.h:363
unsigned int num_channels
Definition: bridge.h:373
struct ast_bridge_technology * technology
Definition: bridge.h:355

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::in_bridge, NULL, ast_bridge::num_channels, and ast_bridge::technology.

Referenced by ast_bridge_peer(), 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 4036 of file bridge.c.

4037{
4038 struct ao2_container *channels;
4039
4040 ast_bridge_lock(bridge);
4042 ast_bridge_unlock(bridge);
4043
4044 return channels;
4045}
struct ao2_container * ast_bridge_peers_nolock(struct ast_bridge *bridge)
Get a container of all channels in the bridge.
Definition: bridge.c:4018
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 4018 of file bridge.c.

4019{
4020 struct ao2_container *channels;
4021 struct ast_bridge_channel *iter;
4022
4025 if (!channels) {
4026 return NULL;
4027 }
4028
4030 ao2_link(channels, iter->chan);
4031 }
4032
4033 return channels;
4034}
@ 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:3973
static int channel_cmp(void *obj, void *arg, int flags)
Definition: bridge.c:3996

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, 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 303 of file bridge.c.

304{
305 struct ast_frame *dup;
306
307 dup = ast_frdup(action);
308 if (!dup) {
309 return -1;
310 }
311 bridge_queue_action_nodup(bridge, dup);
312 return 0;
313}
static void bridge_queue_action_nodup(struct ast_bridge *bridge, struct ast_frame *action)
Definition: bridge.c:292
#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:1951

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 1951 of file bridge.c.

1952{
1953 struct ast_bridge_channel *bridge_channel;
1954
1955 ast_debug(1, "Removing channel %s from bridge %s\n",
1957
1959
1960 /* Try to find the channel that we want to remove */
1961 if (!(bridge_channel = bridge_find_channel(bridge, chan))) {
1963 return -1;
1964 }
1965
1966 ast_bridge_channel_leave_bridge(bridge_channel,
1968
1970
1971 return 0;
1972}

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 3917 of file bridge.c.

3918{
3919 ast_bridge_lock(bridge);
3920 switch (bridge->softmix.video_mode.mode) {
3922 break;
3927 }
3929 }
3930 break;
3935 }
3938 }
3942 }
3944 }
3946 break;
3947 }
3948 ast_bridge_unlock(bridge);
3949}

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 3705 of file bridge.c.

3706{
3707 ast_bridge_lock(bridge);
3708 bridge->softmix.binaural_active = binaural_active;
3709 ast_bridge_unlock(bridge);
3710}
unsigned int binaural_active
Definition: bridge.h:295

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 3712 of file bridge.c.

3713{
3714 ast_bridge_lock(bridge);
3715 bridge->softmix.internal_sample_rate = sample_rate;
3716 ast_bridge_unlock(bridge);
3717}
unsigned int internal_sample_rate
The internal sample rate softmix uses to mix channels.
Definition: bridge.h:285

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 3719 of file bridge.c.

3720{
3721 ast_bridge_lock(bridge);
3722 bridge->softmix.maximum_sample_rate = sample_rate;
3723 ast_bridge_unlock(bridge);
3724}
unsigned int maximum_sample_rate
The maximum sample rate softmix uses to mix channels.
Definition: bridge.h:306

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 3698 of file bridge.c.

3699{
3700 ast_bridge_lock(bridge);
3701 bridge->softmix.internal_mixing_interval = mixing_interval;
3702 ast_bridge_unlock(bridge);
3703}
unsigned int internal_mixing_interval
The mixing interval indicates how quickly softmix mixing should occur to mix audio.
Definition: bridge.h:293

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 3807 of file bridge.c.

3808{
3810
3811 ast_bridge_lock(bridge);
3812 bridge->softmix.video_mode.mode_data.sfu_data.estimated_bitrate = estimated_bitrate;
3813 ast_bridge_unlock(bridge);
3814}
struct ast_bridge_video_sfu_data sfu_data
Definition: bridge.h:165

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 3789 of file bridge.c.

3790{
3792
3793 ast_bridge_lock(bridge);
3794 bridge->softmix.video_mode.mode_data.sfu_data.remb_send_interval = remb_send_interval;
3795 ast_bridge_unlock(bridge);
3796}
unsigned int remb_send_interval
Definition: bridge.h:151

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 3966 of file bridge.c.

3967{
3968 ast_bridge_lock(bridge);
3969 bridge->softmix.send_sdp_label = send_sdp_label;
3970 ast_bridge_unlock(bridge);
3971}
unsigned int send_sdp_label
Definition: bridge.h:300

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 3774 of file bridge.c.

3775{
3776 ast_bridge_lock(bridge);
3777 cleanup_video_mode(bridge);
3779 ast_bridge_unlock(bridge);
3780}
static void cleanup_video_mode(struct ast_bridge *bridge)
Definition: bridge.c:3726

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 3749 of file bridge.c.

3750{
3751 ast_bridge_lock(bridge);
3752 cleanup_video_mode(bridge);
3754 if (video_src_chan) {
3756 ast_verb(5, "Video source in bridge '%s' (%s) is now '%s' (%s)\n",
3757 bridge->name, bridge->uniqueid,
3758 ast_channel_name(video_src_chan),
3759 ast_channel_uniqueid(video_src_chan));
3760 ast_indicate(video_src_chan, AST_CONTROL_VIDUPDATE);
3761 }
3763 ast_bridge_unlock(bridge);
3764}
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:4277
@ 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:401

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 3766 of file bridge.c.

3767{
3768 ast_bridge_lock(bridge);
3769 cleanup_video_mode(bridge);
3771 ast_bridge_unlock(bridge);
3772}

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 4352 of file bridge.c.

4353{
4354 char *writevar;
4355 char *erasevar;
4356
4357 if (attended) {
4358 writevar = ATTENDEDTRANSFER;
4359 erasevar = BLINDTRANSFER;
4360 } else {
4361 writevar = BLINDTRANSFER;
4362 erasevar = ATTENDEDTRANSFER;
4363 }
4364
4365 pbx_builtin_setvar_helper(chan, writevar, value);
4366 pbx_builtin_setvar_helper(chan, erasevar, NULL);
4367}
#define BLINDTRANSFER
Definition: bridge.c:136
#define ATTENDEDTRANSFER
Definition: bridge.c:139
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 3782 of file bridge.c.

3783{
3784 ast_bridge_lock(bridge);
3785 bridge->softmix.video_mode.video_update_discard = video_update_discard;
3786 ast_bridge_unlock(bridge);
3787}
unsigned int video_update_discard
Definition: bridge.h:168

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:3007

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 3007 of file bridge.c.

3008{
3009 struct ast_bridge_channel *bridge_channel;
3010/* XXX ASTERISK-21271 the case of a dissolved bridge while channel is suspended is not handled. */
3011/* XXX ASTERISK-21271 suspend/unsuspend needs to be rethought. The caller must block until it has successfully suspended the channel for temporary control. */
3012/* 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. */
3013
3015
3016 if (!(bridge_channel = bridge_find_channel(bridge, chan))) {
3018 return -1;
3019 }
3020
3022
3024
3025 return 0;
3026}
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 3295 of file bridge.c.

3300{
3302
3303 return bridge_other_hook(features, hook_cb, hook_pvt, destructor, remove_flags,
3305}
@ 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:3047

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 3047 of file bridge.c.

3048{
3049 technology->suspended = 1;
3050}

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:263

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 263 of file bridge.c.

264{
266
268
269 /* Ensure the bridge technology is registered before removing it */
271 if (current == technology) {
273 ast_verb(5, "Unregistered bridge technology %s\n", technology->name);
274 break;
275 }
276 }
278
280
281 return current ? 0 : -1;
282}
#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:3052

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

Definition at line 3052 of file bridge.c.

3053{
3054 /*
3055 * XXX We may want the act of unsuspending a bridge technology
3056 * to prod all existing bridges to see if they should start
3057 * using it.
3058 */
3059 technology->suspended = 0;
3060}

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 4408 of file bridge.c.

4409{
4410 struct ast_bridge *bridge;
4411
4412 ast_channel_lock(chan);
4413 bridge = ast_channel_get_bridge(chan);
4414 ast_channel_unlock(chan);
4415
4416 if (bridge && ast_test_flag(&bridge->feature_flags,
4418 ao2_ref(bridge, -1);
4419 bridge = NULL;
4420 }
4421
4422 return bridge;
4423}
@ AST_BRIDGE_FLAG_MASQUERADE_ONLY
@ AST_BRIDGE_FLAG_INVISIBLE
struct ast_flags feature_flags
Definition: bridge.h:369

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(), 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 4677 of file bridge.c.

4679{
4680 RAII_VAR(struct ast_bridge *, to_transferee_bridge, NULL, ao2_cleanup);
4681 RAII_VAR(struct ast_bridge *, to_target_bridge, NULL, ao2_cleanup);
4682 RAII_VAR(struct ast_bridge_channel *, to_transferee_bridge_channel, NULL, ao2_cleanup);
4683 RAII_VAR(struct ast_bridge_channel *, to_target_bridge_channel, NULL, ao2_cleanup);
4685 RAII_VAR(struct ast_channel *, transferee, NULL, ao2_cleanup);
4686 RAII_VAR(struct ast_attended_transfer_message *, transfer_msg, NULL, ao2_cleanup);
4687 struct ast_bridge *the_bridge = NULL;
4688 struct ast_channel *chan_bridged;
4689 struct ast_channel *chan_unbridged;
4690 int transfer_prohibited;
4691 int do_bridge_transfer;
4692 enum ast_transfer_result res;
4693 const char *app = NULL;
4694 int hangup_target = 0;
4695
4696 to_transferee_bridge = ast_bridge_transfer_acquire_bridge(to_transferee);
4697 to_target_bridge = ast_bridge_transfer_acquire_bridge(to_transfer_target);
4698
4699 transfer_msg = ast_attended_transfer_message_create(1, to_transferee, to_transferee_bridge,
4700 to_transfer_target, to_target_bridge, NULL, NULL);
4701 if (!transfer_msg) {
4702 ast_log(LOG_ERROR, "Unable to create Stasis publication for attended transfer from %s\n",
4703 ast_channel_name(to_transferee));
4705 }
4706
4707 /* They can't both be unbridged, you silly goose! */
4708 if (!to_transferee_bridge && !to_target_bridge) {
4710 goto end;
4711 }
4712
4713 ast_channel_lock(to_transferee);
4714 to_transferee_bridge_channel = ast_channel_get_bridge_channel(to_transferee);
4715 ast_channel_unlock(to_transferee);
4716
4717 ast_channel_lock(to_transfer_target);
4718 to_target_bridge_channel = ast_channel_get_bridge_channel(to_transfer_target);
4719 ast_channel_unlock(to_transfer_target);
4720
4721 if (to_transferee_bridge_channel) {
4722 /* Take off hold if they are on hold. */
4723 if (ast_bridge_channel_write_unhold(to_transferee_bridge_channel)) {
4724 ast_log(LOG_ERROR, "Transferee channel disappeared during transfer!\n");
4726 goto end;
4727 }
4728 }
4729
4730 if (to_target_bridge_channel) {
4731 const char *target_complete_sound;
4732
4733 /* Take off hold if they are on hold. */
4734 if (ast_bridge_channel_write_unhold(to_target_bridge_channel)) {
4735 ast_log(LOG_ERROR, "Target channel disappeared during transfer!\n");
4737 goto end;
4738 }
4739
4740 /* Is there a courtesy sound to play to the target? */
4741 ast_channel_lock(to_transfer_target);
4742 target_complete_sound = pbx_builtin_getvar_helper(to_transfer_target,
4743 "ATTENDED_TRANSFER_COMPLETE_SOUND");
4744 if (!ast_strlen_zero(target_complete_sound)) {
4745 target_complete_sound = ast_strdupa(target_complete_sound);
4746 } else {
4747 target_complete_sound = NULL;
4748 }
4749 ast_channel_unlock(to_transfer_target);
4750 if (!target_complete_sound) {
4751 ast_channel_lock(to_transferee);
4752 target_complete_sound = pbx_builtin_getvar_helper(to_transferee,
4753 "ATTENDED_TRANSFER_COMPLETE_SOUND");
4754 if (!ast_strlen_zero(target_complete_sound)) {
4755 target_complete_sound = ast_strdupa(target_complete_sound);
4756 } else {
4757 target_complete_sound = NULL;
4758 }
4759 ast_channel_unlock(to_transferee);
4760 }
4761 if (target_complete_sound) {
4762 ast_bridge_channel_write_playfile(to_target_bridge_channel, NULL,
4763 target_complete_sound, NULL);
4764 }
4765 }
4766
4767 /* Let's get the easy one out of the way first */
4768 if (to_transferee_bridge && to_target_bridge) {
4769
4770 if (!to_transferee_bridge_channel || !to_target_bridge_channel) {
4772 goto end;
4773 }
4774
4775 ast_bridge_lock_both(to_transferee_bridge, to_target_bridge);
4776 res = two_bridge_attended_transfer(to_transferee, to_transferee_bridge_channel,
4777 to_transfer_target, to_target_bridge_channel,
4778 to_transferee_bridge, to_target_bridge, transfer_msg);
4779 ast_bridge_unlock(to_transferee_bridge);
4780 ast_bridge_unlock(to_target_bridge);
4781
4782 hangup_target = 1;
4783 goto end;
4784 }
4785
4786 the_bridge = to_transferee_bridge ?: to_target_bridge;
4787 chan_bridged = to_transferee_bridge ? to_transferee : to_transfer_target;
4788 chan_unbridged = to_transferee_bridge ? to_transfer_target : to_transferee;
4789
4790 /*
4791 * Race condition makes it possible for app to be NULL, so get the app prior to
4792 * transferring with a fallback of "unknown".
4793 */
4794 app = ast_strdupa(ast_channel_appl(chan_unbridged) ?: "unknown");
4795
4796 {
4797 int chan_count;
4799
4800 channels = ast_bridge_peers_nolock(the_bridge);
4801 if (!channels) {
4803 goto end;
4804 }
4805 chan_count = ao2_container_count(channels);
4806 if (chan_count <= 1) {
4808 goto end;
4809 }
4810 transfer_prohibited = ast_test_flag(&the_bridge->feature_flags,
4812 do_bridge_transfer = ast_test_flag(&the_bridge->feature_flags,
4814 chan_count > 2;
4815 }
4816
4817 if (transfer_prohibited) {
4819 goto end;
4820 }
4821
4822 set_transfer_variables_all(to_transferee, channels, 1);
4823
4824 if (do_bridge_transfer) {
4825 /*
4826 * Hang up the target if it was bridged. Note, if it is not bridged
4827 * it is hung up during the masquerade.
4828 */
4829 hangup_target = chan_bridged == to_transfer_target;
4830 ast_bridge_lock(the_bridge);
4831 res = attended_transfer_bridge(chan_bridged, chan_unbridged, the_bridge, NULL, transfer_msg);
4832 ast_bridge_unlock(the_bridge);
4833 goto end;
4834 }
4835
4836 transferee = get_transferee(channels, chan_bridged);
4837 if (!transferee) {
4839 goto end;
4840 }
4841
4842 if (bridge_channel_internal_queue_attended_transfer(transferee, chan_unbridged)) {
4844 goto end;
4845 }
4846
4847 ast_bridge_remove(the_bridge, chan_bridged);
4848
4851
4852end:
4853 if ((res == AST_BRIDGE_TRANSFER_SUCCESS && hangup_target) || res == AST_BRIDGE_TRANSFER_FAIL) {
4854 ast_softhangup(to_transfer_target, AST_SOFTHANGUP_DEV);
4855 }
4856
4857 transfer_msg->result = res;
4859 return res;
4860}
static const char app[]
Definition: app_adsiprog.c:56
ast_mutex_t lock
Definition: app_sla.c:331
#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:4182
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:4611
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:4221
struct ast_bridge * ast_bridge_transfer_acquire_bridge(struct ast_channel *chan)
Acquire the channel's bridge for transfer purposes.
Definition: bridge.c:4408
int ast_bridge_remove(struct ast_bridge *bridge, struct ast_channel *chan)
Remove a channel from a bridge.
Definition: bridge.c:1951
static void set_transfer_variables_all(struct ast_channel *transferer, struct ao2_container *channels, int is_attended)
Definition: bridge.c:4383
ast_transfer_result
Definition: bridge.h:1098
@ AST_BRIDGE_TRANSFER_NOT_PERMITTED
Definition: bridge.h:1102
@ AST_BRIDGE_TRANSFER_SUCCESS
Definition: bridge.h:1100
@ AST_BRIDGE_TRANSFER_INVALID
Definition: bridge.h:1104
@ AST_BRIDGE_TRANSFER_FAIL
Definition: bridge.h:1106
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:2471
@ AST_SOFTHANGUP_DEV
Definition: channel.h:1121
char * end
Definition: eagi_proxy.c:73
#define SCOPED_LOCK(varname, lock, lockfunc, unlockfunc)
Scoped Locks.
Definition: lock.h:583
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 4425 of file bridge.c.

4428{
4429 RAII_VAR(struct ast_bridge *, bridge, NULL, ao2_cleanup);
4430 RAII_VAR(struct ast_bridge_channel *, bridge_channel, NULL, ao2_cleanup);
4432 RAII_VAR(struct ast_channel *, transferee, NULL, ast_channel_cleanup);
4433 RAII_VAR(struct transfer_channel_data *, user_data_wrapper, NULL, ao2_cleanup);
4434 RAII_VAR(struct ast_blind_transfer_message *, transfer_message, NULL, ao2_cleanup);
4435 int do_bridge_transfer;
4436 int transfer_prohibited;
4437 enum ast_transfer_result transfer_result;
4438
4439 transfer_message = ast_blind_transfer_message_create(is_external, transferer, exten, context);
4440 if (!transfer_message) {
4441 /* Out of memory. Not even possible to publish a Stasis message about the
4442 * failure
4443 */
4444 ast_log(LOG_ERROR, "Unable to allocate memory for blind transfer publication from %s\n",
4445 ast_channel_name(transferer));
4447 }
4448
4449 bridge = ast_bridge_transfer_acquire_bridge(transferer);
4450 if (!bridge) {
4451 transfer_result = AST_BRIDGE_TRANSFER_INVALID;
4452 goto publish;
4453 }
4454
4455 ast_bridge_lock(bridge);
4456 transfer_message->bridge = ast_bridge_snapshot_create(bridge);
4457 ast_bridge_unlock(bridge);
4458 if (!transfer_message->bridge) {
4459 transfer_result = AST_BRIDGE_TRANSFER_FAIL;
4460 goto publish;
4461 }
4462
4463 transferee = ast_bridge_peer(bridge, transferer);
4464 if (transferee) {
4465 transfer_message->transferee = ast_channel_snapshot_get_latest(ast_channel_uniqueid(transferee));
4466 if (!transfer_message->transferee) {
4467 transfer_result = AST_BRIDGE_TRANSFER_FAIL;
4468 goto publish;
4469 }
4470 }
4471
4472 ast_channel_lock(transferer);
4473 bridge_channel = ast_channel_get_bridge_channel(transferer);
4474 ast_channel_unlock(transferer);
4475 if (!bridge_channel) {
4476 transfer_result = AST_BRIDGE_TRANSFER_INVALID;
4477 goto publish;
4478 }
4479
4480 user_data_wrapper = ao2_alloc(sizeof(*user_data_wrapper), NULL);
4481 if (!user_data_wrapper) {
4482 transfer_result = AST_BRIDGE_TRANSFER_FAIL;
4483 goto publish;
4484 }
4485
4486 user_data_wrapper->data = user_data;
4487
4488 /* Take off hold if they are on hold. */
4489 ast_bridge_channel_write_unhold(bridge_channel);
4490
4491 transfer_result = try_parking(transferer, context, exten, new_channel_cb, user_data_wrapper);
4492 if (transfer_result == AST_BRIDGE_TRANSFER_SUCCESS) {
4493 goto publish;
4494 }
4495
4496 /* Since parking didn't take control of the user_data_wrapper, we are just going to raise the completed flag now. */
4497 user_data_wrapper->completed = 1;
4498
4499 {
4501
4503 if (!channels) {
4504 transfer_result = AST_BRIDGE_TRANSFER_FAIL;
4505 goto publish;
4506 }
4507 if (ao2_container_count(channels) <= 1) {
4508 transfer_result = AST_BRIDGE_TRANSFER_INVALID;
4509 goto publish;
4510 }
4511 transfer_prohibited = ast_test_flag(&bridge->feature_flags,
4513 do_bridge_transfer = ast_test_flag(&bridge->feature_flags,
4516 }
4517
4518 if (transfer_prohibited) {
4519 transfer_result = AST_BRIDGE_TRANSFER_NOT_PERMITTED;
4520 goto publish;
4521 }
4522
4523 set_transfer_variables_all(transferer, channels, 0);
4524
4525 if (do_bridge_transfer) {
4526 transfer_result = blind_transfer_bridge(is_external, transferer, bridge,
4527 exten, context, transferee, new_channel_cb, user_data_wrapper, transfer_message);
4528 goto publish;
4529 }
4530
4531 /* Reaching this portion means that we're dealing with a two-party bridge */
4532
4533 if (!transferee) {
4534 transfer_result = AST_BRIDGE_TRANSFER_FAIL;
4535 goto publish;
4536 }
4537
4539 new_channel_cb, user_data_wrapper)) {
4540 transfer_result = AST_BRIDGE_TRANSFER_FAIL;
4541 goto publish;
4542 }
4543
4544 ast_bridge_remove(bridge, transferer);
4545 transfer_result = AST_BRIDGE_TRANSFER_SUCCESS;
4546
4547publish:
4548 transfer_message->result = transfer_result;
4549 ast_bridge_publish_blind_transfer(transfer_message);
4550 return transfer_result;
4551}
#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:4075
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:4326
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:4111
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:2969
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:1119

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 2920 of file bridge.c.

2921{
2922 struct ast_bridge *chan_bridge;
2923 struct ast_bridge *peer_bridge;
2924 struct ast_bridge_channel *chan_bridge_channel;
2925 struct ast_bridge_channel *peer_bridge_channel;
2926 int res = 0;
2927
2928 chan_bridge = optimize_lock_chan_stack(chan);
2929 if (!chan_bridge) {
2930 return res;
2931 }
2932 chan_bridge_channel = ast_channel_internal_bridge_channel(chan);
2933
2934 peer_bridge = optimize_lock_peer_stack(peer);
2935 if (peer_bridge) {
2936 peer_bridge_channel = ast_channel_internal_bridge_channel(peer);
2937
2938 res = try_swap_optimize_out(chan_bridge, chan_bridge_channel,
2939 peer_bridge, peer_bridge_channel, pvt);
2940 if (!res) {
2941 res = try_merge_optimize_out(chan_bridge, chan_bridge_channel,
2942 peer_bridge, peer_bridge_channel, pvt);
2943 } else if (0 < res) {
2944 res = 0;
2945 }
2946
2947 /* Release peer locks. */
2948 ast_bridge_unlock(peer_bridge);
2949 ast_bridge_channel_unlock(peer_bridge_channel);
2950 ast_channel_unlock(peer);
2951 }
2952
2953 /* Release chan locks. */
2954 ast_bridge_unlock(chan_bridge);
2955 ast_bridge_channel_unlock(chan_bridge_channel);
2956
2957 return res;
2958}
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:2869
static struct ast_bridge * optimize_lock_chan_stack(struct ast_channel *chan)
Definition: bridge.c:2579
static struct ast_bridge * optimize_lock_peer_stack(struct ast_channel *peer)
Definition: bridge.c:2624
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:2745
#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:3028

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 3028 of file bridge.c.

3029{
3030 struct ast_bridge_channel *bridge_channel;
3031/* XXX ASTERISK-21271 the case of a dissolved bridge while channel is suspended is not handled. */
3032
3034
3035 if (!(bridge_channel = bridge_find_channel(bridge, chan))) {
3037 return -1;
3038 }
3039
3041
3043
3044 return 0;
3045}
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 3816 of file bridge.c.

3817{
3819
3820 /* If the channel doesn't support video, we don't care about it */
3822 return;
3823 }
3824
3825 ast_bridge_lock(bridge);
3827
3828 if (data->chan_vsrc == chan) {
3829 data->average_talking_energy = talker_energy;
3830 } else if ((data->average_talking_energy < talker_energy) && is_keyframe) {
3831 if (data->chan_old_vsrc) {
3833 }
3834 if (data->chan_vsrc) {
3835 data->chan_old_vsrc = data->chan_vsrc;
3837 }
3838 data->chan_vsrc = ast_channel_ref(chan);
3839 data->average_talking_energy = talker_energy;
3840 ast_verb(5, "Video source in bridge '%s' (%s) is now '%s' (%s)\n",
3841 bridge->name, bridge->uniqueid,
3846 } else if ((data->average_talking_energy < talker_energy) && !is_keyframe) {
3848 } else if (!data->chan_vsrc && is_keyframe) {
3849 data->chan_vsrc = ast_channel_ref(chan);
3850 data->average_talking_energy = talker_energy;
3851 ast_verb(5, "Video source in bridge '%s' (%s) is now '%s' (%s)\n",
3852 bridge->name, bridge->uniqueid,
3857 } else if (!data->chan_old_vsrc && is_keyframe) {
3858 data->chan_old_vsrc = ast_channel_ref(chan);
3860 }
3861 ast_bridge_unlock(bridge);
3862}
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:121

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 1212 of file bridge.c.

1213{
1215 pbx_builtin_setvar_helper(chan, "BRIDGEPEER", name);
1216 pbx_builtin_setvar_helper(chan, "BRIDGEPVTCALLID", pvtid);
1218}
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 3951 of file bridge.c.

3952{
3953 switch (video_mode) {
3955 return "talker";
3957 return "single";
3959 return "sfu";
3961 default:
3962 return "none";
3963 }
3964}

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 174 of file bridge.c.

175{
176 return ao2_bump(bridges);
177}
#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 2960 of file bridge.c.

2962{
2963 struct merge_direction merge;
2964
2965 if (!bridge_allows_optimization(chan_bridge) || !bridge_allows_optimization(peer_bridge)) {
2967 }
2968
2969 switch (bridges_allow_swap_optimization(chan_bridge, peer_bridge)) {
2974 case SWAP_PROHIBITED:
2975 default:
2976 break;
2977 }
2978
2979 /* Two channels will be kicked from the bridges, the unreal;1 and unreal;2 channels */
2980 if (bridges_allow_merge_optimization(chan_bridge, peer_bridge, 2, &merge) != MERGE_ALLOWED) {
2982 }
2983
2984 if (merge.dest == chan_bridge) {
2986 } else {
2988 }
2989}
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:2835
static enum bridge_allow_swap bridges_allow_swap_optimization(struct ast_bridge *chan_bridge, struct ast_bridge *peer_bridge)
Definition: bridge.c:2689
static int bridge_allows_optimization(struct ast_bridge *bridge)
Definition: bridge.c:2560
@ AST_BRIDGE_OPTIMIZE_PROHIBITED
Definition: bridge.h:884
@ AST_BRIDGE_OPTIMIZE_MERGE_TO_CHAN_BRIDGE
Definition: bridge.h:880
@ AST_BRIDGE_OPTIMIZE_SWAP_TO_PEER_BRIDGE
Definition: bridge.h:878
@ AST_BRIDGE_OPTIMIZE_MERGE_TO_PEER_BRIDGE
Definition: bridge.h:882
@ AST_BRIDGE_OPTIMIZE_SWAP_TO_CHAN_BRIDGE
Definition: bridge.h:876

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 5543 of file bridge.c.

5544{
5546
5548 return -1;
5549 }
5550
5552 if (!bridge_manager) {
5553 return -1;
5554 }
5555
5558 if (!bridges) {
5559 return -1;
5560 }
5562
5564
5566
5567 ast_manager_register_xml_core("BridgeTechnologyList", 0, manager_bridge_tech_list);
5568 ast_manager_register_xml_core("BridgeTechnologySuspend", 0, manager_bridge_tech_suspend);
5569 ast_manager_register_xml_core("BridgeTechnologyUnsuspend", 0, manager_bridge_tech_unsuspend);
5570
5571 return 0;
5572}
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:172
static int manager_bridge_tech_list(struct mansession *s, const struct message *m)
Definition: bridge.c:5460
static int manager_bridge_tech_suspend(struct mansession *s, const struct message *m)
Definition: bridge.c:5450
static int manager_bridge_tech_unsuspend(struct mansession *s, const struct message *m)
Definition: bridge.c:5455
static struct ast_cli_entry bridge_cli[]
Definition: bridge.c:5404
static int bridge_sort_cmp(const void *obj_left, const void *obj_right, int flags)
Definition: bridge.c:4990
static void bridge_prnt_obj(void *v_obj, void *where, ao2_prnt_fn *prnt)
Definition: bridge.c:5513
static void bridge_cleanup(void)
Definition: bridge.c:5529
static struct bridge_manager_controller * bridge_manager_create(void)
Definition: bridge.c:4951
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:202
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 3798 of file bridge.c.

3799{
3801
3802 ast_bridge_lock(bridge);
3804 ast_bridge_unlock(bridge);
3805}
enum ast_bridge_video_sfu_remb_behavior remb_behavior
Definition: bridge.h:153

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_SUCCESSSuccesfully transferred the bridge

Definition at line 4221 of file bridge.c.

4224{
4225#define BRIDGE_LOCK_ONE_OR_BOTH(b1, b2) \
4226 do { \
4227 if (b2) { \
4228 ast_bridge_lock_both(b1, b2); \
4229 } else { \
4230 ast_bridge_lock(b1); \
4231 } \
4232 } while (0)
4233
4234 static const char *dest = "_attended@transfer/m";
4235 struct ast_channel *local_chan;
4236 int cause;
4237 int res;
4238 const char *app = NULL;
4239 struct ast_format_cap *caps;
4240
4241 ast_channel_lock(chan1);
4242 caps = ao2_bump(ast_channel_nativeformats(chan1));
4243 ast_channel_unlock(chan1);
4244
4245 local_chan = ast_request("Local", caps, NULL, chan1, dest, &cause);
4246
4247 ao2_cleanup(caps);
4248
4249 if (!local_chan) {
4251 }
4252
4253 ast_channel_lock_both(local_chan, chan1);
4256 ast_channel_unlock(local_chan);
4257 ast_channel_unlock(chan1);
4258
4259 if (bridge2) {
4260 res = ast_local_setup_bridge(local_chan, bridge2, chan2, NULL);
4261 } else {
4263 res = ast_local_setup_masquerade(local_chan, chan2);
4264 }
4265
4266 if (res) {
4267 ast_hangup(local_chan);
4269 }
4270
4271 /*
4272 * Since bridges need to be unlocked before entering ast_bridge_impart and
4273 * core_local may call into it then the bridges need to be unlocked here.
4274 */
4275 ast_bridge_unlock(bridge1);
4276 if (bridge2) {
4277 ast_bridge_unlock(bridge2);
4278 }
4279
4280 if (ast_call(local_chan, dest, 0)) {
4281 ast_hangup(local_chan);
4282 BRIDGE_LOCK_ONE_OR_BOTH(bridge1, bridge2);
4284 }
4285
4286 /* Get a ref for use later since this one is being stolen */
4287 ao2_ref(local_chan, +1);
4288 if (ast_bridge_impart(bridge1, local_chan, chan1, NULL,
4290 ast_hangup(local_chan);
4291 ao2_cleanup(local_chan);
4292 BRIDGE_LOCK_ONE_OR_BOTH(bridge1, bridge2);
4294 }
4295 BRIDGE_LOCK_ONE_OR_BOTH(bridge1, bridge2);
4296
4297 if (bridge2) {
4298 void *tech;
4299 struct ast_channel *locals[2];
4300
4301 /* Have to lock everything just in case a hangup comes in early */
4302 ast_local_lock_all(local_chan, &tech, &locals[0], &locals[1]);
4303 if (!locals[0] || !locals[1]) {
4304 ast_log(LOG_ERROR, "Transfer failed probably due to an early hangup - "
4305 "missing other half of '%s'\n", ast_channel_name(local_chan));
4307 ao2_cleanup(local_chan);
4309 }
4310
4311 /* Make sure the peer is properly set */
4312 if (local_chan != locals[0]) {
4313 SWAP(locals[0], locals[1]);
4314 }
4315
4318 } else {
4319 ast_attended_transfer_message_add_app(transfer_msg, app, local_chan);
4320 }
4321
4322 ao2_cleanup(local_chan);
4324}
#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:6461
@ AST_CHANNEL_REQUESTOR_REPLACEMENT
Definition: channel.h:1479
#define ast_channel_lock_both(chan1, chan2)
Lock two channels.
Definition: channel.h:2929
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:6434
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:6354
static struct ao2_container * locals
Definition: core_local.c:138
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:256
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:601
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:241
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:643
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 4111 of file bridge.c.

4117{
4118 struct ast_channel *local;
4119 char chan_name[AST_MAX_EXTENSION + AST_MAX_CONTEXT + 2];
4120 int cause;
4121 struct ast_format_cap *caps;
4122
4123 ast_channel_lock(transferer);
4124 caps = ao2_bump(ast_channel_nativeformats(transferer));
4125 ast_channel_unlock(transferer);
4126
4127 snprintf(chan_name, sizeof(chan_name), "%s@%s", exten, context);
4128 local = ast_request("Local", caps, NULL, transferer,
4129 chan_name, &cause);
4130
4131 ao2_cleanup(caps);
4132
4133 if (!local) {
4135 }
4136
4137 ast_channel_lock_both(local, transferer);
4139
4141 if (!transfer_message->replace_channel) {
4142 ast_hangup(local);
4144 }
4145
4147 ast_channel_unlock(local);
4148 ast_channel_unlock(transferer);
4149
4150 if (new_channel_cb) {
4151 new_channel_cb(local, user_data_wrapper, AST_BRIDGE_TRANSFER_MULTI_PARTY);
4152 }
4153
4154 if (ast_call(local, chan_name, 0)) {
4155 ast_hangup(local);
4157 }
4158
4159 if (ast_bridge_impart(bridge, local, transferer, NULL,
4161 ast_hangup(local);
4163 }
4164
4166}
@ AST_BRIDGE_TRANSFER_MULTI_PARTY
Definition: bridge.h:1113
#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 588 of file bridge.c.

589{
590#if 0 /* In case we need to know when the destructor is calling us. */
591 int in_destructor = !ao2_ref(bridge, 0);
592#endif
593
594 switch (action->subclass.integer) {
596 ast_bridge_unlock(bridge);
597 bridge_tech_deferred_destroy(bridge, action);
598 ast_bridge_lock(bridge);
599 break;
601 ast_bridge_unlock(bridge);
602 bridge->v_table->dissolving(bridge);
603 ast_bridge_lock(bridge);
604 break;
605 default:
606 /* Unexpected deferred action type. Should never happen. */
607 ast_assert(0);
608 break;
609 }
610}
static void bridge_tech_deferred_destroy(struct ast_bridge *bridge, struct ast_frame *action)
Definition: bridge.c:560
@ BRIDGE_CHANNEL_ACTION_DEFERRED_TECH_DESTROY
@ BRIDGE_CHANNEL_ACTION_DEFERRED_DISSOLVING
ast_bridge_dissolving_fn dissolving
Definition: bridge.h:263
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 706 of file bridge.c.

707{
708 struct ast_bridge *bridge;
709
710 /* Check v_table that all methods are present. */
711 if (!v_table
712 || !v_table->name
713 || !v_table->destroy
715 || !v_table->push
716 || !v_table->pull
719 ast_log(LOG_ERROR, "Virtual method table for bridge class %s not complete.\n",
720 v_table && v_table->name ? v_table->name : "<unknown>");
721 ast_assert(0);
722 return NULL;
723 }
724
725 bridge = ao2_alloc(size, destroy_bridge);
726 if (!bridge) {
727 return NULL;
728 }
729
730 if (ast_string_field_init(bridge, 80)) {
731 ao2_cleanup(bridge);
732 return NULL;
733 }
734
735 bridge->v_table = v_table;
736
738
739 return bridge;
740}
static void destroy_bridge(void *obj)
Definition: bridge.c:640
@ AST_MEDIA_TYPE_END
Definition: codec.h:36
ast_bridge_push_channel_fn push
Definition: bridge.h:265
const char * name
Definition: bridge.h:259
ast_bridge_destructor_fn destroy
Definition: bridge.h:261
ast_bridge_merge_priority_fn get_merge_priority
Definition: bridge.h:271
ast_bridge_pull_channel_fn pull
Definition: bridge.h:267
struct ast_vector_int media_types
Definition: bridge.h:404
#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 2560 of file bridge.c.

2561{
2562 return !(bridge->inhibit_merge
2563 || bridge->dissolved
2565}
unsigned int dissolved
Definition: bridge.h:390
unsigned int inhibit_merge
Count of the active temporary requests to inhibit bridge merges. Zero if merges are allowed.
Definition: bridge.h:384

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 821 of file bridge.c.

822{
823}

◆ bridge_base_dissolving()

static void bridge_base_dissolving ( struct ast_bridge self)
static

Definition at line 832 of file bridge.c.

833{
834 ao2_unlink(bridges, self);
835}
#define ao2_unlink(container, obj)
Remove an object from a container.
Definition: astobj2.h:1578

References ao2_unlink, and bridges.

◆ bridge_base_get_merge_priority()

static int bridge_base_get_merge_priority ( struct ast_bridge self)
static

Definition at line 898 of file bridge.c.

899{
900 return 0;
901}

◆ 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:923
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:742
struct ast_bridge * bridge_alloc(size_t size, const struct ast_bridge_methods *v_table)
Definition: bridge.c:706

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

Definition at line 742 of file bridge.c.

743{
744 char uuid_hold[AST_UUID_STR_LEN];
745
746 if (!self) {
747 return NULL;
748 }
749
750 if (!ast_strlen_zero(id)) {
751 ast_string_field_set(self, uniqueid, id);
752 } else {
754 ast_string_field_set(self, uniqueid, uuid_hold);
755 }
756 ast_string_field_set(self, creator, creator);
757 if (!ast_strlen_zero(creator)) {
759 }
760
761 ast_set_flag(&self->feature_flags, flags);
762 self->allowed_capabilities = capabilities;
763
764 if (!(flags & AST_BRIDGE_FLAG_INVISIBLE)) {
765 if (bridge_topics_init(self) != 0) {
766 ast_log(LOG_WARNING, "Bridge %s: Could not initialize topics\n",
767 self->uniqueid);
768 ao2_ref(self, -1);
769 return NULL;
770 }
771 }
772
773 /* Use our helper function to find the "best" bridge technology. */
774 self->technology = find_best_technology(capabilities, self);
775 if (!self->technology) {
776 ast_log(LOG_WARNING, "Bridge %s: Could not create class %s. No technology to support it.\n",
777 self->uniqueid, self->v_table->name);
778 ao2_ref(self, -1);
779 return NULL;
780 }
781
782 /* Pass off the bridge to the technology to manipulate if needed */
783 ast_debug(1, "Bridge %s: calling %s technology constructor\n",
784 self->uniqueid, self->technology->name);
785 if (self->technology->create && self->technology->create(self)) {
786 ast_log(LOG_WARNING, "Bridge %s: failed to setup bridge technology %s\n",
787 self->uniqueid, self->technology->name);
788 ao2_ref(self, -1);
789 return NULL;
790 }
791 ast_debug(1, "Bridge %s: calling %s technology start\n",
792 self->uniqueid, self->technology->name);
793 if (self->technology->start && self->technology->start(self)) {
794 ast_log(LOG_WARNING, "Bridge %s: failed to start bridge technology %s\n",
795 self->uniqueid, self->technology->name);
796 ao2_ref(self, -1);
797 return NULL;
798 }
799
800 if (!(flags & AST_BRIDGE_FLAG_INVISIBLE)) {
801 if (!ast_bridge_topic(self)) {
802 ao2_ref(self, -1);
803 return NULL;
804 }
805 }
806
807 self->creationtime = ast_tvnow();
808
809 return self;
810}
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:499
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:408
uint32_t allowed_capabilities
Definition: bridge.h:371
#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_FLAG_INVISIBLE, ast_bridge_topic(), 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_topics_init(), ast_bridge_technology::create, ast_bridge::creationtime, ast_bridge::creator, ast_bridge::feature_flags, find_best_technology(), LOG_WARNING, name, ast_bridge_methods::name, ast_bridge_technology::name, NULL, 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 882 of file bridge.c.

883{
884 self->reconfigured = 1;
885}
unsigned int reconfigured
Definition: bridge.h:388

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 867 of file bridge.c.

868{
870}
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:3501
@ 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 852 of file bridge.c.

853{
854 return 0;
855}

◆ 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 918 of file bridge.c.

919{
920 return 0;
921}

◆ 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 2007 of file bridge.c.

2008{
2009 struct ast_bridge *old_bridge;
2010
2011 ao2_ref(new_bridge, +1);
2012 ast_bridge_channel_lock(bridge_channel);
2013 ast_channel_lock(bridge_channel->chan);
2014 old_bridge = bridge_channel->bridge;
2015 bridge_channel->bridge = new_bridge;
2016 ast_channel_internal_bridge_set(bridge_channel->chan, new_bridge);
2017 ast_channel_unlock(bridge_channel->chan);
2018 ast_bridge_channel_unlock(bridge_channel);
2019 ao2_ref(old_bridge, -1);
2020}
#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 433 of file bridge.c.

434{
435 /* Tell the bridge technology we are joining so they set us up */
436 ast_debug(1, "Bridge %s: %p(%s) is joining %s technology\n",
437 bridge->uniqueid, bridge_channel, ast_channel_name(bridge_channel->chan),
438 bridge->technology->name);
439 if (bridge->technology->join
440 && bridge->technology->join(bridge, bridge_channel)) {
441 /* We cannot leave the channel partially in the bridge so we must kick it out */
442 ast_debug(1, "Bridge %s: %p(%s) failed to join %s technology (Kicking it out)\n",
443 bridge->uniqueid, bridge_channel, ast_channel_name(bridge_channel->chan),
444 bridge->technology->name);
445 bridge_channel->just_joined = 1;
447 return;
448 }
449
450 bridge_channel->just_joined = 0;
451
452 /*
453 * When a channel joins the bridge its streams need to be mapped to the bridge's
454 * media types vector. This way all streams map to the same media type index for
455 * a given channel.
456 */
457 if (bridge_channel->bridge->technology->stream_topology_changed) {
458 bridge_channel->bridge->technology->stream_topology_changed(
459 bridge_channel->bridge, bridge_channel);
460 } else {
461 ast_bridge_channel_stream_map(bridge_channel);
462 }
463}
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 1711 of file bridge.c.

1712{
1713 struct ast_bridge_channel *bridge_channel = data;
1714 int res = 0;
1715
1716 if (bridge_channel->callid) {
1717 ast_callid_threadassoc_add(bridge_channel->callid);
1718 }
1719
1720 res = bridge_channel_internal_join(bridge_channel);
1721
1722 /*
1723 * cleanup
1724 *
1725 * If bridge_channel->swap is not NULL then the join failed.
1726 */
1727 ao2_t_cleanup(bridge_channel->swap, "Bridge complete: Departable impart join failed");
1728 bridge_channel->swap = NULL;
1729 ast_bridge_features_destroy(bridge_channel->features);
1730 bridge_channel->features = NULL;
1731
1734 /* If join failed there will be impart threads waiting. */
1735 bridge_channel_impart_signal(bridge_channel->chan);
1736 ast_bridge_discard_after_goto(bridge_channel->chan);
1737
1738 return NULL;
1739}
@ 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:2308

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 1549 of file bridge.c.

1550{
1551 struct ast_datastore *datastore;
1552 struct bridge_channel_impart_ds_head *ds_head;
1553
1554 ast_channel_lock(chan);
1555
1557 if (!datastore) {
1559 if (!datastore) {
1560 ast_channel_unlock(chan);
1561 return -1;
1562 }
1563 ds_head = ast_calloc(1, sizeof(*ds_head));
1564 if (!ds_head) {
1565 ast_channel_unlock(chan);
1566 ast_datastore_free(datastore);
1567 return -1;
1568 }
1569 datastore->data = ds_head;
1570 ast_channel_datastore_add(chan, datastore);
1571 } else {
1572 ds_head = datastore->data;
1573 ast_assert(ds_head != NULL);
1574 }
1575
1576 AST_LIST_INSERT_TAIL(ds_head, cond, node);
1577
1578 ast_channel_unlock(chan);
1579 return 0;
1580}
#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:1532
int ast_channel_datastore_add(struct ast_channel *chan, struct ast_datastore *datastore)
Add a datastore to a channel.
Definition: channel.c:2385
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:2399
#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 1508 of file bridge.c.

1509{
1511 ast_free(doomed);
1512}
static void bridge_channel_impart_ds_head_signal(struct bridge_channel_impart_ds_head *ds_head)
Definition: bridge.c:1494

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 1523 of file bridge.c.

1524{
1525 /*
1526 * Signal any waiting impart threads. The masquerade is going to kill
1527 * old_chan and we don't need to be waiting on new_chan.
1528 */
1530}

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 1494 of file bridge.c.

1495{
1496 if (ds_head) {
1498
1499 while ((cond = AST_LIST_REMOVE_HEAD(ds_head, node))) {
1500 ast_mutex_lock(&cond->lock);
1501 cond->done = 1;
1502 ast_cond_signal(&cond->cond);
1503 ast_mutex_unlock(&cond->lock);
1504 }
1505 }
1506}
#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:190
#define ast_mutex_lock(a)
Definition: lock.h:189
#define ast_cond_signal(cond)
Definition: lock.h:203

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 1601 of file bridge.c.

1602{
1603 ast_mutex_lock(&cond->lock);
1604 while (!cond->done) {
1605 ast_cond_wait(&cond->cond, &cond->lock);
1606 }
1607 ast_mutex_unlock(&cond->lock);
1608}
#define ast_cond_wait(cond, mutex)
Definition: lock.h:205

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 1742 of file bridge.c.

1743{
1744 struct ast_bridge_channel *bridge_channel = data;
1745 struct ast_channel *chan;
1746
1747 if (bridge_channel->callid) {
1749 }
1750
1752 chan = bridge_channel->chan;
1753
1754 /* cleanup */
1755 ast_channel_lock(chan);
1757 ast_channel_unlock(chan);
1758 /* Lock here for ast_bridge_channel_get_chan */
1762 /* If bridge_channel->swap is not NULL then the join failed. */
1763 ao2_t_cleanup(bridge_channel->swap, "Bridge complete: Independent impart join failed");
1767
1769
1771 /* If join failed there will be impart threads waiting. */
1774 return NULL;
1775}
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 2022 of file bridge.c.

2023{
2024 struct ast_bridge_features *features = bridge_channel->features;
2025 struct ast_bridge_hook *hook;
2026 struct ao2_iterator iter;
2027
2028 /* Run any moving hooks. */
2029 iter = ao2_iterator_init(features->other_hooks, 0);
2030 for (; (hook = ao2_iterator_next(&iter)); ao2_ref(hook, -1)) {
2031 int remove_me;
2033
2034 if (hook->type != AST_BRIDGE_HOOK_TYPE_MOVE) {
2035 continue;
2036 }
2038 remove_me = move_cb(bridge_channel, hook->hook_pvt, src, dst);
2039 if (remove_me) {
2040 ast_debug(1, "Move detection hook %p is being removed from %p(%s)\n",
2041 hook, bridge_channel, ast_channel_name(bridge_channel->chan));
2042 ao2_unlink(features->other_hooks, hook);
2043 }
2044 }
2045 ao2_iterator_destroy(&iter);
2046}
#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 5529 of file bridge.c.

5530{
5531 ast_manager_unregister("BridgeTechnologyList");
5532 ast_manager_unregister("BridgeTechnologySuspend");
5533 ast_manager_unregister("BridgeTechnologyUnsuspend");
5535 ao2_container_unregister("bridges");
5536
5538 bridges = NULL;
5541}
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:8041

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 474 of file bridge.c.

475{
476 struct ast_bridge_channel *bridge_channel;
477
478 if (bridge->dissolved) {
479 /*
480 * No sense in completing the join on channels for a dissolved
481 * bridge. They are just going to be removed soon anyway.
482 * However, we do have reason to abort here because the bridge
483 * technology may not be able to handle the number of channels
484 * still in the bridge.
485 */
486 return;
487 }
488
489 AST_LIST_TRAVERSE(&bridge->channels, bridge_channel, entry) {
491 if (!bridge_channel->just_joined) {
492 continue;
493 }
494 bridge_channel_complete_join(bridge, bridge_channel);
495 }
496}
static void bridge_channel_complete_join(struct ast_bridge *bridge, struct ast_bridge_channel *bridge_channel)
Definition: bridge.c:433
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, and ast_bridge_channel::just_joined.

Referenced by bridge_reconfigured().

◆ bridge_dissolve()

void bridge_dissolve ( struct ast_bridge bridge,
int  cause 
)

Definition at line 315 of file bridge.c.

316{
317 struct ast_bridge_channel *bridge_channel;
318 struct ast_frame action = {
321 };
322
323 if (bridge->dissolved) {
324 return;
325 }
326 bridge->dissolved = 1;
327
328 if (cause <= 0) {
330 }
331 bridge->cause = cause;
332
333 ast_debug(1, "Bridge %s: dissolving bridge with cause %d(%s)\n",
334 bridge->uniqueid, cause, ast_cause2str(cause));
335
336 AST_LIST_TRAVERSE(&bridge->channels, bridge_channel, entry) {
337 ast_bridge_channel_leave_bridge(bridge_channel,
339 }
340
341 /* Must defer dissolving bridge because it is already locked. */
342 ast_bridge_queue_action(bridge, &action);
343}
int ast_bridge_queue_action(struct ast_bridge *bridge, struct ast_frame *action)
Put an action onto the specified bridge.
Definition: bridge.c:303
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:386
enum ast_frame_type frametype

References ast_bridge_channel_leave_bridge(), ast_bridge_queue_action(), ast_cause2str(), AST_CAUSE_NORMAL_CLEARING, ast_debug, AST_FRAME_BRIDGE_ACTION, AST_LIST_TRAVERSE, BRIDGE_CHANNEL_ACTION_DEFERRED_DISSOLVING, BRIDGE_CHANNEL_STATE_END_NO_DISSOLVE, ast_bridge::cause, ast_bridge::channels, ast_bridge::dissolved, ast_frame::frametype, and ast_bridge::uniqueid.

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 355 of file bridge.c.

356{
357 if (bridge->dissolved) {
358 return;
359 }
360
361 if (bridge_channel->features->usable
362 && ast_test_flag(&bridge_channel->features->feature_flags,
364 /* The stolen channel controlled the bridge it was stolen from. */
365 bridge_dissolve(bridge, 0);
366 return;
367 }
368 if (bridge->num_channels < 2
370 /*
371 * The stolen channel has not left enough channels to keep the
372 * bridge alive. Assume the stolen channel hung up.
373 */
374 bridge_dissolve(bridge, 0);
375 return;
376 }
377}

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 2048 of file bridge.c.

2050{
2051 struct ast_bridge_channel *bridge_channel;
2052 unsigned int idx;
2053
2054 ast_debug(1, "Merging bridge %s into bridge %s\n",
2055 src_bridge->uniqueid, dst_bridge->uniqueid);
2056
2057 ast_bridge_publish_merge(dst_bridge, src_bridge);
2058
2059 /*
2060 * Move channels from src_bridge over to dst_bridge.
2061 *
2062 * We must use AST_LIST_TRAVERSE_SAFE_BEGIN() because
2063 * bridge_channel_internal_pull() alters the list we are traversing.
2064 */
2065 AST_LIST_TRAVERSE_SAFE_BEGIN(&src_bridge->channels, bridge_channel, entry) {
2066 if (bridge_channel->state != BRIDGE_CHANNEL_STATE_WAIT) {
2067 /*
2068 * The channel is already leaving let it leave normally because
2069 * pulling it may delete hooks that should run for this channel.
2070 */
2071 continue;
2072 }
2073 if (ast_test_flag(&bridge_channel->features->feature_flags,
2075 continue;
2076 }
2077
2078 if (kick_me) {
2079 for (idx = 0; idx < num_kick; ++idx) {
2080 if (bridge_channel == kick_me[idx]) {
2081 ast_bridge_channel_leave_bridge(bridge_channel,
2083 break;
2084 }
2085 }
2086 }
2087 bridge_channel_internal_pull(bridge_channel);
2088 if (bridge_channel->state != BRIDGE_CHANNEL_STATE_WAIT) {
2089 /*
2090 * The channel died as a result of being pulled or it was
2091 * kicked. Leave it pointing to the original bridge.
2092 */
2093 continue;
2094 }
2095
2096 bridge_channel_moving(bridge_channel, bridge_channel->bridge, dst_bridge);
2097
2098 /* Point to new bridge.*/
2099 bridge_channel_change_bridge(bridge_channel, dst_bridge);
2100
2101 if (bridge_channel_internal_push(bridge_channel)) {
2102 ast_bridge_features_remove(bridge_channel->features,
2104 ast_bridge_channel_leave_bridge(bridge_channel,
2106 }
2107 }
2109
2110 if (kick_me) {
2111 /*
2112 * Now we can kick any channels in the dst_bridge without
2113 * potentially dissolving the bridge.
2114 */
2115 for (idx = 0; idx < num_kick; ++idx) {
2116 bridge_channel = kick_me[idx];
2117 ast_bridge_channel_lock(bridge_channel);
2118 if (bridge_channel->state == BRIDGE_CHANNEL_STATE_WAIT) {
2121 bridge_channel_internal_pull(bridge_channel);
2122 }
2123 ast_bridge_channel_unlock(bridge_channel);
2124 }
2125 }
2126
2127 bridge_reconfigured(dst_bridge, !optimized);
2128 bridge_reconfigured(src_bridge, !optimized);
2129
2130 ast_debug(1, "Merged bridge %s into bridge %s\n",
2131 src_bridge->uniqueid, dst_bridge->uniqueid);
2132}
static void bridge_channel_change_bridge(struct ast_bridge_channel *bridge_channel, struct ast_bridge *new_bridge)
Definition: bridge.c:2007
static void bridge_channel_moving(struct ast_bridge_channel *bridge_channel, struct ast_bridge *src, struct ast_bridge *dst)
Definition: bridge.c:2022
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_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 2314 of file bridge.c.

2316{
2317 struct ast_bridge *orig_bridge;
2318 int was_in_bridge;
2319 int res = 0;
2320
2321 if (bridge_channel->swap) {
2322 ast_debug(1, "Moving %p(%s) into bridge %s swapping with %s\n",
2323 bridge_channel, ast_channel_name(bridge_channel->chan), dst_bridge->uniqueid,
2324 ast_channel_name(bridge_channel->swap));
2325 } else {
2326 ast_debug(1, "Moving %p(%s) into bridge %s\n",
2327 bridge_channel, ast_channel_name(bridge_channel->chan), dst_bridge->uniqueid);
2328 }
2329
2330 orig_bridge = bridge_channel->bridge;
2331 was_in_bridge = bridge_channel->in_bridge;
2332
2333 bridge_channel_internal_pull(bridge_channel);
2334 if (bridge_channel->state != BRIDGE_CHANNEL_STATE_WAIT) {
2335 /*
2336 * The channel died as a result of being pulled. Leave it
2337 * pointing to the original bridge.
2338 *
2339 * Clear out the swap channel pointer. A ref is not held
2340 * by bridge_channel->swap at this point.
2341 */
2342 bridge_channel->swap = NULL;
2343 bridge_reconfigured(orig_bridge, 0);
2344 return -1;
2345 }
2346
2347 /* Point to new bridge.*/
2348 ao2_ref(orig_bridge, +1);/* Keep a ref in case the push fails. */
2349 bridge_channel_change_bridge(bridge_channel, dst_bridge);
2350
2351 bridge_channel_moving(bridge_channel, orig_bridge, dst_bridge);
2352
2353 if (bridge_channel_internal_push_full(bridge_channel, optimized)) {
2354 /* Try to put the channel back into the original bridge. */
2355 ast_bridge_features_remove(bridge_channel->features,
2357 if (attempt_recovery && was_in_bridge) {
2358 /* Point back to original bridge. */
2359 bridge_channel_change_bridge(bridge_channel, orig_bridge);
2360
2361 if (bridge_channel_internal_push(bridge_channel)) {
2362 ast_bridge_features_remove(bridge_channel->features,
2364 ast_bridge_channel_leave_bridge(bridge_channel,
2366 }
2367 } else {
2368 ast_bridge_channel_leave_bridge(bridge_channel,
2370 bridge_channel_settle_owed_events(orig_bridge, bridge_channel);
2371 }
2372 res = -1;
2373 } else if (!optimized) {
2374 bridge_channel_settle_owed_events(orig_bridge, bridge_channel);
2375 }
2376
2377 bridge_reconfigured(dst_bridge, !optimized);
2378 bridge_reconfigured(orig_bridge, !optimized);
2379 ao2_ref(orig_bridge, -1);
2380 return res;
2381}
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 3539 of file bridge.c.

3540{
3541 const struct ast_bridge_hook_dtmf *hook_left = obj_left;
3542 const struct ast_bridge_hook_dtmf *hook_right = obj_right;
3543 const char *right_key = obj_right;
3544 int cmp;
3545
3546 switch (flags & (OBJ_POINTER | OBJ_KEY | OBJ_PARTIAL_KEY)) {
3547 default:
3548 case OBJ_POINTER:
3549 right_key = hook_right->dtmf.code;
3550 /* Fall through */
3551 case OBJ_KEY:
3552 cmp = strcasecmp(hook_left->dtmf.code, right_key);
3553 break;
3554 case OBJ_PARTIAL_KEY:
3555 cmp = strncasecmp(hook_left->dtmf.code, right_key, strlen(right_key));
3556 break;
3557 }
3558 return cmp;
3559}
#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 622 of file bridge.c.

623{
624 struct ast_frame *action;
625
626 while ((action = AST_LIST_REMOVE_HEAD(&bridge->action_queue, frame_list))) {
627 switch (action->frametype) {
629 bridge_action_bridge(bridge, action);
630 break;
631 default:
632 /* Unexpected deferred frame type. Should never happen. */
633 ast_assert(0);
634 break;
635 }
636 ast_frfree(action);
637 }
638}
static void bridge_action_bridge(struct ast_bridge *bridge, struct ast_frame *action)
Definition: bridge.c:588
#define ast_frfree(fr)
struct ast_bridge::@190 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 3139 of file bridge.c.

3140{
3141 struct ast_bridge_hook *hook = vhook;
3142
3143 if (hook->destructor) {
3144 hook->destructor(hook->hook_pvt);
3145 }
3146}

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 3162 of file bridge.c.

3167{
3168 struct ast_bridge_hook *hook;
3169
3170 /* Allocate new hook and setup it's basic variables */
3172 if (hook) {
3173 hook->callback = callback;
3174 hook->destructor = destructor;
3175 hook->hook_pvt = hook_pvt;
3177 }
3178
3179 return hook;
3180}
#define ao2_alloc_options(data_size, destructor_fn, options)
Definition: astobj2.h:404
static void bridge_hook_destroy(void *vhook)
Definition: bridge.c:3139
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 1777 of file bridge.c.

1783{
1784 int res = 0;
1785 struct ast_bridge_channel *bridge_channel;
1786
1787 /* Imparted channels cannot have a PBX. */
1788 if (ast_channel_pbx(chan)) {
1789 ast_log(AST_LOG_WARNING, "Channel %s has a PBX thread and cannot be imparted into bridge %s\n",
1792 return -1;
1793 }
1794
1795 /* Supply an empty features structure if the caller did not. */
1796 if (!features) {
1798 if (!features) {
1799 return -1;
1800 }
1801 }
1802
1803 /* Try to allocate a structure for the bridge channel */
1804 bridge_channel = bridge_channel_internal_alloc(bridge);
1805 if (!bridge_channel) {
1807 return -1;
1808 }
1809
1812 ast_log(AST_LOG_NOTICE, "Channel %s is a zombie and cannot be imparted into bridge %s\n",
1814 res = -1;
1815 } else {
1817 }
1819 bridge_channel->chan = chan;
1820 bridge_channel->swap = ao2_t_bump(swap, "Setting up bridge impart");
1821 bridge_channel->features = features;
1822 bridge_channel->inhibit_colp = !!(flags & AST_BRIDGE_IMPART_INHIBIT_JOIN_COLP);
1823 bridge_channel->depart_wait =
1825 bridge_channel->callid = ast_read_threadstorage_callid();
1826
1827 /* allow subclass to peek at swap channel before it can hangup */
1828 if (bridge->v_table->push_peek && !res) {
1829 struct ast_bridge_channel *bcswap = NULL;
1830
1832 if (bridge_channel->swap) {
1833 bcswap = bridge_find_channel(bridge, bridge_channel->swap);
1834 }
1835 res = bridge->v_table->push_peek(bridge, bridge_channel, bcswap);
1837 }
1838
1839 /* Actually create the thread that will handle the channel */
1840 if (!res) {
1842 }
1843 if (!res) {
1845 res = ast_pthread_create_detached(&bridge_channel->thread, NULL,
1846 bridge_channel_ind_thread, bridge_channel);
1847 } else {
1848 res = ast_pthread_create(&bridge_channel->thread, NULL,
1849 bridge_channel_depart_thread, bridge_channel);
1850 }
1851
1852 if (!res) {
1854 }
1855 }
1856
1857 if (res) {
1858 /* cleanup */
1862 /* Lock here for ast_bridge_channel_get_chan */
1863 ao2_lock(bridge_channel);
1864 bridge_channel->chan = NULL;
1865 ao2_unlock(bridge_channel);
1866 ao2_t_cleanup(bridge_channel->swap, "Bridge complete: Impart failed");
1867 bridge_channel->swap = NULL;
1868 ast_bridge_features_destroy(bridge_channel->features);
1869 bridge_channel->features = NULL;
1870
1871 ao2_ref(bridge_channel, -1);
1872 return -1;
1873 }
1874
1875 return 0;
1876}
#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:1601
struct ast_bridge_features * ast_bridge_features_new(void)
Allocate a new bridge features struct.
Definition: bridge.c:3683
static void * bridge_channel_depart_thread(void *data)
Thread responsible for imparted bridged channels to be departed.
Definition: bridge.c:1711
static int bridge_channel_impart_add(struct ast_channel *chan, struct bridge_channel_impart_cond *cond)
Definition: bridge.c:1549
static void * bridge_channel_ind_thread(void *data)
Thread responsible for independent imparted bridged channels.
Definition: bridge.c:1742
@ AST_BRIDGE_IMPART_CHAN_DEPARTABLE
Definition: bridge.h:588
@ AST_BRIDGE_IMPART_CHAN_MASK
Definition: bridge.h:586
@ AST_BRIDGE_IMPART_INHIBIT_JOIN_COLP
Definition: bridge.h:592
#define AST_LOG_WARNING
ast_callid ast_read_threadstorage_callid(void)
extracts the callerid from the thread
Definition: logger.c:2286
#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 4951 of file bridge.c.

4952{
4953 struct bridge_manager_controller *manager;
4954
4955 manager = ao2_alloc(sizeof(*manager), bridge_manager_destroy);
4956 if (!manager) {
4957 /* Well. This isn't good. */
4958 return NULL;
4959 }
4960 ast_cond_init(&manager->cond, NULL);
4962
4963 /* Create the bridge manager thread. */
4964 if (ast_pthread_create(&manager->thread, NULL, bridge_manager_thread, manager)) {
4965 /* Well. This isn't good either. */
4966 manager->thread = AST_PTHREADT_NULL;
4967 ao2_ref(manager, -1);
4968 manager = NULL;
4969 }
4970
4971 return manager;
4972}
static void bridge_manager_destroy(void *obj)
Definition: bridge.c:4919
static void * bridge_manager_thread(void *data)
Definition: bridge.c:4886
#define AST_LIST_HEAD_INIT_NOLOCK(head)
Initializes a list head structure.
Definition: linkedlists.h:681
#define AST_PTHREADT_NULL
Definition: lock.h:66
struct bridge_manager_controller::@308 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 4919 of file bridge.c.

4920{
4921 struct bridge_manager_controller *manager = obj;
4923
4924 if (manager->thread != AST_PTHREADT_NULL) {
4925 /* Stop the manager thread. */
4926 ao2_lock(manager);
4927 manager->stop = 1;
4928 ast_cond_signal(&manager->cond);
4929 ao2_unlock(manager);
4930 ast_debug(1, "Waiting for bridge manager thread to die.\n");
4931 pthread_join(manager->thread, NULL);
4932 }
4933
4934 /* Destroy the service request queue. */
4935 while ((request = AST_LIST_REMOVE_HEAD(&manager->service_requests, node))) {
4936 ao2_ref(request->bridge, -1);
4938 }
4939
4940 ast_cond_destroy(&manager->cond);
4941}
unsigned int stop
Definition: bridge.c:168

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 4869 of file bridge.c.

4870{
4871 ast_bridge_lock(bridge);
4872 if (bridge->callid) {
4874 }
4875
4876 /* Do any pending bridge actions. */
4877 bridge_handle_actions(bridge);
4878 ast_bridge_unlock(bridge);
4879}
static void bridge_handle_actions(struct ast_bridge *bridge)
Definition: bridge.c:622
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:2295
ast_callid callid
Definition: bridge.h:361

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 186 of file bridge.c.

187{
189
191 if (bridge_manager->stop) {
193 return;
194 }
195
196 /* Create the service request. */
197 request = ast_calloc(1, sizeof(*request));
198 if (!request) {
199 /* Well. This isn't good. */
201 return;
202 }
203 ao2_ref(bridge, +1);
204 request->bridge = bridge;
205
206 /* Put request into the queue and wake the bridge manager. */
210}
struct ast_bridge * bridge
Definition: bridge.c:157

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 4886 of file bridge.c.

4887{
4888 struct bridge_manager_controller *manager = data;
4890
4891 ao2_lock(manager);
4892 while (!manager->stop) {
4894 if (!request) {
4895 ast_cond_wait(&manager->cond, ao2_object_get_lockaddr(manager));
4896 continue;
4897 }
4898 ao2_unlock(manager);
4899
4900 /* Service the bridge. */
4902 ao2_ref(request->bridge, -1);
4904
4905 ao2_lock(manager);
4906 }
4907 ao2_unlock(manager);
4908
4909 return NULL;
4910}
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:4869

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 2153 of file bridge.c.

2154{
2155 struct merge_direction merge = { NULL, NULL };
2156 int bridge1_priority;
2157 int bridge2_priority;
2158
2159 if (!ast_test_flag(&bridge1->feature_flags,
2161 && !ast_test_flag(&bridge2->feature_flags,
2163 /*
2164 * Can merge either way. Merge to the higher priority merge
2165 * bridge. Otherwise merge to the larger bridge.
2166 */
2167 bridge1_priority = bridge1->v_table->get_merge_priority(bridge1);
2168 bridge2_priority = bridge2->v_table->get_merge_priority(bridge2);
2169 if (bridge2_priority < bridge1_priority) {
2170 merge.dest = bridge1;
2171 merge.src = bridge2;
2172 } else if (bridge1_priority < bridge2_priority) {
2173 merge.dest = bridge2;
2174 merge.src = bridge1;
2175 } else {
2176 /* Merge to the larger bridge. */
2177 if (bridge2->num_channels <= bridge1->num_channels) {
2178 merge.dest = bridge1;
2179 merge.src = bridge2;
2180 } else {
2181 merge.dest = bridge2;
2182 merge.src = bridge1;
2183 }
2184 }
2187 /* Can merge only one way. */
2188 merge.dest = bridge1;
2189 merge.src = bridge2;
2192 /* Can merge only one way. */
2193 merge.dest = bridge2;
2194 merge.src = bridge1;
2195 }
2196
2197 return merge;
2198}
@ AST_BRIDGE_FLAG_MERGE_INHIBIT_TO
@ AST_BRIDGE_FLAG_MERGE_INHIBIT_FROM
struct ast_bridge * src
Definition: bridge.c:2138
struct ast_bridge * dest
Definition: bridge.c:2136

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 2991 of file bridge.c.

2992{
2993 int new_request;
2994
2995 new_request = bridge->inhibit_merge + request;
2996 ast_assert(0 <= new_request);
2997 bridge->inhibit_merge = new_request;
2998}

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 2216 of file bridge.c.

2217{
2218 struct merge_direction merge;
2219 struct ast_bridge_channel **kick_them = NULL;
2220
2221 /* Sanity check. */
2222 ast_assert(dst_bridge && src_bridge && dst_bridge != src_bridge && (!num_kick || kick_me));
2223
2224 if (dst_bridge->dissolved || src_bridge->dissolved) {
2225 ast_debug(1, "Can't merge bridges %s and %s, at least one bridge is dissolved.\n",
2226 src_bridge->uniqueid, dst_bridge->uniqueid);
2227 return -1;
2228 }
2231 ast_debug(1, "Can't merge bridges %s and %s, masquerade only.\n",
2232 src_bridge->uniqueid, dst_bridge->uniqueid);
2233 return -1;
2234 }
2235 if (dst_bridge->inhibit_merge || src_bridge->inhibit_merge) {
2236 ast_debug(1, "Can't merge bridges %s and %s, merging temporarily inhibited.\n",
2237 src_bridge->uniqueid, dst_bridge->uniqueid);
2238 return -1;
2239 }
2240
2241 if (merge_best_direction) {
2242 merge = bridge_merge_determine_direction(dst_bridge, src_bridge);
2243 } else {
2244 merge.dest = dst_bridge;
2245 merge.src = src_bridge;
2246 }
2247
2248 if (!merge.dest
2249 || ast_test_flag(&merge.dest->feature_flags, AST_BRIDGE_FLAG_MERGE_INHIBIT_TO)
2250 || ast_test_flag(&merge.src->feature_flags, AST_BRIDGE_FLAG_MERGE_INHIBIT_FROM)) {
2251 ast_debug(1, "Can't merge bridges %s and %s, merging inhibited.\n",
2252 src_bridge->uniqueid, dst_bridge->uniqueid);
2253 return -1;
2254 }
2255 if (merge.src->num_channels < 2) {
2256 /*
2257 * For a two party bridge, a channel may be temporarily removed
2258 * from the source bridge or the initial bridge members have not
2259 * joined yet.
2260 */
2261 ast_debug(1, "Can't merge bridge %s into bridge %s, not enough channels in source bridge.\n",
2262 merge.src->uniqueid, merge.dest->uniqueid);
2263 return -1;
2264 }
2265 if (2 + num_kick < merge.dest->num_channels + merge.src->num_channels
2266 && !(merge.dest->technology->capabilities & AST_BRIDGE_CAPABILITY_MULTIMIX)
2267 && (!ast_test_flag(&merge.dest->feature_flags, AST_BRIDGE_FLAG_SMART)
2268 || !(merge.dest->allowed_capabilities & AST_BRIDGE_CAPABILITY_MULTIMIX))) {
2269 ast_debug(1, "Can't merge bridge %s into bridge %s, multimix is needed and it cannot be acquired.\n",
2270 merge.src->uniqueid, merge.dest->uniqueid);
2271 return -1;
2272 }
2273
2274 if (num_kick) {
2275 unsigned int num_to_kick = 0;
2276 unsigned int idx;
2277
2278 kick_them = ast_alloca(num_kick * sizeof(*kick_them));
2279 for (idx = 0; idx < num_kick; ++idx) {
2280 kick_them[num_to_kick] = bridge_find_channel(merge.src, kick_me[idx]);
2281 if (!kick_them[num_to_kick]) {
2282 kick_them[num_to_kick] = bridge_find_channel(merge.dest, kick_me[idx]);
2283 }
2284 if (kick_them[num_to_kick]) {
2285 ++num_to_kick;
2286 }
2287 }
2288
2289 if (num_to_kick != num_kick) {
2290 ast_debug(1, "Can't merge bridge %s into bridge %s, at least one kicked channel is not in either bridge.\n",
2291 merge.src->uniqueid, merge.dest->uniqueid);
2292 return -1;
2293 }
2294 }
2295
2296 bridge_do_merge(merge.dest, merge.src, kick_them, num_kick, 0);
2297 return 0;
2298}
#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:2048
static struct merge_direction bridge_merge_determine_direction(struct ast_bridge *bridge1, struct ast_bridge *bridge2)
Definition: bridge.c:2153
@ AST_BRIDGE_CAPABILITY_MULTIMIX
Definition: bridge.h:94
@ 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 2399 of file bridge.c.

2400{
2401 struct ast_bridge_channel *bridge_channel;
2402
2403 if (dst_bridge->dissolved || src_bridge->dissolved) {
2404 ast_debug(1, "Can't move channel %s from bridge %s into bridge %s, at least one bridge is dissolved.\n",
2405 ast_channel_name(chan), src_bridge->uniqueid, dst_bridge->uniqueid);
2406 return -1;
2407 }
2410 ast_debug(1, "Can't move channel %s from bridge %s into bridge %s, masquerade only.\n",
2411 ast_channel_name(chan), src_bridge->uniqueid, dst_bridge->uniqueid);
2412 return -1;
2413 }
2414 if (dst_bridge->inhibit_merge || src_bridge->inhibit_merge) {
2415 ast_debug(1, "Can't move channel %s from bridge %s into bridge %s, temporarily inhibited.\n",
2416 ast_channel_name(chan), src_bridge->uniqueid, dst_bridge->uniqueid);
2417 return -1;
2418 }
2419
2420 bridge_channel = bridge_find_channel(src_bridge, chan);
2421 if (!bridge_channel) {
2422 ast_debug(1, "Can't move channel %s from bridge %s into bridge %s, channel not in bridge.\n",
2423 ast_channel_name(chan), src_bridge->uniqueid, dst_bridge->uniqueid);
2424 return -1;
2425 }
2426 if (bridge_channel->state != BRIDGE_CHANNEL_STATE_WAIT) {
2427 ast_debug(1, "Can't move channel %s from bridge %s into bridge %s, channel leaving bridge.\n",
2428 ast_channel_name(chan), src_bridge->uniqueid, dst_bridge->uniqueid);
2429 return -1;
2430 }
2431 if (ast_test_flag(&bridge_channel->features->feature_flags,
2433 ast_debug(1, "Can't move channel %s from bridge %s into bridge %s, channel immovable.\n",
2434 ast_channel_name(chan), src_bridge->uniqueid, dst_bridge->uniqueid);
2435 return -1;
2436 }
2437
2438 if (swap) {
2439 struct ast_bridge_channel *bridge_channel_swap;
2440
2441 bridge_channel_swap = bridge_find_channel(dst_bridge, swap);
2442 if (!bridge_channel_swap) {
2443 ast_debug(1, "Can't move channel %s from bridge %s into bridge %s, swap channel %s not in bridge.\n",
2444 ast_channel_name(chan), src_bridge->uniqueid, dst_bridge->uniqueid,
2446 return -1;
2447 }
2448 if (bridge_channel_swap->state != BRIDGE_CHANNEL_STATE_WAIT) {
2449 ast_debug(1, "Can't move channel %s from bridge %s into bridge %s, swap channel %s leaving bridge.\n",
2450 ast_channel_name(chan), src_bridge->uniqueid, dst_bridge->uniqueid,
2452 return -1;
2453 }
2454 }
2455
2456 bridge_channel->swap = swap;
2457 return bridge_do_move(dst_bridge, bridge_channel, attempt_recovery, 0);
2458}
int bridge_do_move(struct ast_bridge *dst_bridge, struct ast_bridge_channel *bridge_channel, int attempt_recovery, unsigned int optimized)
Definition: bridge.c:2314

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 3231 of file bridge.c.

3237{
3238 struct ast_bridge_hook *hook;
3239 int res;
3240
3241 /* Allocate new hook and setup it's various variables */
3242 hook = bridge_hook_generic(sizeof(*hook), callback, hook_pvt, destructor,
3243 remove_flags);
3244 if (!hook) {
3245 return -1;
3246 }
3247 hook->type = type;
3248
3249 /* Once done we put it in the container. */
3250 res = ao2_link(features->other_hooks, hook) ? 0 : -1;
3251 if (res) {
3252 /*
3253 * Could not link the hook into the container.
3254 *
3255 * Remove the hook_pvt destructor call from the hook since we
3256 * are returning failure to install the hook.
3257 */
3258 hook->destructor = NULL;
3259 }
3260 ao2_ref(hook, -1);
3261
3262 return res;
3263}
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 5513 of file bridge.c.

5514{
5515 struct ast_bridge *bridge = v_obj;
5516
5517 if (!bridge) {
5518 return;
5519 }
5520 prnt(where, "%s %s chans:%u",
5521 bridge->uniqueid, bridge->v_table->name, bridge->num_channels);
5522}

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 292 of file bridge.c.

293{
294 ast_debug(1, "Bridge %s: queueing action type:%u sub:%d\n",
295 bridge->uniqueid, action->frametype, action->subclass.integer);
296
297 ast_bridge_lock(bridge);
299 ast_bridge_unlock(bridge);
301}
static void bridge_manager_service_req(struct ast_bridge *bridge)
Definition: bridge.c:186

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 1403 of file bridge.c.

1404{
1405 if (!bridge->reconfigured) {
1406 return;
1407 }
1408 bridge->reconfigured = 0;
1410 && smart_bridge_operation(bridge)) {
1411 /* Smart bridge failed. */
1412 bridge_dissolve(bridge, 0);
1413 return;
1414 }
1415 bridge_complete_join(bridge);
1416
1417 if (bridge->dissolved) {
1418 return;
1419 }
1421 set_bridge_peer_vars(bridge);
1423
1424 if (colp_update) {
1426 }
1427}
static void check_bridge_play_sounds(struct ast_bridge *bridge)
Definition: bridge.c:1203
static int smart_bridge_operation(struct ast_bridge *bridge)
Definition: bridge.c:972
static void bridge_reconfigured_connected_line_update(struct ast_bridge *bridge)
Definition: bridge.c:385
static void bridge_complete_join(struct ast_bridge *bridge)
Definition: bridge.c:474
static void set_bridge_peer_vars(struct ast_bridge *bridge)
Definition: bridge.c:1386

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 385 of file bridge.c.

386{
388 struct ast_bridge_channel *bridge_channel = AST_LIST_FIRST(&bridge->channels), *peer;
389 unsigned char data[1024];
390 size_t datalen;
391
392 if (!bridge_channel ||
394 !(peer = ast_bridge_channel_peer(bridge_channel)) ||
397 ast_check_hangup_locked(bridge_channel->chan) ||
398 ast_check_hangup_locked(peer->chan)) {
399 return;
400 }
401
403
404 ast_channel_lock(bridge_channel->chan);
406 ast_channel_unlock(bridge_channel->chan);
407
408 if ((datalen = ast_connected_line_build_data(data, sizeof(data), &connected, NULL)) != (size_t) -1) {
410 }
411
412 ast_channel_lock(peer->chan);
414 ast_channel_unlock(peer->chan);
415
416 if ((datalen = ast_connected_line_build_data(data, sizeof(data), &connected, NULL)) != (size_t) -1) {
418 }
419
421}
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:2072
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:8697
void ast_party_connected_line_init(struct ast_party_connected_line *init)
Initialize the given connected line structure.
Definition: channel.c:2022
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:8293
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:456

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:691
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 691 of file bridge.c.

692{
693 if (bridge) {
694 bridge->construction_completed = 1;
695 ast_bridge_lock(bridge);
697 ast_bridge_unlock(bridge);
698 if (!ao2_link(bridges, bridge)) {
699 ast_bridge_destroy(bridge, 0);
700 bridge = NULL;
701 }
702 }
703 return bridge;
704}
int ast_bridge_destroy(struct ast_bridge *bridge, int cause)
Destroy a bridge.
Definition: bridge.c:944
unsigned int construction_completed
Definition: bridge.h:392

References ao2_link, ast_bridge_destroy(), ast_bridge_lock, ast_bridge_publish_state(), ast_bridge_unlock, bridges, ast_bridge::construction_completed, and NULL.

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 5082 of file bridge.c.

5083{
5084 const char *uniqueid = obj;
5085 struct ast_cli_args *a = arg;
5086 struct ast_channel_snapshot *snapshot;
5087
5088 snapshot = ast_channel_snapshot_get_latest(uniqueid);
5089 if (!snapshot) {
5090 return 0;
5091 }
5092
5093 ast_cli(a->fd, "Channel: %s\n", snapshot->base->name);
5094 ao2_ref(snapshot, -1);
5095
5096 return 0;
5097}
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 4990 of file bridge.c.

4991{
4992 const struct ast_bridge *bridge_left = obj_left;
4993 const struct ast_bridge *bridge_right = obj_right;
4994 const char *right_key = obj_right;
4995 int cmp;
4996
4997 switch (flags & (OBJ_POINTER | OBJ_KEY | OBJ_PARTIAL_KEY)) {
4998 default:
4999 case OBJ_POINTER:
5000 right_key = bridge_right->uniqueid;
5001 /* Fall through */
5002 case OBJ_KEY:
5003 cmp = strcmp(bridge_left->uniqueid, right_key);
5004 break;
5005 case OBJ_PARTIAL_KEY:
5006 cmp = strncmp(bridge_left->uniqueid, right_key, strlen(right_key));
5007 break;
5008 }
5009 return cmp;
5010}

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 4568 of file bridge.c.

4570{
4571 struct ast_bridge_channel *bridged_to_source;
4572
4573 bridged_to_source = ast_bridge_channel_peer(source_bridge_channel);
4574 if (bridged_to_source
4575 && bridged_to_source->state == BRIDGE_CHANNEL_STATE_WAIT
4576 && !ast_test_flag(&bridged_to_source->features->feature_flags,
4578 bridged_to_source->swap = swap_channel;
4579 if (bridge_do_move(dest_bridge, bridged_to_source, 1, 0)) {
4581 }
4582 /* Must kick the source channel out of its bridge. */
4583 ast_bridge_channel_leave_bridge(source_bridge_channel,
4586 } else {
4588 }
4589}

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 560 of file bridge.c.

561{
562 struct tech_deferred_destroy *deferred = action->data.ptr;
563 struct ast_bridge dummy_bridge = {
564 .technology = deferred->tech,
565 .tech_pvt = deferred->tech_pvt,
566 .creator = bridge->creator,
567 .name = bridge->name,
568 .uniqueid = bridge->uniqueid,
569 };
570
571 ast_debug(1, "Bridge %s: calling %s technology destructor (deferred, dummy)\n",
572 dummy_bridge.uniqueid, dummy_bridge.technology->name);
573 dummy_bridge.technology->destroy(&dummy_bridge);
574 ast_module_unref(dummy_bridge.technology->mod);
575}
#define ast_module_unref(mod)
Release a reference to the module.
Definition: module.h:469
void(* destroy)(struct ast_bridge *bridge)
Destroy a bridging technology instance for a bridge.
const ast_string_field creator
Definition: bridge.h:401
union ast_frame::@226 data
struct ast_bridge_technology * tech
Definition: bridge.c:546

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 2689 of file bridge.c.

2691{
2692 int chan_priority;
2693 int peer_priority;
2694
2695 if (!ast_test_flag(&chan_bridge->feature_flags,
2698 && !ast_test_flag(&peer_bridge->feature_flags,
2701 /*
2702 * Can swap either way. Swap to the higher priority merge
2703 * bridge.
2704 */
2705 chan_priority = chan_bridge->v_table->get_merge_priority(chan_bridge);
2706 peer_priority = peer_bridge->v_table->get_merge_priority(peer_bridge);
2707 if (chan_bridge->num_channels == 2
2708 && chan_priority <= peer_priority) {
2709 return SWAP_TO_PEER_BRIDGE;
2710 } else if (peer_bridge->num_channels == 2
2711 && peer_priority <= chan_priority) {
2712 return SWAP_TO_CHAN_BRIDGE;
2713 }
2714 } else if (chan_bridge->num_channels == 2
2717 /* Can swap optimize only one way. */
2718 return SWAP_TO_PEER_BRIDGE;
2719 } else if (peer_bridge->num_channels == 2
2722 /* Can swap optimize only one way. */
2723 return SWAP_TO_CHAN_BRIDGE;
2724 }
2725
2726 return SWAP_PROHIBITED;
2727}
@ 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 3996 of file bridge.c.

3997{
3998 const struct ast_channel *left = obj;
3999 const struct ast_channel *right = arg;
4000 const char *right_name = arg;
4001 int cmp;
4002
4003 switch (flags & (OBJ_POINTER | OBJ_KEY | OBJ_PARTIAL_KEY)) {
4004 default:
4005 case OBJ_POINTER:
4006 right_name = ast_channel_name(right);
4007 /* Fall through */
4008 case OBJ_KEY:
4009 cmp = strcmp(ast_channel_name(left), right_name);
4010 break;
4011 case OBJ_PARTIAL_KEY:
4012 cmp = strncmp(ast_channel_name(left), right_name, strlen(right_name));
4013 break;
4014 }
4015 return cmp ? 0 : CMP_MATCH;
4016}
@ 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 3973 of file bridge.c.

3974{
3975 const struct ast_channel *chan = obj;
3976 const char *name = obj;
3977 int hash;
3978
3979 switch (flags & (OBJ_POINTER | OBJ_KEY | OBJ_PARTIAL_KEY)) {
3980 default:
3981 case OBJ_POINTER:
3982 name = ast_channel_name(chan);
3983 /* Fall through */
3984 case OBJ_KEY:
3985 hash = ast_str_hash(name);
3986 break;
3987 case OBJ_PARTIAL_KEY:
3988 /* Should never happen in hash callback. */
3989 ast_assert(0);
3990 hash = 0;
3991 break;
3992 }
3993 return hash;
3994}
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 1175 of file bridge.c.

1176{
1177 const char *play_file;
1178
1179 ast_channel_lock(bridge_channel->chan);
1180 play_file = pbx_builtin_getvar_helper(bridge_channel->chan, "BRIDGE_PLAY_SOUND");
1181 if (!ast_strlen_zero(play_file)) {
1183 pbx_builtin_setvar_helper(bridge_channel->chan, "BRIDGE_PLAY_SOUND", NULL);
1184 } else {
1185 play_file = NULL;
1186 }
1187 ast_channel_unlock(bridge_channel->chan);
1188
1189 if (play_file) {
1191 }
1192}
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 1203 of file bridge.c.

1204{
1205 struct ast_bridge_channel *bridge_channel;
1206
1207 AST_LIST_TRAVERSE(&bridge->channels, bridge_channel, entry) {
1208 check_bridge_play_sound(bridge_channel);
1209 }
1210}
static void check_bridge_play_sound(struct ast_bridge_channel *bridge_channel)
Definition: bridge.c:1175

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

Referenced by bridge_reconfigured().

◆ cleanup_video_mode()

static void cleanup_video_mode ( struct ast_bridge bridge)
static

Definition at line 3726 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 5028 of file bridge.c.

5029{
5032
5033 return NULL;
5034}
static int complete_bridge_live_search(void *obj, void *arg, int flags)
Definition: bridge.c:5017
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 5017 of file bridge.c.

5018{
5019 struct ast_bridge *bridge = obj;
5020
5022 return CMP_STOP;
5023 }
5024
5025 return 0;
5026}
#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:2756

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 5183 of file bridge.c.

5184{
5185 struct ast_bridge *bridge;
5186 struct ast_bridge_channel *bridge_channel;
5187 int wordlen;
5188
5189 bridge = ast_bridge_find_by_id(bridge_name);
5190 if (!bridge) {
5191 return NULL;
5192 }
5193
5194 wordlen = strlen(word);
5195
5197 AST_LIST_TRAVERSE(&bridge->channels, bridge_channel, entry) {
5198 if (!strncasecmp(ast_channel_name(bridge_channel->chan), word, wordlen)) {
5199 if (ast_cli_completion_add(ast_strdup(ast_channel_name(bridge_channel->chan)))) {
5200 break;
5201 }
5202 }
5203 }
5205
5206 ao2_ref(bridge, -1);
5207
5208 return NULL;
5209}
struct ast_bridge * ast_bridge_find_by_id(const char *bridge_id)
Find bridge by id.
Definition: bridge.c:5012

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, and NULL.

Referenced by handle_bridge_kick_channel().

◆ complete_bridge_technology()

static char * complete_bridge_technology ( const char *  word)
static

Definition at line 5332 of file bridge.c.

5333{
5334 struct ast_bridge_technology *cur;
5335 int wordlen;
5336
5337 wordlen = strlen(word);
5340 if (!strncasecmp(cur->name, word, wordlen)) {
5342 break;
5343 }
5344 }
5345 }
5347
5348 return NULL;
5349}
#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 640 of file bridge.c.

641{
642 struct ast_bridge *bridge = obj;
643
644 ast_debug(1, "Bridge %s: actually destroying %s bridge, nobody wants it anymore\n",
645 bridge->uniqueid, bridge->v_table->name);
646
647 if (bridge->construction_completed) {
648 bridge_topics_destroy(bridge);
649 }
650
651 /* Do any pending actions in the context of destruction. */
652 ast_bridge_lock(bridge);
653 bridge_handle_actions(bridge);
654 ast_bridge_unlock(bridge);
655
656 /* There should not be any channels left in the bridge. */
658
659 ast_debug(1, "Bridge %s: calling %s bridge destructor\n",
660 bridge->uniqueid, bridge->v_table->name);
661 bridge->v_table->destroy(bridge);
662
663 /* Pass off the bridge to the technology to destroy if needed */
664 if (bridge->technology) {
665 ast_debug(1, "Bridge %s: calling %s technology stop\n",
666 bridge->uniqueid, bridge->technology->name);
667 if (bridge->technology->stop) {
668 ast_bridge_lock(bridge);
669 bridge->technology->stop(bridge);
670 ast_bridge_unlock(bridge);
671 }
672 ast_debug(1, "Bridge %s: calling %s technology destructor\n",
673 bridge->uniqueid, bridge->technology->name);
674 if (bridge->technology->destroy) {
675 bridge->technology->destroy(bridge);
676 }
678 bridge->technology = NULL;
679 }
680
682
683 bridge->callid = 0;
684
685 cleanup_video_mode(bridge);
686
689}
#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:406
#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_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 1269 of file bridge.c.

1270{
1271 int need_separator = 0;
1272 unsigned int idx;
1273 const char *src;
1274 char *pos;
1275
1276 pos = buf;
1277 for (idx = 0; idx < num_names; ++idx) {
1278 if (idx == cur_idx) {
1279 continue;
1280 }
1281
1282 if (need_separator) {
1283 *pos++ = ',';
1284 }
1285 need_separator = 1;
1286
1287 /* Copy name into buffer. */
1288 src = names[idx];
1289 while (*src) {
1290 *pos++ = *src++;
1291 }
1292 }
1293 *pos = '\0';
1294}
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 499 of file bridge.c.

500{
502 struct ast_bridge_technology *best = NULL;
503
506 if (current->suspended) {
507 ast_debug(1, "Bridge technology %s is suspended. Skipping.\n",
508 current->name);
509 continue;
510 }
511 if (!(current->capabilities & capabilities)) {
512 ast_debug(1, "Bridge technology %s does not have any capabilities we want.\n",
513 current->name);
514 continue;
515 }
516 if (best && current->preference <= best->preference) {
517 ast_debug(1, "Bridge technology %s has less preference than %s (%u <= %u). Skipping.\n",
518 current->name, best->name, current->preference, best->preference);
519 continue;
520 }
521 if (current->compatible && !current->compatible(bridge)) {
522 ast_debug(1, "Bridge technology %s is not compatible with properties of existing bridge.\n",
523 current->name);
524 continue;
525 }
526 if (!ast_module_running_ref(current->mod)) {
527 ast_debug(1, "Bridge technology %s is not running, skipping.\n", current->name);
528 continue;
529 }
530 if (best) {
531 ast_module_unref(best->mod);
532 }
533 best = current;
534 }
535
536 if (best) {
537 ast_debug(1, "Chose bridge technology %s\n", best->name);
538 }
539
541
542 return best;
543}
#define ast_module_running_ref(mod)
Hold a reference to the module if it is running.
Definition: module.h:455

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 4182 of file bridge.c.

4183{
4184 struct ao2_iterator channel_iter;
4185 struct ast_channel *transferee;
4186
4187 for (channel_iter = ao2_iterator_init(channels, 0);
4188 (transferee = ao2_iterator_next(&channel_iter));
4189 ao2_cleanup(transferee)) {
4190 if (transferee != transferer) {
4191 break;
4192 }
4193 }
4194
4195 ao2_iterator_destroy(&channel_iter);
4196 return transferee;
4197}

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 5211 of file bridge.c.

5212{
5213 static const char * const completions[] = { "all", NULL };
5214 struct ast_bridge *bridge;
5215
5216 switch (cmd) {
5217 case CLI_INIT:
5218 e->command = "bridge kick";
5219 e->usage =
5220 "Usage: bridge kick <bridge-id> <channel-name | all>\n"
5221 " Kick the <channel-name> channel out of the <bridge-id> bridge\n"
5222 " If all is specified as the channel name then all channels will be\n"
5223 " kicked out of the bridge.\n";
5224 return NULL;
5225 case CLI_GENERATE:
5226 if (a->pos == 2) {
5227 return complete_bridge_live(a->word);
5228 }
5229 if (a->pos == 3) {
5230 ast_cli_complete(a->word, completions, -1);
5231 return complete_bridge_participant(a->argv[2], a->word);
5232 }
5233 return NULL;
5234 }
5235
5236 if (a->argc != 4) {
5237 return CLI_SHOWUSAGE;
5238 }
5239
5240 bridge = ast_bridge_find_by_id(a->argv[2]);
5241 if (!bridge) {
5242 ast_cli(a->fd, "Bridge '%s' not found\n", a->argv[2]);
5243 return CLI_SUCCESS;
5244 }
5245
5246 if (!strcasecmp(a->argv[3], "all")) {
5247 struct ast_bridge_channel *bridge_channel;
5248
5249 ast_cli(a->fd, "Kicking all channels from bridge '%s'\n", a->argv[2]);
5250
5252 AST_LIST_TRAVERSE(&bridge->channels, bridge_channel, entry) {
5253 ast_bridge_channel_queue_callback(bridge_channel, 0, kick_it, NULL, 0);
5254 }
5256 } else {
5257 struct ast_channel *chan;
5258
5259 chan = ast_channel_get_by_name_prefix(a->argv[3], strlen(a->argv[3]));
5260 if (!chan) {
5261 ast_cli(a->fd, "Channel '%s' not found\n", a->argv[3]);
5262 ao2_ref(bridge, -1);
5263 return CLI_SUCCESS;
5264 }
5265
5266 ast_cli(a->fd, "Kicking channel '%s' from bridge '%s'\n",
5267 ast_channel_name(chan), a->argv[2]);
5268 ast_bridge_kick(bridge, chan);
5269 ast_channel_unref(chan);
5270 }
5271
5272 ao2_ref(bridge, -1);
5273 return CLI_SUCCESS;
5274}
int ast_bridge_kick(struct ast_bridge *bridge, struct ast_channel *chan)
Kick a channel from a bridge.
Definition: bridge.c:1979
static char * complete_bridge_live(const char *word)
Definition: bridge.c:5028
static char * complete_bridge_participant(const char *bridge_name, const char *word)
Definition: bridge.c:5183
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:1434
#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:1841
@ 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(), 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 5036 of file bridge.c.

5037{
5038#define FORMAT_HDR "%-36s %5s %-15s %-15s %s\n"
5039#define FORMAT_ROW "%-36s %5u %-15s %-15s %s\n"
5040
5041 struct ao2_iterator iter;
5042 struct ast_bridge *bridge;
5043
5044 switch (cmd) {
5045 case CLI_INIT:
5046 e->command = "bridge show all";
5047 e->usage =
5048 "Usage: bridge show all\n"
5049 " List all bridges\n";
5050 return NULL;
5051 case CLI_GENERATE:
5052 return NULL;
5053 }
5054
5055 ast_cli(a->fd, FORMAT_HDR, "Bridge-ID", "Chans", "Type", "Technology", "Duration");
5056
5057 iter = ao2_iterator_init(bridges, 0);
5058 for (; (bridge = ao2_iterator_next(&iter)); ao2_ref(bridge, -1)) {
5059 struct ast_bridge_snapshot *snapshot = ast_bridge_get_snapshot(bridge);
5060 char print_time[32];
5061
5062 if (snapshot) {
5063 ast_format_duration_hh_mm_ss(ast_tvnow().tv_sec - snapshot->creationtime.tv_sec, print_time, sizeof(print_time));
5064 ast_cli(a->fd, FORMAT_ROW,
5065 snapshot->uniqueid,
5066 snapshot->num_channels,
5067 S_OR(snapshot->subclass, "<unknown>"),
5068 S_OR(snapshot->technology, "<unknown>"),
5069 print_time);
5070 ao2_ref(snapshot, -1);
5071 }
5072 }
5073 ao2_iterator_destroy(&iter);
5074
5075 return CLI_SUCCESS;
5076
5077#undef FORMAT_HDR
5078#undef FORMAT_ROW
5079}
#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:314
struct timeval creationtime
Definition: bridge.h:343
const ast_string_field uniqueid
Definition: bridge.h:328
unsigned int num_channels
Definition: bridge.h:337
const ast_string_field technology
Definition: bridge.h:328
const ast_string_field subclass
Definition: bridge.h:328
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, NULL, ast_bridge_snapshot::num_channels, S_OR, ast_bridge_snapshot::subclass, ast_bridge_snapshot::technology, ast_bridge_snapshot::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 5099 of file bridge.c.

5100{
5101 struct ast_bridge_snapshot *snapshot;
5102 char print_time[32];
5103
5104 switch (cmd) {
5105 case CLI_INIT:
5106 e->command = "bridge show";
5107 e->usage =
5108 "Usage: bridge show <bridge-id>\n"
5109 " Show information about the <bridge-id> bridge\n";
5110 return NULL;
5111 case CLI_GENERATE:
5112 if (a->pos == 2) {
5113 return complete_bridge_live(a->word);
5114 }
5115 return NULL;
5116 }
5117
5118 if (a->argc != 3) {
5119 return CLI_SHOWUSAGE;
5120 }
5121
5122 snapshot = ast_bridge_get_snapshot_by_uniqueid(a->argv[2]);
5123 if (!snapshot) {
5124 ast_cli(a->fd, "Bridge '%s' not found\n", a->argv[2]);
5125 return CLI_SUCCESS;
5126 }
5127
5128 ast_format_duration_hh_mm_ss(ast_tvnow().tv_sec - snapshot->creationtime.tv_sec, print_time, sizeof(print_time));
5129
5130 ast_cli(a->fd, "Id: %s\n", snapshot->uniqueid);
5131 ast_cli(a->fd, "Type: %s\n", S_OR(snapshot->subclass, "<unknown>"));
5132 ast_cli(a->fd, "Technology: %s\n", S_OR(snapshot->technology, "<unknown>"));
5133 ast_cli(a->fd, "Subclass: %s\n", snapshot->subclass);
5134 ast_cli(a->fd, "Creator: %s\n", snapshot->creator);
5135 ast_cli(a->fd, "Name: %s\n", snapshot->name);
5136 ast_cli(a->fd, "Video-Mode: %s\n", ast_bridge_video_mode_to_string(snapshot->video_mode));
5137 ast_cli(a->fd, "Video-Source-Id: %s\n", snapshot->video_source_id);
5138 ast_cli(a->fd, "Num-Channels: %u\n", snapshot->num_channels);
5139 ast_cli(a->fd, "Num-Active: %u\n", snapshot->num_active);
5140 ast_cli(a->fd, "Duration: %s\n", print_time);
5142 ao2_ref(snapshot, -1);
5143
5144 return CLI_SUCCESS;
5145}
@ 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:3951
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:5082
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:341
unsigned int num_active
Definition: bridge.h:339
const ast_string_field video_source_id
Definition: bridge.h:328
const ast_string_field creator
Definition: bridge.h:328
const ast_string_field name
Definition: bridge.h:328
struct ao2_container * channels
Definition: bridge.h:331

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 5297 of file bridge.c.

5298{
5299#define FORMAT_HDR "%-20s %-20s %8s %s\n"
5300#define FORMAT_ROW "%-20s %-20s %8u %s\n"
5301
5302 struct ast_bridge_technology *cur;
5303
5304 switch (cmd) {
5305 case CLI_INIT:
5306 e->command = "bridge technology show";
5307 e->usage =
5308 "Usage: bridge technology show\n"
5309 " List registered bridge technologies\n";
5310 return NULL;
5311 case CLI_GENERATE:
5312 return NULL;
5313 }
5314
5315 ast_cli(a->fd, FORMAT_HDR, "Name", "Type", "Priority", "Suspended");
5318 const char *type;
5319
5320 /* Decode type for display */
5322
5323 ast_cli(a->fd, FORMAT_ROW, cur->name, type, cur->preference,
5324 AST_CLI_YESNO(cur->suspended));
5325 }
5327 return CLI_SUCCESS;
5328
5329#undef FORMAT
5330}
static const char * tech_capability2str(uint32_t capabilities)
Definition: bridge.c:5277
#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 5351 of file bridge.c.

5352{
5353 struct ast_bridge_technology *cur;
5354 int suspend;
5355 int successful;
5356
5357 switch (cmd) {
5358 case CLI_INIT:
5359 e->command = "bridge technology {suspend|unsuspend}";
5360 e->usage =
5361 "Usage: bridge technology {suspend|unsuspend} <technology-name>\n"
5362 " Suspend or unsuspend a bridge technology.\n";
5363 return NULL;
5364 case CLI_GENERATE:
5365 if (a->pos == 3) {
5366 return complete_bridge_technology(a->word);
5367 }
5368 return NULL;
5369 }
5370
5371 if (a->argc != 4) {
5372 return CLI_SHOWUSAGE;
5373 }
5374
5375 suspend = !strcasecmp(a->argv[2], "suspend");
5376 successful = 0;
5379 if (!strcasecmp(cur->name, a->argv[3])) {
5380 successful = 1;
5381 if (suspend) {
5383 } else {
5385 }
5386 break;
5387 }
5388 }
5390
5391 if (successful) {
5392 if (suspend) {
5393 ast_cli(a->fd, "Suspended bridge technology '%s'\n", a->argv[3]);
5394 } else {
5395 ast_cli(a->fd, "Unsuspended bridge technology '%s'\n", a->argv[3]);
5396 }
5397 } else {
5398 ast_cli(a->fd, "Bridge technology '%s' not found\n", a->argv[3]);
5399 }
5400
5401 return CLI_SUCCESS;
5402}
void ast_bridge_technology_unsuspend(struct ast_bridge_technology *technology)
Unsuspend a bridge technology.
Definition: bridge.c:3052
void ast_bridge_technology_suspend(struct ast_bridge_technology *technology)
Suspend a bridge technology from consideration.
Definition: bridge.c:3047
static char * complete_bridge_technology(const char *word)
Definition: bridge.c:5332
static void suspend(struct cc_core_instance *core_instance)
Definition: ccss.c:3160

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 5416 of file bridge.c.

5417{
5418 const char *name = astman_get_header(m, "BridgeTechnology");
5419 struct ast_bridge_technology *cur;
5420 int successful = 0;
5421
5422 if (ast_strlen_zero(name)) {
5423 astman_send_error(s, m, "BridgeTechnology must be provided");
5424 return 0;
5425 }
5426
5429
5430 if (!strcasecmp(cur->name, name)) {
5431 successful = 1;
5432 if (suspend) {
5434 } else {
5436 }
5437 break;
5438 }
5439 }
5441 if (!successful) {
5442 astman_send_error(s, m, "BridgeTechnology not found");
5443 return 0;
5444 }
5445
5446 astman_send_ack(s, m, (suspend ? "Suspended bridge technology" : "Unsuspended bridge technology"));
5447 return 0;
5448}
void astman_send_error(struct mansession *s, const struct message *m, char *error)
Send error in manager transaction.
Definition: manager.c:3381
void astman_send_ack(struct mansession *s, const struct message *m, char *msg)
Send ack in manager transaction.
Definition: manager.c:3413
const char * astman_get_header(const struct message *m, char *var)
Get header from manager transaction.
Definition: manager.c:3042

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 3445 of file bridge.c.

3446{
3447 struct ast_bridge_hook *hook = obj;
3449
3450 if (ast_test_flag(&hook->remove_flags, *remove_flags)) {
3451 return CMP_MATCH;
3452 } else {
3453 return 0;
3454 }
3455}
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 3465 of file bridge.c.

3466{
3468 hook_remove_match, &remove_flags);
3469}
@ 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:3445

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 3479 of file bridge.c.

3480{
3481 struct ast_bridge_hook *hook;
3482 int changed;
3483
3484 ast_heap_wrlock(hooks);
3485 do {
3486 int idx;
3487
3488 changed = 0;
3489 for (idx = ast_heap_size(hooks); idx; --idx) {
3490 hook = ast_heap_peek(hooks, idx);
3492 ast_heap_remove(hooks, hook);
3493 ao2_ref(hook, -1);
3494 changed = 1;
3495 }
3496 }
3497 } while (changed);
3498 ast_heap_unlock(hooks);
3499}
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 3508 of file bridge.c.

3509{
3510 struct ast_bridge_hook_timer *hook_a = a;
3511 struct ast_bridge_hook_timer *hook_b = b;
3512 int cmp;
3513
3514 cmp = ast_tvcmp(hook_b->timer.trip_time, hook_a->timer.trip_time);
3515 if (cmp) {
3516 return cmp;
3517 }
3518
3519 cmp = hook_b->timer.seqno - hook_a->timer.seqno;
3520 return cmp;
3521}
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 3569 of file bridge.c.

3570{
3571 struct ast_bridge_hook_timer *hook = obj;
3572
3573 return hook->generic.callback(bridge_channel, hook->generic.hook_pvt);
3574}

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 3577 of file bridge.c.

3578{
3579 ao2_cleanup(obj);
3580}

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 1974 of file bridge.c.

1975{
1977}
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 5460 of file bridge.c.

5461{
5462 const char *id = astman_get_header(m, "ActionID");
5463 RAII_VAR(struct ast_str *, id_text, ast_str_create(128), ast_free);
5464 struct ast_bridge_technology *cur;
5465 int num_items = 0;
5466
5467 if (!id_text) {
5468 astman_send_error(s, m, "Internal error");
5469 return -1;
5470 }
5471
5472 if (!ast_strlen_zero(id)) {
5473 ast_str_set(&id_text, 0, "ActionID: %s\r\n", id);
5474 }
5475
5476 astman_send_listack(s, m, "Bridge technology listing will follow", "start");
5477
5480 const char *type;
5481
5483
5484 astman_append(s,
5485 "Event: BridgeTechnologyListItem\r\n"
5486 "BridgeTechnology: %s\r\n"
5487 "BridgeType: %s\r\n"
5488 "BridgePriority: %u\r\n"
5489 "BridgeSuspended: %s\r\n"
5490 "%s"
5491 "\r\n",
5492 cur->name, type, cur->preference, AST_YESNO(cur->suspended),
5493 ast_str_buffer(id_text));
5494 ++num_items;
5495 }
5497
5498 astman_send_list_complete_start(s, m, "BridgeTechnologyListComplete", num_items);
5500
5501 return 0;
5502}
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:3423
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:3459
void astman_send_list_complete_end(struct mansession *s)
End the list complete event.
Definition: manager.c:3467
void astman_append(struct mansession *s, const char *fmt,...)
Definition: manager.c:3302
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 5450 of file bridge.c.

5451{
5452 return handle_manager_bridge_tech_suspend(s, m, 1);
5453}
static int handle_manager_bridge_tech_suspend(struct mansession *s, const struct message *m, int suspend)
Definition: bridge.c:5416

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 5455 of file bridge.c.

5456{
5457 return handle_manager_bridge_tech_suspend(s, m, 0);
5458}

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 3562 of file bridge.c.

3563{
3564 ao2_link(data, obj);
3565 return 0;
3566}

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 2579 of file bridge.c.

2580{
2581 struct ast_bridge *bridge;
2582 struct ast_bridge_channel *bridge_channel;
2583
2585 return NULL;
2586 }
2588 return NULL;
2589 }
2591 /* Channel has an active monitor, audiohook, or framehook. */
2592 return NULL;
2593 }
2594 bridge_channel = ast_channel_internal_bridge_channel(chan);
2595 if (!bridge_channel || ast_bridge_channel_trylock(bridge_channel)) {
2596 return NULL;
2597 }
2598 bridge = bridge_channel->bridge;
2599 if (bridge_channel->activity != BRIDGE_CHANNEL_THREAD_SIMPLE
2600 || bridge_channel->state != BRIDGE_CHANNEL_STATE_WAIT
2602 ast_bridge_channel_unlock(bridge_channel);
2603 return NULL;
2604 }
2605 if (!bridge_channel_internal_allows_optimization(bridge_channel) ||
2608 ast_bridge_channel_unlock(bridge_channel);
2609 return NULL;
2610 }
2611 return bridge;
2612}
#define ast_bridge_trylock(bridge)
Try locking the bridge.
Definition: bridge.h:459
#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:1004
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:2518
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 2624 of file bridge.c.

2625{
2626 struct ast_bridge *bridge;
2627 struct ast_bridge_channel *bridge_channel;
2628
2629 if (ast_channel_trylock(peer)) {
2630 return NULL;
2631 }
2632 if (!AST_LIST_EMPTY(ast_channel_readq(peer))) {
2633 ast_channel_unlock(peer);
2634 return NULL;
2635 }
2637 ast_channel_unlock(peer);
2638 return NULL;
2639 }
2641 /* Peer has an active monitor, audiohook, or framehook. */
2642 ast_channel_unlock(peer);
2643 return NULL;
2644 }
2645 bridge_channel = ast_channel_internal_bridge_channel(peer);
2646 if (!bridge_channel || ast_bridge_channel_trylock(bridge_channel)) {
2647 ast_channel_unlock(peer);
2648 return NULL;
2649 }
2650 bridge = bridge_channel->bridge;
2651 if (bridge_channel->activity != BRIDGE_CHANNEL_THREAD_IDLE
2652 || bridge_channel->state != BRIDGE_CHANNEL_STATE_WAIT
2654 ast_bridge_channel_unlock(bridge_channel);
2655 ast_channel_unlock(peer);
2656 return NULL;
2657 }
2661 ast_bridge_channel_unlock(bridge_channel);
2662 ast_channel_unlock(peer);
2663 return NULL;
2664 }
2665 return bridge;
2666}
@ BRIDGE_CHANNEL_THREAD_IDLE
#define ast_channel_trylock(chan)
Definition: channel.h:2924

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 1386 of file bridge.c.

1387{
1390 return;
1391 }
1392 if (bridge->num_channels < 2) {
1393 return;
1394 }
1395 if (bridge->num_channels == 2) {
1397 AST_LIST_LAST(&bridge->channels)->chan);
1398 } else {
1400 }
1401}
static void set_bridge_peer_vars_2party(struct ast_channel *c0, struct ast_channel *c1)
Definition: bridge.c:1231
static void set_bridge_peer_vars_multiparty(struct ast_bridge *bridge)
Definition: bridge.c:1306
static void set_bridge_peer_vars_holding(struct ast_bridge *bridge)
Definition: bridge.c:1366
@ AST_BRIDGE_CAPABILITY_HOLDING
Definition: bridge.h:86
#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 1231 of file bridge.c.

1232{
1233 const char *c0_name;
1234 const char *c1_name;
1235 const char *c0_pvtid = NULL;
1236 const char *c1_pvtid = NULL;
1237#define UPDATE_BRIDGE_VARS_GET(chan, name, pvtid) \
1238 do { \
1239 name = ast_strdupa(ast_channel_name(chan)); \
1240 if (ast_channel_tech(chan)->get_pvt_uniqueid) { \
1241 pvtid = ast_strdupa(ast_channel_tech(chan)->get_pvt_uniqueid(chan)); \
1242 } \
1243 } while (0)
1244
1245 ast_channel_lock(c1);
1246 UPDATE_BRIDGE_VARS_GET(c1, c1_name, c1_pvtid);
1248
1249 ast_channel_lock(c0);
1250 ast_bridge_vars_set(c0, c1_name, c1_pvtid);
1251 UPDATE_BRIDGE_VARS_GET(c0, c0_name, c0_pvtid);
1253
1254 ast_channel_lock(c1);
1255 ast_bridge_vars_set(c1, c0_name, c0_pvtid);
1257}
#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:1212

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 1366 of file bridge.c.

1367{
1368 struct ast_bridge_channel *bridge_channel;
1369
1370 AST_LIST_TRAVERSE(&bridge->channels, bridge_channel, entry) {
1371 ast_channel_lock(bridge_channel->chan);
1372 ast_bridge_vars_set(bridge_channel->chan, NULL, NULL);
1373 ast_channel_unlock(bridge_channel->chan);
1374 }
1375}

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, 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 1306 of file bridge.c.

1307{
1308/*
1309 * Set a maximum number of channel names for the BRIDGEPEER
1310 * list. The plus one is for the current channel which is not
1311 * put in the list.
1312 */
1313#define MAX_BRIDGEPEER_CHANS (10 + 1)
1314
1315 unsigned int idx;
1316 unsigned int num_names;
1317 unsigned int len;
1318 const char **names;
1319 char *buf;
1320 struct ast_bridge_channel *bridge_channel;
1321
1322 /* Get first MAX_BRIDGEPEER_CHANS channel names. */
1324 names = ast_alloca(num_names * sizeof(*names));
1325 idx = 0;
1326 AST_LIST_TRAVERSE(&bridge->channels, bridge_channel, entry) {
1327 if (num_names <= idx) {
1328 break;
1329 }
1330 ast_channel_lock(bridge_channel->chan);
1331 names[idx++] = ast_strdupa(ast_channel_name(bridge_channel->chan));
1332 ast_channel_unlock(bridge_channel->chan);
1333 }
1334
1335 /* Determine maximum buf size needed. */
1336 len = num_names;
1337 for (idx = 0; idx < num_names; ++idx) {
1338 len += strlen(names[idx]);
1339 }
1340 buf = ast_alloca(len);
1341
1342 /* Set the bridge channel variables. */
1343 idx = 0;
1344 buf[0] = '\0';
1345 AST_LIST_TRAVERSE(&bridge->channels, bridge_channel, entry) {
1346 if (idx < num_names) {
1347 fill_bridgepeer_buf(buf, idx, names, num_names);
1348 }
1349 ++idx;
1350
1351 ast_channel_lock(bridge_channel->chan);
1352 ast_bridge_vars_set(bridge_channel->chan, buf, NULL);
1353 ast_channel_unlock(bridge_channel->chan);
1354 }
1355}
static void fill_bridgepeer_buf(char *buf, unsigned int cur_idx, const char *names[], unsigned int num_names)
Definition: bridge.c:1269
#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, 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 4383 of file bridge.c.

4384{
4385 struct ao2_iterator iter;
4386 struct ast_channel *chan;
4387 const char *transferer_name;
4388 const char *transferer_bridgepeer;
4389
4390 ast_channel_lock(transferer);
4391 transferer_name = ast_strdupa(ast_channel_name(transferer));
4392 transferer_bridgepeer = ast_strdupa(S_OR(pbx_builtin_getvar_helper(transferer, "BRIDGEPEER"), ""));
4393 ast_channel_unlock(transferer);
4394
4395 for (iter = ao2_iterator_init(channels, 0);
4396 (chan = ao2_iterator_next(&iter));
4397 ao2_cleanup(chan)) {
4398 if (chan == transferer) {
4399 ast_bridge_set_transfer_variables(chan, transferer_bridgepeer, is_attended);
4400 } else {
4401 ast_bridge_set_transfer_variables(chan, transferer_name, is_attended);
4402 }
4403 }
4404
4405 ao2_iterator_destroy(&iter);
4406}
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:4352

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 972 of file bridge.c.

973{
974 uint32_t new_capabilities;
975 struct ast_bridge_technology *new_technology;
976 struct ast_bridge_technology *old_technology = bridge->technology;
977 struct ast_bridge_channel *bridge_channel;
979 struct ast_bridge dummy_bridge = {
980 .technology = bridge->technology,
981 .tech_pvt = bridge->tech_pvt,
982 .creator = bridge->creator,
983 .name = bridge->name,
984 .uniqueid = bridge->uniqueid,
985 };
986
987 if (bridge->dissolved) {
988 ast_debug(1, "Bridge %s is dissolved, not performing smart bridge operation.\n",
989 bridge->uniqueid);
990 return 0;
991 }
992
993 /* Determine new bridge technology capabilities needed. */
994 if (2 < bridge->num_channels) {
995 new_capabilities = AST_BRIDGE_CAPABILITY_MULTIMIX;
996 new_capabilities &= bridge->allowed_capabilities;
997 } else {
999 new_capabilities &= bridge->allowed_capabilities;
1000 if (!new_capabilities
1002 /* Allow switching between different multimix bridge technologies. */
1003 new_capabilities = AST_BRIDGE_CAPABILITY_MULTIMIX;
1004 }
1005 }
1006
1007 /* Find a bridge technology to satisfy the new capabilities. */
1008 new_technology = find_best_technology(new_capabilities, bridge);
1009 if (!new_technology) {
1010 int is_compatible = 0;
1011
1012 if (old_technology->compatible) {
1013 is_compatible = old_technology->compatible(bridge);
1014 } else if (old_technology->capabilities & AST_BRIDGE_CAPABILITY_MULTIMIX) {
1015 is_compatible = 1;
1016 } else if (bridge->num_channels <= 2
1017 && (old_technology->capabilities & AST_BRIDGE_CAPABILITY_1TO1MIX)) {
1018 is_compatible = 1;
1019 }
1020
1021 if (is_compatible) {
1022 ast_debug(1, "Bridge %s could not get a new technology, staying with old technology.\n",
1023 bridge->uniqueid);
1024 return 0;
1025 }
1026 ast_log(LOG_WARNING, "Bridge %s has no technology available to support it.\n",
1027 bridge->uniqueid);
1028 return -1;
1029 }
1030 if (new_technology == old_technology) {
1031 ast_debug(1, "Bridge %s is already using the new technology.\n",
1032 bridge->uniqueid);
1033 ast_module_unref(old_technology->mod);
1034 return 0;
1035 }
1036
1037 if (old_technology->destroy) {
1038 struct tech_deferred_destroy deferred_tech_destroy = {
1039 .tech = dummy_bridge.technology,
1040 .tech_pvt = dummy_bridge.tech_pvt,
1041 };
1042 struct ast_frame action = {
1045 .data.ptr = &deferred_tech_destroy,
1046 .datalen = sizeof(deferred_tech_destroy),
1047 };
1048
1049 /*
1050 * We need to defer the bridge technology destroy callback
1051 * because we have the bridge locked.
1052 */
1053 deferred_action = ast_frdup(&action);
1054 if (!deferred_action) {
1055 ast_module_unref(new_technology->mod);
1056 return -1;
1057 }
1058 } else {
1060 }
1061
1062 /*
1063 * We are now committed to changing the bridge technology. We
1064 * must not release the bridge lock until we have installed the
1065 * new bridge technology.
1066 */
1067 ast_verb(4, "Bridge %s: switching from %s technology to %s\n",
1068 bridge->uniqueid, old_technology->name, new_technology->name);
1069
1070 /*
1071 * Since we are soon going to pass this bridge to a new
1072 * technology we need to NULL out the tech_pvt pointer but
1073 * don't worry as it still exists in dummy_bridge, ditto for the
1074 * old technology.
1075 */
1076 bridge->tech_pvt = NULL;
1077 bridge->technology = new_technology;
1078
1079 /* Setup the new bridge technology. */
1080 ast_debug(1, "Bridge %s: calling %s technology constructor\n",
1081 bridge->uniqueid, new_technology->name);
1082 if (new_technology->create && new_technology->create(bridge)) {
1083 ast_log(LOG_WARNING, "Bridge %s: failed to setup bridge technology %s\n",
1084 bridge->uniqueid, new_technology->name);
1085 bridge->tech_pvt = dummy_bridge.tech_pvt;
1086 bridge->technology = dummy_bridge.technology;
1087 ast_module_unref(new_technology->mod);
1088 return -1;
1089 }
1090
1091 /* To ensure that things are sane for the old technology move the channels it
1092 * expects to the dummy bridge
1093 */
1094 AST_LIST_TRAVERSE_SAFE_BEGIN(&bridge->channels, bridge_channel, entry) {
1095 if (bridge_channel->just_joined) {
1096 continue;
1097 }
1098 ast_debug(1, "Bridge %s: moving %p(%s) to dummy bridge temporarily\n",
1099 bridge->uniqueid, bridge_channel, ast_channel_name(bridge_channel->chan));
1101 AST_LIST_INSERT_TAIL(&dummy_bridge.channels, bridge_channel, entry);
1102 dummy_bridge.num_channels++;
1104 dummy_bridge.num_lonely++;
1105 }
1106 if (!bridge_channel->suspended) {
1107 dummy_bridge.num_active++;
1108 }
1109 }
1111
1112 /* Take all the channels out of the old technology */
1113 AST_LIST_TRAVERSE_SAFE_BEGIN(&dummy_bridge.channels, bridge_channel, entry) {
1114 ast_debug(1, "Bridge %s: %p(%s) is leaving %s technology (dummy)\n",
1115 dummy_bridge.uniqueid, bridge_channel, ast_channel_name(bridge_channel->chan),
1116 old_technology->name);
1117 if (old_technology->leave) {
1118 old_technology->leave(&dummy_bridge, bridge_channel);
1119 }
1121 AST_LIST_INSERT_TAIL(&bridge->channels, bridge_channel, entry);
1122 dummy_bridge.num_channels--;
1124 dummy_bridge.num_lonely--;
1125 }
1126 if (!bridge_channel->suspended) {
1127 dummy_bridge.num_active--;
1128 }
1129 }
1131
1132 ast_debug(1, "Bridge %s: calling %s technology stop\n",
1133 dummy_bridge.uniqueid, old_technology->name);
1134 if (old_technology->stop) {
1135 old_technology->stop(&dummy_bridge);
1136 }
1137
1138 /* Add any new channels or re-add existing channels to the bridge. */
1139 AST_LIST_TRAVERSE(&bridge->channels, bridge_channel, entry) {
1140 bridge_channel_complete_join(bridge, bridge_channel);
1141 }
1142
1143 ast_debug(1, "Bridge %s: calling %s technology start\n",
1144 bridge->uniqueid, new_technology->name);
1145 if (new_technology->start && new_technology->start(bridge)) {
1146 ast_log(LOG_WARNING, "Bridge %s: failed to start bridge technology %s\n",
1147 bridge->uniqueid, new_technology->name);
1148 }
1149
1150 /*
1151 * Now that all the channels have been moved over we need to get
1152 * rid of all the information the old technology may have left
1153 * around.
1154 */
1155 if (old_technology->destroy) {
1156 ast_debug(1, "Bridge %s: deferring %s technology destructor\n",
1157 dummy_bridge.uniqueid, old_technology->name);
1159 } else {
1160 ast_debug(1, "Bridge %s: calling %s technology destructor\n",
1161 dummy_bridge.uniqueid, old_technology->name);
1162 ast_module_unref(old_technology->mod);
1163 }
1164
1165 return 0;
1166}
@ 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:357
unsigned int num_active
Definition: bridge.h:375
unsigned int num_lonely
Definition: bridge.h:377

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 5277 of file bridge.c.

5278{
5279 const char *type;
5280
5281 if (capabilities & AST_BRIDGE_CAPABILITY_HOLDING) {
5282 type = "Holding";
5283 } else if (capabilities & AST_BRIDGE_CAPABILITY_EARLY) {
5284 type = "Early";
5285 } else if (capabilities & AST_BRIDGE_CAPABILITY_NATIVE) {
5286 type = "Native";
5287 } else if (capabilities & AST_BRIDGE_CAPABILITY_1TO1MIX) {
5288 type = "1to1Mix";
5289 } else if (capabilities & AST_BRIDGE_CAPABILITY_MULTIMIX) {
5290 type = "MultiMix";
5291 } else {
5292 type = "<Unknown>";
5293 }
5294 return type;
5295}
@ AST_BRIDGE_CAPABILITY_EARLY
Definition: bridge.h:88

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 2869 of file bridge.c.

2873{
2874 struct merge_direction merge;
2875 struct ast_bridge_channel *kick_me[] = {
2876 chan_bridge_channel,
2877 peer_bridge_channel,
2878 };
2879 unsigned int id;
2880
2881 switch (bridges_allow_merge_optimization(chan_bridge, peer_bridge, ARRAY_LEN(kick_me), &merge)) {
2882 case MERGE_ALLOWED:
2883 break;
2884 case MERGE_PROHIBITED:
2885 return 0;
2887 ast_debug(4, "Can't optimize %s -- %s out, not enough channels in bridge %s.\n",
2888 ast_channel_name(chan_bridge_channel->chan),
2889 ast_channel_name(peer_bridge_channel->chan),
2890 merge.src->uniqueid);
2891 return 0;
2892 case MERGE_NO_MULTIMIX:
2893 ast_debug(4, "Can't optimize %s -- %s out, multimix is needed and it cannot be acquired.\n",
2894 ast_channel_name(chan_bridge_channel->chan),
2895 ast_channel_name(peer_bridge_channel->chan));
2896 return 0;
2897 }
2898
2899 ast_verb(4, "Merge optimizing %s -- %s out.\n",
2900 ast_channel_name(chan_bridge_channel->chan),
2901 ast_channel_name(peer_bridge_channel->chan));
2902
2903 id = ast_atomic_fetchadd_int((int *) &optimization_id, +1);
2904
2905 if (pvt && !ast_test_flag(pvt, AST_UNREAL_OPTIMIZE_BEGUN) && pvt->callbacks
2909 id);
2911 }
2912 bridge_do_merge(merge.dest, merge.src, kick_me, ARRAY_LEN(kick_me), 1);
2913 if (pvt && pvt->callbacks && pvt->callbacks->optimization_finished) {
2914 pvt->callbacks->optimization_finished(pvt, 1, id);
2915 }
2916
2917 return -1;
2918}
enum queue_result id
Definition: app_queue.c:1638
static unsigned int optimization_id
Definition: bridge.c:127
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 4326 of file bridge.c.

4329{
4330 RAII_VAR(struct ast_bridge_channel *, transferer_bridge_channel, NULL, ao2_cleanup);
4331
4334 }
4335
4336 ast_channel_lock(transferer);
4337 transferer_bridge_channel = ast_channel_get_bridge_channel(transferer);
4338 ast_channel_unlock(transferer);
4339
4340 if (!transferer_bridge_channel) {
4342 }
4343
4344 if (ast_parking_blind_transfer_park(transferer_bridge_channel,
4345 context, exten, new_channel_cb, user_data_wrapper)) {
4347 }
4348
4350}
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 2745 of file bridge.c.

2749{
2750 struct ast_bridge *dst_bridge;
2751 struct ast_bridge_channel *dst_bridge_channel;
2752 struct ast_bridge_channel *src_bridge_channel;
2753 struct ast_bridge_channel *other;
2754 int res = 1;
2755
2756 switch (bridges_allow_swap_optimization(chan_bridge, peer_bridge)) {
2758 dst_bridge = chan_bridge;
2759 dst_bridge_channel = chan_bridge_channel;
2760 src_bridge_channel = peer_bridge_channel;
2761 break;
2763 dst_bridge = peer_bridge;
2764 dst_bridge_channel = peer_bridge_channel;
2765 src_bridge_channel = chan_bridge_channel;
2766 break;
2767 case SWAP_PROHIBITED:
2768 default:
2769 return 0;
2770 }
2771
2772 other = ast_bridge_channel_peer(src_bridge_channel);
2773 if (other && other->state == BRIDGE_CHANNEL_STATE_WAIT) {
2774 unsigned int id;
2775
2776 if (ast_channel_trylock(other->chan)) {
2777 return 1;
2778 }
2779
2780 id = ast_atomic_fetchadd_int((int *) &optimization_id, +1);
2781
2782 ast_verb(4, "Move-swap optimizing %s <-- %s.\n",
2783 ast_channel_name(dst_bridge_channel->chan),
2784 ast_channel_name(other->chan));
2785
2786 if (pvt && !ast_test_flag(pvt, AST_UNREAL_OPTIMIZE_BEGUN) && pvt->callbacks
2788 pvt->callbacks->optimization_started(pvt, other->chan,
2789 dst_bridge_channel->chan == pvt->owner ? AST_UNREAL_OWNER : AST_UNREAL_CHAN,
2790 id);
2792 }
2793 other->swap = dst_bridge_channel->chan;
2794 if (!bridge_do_move(dst_bridge, other, 1, 1)) {
2795 ast_bridge_channel_leave_bridge(src_bridge_channel,
2797 res = -1;
2798 }
2799 if (pvt && pvt->callbacks && pvt->callbacks->optimization_finished) {
2800 pvt->callbacks->optimization_finished(pvt, res == 1, id);
2801 }
2802 ast_channel_unlock(other->chan);
2803 }
2804 return res;
2805}

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 4611 of file bridge.c.

4617{
4618 struct ast_bridge_channel *kick_me[] = {
4619 to_transferee_bridge_channel,
4620 to_target_bridge_channel,
4621 };
4622 enum ast_transfer_result res;
4623 struct ast_bridge *final_bridge = NULL;
4625
4626 channels = ast_bridge_peers_nolock(to_transferee_bridge);
4627
4628 if (!channels) {
4630 goto end;
4631 }
4632
4633 set_transfer_variables_all(to_transferee, channels, 1);
4634
4635 switch (ast_bridges_allow_optimization(to_transferee_bridge, to_target_bridge)) {
4637 final_bridge = to_transferee_bridge;
4638 res = bridge_swap_attended_transfer(to_transferee_bridge, to_target_bridge_channel, to_transferee);
4639 goto end;
4641 final_bridge = to_target_bridge;
4642 res = bridge_swap_attended_transfer(to_target_bridge, to_transferee_bridge_channel, to_transfer_target);
4643 goto end;
4645 final_bridge = to_transferee_bridge;
4646 bridge_do_merge(to_transferee_bridge, to_target_bridge, kick_me, ARRAY_LEN(kick_me), 0);
4648 goto end;
4650 final_bridge = to_target_bridge;
4651 bridge_do_merge(to_target_bridge, to_transferee_bridge, kick_me, ARRAY_LEN(kick_me), 0);
4653 goto end;
4655 default:
4656 /* Just because optimization wasn't doable doesn't necessarily mean
4657 * that we can actually perform the transfer. Some reasons for non-optimization
4658 * indicate bridge invalidity, so let's check those before proceeding.
4659 */
4660 if (to_transferee_bridge->inhibit_merge || to_transferee_bridge->dissolved ||
4661 to_target_bridge->inhibit_merge || to_target_bridge->dissolved) {
4663 }
4664
4665 return attended_transfer_bridge(to_transferee, to_transfer_target,
4666 to_transferee_bridge, to_target_bridge, transfer_msg);
4667 }
4668
4669end:
4670 if (res == AST_BRIDGE_TRANSFER_SUCCESS) {
4671 ast_attended_transfer_message_add_merge(transfer_msg, final_bridge);
4672 }
4673
4674 return res;
4675}
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:4568
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:2960
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 3583 of file bridge.c.

3584{
3585 /* Break out of the current wrapper if it exists to avoid multiple layers */
3586 if (hook->generic.callback == interval_wrapper_cb) {
3587 hook = hook->generic.hook_pvt;
3588 }
3589
3590 ast_bridge_interval_hook(features, hook->timer.flags, hook->timer.interval,
3592 hook->generic.remove_flags.flags);
3593}
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:3319
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:3569
static void interval_wrapper_pvt_dtor(void *obj)
Destructor for the hook wrapper.
Definition: bridge.c:3577

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:1523
static void bridge_channel_impart_ds_head_dtor(void *doomed)
Definition: bridge.c:1508

Definition at line 1532 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 5404 of file bridge.c.

Referenced by ast_bridging_init(), and bridge_cleanup().

◆ bridge_manager

struct bridge_manager_controller* bridge_manager
static

Bridge manager controller.

Definition at line 172 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 144 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 147 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 150 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 127 of file bridge.c.

Referenced by try_merge_optimize_out(), and try_swap_optimize_out().