Asterisk - The Open Source Telephony Project GIT-master-77d630f
Data Structures | Macros | Enumerations | Functions | Variables
bridge.c File Reference

Bridging API. More...

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

Go to the source code of this file.

Data Structures

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

Macros

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

Enumerations

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

Functions

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

Variables

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

Detailed Description

Bridging API.

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

Definition in file bridge.c.

Macro Definition Documentation

◆ ATTENDEDTRANSFER

#define ATTENDEDTRANSFER   "ATTENDEDTRANSFER"

Definition at line 150 of file bridge.c.

◆ BLINDTRANSFER

#define BLINDTRANSFER   "BLINDTRANSFER"

Definition at line 147 of file bridge.c.

◆ BRIDGE_ARRAY_GROW

#define BRIDGE_ARRAY_GROW   32

Definition at line 144 of file bridge.c.

◆ BRIDGE_ARRAY_START

#define BRIDGE_ARRAY_START   128

Definition at line 141 of file bridge.c.

◆ BRIDGE_LOCK_ONE_OR_BOTH

#define BRIDGE_LOCK_ONE_OR_BOTH (   b1,
  b2 
)

◆ FORMAT_HDR [1/2]

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

◆ FORMAT_HDR [2/2]

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

◆ FORMAT_ROW [1/2]

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

◆ FORMAT_ROW [2/2]

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

◆ MAX_BRIDGEPEER_CHANS

#define MAX_BRIDGEPEER_CHANS   (10 + 1)

◆ UPDATE_BRIDGE_VARS_GET

#define UPDATE_BRIDGE_VARS_GET (   chan,
  name,
  pvtid 
)

Enumeration Type Documentation

◆ bridge_allow_merge

Enumerator
MERGE_PROHIBITED 

Bridge properties prohibit merge optimization

MERGE_NOT_ENOUGH_CHANNELS 

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

MERGE_NO_MULTIMIX 

Merge optimization cannot occur because multimix capability could not be requested

MERGE_ALLOWED 

Merge optimization allowed between bridges

Definition at line 2890 of file bridge.c.

2890 {
2891 /*! Bridge properties prohibit merge optimization */
2893 /*! Merge optimization cannot occur because the source bridge has too few channels */
2895 /*! Merge optimization cannot occur because multimix capability could not be requested */
2897 /*! Merge optimization allowed between bridges */
2899};
@ MERGE_ALLOWED
Definition: bridge.c:2898
@ MERGE_NOT_ENOUGH_CHANNELS
Definition: bridge.c:2894
@ MERGE_NO_MULTIMIX
Definition: bridge.c:2896
@ MERGE_PROHIBITED
Definition: bridge.c:2892

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

2751 {
2752 /*! Bridges cannot allow for a swap optimization to occur */
2754 /*! Bridge swap optimization can occur into the chan_bridge */
2756 /*! Bridge swap optimization can occur into the peer_bridge */
2758};
@ SWAP_PROHIBITED
Definition: bridge.c:2753
@ SWAP_TO_PEER_BRIDGE
Definition: bridge.c:2757
@ SWAP_TO_CHAN_BRIDGE
Definition: bridge.c:2755

Function Documentation

◆ __ast_bridge_technology_register()

int __ast_bridge_technology_register ( struct ast_bridge_technology technology,
struct ast_module mod 
)

Register a bridge technology for use.

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

Example usage:

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

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

Definition at line 223 of file bridge.c.

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

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

◆ ast_bridge_add_channel()

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

Add an arbitrary channel to a bridge.

Since
12.0.0

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

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

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

Definition at line 2540 of file bridge.c.

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

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_debug, 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, noanswer, NULL, pbx_builtin_getvar_helper(), RAII_VAR, and value.

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

◆ ast_bridge_base_new()

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

Create a new base class bridge.

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

Example usage:

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

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

Definition at line 999 of file bridge.c.

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

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

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

◆ ast_bridge_depart()

int ast_bridge_depart ( struct ast_channel chan)

Depart a channel from a bridge.

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

Example usage:

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

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

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

Definition at line 1975 of file bridge.c.

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

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

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

◆ ast_bridge_destroy()

int ast_bridge_destroy ( struct ast_bridge bridge,
int  cause 
)

Destroy a bridge.

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

Example usage:

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

This destroys a bridge that was previously created.

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

Definition at line 1009 of file bridge.c.

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

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

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

◆ ast_bridge_dtmf_hook()

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

Attach a DTMF hook to a bridge features structure.

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

Example usage:

struct ast_bridge_features features;
ast_bridge_dtmf_hook(&features, "#", pound_callback, NULL, NULL, 0);
int ast_bridge_features_init(struct ast_bridge_features *features)
Initialize bridge features structure.
Definition: bridge.c:3699
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:3261
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 3261 of file bridge.c.

3267{
3268 struct ast_bridge_hook_dtmf *hook;
3269 int res;
3270
3271 /* Allocate new hook and setup it's various variables */
3272 hook = (struct ast_bridge_hook_dtmf *) bridge_hook_generic(sizeof(*hook), callback,
3273 hook_pvt, destructor, remove_flags);
3274 if (!hook) {
3275 return -1;
3276 }
3278 ast_copy_string(hook->dtmf.code, dtmf, sizeof(hook->dtmf.code));
3279
3280 /* Once done we put it in the container. */
3281 res = ao2_link(features->dtmf_hooks, hook) ? 0 : -1;
3282 if (res) {
3283 /*
3284 * Could not link the hook into the container.
3285 *
3286 * Remove the hook_pvt destructor call from the hook since we
3287 * are returning failure to install the hook.
3288 */
3289 hook->generic.destructor = NULL;
3290 }
3291 ao2_ref(hook, -1);
3292
3293 return res;
3294}
#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:3241
@ AST_BRIDGE_HOOK_TYPE_DTMF
static struct ast_channel * callback(struct ast_channelstorage_instance *driver, ao2_callback_data_fn *cb_fn, void *arg, void *data, int ao2_flags)
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(), callback(), 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:3732

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

3733{
3734 struct ast_bridge_hook_timer *hook;
3735
3736 /* Destroy the interval hooks heap. */
3737 if (features->interval_hooks) {
3738 while ((hook = ast_heap_pop(features->interval_hooks))) {
3739 ao2_ref(hook, -1);
3740 }
3741 features->interval_hooks = ast_heap_destroy(features->interval_hooks);
3742 }
3743
3744 /* Destroy the miscellaneous other hooks container. */
3745 ao2_cleanup(features->other_hooks);
3746 features->other_hooks = NULL;
3747
3748 /* Destroy the DTMF hooks container. */
3749 ao2_cleanup(features->dtmf_hooks);
3750 features->dtmf_hooks = NULL;
3751}
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:3762
void ast_bridge_features_destroy(struct ast_bridge_features *features)
Destroy an allocated bridge features struct.
Definition: bridge.c:3753

Definition at line 3753 of file bridge.c.

3754{
3755 if (!features) {
3756 return;
3757 }
3759 ast_free(features);
3760}
#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:3732

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

Definition at line 3169 of file bridge.c.

3170{
3172
3173 if (ARRAY_LEN(builtin_features_handlers) <= feature) {
3174 return -1;
3175 }
3176
3178 if (!callback) {
3179 return -1;
3180 }
3181 callback(bridge_channel, hook_pvt);
3182
3183 return 0;
3184}
static ast_bridge_hook_callback builtin_features_handlers[AST_BRIDGE_BUILTIN_END]
Definition: bridge.c:158
int(* ast_bridge_hook_callback)(struct ast_bridge_channel *bridge_channel, void *hook_pvt)
Hook callback type.
#define ARRAY_LEN(a)
Definition: utils.h:703

References ARRAY_LEN, builtin_features_handlers, and callback().

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

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

3450{
3451 if (ARRAY_LEN(builtin_features_handlers) <= feature
3452 || !builtin_features_handlers[feature]) {
3453 return -1;
3454 }
3455
3456 /* If no alternate DTMF stream was provided use the default one */
3457 if (ast_strlen_zero(dtmf)) {
3458 dtmf = builtin_features_dtmf[feature];
3459 /* If no DTMF is still available (ie: it has been disabled) then error out now */
3460 if (ast_strlen_zero(dtmf)) {
3461 ast_debug(1, "Failed to enable built in feature %u on %p, no DTMF string is available for it.\n",
3462 feature, features);
3463 return -1;
3464 }
3465 }
3466
3467 /*
3468 * The rest is basically pretty easy. We create another hook
3469 * using the built in feature's DTMF callback. Easy as pie.
3470 */
3471 return ast_bridge_dtmf_hook(features, dtmf, builtin_features_handlers[feature],
3472 config, destructor, remove_flags);
3473}
static char builtin_features_dtmf[AST_BRIDGE_BUILTIN_END][MAXIMUM_DTMF_FEATURE_STRING]
Definition: bridge.c:155
int ast_bridge_dtmf_hook(struct ast_bridge_features *features, const char *dtmf, ast_bridge_hook_callback callback, void *hook_pvt, ast_bridge_hook_pvt_destructor destructor, enum ast_bridge_hook_remove_flags remove_flags)
Attach a DTMF hook to a bridge features structure.
Definition: bridge.c:3261
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 3699 of file bridge.c.

3700{
3701 /* Zero out the structure */
3702 memset(features, 0, sizeof(*features));
3703
3704 /* Initialize the DTMF hooks container */
3707 if (!features->dtmf_hooks) {
3708 return -1;
3709 }
3710
3711 /* Initialize the miscellaneous other hooks container */
3713 NULL);
3714 if (!features->other_hooks) {
3715 return -1;
3716 }
3717
3718 /* Initialize the interval hooks heap */
3720 offsetof(struct ast_bridge_hook_timer, timer.heap_index));
3721 if (!features->interval_hooks) {
3722 return -1;
3723 }
3724
3725 features->dtmf_passthrough = 1;
3726 features->text_messaging = 1;
3727
3728 return 0;
3729}
@ 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:3587
static int bridge_dtmf_hook_sort(const void *obj_left, const void *obj_right, int flags)
Definition: bridge.c:3618
static struct ast_timer * timer
Definition: chan_iax2.c:388
#define ast_heap_create(init_height, cmp_fn, index_offset)
Create a max heap.
Definition: heap.h:100
unsigned int dtmf_passthrough
unsigned int text_messaging

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

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

◆ ast_bridge_features_limits_construct()

int ast_bridge_features_limits_construct ( struct ast_bridge_features_limits limits)

Constructor function for ast_bridge_features_limits.

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

Definition at line 3475 of file bridge.c.

3476{
3477 memset(limits, 0, sizeof(*limits));
3478
3479 if (ast_string_field_init(limits, 256)) {
3480 return -1;
3481 }
3482
3483 return 0;
3484}
#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 3486 of file bridge.c.

3487{
3489}
#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 3674 of file bridge.c.

3675{
3676 struct ast_bridge_hook_timer *hook;
3677 int idx;
3678
3679 /* Merge hook containers */
3682
3683 /* Merge hook heaps */
3685 for (idx = 1; (hook = ast_heap_peek(from->interval_hooks, idx)); idx++) {
3686 wrap_hook(into, hook);
3687 }
3689
3690 /* Merge feature flags */
3691 into->feature_flags.flags |= from->feature_flags.flags;
3692 into->usable |= from->usable;
3693
3694 into->mute |= from->mute;
3695 into->dtmf_passthrough |= from->dtmf_passthrough;
3696}
#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:3641
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:3662
#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:218

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

3763{
3764 struct ast_bridge_features *features;
3765
3766 features = ast_malloc(sizeof(*features));
3767 if (features) {
3768 if (ast_bridge_features_init(features)) {
3770 features = NULL;
3771 }
3772 }
3773
3774 return features;
3775}
#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:3699

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

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

Definition at line 3141 of file bridge.c.

3142{
3143 if (ARRAY_LEN(builtin_features_handlers) <= feature
3144 || builtin_features_handlers[feature]) {
3145 return -1;
3146 }
3147
3148 if (!ast_strlen_zero(dtmf)) {
3149 ast_copy_string(builtin_features_dtmf[feature], dtmf, sizeof(builtin_features_dtmf[feature]));
3150 }
3151
3153
3154 return 0;
3155}

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

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

3581{
3582 hooks_remove_container(features->dtmf_hooks, remove_flags);
3583 hooks_remove_container(features->other_hooks, remove_flags);
3584 hooks_remove_heap(features->interval_hooks, remove_flags);
3585}
static void hooks_remove_heap(struct ast_heap *hooks, enum ast_bridge_hook_remove_flags remove_flags)
Definition: bridge.c:3558
static void hooks_remove_container(struct ao2_container *hooks, enum ast_bridge_hook_remove_flags remove_flags)
Definition: bridge.c:3544

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

3507{
3508 ast_set_flag(&features->feature_flags, flag);
3509 features->usable = 1;
3510}
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:3491
int ast_bridge_features_limits_construct(struct ast_bridge_features_limits *limits)
Constructor function for ast_bridge_features_limits.
Definition: bridge.c:3475
void ast_bridge_features_limits_destroy(struct ast_bridge_features_limits *limits)
Destructor function for ast_bridge_features_limits.
Definition: bridge.c:3486
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 3491 of file bridge.c.

3494{
3497
3499 return callback(features, limits, remove_flags);
3500 }
3501
3502 ast_log(LOG_ERROR, "Attempted to set limits without an AST_BRIDGE_BUILTIN_INTERVAL_LIMITS callback registered.\n");
3503 return -1;
3504}
static ast_bridge_builtin_set_limits_fn builtin_interval_handlers[AST_BRIDGE_BUILTIN_INTERVAL_END]
Definition: bridge.c:161
int(* ast_bridge_builtin_set_limits_fn)(struct ast_bridge_features *features, struct ast_bridge_features_limits *limits, enum ast_bridge_hook_remove_flags remove_flags)
Attach interval hooks to a bridge features structure.
@ AST_BRIDGE_BUILTIN_INTERVAL_LIMITS

References AST_BRIDGE_BUILTIN_INTERVAL_LIMITS, ast_log, builtin_interval_handlers, callback(), 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:3157

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

Definition at line 3157 of file bridge.c.

3158{
3159 if (ARRAY_LEN(builtin_features_handlers) <= feature
3160 || !builtin_features_handlers[feature]) {
3161 return -1;
3162 }
3163
3165
3166 return 0;
3167}

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

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

References ao2_find, bridges, and OBJ_SEARCH_KEY.

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

◆ ast_bridge_hangup_hook()

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

Attach a hangup hook to a bridge features structure.

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

Example usage:

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

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

3349{
3350 return bridge_other_hook(features, callback, hook_pvt, destructor, remove_flags,
3352}
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:3310
@ AST_BRIDGE_HOOK_TYPE_HANGUP

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

Referenced by add_normal_hooks(), and bridge_personality_atxfer_push().

◆ ast_bridge_impart()

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

Impart a channel to a bridge (non-blocking)

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

Example usage:

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

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

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

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

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

Definition at line 1947 of file bridge.c.

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

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

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

◆ ast_bridge_interval_hook()

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

Attach an interval hook to a bridge features structure.

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

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

3405{
3406 struct ast_bridge_hook_timer *hook;
3407 int res;
3408
3409 if (!features ||!interval || !callback) {
3410 return -1;
3411 }
3412
3413 /* Allocate new hook and setup it's various variables */
3414 hook = (struct ast_bridge_hook_timer *) bridge_hook_generic(sizeof(*hook), callback,
3415 hook_pvt, destructor, remove_flags);
3416 if (!hook) {
3417 return -1;
3418 }
3420 hook->timer.interval = interval;
3421 hook->timer.trip_time = ast_tvadd(ast_tvnow(), ast_samp2tv(interval, 1000));
3422 hook->timer.seqno = ast_atomic_fetchadd_int((int *) &features->interval_sequence, +1);
3423 hook->timer.flags = flags;
3424
3425 ast_debug(1, "Putting interval hook %p with interval %u in the heap on features %p\n",
3426 hook, hook->timer.interval, features);
3428 res = ast_heap_push(features->interval_hooks, hook);
3430 if (res) {
3431 /*
3432 * Could not push the hook into the heap
3433 *
3434 * Remove the hook_pvt destructor call from the hook since we
3435 * are returning failure to install the hook.
3436 */
3437 hook->generic.destructor = NULL;
3438 ao2_ref(hook, -1);
3439 }
3440
3441 return res ? -1 : 0;
3442}
@ 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:764
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:2280
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(), callback(), 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:3186

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

Definition at line 3186 of file bridge.c.

3187{
3188 if (ARRAY_LEN(builtin_interval_handlers) <= interval
3189 || builtin_interval_handlers[interval]) {
3190 return -1;
3191 }
3192
3194
3195 return 0;
3196}

References ARRAY_LEN, builtin_interval_handlers, and callback().

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

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

Definition at line 3198 of file bridge.c.

3199{
3200 if (ARRAY_LEN(builtin_interval_handlers) <= interval
3201 || !builtin_interval_handlers[interval]) {
3202 return -1;
3203 }
3204
3205 builtin_interval_handlers[interval] = NULL;
3206
3207 return 0;
3208
3209}

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

3971{
3972 int res = 0;
3973
3974 ast_bridge_lock(bridge);
3975 switch (bridge->softmix.video_mode.mode) {
3977 break;
3980 res = 1;
3981 }
3982 break;
3985 res = 1;
3986 } else if (bridge->softmix.video_mode.mode_data.talker_src_data.chan_old_vsrc == chan) {
3987 res = 2;
3988 }
3990 break;
3991 }
3992 ast_bridge_unlock(bridge);
3993 return res;
3994}
@ AST_BRIDGE_VIDEO_MODE_SINGLE_SRC
Definition: bridge.h:106
@ AST_BRIDGE_VIDEO_MODE_TALKER_SRC
Definition: bridge.h:109
@ AST_BRIDGE_VIDEO_MODE_NONE
Definition: bridge.h:104
@ AST_BRIDGE_VIDEO_MODE_SFU
Definition: bridge.h:113
struct ast_bridge_video_mode video_mode
Definition: bridge.h:283
union ast_bridge_video_mode::@194 mode_data
struct ast_bridge_video_single_src_data single_src_data
Definition: bridge.h:167
struct ast_bridge_video_talker_src_data talker_src_data
Definition: bridge.h:168
enum ast_bridge_video_mode_type mode
Definition: bridge.h:164
struct ast_channel * chan_vsrc
Definition: bridge.h:120
struct ast_channel * chan_old_vsrc
Definition: bridge.h:131
struct ast_channel * chan_vsrc
Definition: bridge.h:127
struct ast_bridge_softmix softmix
Definition: bridge.h:371

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

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

◆ ast_bridge_join()

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

Join a channel to a bridge (blocking)

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

Example usage:

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

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

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

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

Definition at line 1690 of file bridge.c.

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

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

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

◆ ast_bridge_join_hook()

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

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

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

Example usage:

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

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

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

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

Referenced by agent_request_exec(), and confbridge_exec().

◆ ast_bridge_kick()

int ast_bridge_kick ( struct ast_bridge bridge,
struct ast_channel chan 
)

Kick a channel from a bridge.

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

Example usage:

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

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

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

Definition at line 2048 of file bridge.c.

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

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

Referenced by handle_bridge_kick_channel(), and manager_bridge_kick().

◆ ast_bridge_leave_hook()

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

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

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

Example usage:

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

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

3369{
3370 return bridge_other_hook(features, callback, hook_pvt, destructor, remove_flags,
3372}
@ AST_BRIDGE_HOOK_TYPE_LEAVE

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

Referenced by confbridge_exec().

◆ ast_bridge_merge()

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

Merge two bridges together.

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

Example usage:

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

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

Definition at line 2369 of file bridge.c.

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

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

◆ ast_bridge_merge_inhibit()

void ast_bridge_merge_inhibit ( struct ast_bridge bridge,
int  request 
)

Adjust the bridge merge inhibit request count.

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

Definition at line 3079 of file bridge.c.

3080{
3081 ast_bridge_lock(bridge);
3083 ast_bridge_unlock(bridge);
3084}
void bridge_merge_inhibit_nolock(struct ast_bridge *bridge, int request)
Definition: bridge.c:3070
static int request(void *obj)
Definition: chan_pjsip.c:2619

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

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

◆ ast_bridge_move()

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

Move a channel from one bridge to another.

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

Definition at line 2529 of file bridge.c.

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

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

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

◆ ast_bridge_move_hook()

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

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

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

Example usage:

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

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

3391{
3393
3394 return bridge_other_hook(features, hook_cb, hook_pvt, destructor, remove_flags,
3396}
@ 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(), callback(), ast_bridge_hook::destructor, hook_cb(), ast_bridge_hook::hook_pvt, and ast_bridge_hook::remove_flags.

Referenced by bridge_stasis_pull().

◆ ast_bridge_notify_masquerade()

void ast_bridge_notify_masquerade ( struct ast_channel chan)

Notify bridging that this channel was just masqueraded.

Since
12.0.0
Parameters
chanChannel just involved in a masquerade

Definition at line 1511 of file bridge.c.

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

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

Referenced by channel_do_masquerade().

◆ ast_bridge_number_video_src()

int ast_bridge_number_video_src ( struct ast_bridge bridge)

◆ ast_bridge_peer()

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

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

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

Definition at line 4154 of file bridge.c.

4155{
4156 struct ast_channel *peer;
4157
4159 peer = ast_bridge_peer_nolock(bridge, chan);
4161
4162 return peer;
4163}
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:4126
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 4126 of file bridge.c.

4127{
4128 struct ast_channel *peer = NULL;
4129 struct ast_bridge_channel *iter;
4130
4131 /* Asking for the peer channel only makes sense on a two-party bridge. */
4132 if (bridge->num_channels == 2
4135 int in_bridge = 0;
4136
4138 if (iter->chan != chan) {
4139 peer = iter->chan;
4140 } else {
4141 in_bridge = 1;
4142 }
4143 }
4144 if (in_bridge && peer) {
4145 ast_channel_ref(peer);
4146 } else {
4147 peer = NULL;
4148 }
4149 }
4150
4151 return peer;
4152}
@ AST_BRIDGE_CAPABILITY_NATIVE
Definition: bridge.h:94
#define AST_LIST_TRAVERSE(head, var, field)
Loops over (traverses) the entries in a list.
Definition: linkedlists.h:491
struct ast_bridge_channel::@196 entry
unsigned int in_bridge
struct ast_bridge_channels_list channels
Definition: bridge.h:367
unsigned int num_channels
Definition: bridge.h:377
struct ast_bridge_technology * technology
Definition: bridge.h:359

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

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

◆ ast_bridge_peers()

struct ao2_container * ast_bridge_peers ( struct ast_bridge bridge)

Get a container of all channels in the bridge.

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

Definition at line 4115 of file bridge.c.

4116{
4117 struct ao2_container *channels;
4118
4119 ast_bridge_lock(bridge);
4121 ast_bridge_unlock(bridge);
4122
4123 return channels;
4124}
struct ao2_container * ast_bridge_peers_nolock(struct ast_bridge *bridge)
Get a container of all channels in the bridge.
Definition: bridge.c:4097
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 4097 of file bridge.c.

4098{
4099 struct ao2_container *channels;
4100 struct ast_bridge_channel *iter;
4101
4104 if (!channels) {
4105 return NULL;
4106 }
4107
4109 ao2_link(channels, iter->chan);
4110 }
4111
4112 return channels;
4113}
@ 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:4052
static int channel_cmp(void *obj, void *arg, int flags)
Definition: bridge.c:4075

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

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

◆ ast_bridge_queue_action()

int ast_bridge_queue_action ( struct ast_bridge bridge,
struct ast_frame action 
)

Put an action onto the specified bridge.

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

Definition at line 314 of file bridge.c.

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

References ast_frdup, and bridge_queue_action_nodup().

Referenced by bridge_dissolve().

◆ ast_bridge_remove()

int ast_bridge_remove ( struct ast_bridge bridge,
struct ast_channel chan 
)

Remove a channel from a bridge.

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

Example usage:

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

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

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

Definition at line 2020 of file bridge.c.

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

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

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

◆ ast_bridge_remove_video_src()

void ast_bridge_remove_video_src ( struct ast_bridge bridge,
struct ast_channel chan 
)

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

Definition at line 3996 of file bridge.c.

3997{
3998 ast_bridge_lock(bridge);
3999 switch (bridge->softmix.video_mode.mode) {
4001 break;
4006 }
4008 }
4009 break;
4014 }
4017 }
4021 }
4023 }
4025 break;
4026 }
4027 ast_bridge_unlock(bridge);
4028}

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

3785{
3786 ast_bridge_lock(bridge);
3787 bridge->softmix.binaural_active = binaural_active;
3788 ast_bridge_unlock(bridge);
3789}
unsigned int binaural_active
Definition: bridge.h:299

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

Referenced by join_conference_bridge().

◆ ast_bridge_set_internal_sample_rate()

void ast_bridge_set_internal_sample_rate ( struct ast_bridge bridge,
unsigned int  sample_rate 
)

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

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

Definition at line 3791 of file bridge.c.

3792{
3793 ast_bridge_lock(bridge);
3794 bridge->softmix.internal_sample_rate = sample_rate;
3795 ast_bridge_unlock(bridge);
3796}
unsigned int internal_sample_rate
The internal sample rate softmix uses to mix channels.
Definition: bridge.h:289

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

Referenced by join_conference_bridge().

◆ ast_bridge_set_maximum_sample_rate()

void ast_bridge_set_maximum_sample_rate ( struct ast_bridge bridge,
unsigned int  sample_rate 
)

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

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

Definition at line 3798 of file bridge.c.

3799{
3800 ast_bridge_lock(bridge);
3801 bridge->softmix.maximum_sample_rate = sample_rate;
3802 ast_bridge_unlock(bridge);
3803}
unsigned int maximum_sample_rate
The maximum sample rate softmix uses to mix channels.
Definition: bridge.h:310

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

Referenced by join_conference_bridge().

◆ ast_bridge_set_mixing_interval()

void ast_bridge_set_mixing_interval ( struct ast_bridge bridge,
unsigned int  mixing_interval 
)

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

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

Definition at line 3777 of file bridge.c.

3778{
3779 ast_bridge_lock(bridge);
3780 bridge->softmix.internal_mixing_interval = mixing_interval;
3781 ast_bridge_unlock(bridge);
3782}
unsigned int internal_mixing_interval
The mixing interval indicates how quickly softmix mixing should occur to mix audio.
Definition: bridge.h:297

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

Referenced by join_conference_bridge().

◆ ast_bridge_set_remb_estimated_bitrate()

void ast_bridge_set_remb_estimated_bitrate ( struct ast_bridge bridge,
float  estimated_bitrate 
)

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

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

Definition at line 3886 of file bridge.c.

3887{
3889
3890 ast_bridge_lock(bridge);
3891 bridge->softmix.video_mode.mode_data.sfu_data.estimated_bitrate = estimated_bitrate;
3892 ast_bridge_unlock(bridge);
3893}
struct ast_bridge_video_sfu_data sfu_data
Definition: bridge.h:169

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

Referenced by join_conference_bridge().

◆ ast_bridge_set_remb_send_interval()

void ast_bridge_set_remb_send_interval ( struct ast_bridge bridge,
unsigned int  remb_send_interval 
)

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

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

Definition at line 3868 of file bridge.c.

3869{
3871
3872 ast_bridge_lock(bridge);
3873 bridge->softmix.video_mode.mode_data.sfu_data.remb_send_interval = remb_send_interval;
3874 ast_bridge_unlock(bridge);
3875}
unsigned int remb_send_interval
Definition: bridge.h:155

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

Referenced by join_conference_bridge().

◆ ast_bridge_set_send_sdp_label()

void ast_bridge_set_send_sdp_label ( struct ast_bridge bridge,
unsigned int  send_sdp_label 
)

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

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

Definition at line 4045 of file bridge.c.

4046{
4047 ast_bridge_lock(bridge);
4048 bridge->softmix.send_sdp_label = send_sdp_label;
4049 ast_bridge_unlock(bridge);
4050}
unsigned int send_sdp_label
Definition: bridge.h:304

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

Referenced by bridge_stasis_new(), and join_conference_bridge().

◆ ast_bridge_set_sfu_video_mode()

void ast_bridge_set_sfu_video_mode ( struct ast_bridge bridge)

Set the bridge to be a selective forwarding unit.

Definition at line 3853 of file bridge.c.

3854{
3855 ast_bridge_lock(bridge);
3856 cleanup_video_mode(bridge);
3858 ast_bridge_unlock(bridge);
3859}
static void cleanup_video_mode(struct ast_bridge *bridge)
Definition: bridge.c:3805

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

3829{
3830 ast_bridge_lock(bridge);
3831 cleanup_video_mode(bridge);
3833 if (video_src_chan) {
3835 ast_verb(5, "Video source in bridge '%s' (%s) is now '%s' (%s)\n",
3836 bridge->name, bridge->uniqueid,
3837 ast_channel_name(video_src_chan),
3838 ast_channel_uniqueid(video_src_chan));
3839 ast_indicate(video_src_chan, AST_CONTROL_VIDUPDATE);
3840 }
3842 ast_bridge_unlock(bridge);
3843}
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:4243
@ AST_CONTROL_VIDUPDATE
void ast_bridge_publish_state(struct ast_bridge *bridge)
Publish the state of a bridge.
const ast_string_field name
Definition: bridge.h:405

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

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

◆ ast_bridge_set_talker_src_video_mode()

void ast_bridge_set_talker_src_video_mode ( struct ast_bridge bridge)

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

Definition at line 3845 of file bridge.c.

3846{
3847 ast_bridge_lock(bridge);
3848 cleanup_video_mode(bridge);
3850 ast_bridge_unlock(bridge);
3851}

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

4432{
4433 char *writevar;
4434 char *erasevar;
4435
4436 if (attended) {
4437 writevar = ATTENDEDTRANSFER;
4438 erasevar = BLINDTRANSFER;
4439 } else {
4440 writevar = BLINDTRANSFER;
4441 erasevar = ATTENDEDTRANSFER;
4442 }
4443
4444 pbx_builtin_setvar_helper(chan, writevar, value);
4445 pbx_builtin_setvar_helper(chan, erasevar, NULL);
4446}
#define BLINDTRANSFER
Definition: bridge.c:147
#define ATTENDEDTRANSFER
Definition: bridge.c:150
int pbx_builtin_setvar_helper(struct ast_channel *chan, const char *name, const char *value)
Add a variable to the channel variable stack, removing the most recently set value for the same name.

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

3862{
3863 ast_bridge_lock(bridge);
3864 bridge->softmix.video_mode.video_update_discard = video_update_discard;
3865 ast_bridge_unlock(bridge);
3866}
unsigned int video_update_discard
Definition: bridge.h:172

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

Referenced by bridge_stasis_new(), and join_conference_bridge().

◆ ast_bridge_suspend()

int ast_bridge_suspend ( struct ast_bridge bridge,
struct ast_channel chan 
)

Suspend a channel temporarily from a bridge.

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

Example usage:

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

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

3087{
3088 struct ast_bridge_channel *bridge_channel;
3089/* XXX ASTERISK-21271 the case of a dissolved bridge while channel is suspended is not handled. */
3090/* XXX ASTERISK-21271 suspend/unsuspend needs to be rethought. The caller must block until it has successfully suspended the channel for temporary control. */
3091/* 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. */
3092
3094
3095 if (!(bridge_channel = bridge_find_channel(bridge, chan))) {
3097 return -1;
3098 }
3099
3101
3103
3104 return 0;
3105}
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 3374 of file bridge.c.

3379{
3381
3382 return bridge_other_hook(features, hook_cb, hook_pvt, destructor, remove_flags,
3384}
@ AST_BRIDGE_HOOK_TYPE_TALK

References AST_BRIDGE_HOOK_TYPE_TALK, bridge_other_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:3126

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

3127{
3128 technology->suspended = 1;
3129}

References ast_bridge_technology::suspended.

Referenced by handle_bridge_technology_suspend(), and handle_manager_bridge_tech_suspend().

◆ ast_bridge_technology_unregister()

int ast_bridge_technology_unregister ( struct ast_bridge_technology technology)

Unregister a bridge technology from use.

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

Example usage:

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

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

Definition at line 274 of file bridge.c.

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

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

Referenced by dahdi_native_unload(), and unload_module().

◆ ast_bridge_technology_unsuspend()

void ast_bridge_technology_unsuspend ( struct ast_bridge_technology technology)

Unsuspend a bridge technology.

Parameters
technologyThe bridge technology to unsuspend

Example usage:

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

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

Definition at line 3131 of file bridge.c.

3132{
3133 /*
3134 * XXX We may want the act of unsuspending a bridge technology
3135 * to prod all existing bridges to see if they should start
3136 * using it.
3137 */
3138 technology->suspended = 0;
3139}

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

4488{
4489 struct ast_bridge *bridge;
4490
4491 ast_channel_lock(chan);
4492 bridge = ast_channel_get_bridge(chan);
4493 ast_channel_unlock(chan);
4494
4495 if (bridge && ast_test_flag(&bridge->feature_flags,
4497 ao2_ref(bridge, -1);
4498 bridge = NULL;
4499 }
4500
4501 return bridge;
4502}
@ AST_BRIDGE_FLAG_MASQUERADE_ONLY
@ AST_BRIDGE_FLAG_INVISIBLE
struct ast_flags feature_flags
Definition: bridge.h:373

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

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

◆ ast_bridge_transfer_attended()

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

Attended transfer.

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

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

Definition at line 4756 of file bridge.c.

4758{
4759 RAII_VAR(struct ast_bridge *, to_transferee_bridge, NULL, ao2_cleanup);
4760 RAII_VAR(struct ast_bridge *, to_target_bridge, NULL, ao2_cleanup);
4761 RAII_VAR(struct ast_bridge_channel *, to_transferee_bridge_channel, NULL, ao2_cleanup);
4762 RAII_VAR(struct ast_bridge_channel *, to_target_bridge_channel, NULL, ao2_cleanup);
4764 RAII_VAR(struct ast_channel *, transferee, NULL, ao2_cleanup);
4765 RAII_VAR(struct ast_attended_transfer_message *, transfer_msg, NULL, ao2_cleanup);
4766 struct ast_bridge *the_bridge = NULL;
4767 struct ast_channel *chan_bridged;
4768 struct ast_channel *chan_unbridged;
4769 int transfer_prohibited;
4770 int do_bridge_transfer;
4771 enum ast_transfer_result res;
4772 const char *app = NULL;
4773 int hangup_target = 0;
4774
4775 to_transferee_bridge = ast_bridge_transfer_acquire_bridge(to_transferee);
4776 to_target_bridge = ast_bridge_transfer_acquire_bridge(to_transfer_target);
4777
4778 transfer_msg = ast_attended_transfer_message_create(1, to_transferee, to_transferee_bridge,
4779 to_transfer_target, to_target_bridge, NULL, NULL);
4780 if (!transfer_msg) {
4781 ast_log(LOG_ERROR, "Unable to create Stasis publication for attended transfer from %s\n",
4782 ast_channel_name(to_transferee));
4784 }
4785
4786 /* They can't both be unbridged, you silly goose! */
4787 if (!to_transferee_bridge && !to_target_bridge) {
4789 goto end;
4790 }
4791
4792 ast_channel_lock(to_transferee);
4793 to_transferee_bridge_channel = ast_channel_get_bridge_channel(to_transferee);
4794 ast_channel_unlock(to_transferee);
4795
4796 ast_channel_lock(to_transfer_target);
4797 to_target_bridge_channel = ast_channel_get_bridge_channel(to_transfer_target);
4798 ast_channel_unlock(to_transfer_target);
4799
4800 if (to_transferee_bridge_channel) {
4801 /* Take off hold if they are on hold. */
4802 if (ast_bridge_channel_write_unhold(to_transferee_bridge_channel)) {
4803 ast_log(LOG_ERROR, "Transferee channel disappeared during transfer!\n");
4805 goto end;
4806 }
4807 }
4808
4809 if (to_target_bridge_channel) {
4810 const char *target_complete_sound;
4811
4812 /* Take off hold if they are on hold. */
4813 if (ast_bridge_channel_write_unhold(to_target_bridge_channel)) {
4814 ast_log(LOG_ERROR, "Target channel disappeared during transfer!\n");
4816 goto end;
4817 }
4818
4819 /* Is there a courtesy sound to play to the target? */
4820 ast_channel_lock(to_transfer_target);
4821 target_complete_sound = pbx_builtin_getvar_helper(to_transfer_target,
4822 "ATTENDED_TRANSFER_COMPLETE_SOUND");
4823 if (!ast_strlen_zero(target_complete_sound)) {
4824 target_complete_sound = ast_strdupa(target_complete_sound);
4825 } else {
4826 target_complete_sound = NULL;
4827 }
4828 ast_channel_unlock(to_transfer_target);
4829 if (!target_complete_sound) {
4830 ast_channel_lock(to_transferee);
4831 target_complete_sound = pbx_builtin_getvar_helper(to_transferee,
4832 "ATTENDED_TRANSFER_COMPLETE_SOUND");
4833 if (!ast_strlen_zero(target_complete_sound)) {
4834 target_complete_sound = ast_strdupa(target_complete_sound);
4835 } else {
4836 target_complete_sound = NULL;
4837 }
4838 ast_channel_unlock(to_transferee);
4839 }
4840 if (target_complete_sound) {
4841 ast_bridge_channel_write_playfile(to_target_bridge_channel, NULL,
4842 target_complete_sound, NULL);
4843 }
4844 }
4845
4846 /* Let's get the easy one out of the way first */
4847 if (to_transferee_bridge && to_target_bridge) {
4848
4849 if (!to_transferee_bridge_channel || !to_target_bridge_channel) {
4851 goto end;
4852 }
4853
4854 ast_bridge_lock_both(to_transferee_bridge, to_target_bridge);
4855 res = two_bridge_attended_transfer(to_transferee, to_transferee_bridge_channel,
4856 to_transfer_target, to_target_bridge_channel,
4857 to_transferee_bridge, to_target_bridge, transfer_msg);
4858 ast_bridge_unlock(to_transferee_bridge);
4859 ast_bridge_unlock(to_target_bridge);
4860
4861 hangup_target = 1;
4862 goto end;
4863 }
4864
4865 the_bridge = to_transferee_bridge ?: to_target_bridge;
4866 chan_bridged = to_transferee_bridge ? to_transferee : to_transfer_target;
4867 chan_unbridged = to_transferee_bridge ? to_transfer_target : to_transferee;
4868
4869 /*
4870 * Race condition makes it possible for app to be NULL, so get the app prior to
4871 * transferring with a fallback of "unknown".
4872 */
4873 app = ast_strdupa(ast_channel_appl(chan_unbridged) ?: "unknown");
4874
4875 {
4876 int chan_count;
4878
4879 channels = ast_bridge_peers_nolock(the_bridge);
4880 if (!channels) {
4882 goto end;
4883 }
4884 chan_count = ao2_container_count(channels);
4885 if (chan_count <= 1) {
4887 goto end;
4888 }
4889 transfer_prohibited = ast_test_flag(&the_bridge->feature_flags,
4891 do_bridge_transfer = ast_test_flag(&the_bridge->feature_flags,
4893 chan_count > 2;
4894 }
4895
4896 if (transfer_prohibited) {
4898 goto end;
4899 }
4900
4901 set_transfer_variables_all(to_transferee, channels, 1);
4902
4903 if (do_bridge_transfer) {
4904 /*
4905 * Hang up the target if it was bridged. Note, if it is not bridged
4906 * it is hung up during the masquerade.
4907 */
4908 hangup_target = chan_bridged == to_transfer_target;
4909 ast_bridge_lock(the_bridge);
4910 res = attended_transfer_bridge(chan_bridged, chan_unbridged, the_bridge, NULL, transfer_msg);
4911 ast_bridge_unlock(the_bridge);
4912 goto end;
4913 }
4914
4915 transferee = get_transferee(channels, chan_bridged);
4916 if (!transferee) {
4918 goto end;
4919 }
4920
4921 if (bridge_channel_internal_queue_attended_transfer(transferee, chan_unbridged)) {
4923 goto end;
4924 }
4925
4926 ast_bridge_remove(the_bridge, chan_bridged);
4927
4930
4931end:
4932 if ((res == AST_BRIDGE_TRANSFER_SUCCESS && hangup_target) || res == AST_BRIDGE_TRANSFER_FAIL) {
4933 ast_softhangup(to_transfer_target, AST_SOFTHANGUP_DEV);
4934 }
4935
4936 transfer_msg->result = res;
4938 return res;
4939}
static const char app[]
Definition: app_adsiprog.c:56
ast_mutex_t lock
Definition: app_sla.c:337
#define ast_strdupa(s)
duplicate a string in memory from the stack
Definition: astmm.h:298
int ao2_container_count(struct ao2_container *c)
Returns the number of elements in a container.
static struct ast_channel * get_transferee(struct ao2_container *channels, struct ast_channel *transferer)
Definition: bridge.c:4261
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:4690
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:4300
struct ast_bridge * ast_bridge_transfer_acquire_bridge(struct ast_channel *chan)
Acquire the channel's bridge for transfer purposes.
Definition: bridge.c:4487
int ast_bridge_remove(struct ast_bridge *bridge, struct ast_channel *chan)
Remove a channel from a bridge.
Definition: bridge.c:2020
static void set_transfer_variables_all(struct ast_channel *transferer, struct ao2_container *channels, int is_attended)
Definition: bridge.c:4462
ast_transfer_result
Definition: bridge.h:1102
@ AST_BRIDGE_TRANSFER_NOT_PERMITTED
Definition: bridge.h:1106
@ AST_BRIDGE_TRANSFER_SUCCESS
Definition: bridge.h:1104
@ AST_BRIDGE_TRANSFER_INVALID
Definition: bridge.h:1108
@ AST_BRIDGE_TRANSFER_FAIL
Definition: bridge.h:1110
int ast_bridge_channel_write_unhold(struct ast_bridge_channel *bridge_channel)
Write an unhold frame into the bridge.
int ast_bridge_channel_write_playfile(struct ast_bridge_channel *bridge_channel, ast_bridge_custom_play_fn custom_play, const char *playfile, const char *moh_class)
Write a bridge action play file frame into the bridge.
int bridge_channel_internal_queue_attended_transfer(struct ast_channel *transferee, struct ast_channel *unbridged_chan)
@ AST_BRIDGE_FLAG_TRANSFER_BRIDGE_ONLY
@ AST_BRIDGE_FLAG_TRANSFER_PROHIBITED
const char * ast_channel_appl(const struct ast_channel *chan)
@ AST_SOFTHANGUP_DEV
Definition: channel.h:1141
int ast_softhangup(struct ast_channel *chan, int cause)
Softly hangup up a channel.
Definition: channel.c:2441
char * end
Definition: eagi_proxy.c:73
#define SCOPED_LOCK(varname, lock, lockfunc, unlockfunc)
Scoped Locks.
Definition: lock.h:590
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 4504 of file bridge.c.

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

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

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

◆ ast_bridge_unreal_optimize_out()

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

Check and optimize out the unreal channels between bridges.

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

Definition at line 2999 of file bridge.c.

3000{
3001 struct ast_bridge *chan_bridge;
3002 struct ast_bridge *peer_bridge;
3003 struct ast_bridge_channel *chan_bridge_channel;
3004 struct ast_bridge_channel *peer_bridge_channel;
3005 int res = 0;
3006
3007 chan_bridge = optimize_lock_chan_stack(chan);
3008 if (!chan_bridge) {
3009 return res;
3010 }
3011 chan_bridge_channel = ast_channel_internal_bridge_channel(chan);
3012
3013 peer_bridge = optimize_lock_peer_stack(peer);
3014 if (peer_bridge) {
3015 peer_bridge_channel = ast_channel_internal_bridge_channel(peer);
3016
3017 res = try_swap_optimize_out(chan_bridge, chan_bridge_channel,
3018 peer_bridge, peer_bridge_channel, pvt);
3019 if (!res) {
3020 res = try_merge_optimize_out(chan_bridge, chan_bridge_channel,
3021 peer_bridge, peer_bridge_channel, pvt);
3022 } else if (0 < res) {
3023 res = 0;
3024 }
3025
3026 /* Release peer locks. */
3027 ast_bridge_unlock(peer_bridge);
3028 ast_bridge_channel_unlock(peer_bridge_channel);
3029 ast_channel_unlock(peer);
3030 }
3031
3032 /* Release chan locks. */
3033 ast_bridge_unlock(chan_bridge);
3034 ast_bridge_channel_unlock(chan_bridge_channel);
3035
3036 return res;
3037}
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:2948
static struct ast_bridge * optimize_lock_chan_stack(struct ast_channel *chan)
Definition: bridge.c:2658
static struct ast_bridge * optimize_lock_peer_stack(struct ast_channel *peer)
Definition: bridge.c:2703
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:2824
#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:3107

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

3108{
3109 struct ast_bridge_channel *bridge_channel;
3110/* XXX ASTERISK-21271 the case of a dissolved bridge while channel is suspended is not handled. */
3111
3113
3114 if (!(bridge_channel = bridge_find_channel(bridge, chan))) {
3116 return -1;
3117 }
3118
3120
3122
3123 return 0;
3124}
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 3895 of file bridge.c.

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

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

Referenced by softmix_bridge_write_video().

◆ ast_bridge_vars_set()

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

Sets BRIDGECHANNEL and BRIDGEPVTCALLID for a channel.

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

Definition at line 1281 of file bridge.c.

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

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

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

◆ ast_bridge_video_mode_to_string()

const char * ast_bridge_video_mode_to_string ( enum ast_bridge_video_mode_type  video_mode)

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

Parameters
video_modeThe video mode
Returns
A string representation of video_mode

Definition at line 4030 of file bridge.c.

4031{
4032 switch (video_mode) {
4034 return "talker";
4036 return "single";
4038 return "sfu";
4040 default:
4041 return "none";
4042 }
4043}

References AST_BRIDGE_VIDEO_MODE_NONE, AST_BRIDGE_VIDEO_MODE_SFU, AST_BRIDGE_VIDEO_MODE_SINGLE_SRC, and AST_BRIDGE_VIDEO_MODE_TALKER_SRC.

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

◆ ast_bridges()

struct ao2_container * ast_bridges ( void  )

Returns the global bridges container.

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

Definition at line 185 of file bridge.c.

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

References ao2_bump, and bridges.

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

◆ ast_bridges_allow_optimization()

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

Determine if bridges allow for optimization to occur betweem them.

Since
12.0.0
Parameters
chan_bridgeFirst bridge being tested
peer_bridgeSecond bridge being tested

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

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

Definition at line 3039 of file bridge.c.

3041{
3042 struct merge_direction merge;
3043
3044 if (!bridge_allows_optimization(chan_bridge) || !bridge_allows_optimization(peer_bridge)) {
3046 }
3047
3048 switch (bridges_allow_swap_optimization(chan_bridge, peer_bridge)) {
3053 case SWAP_PROHIBITED:
3054 default:
3055 break;
3056 }
3057
3058 /* Two channels will be kicked from the bridges, the unreal;1 and unreal;2 channels */
3059 if (bridges_allow_merge_optimization(chan_bridge, peer_bridge, 2, &merge) != MERGE_ALLOWED) {
3061 }
3062
3063 if (merge.dest == chan_bridge) {
3065 } else {
3067 }
3068}
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:2914
static enum bridge_allow_swap bridges_allow_swap_optimization(struct ast_bridge *chan_bridge, struct ast_bridge *peer_bridge)
Definition: bridge.c:2768
static int bridge_allows_optimization(struct ast_bridge *bridge)
Definition: bridge.c:2639
@ AST_BRIDGE_OPTIMIZE_PROHIBITED
Definition: bridge.h:888
@ AST_BRIDGE_OPTIMIZE_MERGE_TO_CHAN_BRIDGE
Definition: bridge.h:884
@ AST_BRIDGE_OPTIMIZE_SWAP_TO_PEER_BRIDGE
Definition: bridge.h:882
@ AST_BRIDGE_OPTIMIZE_MERGE_TO_PEER_BRIDGE
Definition: bridge.h:886
@ AST_BRIDGE_OPTIMIZE_SWAP_TO_CHAN_BRIDGE
Definition: bridge.h:880

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

Referenced by two_bridge_attended_transfer().

◆ ast_bridging_init()

int ast_bridging_init ( void  )

Initialize the bridging system.

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

Definition at line 5623 of file bridge.c.

5624{
5626
5628 return -1;
5629 }
5630
5632 if (!bridge_manager) {
5633 return -1;
5634 }
5635
5638 if (!bridges) {
5639 return -1;
5640 }
5642
5644
5646
5647 ast_manager_register_xml_core("BridgeTechnologyList", 0, manager_bridge_tech_list);
5648 ast_manager_register_xml_core("BridgeTechnologySuspend", 0, manager_bridge_tech_suspend);
5649 ast_manager_register_xml_core("BridgeTechnologyUnsuspend", 0, manager_bridge_tech_unsuspend);
5650
5651 return 0;
5652}
int ast_register_cleanup(void(*func)(void))
Register a function to be executed before Asterisk gracefully exits.
Definition: clicompat.c:19
#define ao2_container_alloc_rbtree(ao2_options, container_options, sort_fn, cmp_fn)
Allocate and initialize a red-black tree container.
Definition: astobj2.h:1349
int ao2_container_register(const char *name, struct ao2_container *self, ao2_prnt_obj_fn *prnt_obj)
Register a container for CLI stats and integrity check.
static struct bridge_manager_controller * bridge_manager
Definition: bridge.c:183
static int manager_bridge_tech_list(struct mansession *s, const struct message *m)
Definition: bridge.c:5540
static int manager_bridge_tech_suspend(struct mansession *s, const struct message *m)
Definition: bridge.c:5530
static int manager_bridge_tech_unsuspend(struct mansession *s, const struct message *m)
Definition: bridge.c:5535
static struct ast_cli_entry bridge_cli[]
Definition: bridge.c:5484
static int bridge_sort_cmp(const void *obj_left, const void *obj_right, int flags)
Definition: bridge.c:5069
static void bridge_prnt_obj(void *v_obj, void *where, ao2_prnt_fn *prnt)
Definition: bridge.c:5593
static void bridge_cleanup(void)
Definition: bridge.c:5609
static struct bridge_manager_controller * bridge_manager_create(void)
Definition: bridge.c:5030
void ast_bridging_init_basic(void)
#define ast_cli_register_multiple(e, len)
Register multiple commands.
Definition: cli.h:265
#define ast_manager_register_xml_core(action, authority, func)
Register a manager callback using XML documentation to describe the manager.
Definition: manager.h:203
int ast_stasis_bridging_init(void)

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

Referenced by asterisk_daemon().

◆ ast_brige_set_remb_behavior()

void ast_brige_set_remb_behavior ( struct ast_bridge bridge,
enum ast_bridge_video_sfu_remb_behavior  behavior 
)

Set the REMB report generation behavior on a bridge.

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

Definition at line 3877 of file bridge.c.

3878{
3880
3881 ast_bridge_lock(bridge);
3883 ast_bridge_unlock(bridge);
3884}
enum ast_bridge_video_sfu_remb_behavior remb_behavior
Definition: bridge.h:157

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

Referenced by join_conference_bridge().

◆ attended_transfer_bridge()

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

Perform an attended transfer of a bridge.

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

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

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

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

Definition at line 4300 of file bridge.c.

4303{
4304#define BRIDGE_LOCK_ONE_OR_BOTH(b1, b2) \
4305 do { \
4306 if (b2) { \
4307 ast_bridge_lock_both(b1, b2); \
4308 } else { \
4309 ast_bridge_lock(b1); \
4310 } \
4311 } while (0)
4312
4313 static const char *dest = "_attended@transfer/m";
4314 struct ast_channel *local_chan;
4315 int cause;
4316 int res;
4317 const char *app = NULL;
4318 struct ast_format_cap *caps;
4319
4320 ast_channel_lock(chan1);
4321 caps = ao2_bump(ast_channel_nativeformats(chan1));
4322 ast_channel_unlock(chan1);
4323
4324 local_chan = ast_request("Local", caps, NULL, chan1, dest, &cause);
4325
4326 ao2_cleanup(caps);
4327
4328 if (!local_chan) {
4330 }
4331
4332 ast_channel_lock_both(local_chan, chan1);
4335 ast_channel_unlock(local_chan);
4336 ast_channel_unlock(chan1);
4337
4338 if (bridge2) {
4339 res = ast_local_setup_bridge(local_chan, bridge2, chan2, NULL);
4340 } else {
4342 res = ast_local_setup_masquerade(local_chan, chan2);
4343 }
4344
4345 if (res) {
4346 ast_hangup(local_chan);
4348 }
4349
4350 /*
4351 * Since bridges need to be unlocked before entering ast_bridge_impart and
4352 * core_local may call into it then the bridges need to be unlocked here.
4353 */
4354 ast_bridge_unlock(bridge1);
4355 if (bridge2) {
4356 ast_bridge_unlock(bridge2);
4357 }
4358
4359 if (ast_call(local_chan, dest, 0)) {
4360 ast_hangup(local_chan);
4361 BRIDGE_LOCK_ONE_OR_BOTH(bridge1, bridge2);
4363 }
4364
4365 /* Get a ref for use later since this one is being stolen */
4366 ao2_ref(local_chan, +1);
4367 if (ast_bridge_impart(bridge1, local_chan, chan1, NULL,
4369 ast_hangup(local_chan);
4370 ao2_cleanup(local_chan);
4371 BRIDGE_LOCK_ONE_OR_BOTH(bridge1, bridge2);
4373 }
4374 BRIDGE_LOCK_ONE_OR_BOTH(bridge1, bridge2);
4375
4376 if (bridge2) {
4377 void *tech;
4378 struct ast_channel *locals[2];
4379
4380 /* Have to lock everything just in case a hangup comes in early */
4381 ast_local_lock_all(local_chan, &tech, &locals[0], &locals[1]);
4382 if (!locals[0] || !locals[1]) {
4383 ast_log(LOG_ERROR, "Transfer failed probably due to an early hangup - "
4384 "missing other half of '%s'\n", ast_channel_name(local_chan));
4386 ao2_cleanup(local_chan);
4388 }
4389
4390 /* Make sure the peer is properly set */
4391 if (local_chan != locals[0]) {
4392 SWAP(locals[0], locals[1]);
4393 }
4394
4397 } else {
4398 ast_attended_transfer_message_add_app(transfer_msg, app, local_chan);
4399 }
4400
4401 ao2_cleanup(local_chan);
4403}
#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:6429
@ AST_CHANNEL_REQUESTOR_REPLACEMENT
Definition: channel.h:1527
#define ast_channel_lock_both(chan1, chan2)
Lock two channels.
Definition: channel.h:2979
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:6402
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:6322
static struct ao2_container * locals
Definition: core_local.c:150
void ast_local_unlock_all(void *tech_pvt, struct ast_channel *base_chan, struct ast_channel *base_owner)
Remove a reference to the given local channel's private tech, unlock the given local channel's privat...
Definition: core_local.c:268
int ast_local_setup_bridge(struct ast_channel *ast, struct ast_bridge *bridge, struct ast_channel *swap, struct ast_bridge_features *features)
Setup the outgoing local channel to join a bridge on ast_call().
Definition: core_local.c:613
void ast_local_lock_all(struct ast_channel *chan, void **tech_pvt, struct ast_channel **base_chan, struct ast_channel **base_owner)
Add a reference to the local channel's private tech, lock the local channel's private base,...
Definition: core_local.c:253
int ast_local_setup_masquerade(struct ast_channel *ast, struct ast_channel *masq)
Setup the outgoing local channel to masquerade into a channel on ast_call().
Definition: core_local.c:655
int ast_attended_transfer_message_add_link(struct ast_attended_transfer_message *transfer_msg, struct ast_channel *locals[2])
Add details for an attended transfer that has a link between bridges.
const struct ast_channel_tech * tech
Format capabilities structure, holds formats + preference order + etc.
Definition: format_cap.c:54
#define SWAP(a, b)
Definition: utils.h:253

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

4196{
4197 struct ast_channel *local;
4198 char chan_name[AST_MAX_EXTENSION + AST_MAX_CONTEXT + 2];
4199 int cause;
4200 struct ast_format_cap *caps;
4201
4202 ast_channel_lock(transferer);
4203 caps = ao2_bump(ast_channel_nativeformats(transferer));
4204 ast_channel_unlock(transferer);
4205
4206 snprintf(chan_name, sizeof(chan_name), "%s@%s", exten, context);
4207 local = ast_request("Local", caps, NULL, transferer,
4208 chan_name, &cause);
4209
4210 ao2_cleanup(caps);
4211
4212 if (!local) {
4214 }
4215
4216 ast_channel_lock_both(local, transferer);
4218
4220 if (!transfer_message->replace_channel) {
4221 ast_hangup(local);
4223 }
4224
4226 ast_channel_unlock(local);
4227 ast_channel_unlock(transferer);
4228
4229 if (new_channel_cb) {
4230 new_channel_cb(local, user_data_wrapper, AST_BRIDGE_TRANSFER_MULTI_PARTY);
4231 }
4232
4233 if (ast_call(local, chan_name, 0)) {
4234 ast_hangup(local);
4236 }
4237
4238 if (ast_bridge_impart(bridge, local, transferer, NULL,
4240 ast_hangup(local);
4242 }
4243
4245}
@ AST_BRIDGE_TRANSFER_MULTI_PARTY
Definition: bridge.h:1117
#define AST_MAX_CONTEXT
Definition: channel.h:135
#define AST_MAX_EXTENSION
Definition: channel.h:134
struct ast_channel_snapshot * replace_channel

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

Referenced by ast_bridge_transfer_blind().

◆ bridge_action_bridge()

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

Definition at line 607 of file bridge.c.

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

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

Referenced by bridge_handle_actions().

◆ bridge_alloc()

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

Definition at line 747 of file bridge.c.

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

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

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

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

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

◆ bridge_base_destroy()

static void bridge_base_destroy ( struct ast_bridge self)
static

Definition at line 880 of file bridge.c.

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

References ast_debug, BRIDGE_PRINTF_SPEC, and BRIDGE_PRINTF_VARS.

◆ bridge_base_dissolving()

static void bridge_base_dissolving ( struct ast_bridge self)
static

Definition at line 893 of file bridge.c.

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

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

◆ bridge_base_get_merge_priority()

static int bridge_base_get_merge_priority ( struct ast_bridge self)
static

Definition at line 963 of file bridge.c.

964{
965 return 0;
966}

◆ bridge_base_init()

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

Initialize the base class of the bridge.

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

Example usage:

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

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

Definition at line 783 of file bridge.c.

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

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

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

◆ bridge_base_notify_masquerade()

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

Definition at line 947 of file bridge.c.

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

References ast_bridge::reconfigured.

◆ bridge_base_pull()

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

Definition at line 932 of file bridge.c.

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

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

◆ bridge_base_push()

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

Definition at line 917 of file bridge.c.

918{
919 return 0;
920}

◆ bridge_base_push_peek()

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

Definition at line 983 of file bridge.c.

984{
985 return 0;
986}

◆ bridge_channel_change_bridge()

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

Definition at line 2076 of file bridge.c.

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

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

Referenced by bridge_do_merge(), and bridge_do_move().

◆ bridge_channel_complete_join()

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

Definition at line 452 of file bridge.c.

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

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

Referenced by bridge_complete_join(), and smart_bridge_operation().

◆ bridge_channel_depart_thread()

static void * bridge_channel_depart_thread ( void *  data)
static

Thread responsible for imparted bridged channels to be departed.

Definition at line 1780 of file bridge.c.

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

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

Referenced by bridge_impart_internal().

◆ bridge_channel_impart_add()

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

Definition at line 1618 of file bridge.c.

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

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

Referenced by bridge_impart_internal().

◆ bridge_channel_impart_ds_head_dtor()

static void bridge_channel_impart_ds_head_dtor ( void *  doomed)
static

Definition at line 1577 of file bridge.c.

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

References ast_free, and bridge_channel_impart_ds_head_signal().

◆ bridge_channel_impart_ds_head_fixup()

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

Definition at line 1592 of file bridge.c.

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

References bridge_channel_impart_ds_head_signal().

◆ bridge_channel_impart_ds_head_signal()

static void bridge_channel_impart_ds_head_signal ( struct bridge_channel_impart_ds_head ds_head)
static

Definition at line 1563 of file bridge.c.

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

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

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

◆ bridge_channel_impart_signal()

void bridge_channel_impart_signal ( struct ast_channel chan)

◆ bridge_channel_impart_wait()

static void bridge_channel_impart_wait ( struct bridge_channel_impart_cond cond)
static

Definition at line 1670 of file bridge.c.

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

References ast_cond_wait, ast_mutex_lock, ast_mutex_unlock, and cond.

Referenced by bridge_impart_internal().

◆ bridge_channel_ind_thread()

static void * bridge_channel_ind_thread ( void *  data)
static

Thread responsible for independent imparted bridged channels.

Definition at line 1811 of file bridge.c.

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

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

Referenced by bridge_impart_internal().

◆ bridge_channel_moving()

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

Definition at line 2091 of file bridge.c.

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

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

Referenced by bridge_do_merge(), and bridge_do_move().

◆ bridge_cleanup()

static void bridge_cleanup ( void  )
static

Definition at line 5609 of file bridge.c.

5610{
5611 ast_manager_unregister("BridgeTechnologyList");
5612 ast_manager_unregister("BridgeTechnologySuspend");
5613 ast_manager_unregister("BridgeTechnologyUnsuspend");
5615 ao2_container_unregister("bridges");
5616
5618 bridges = NULL;
5621}
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:7698

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

Referenced by ast_bridging_init().

◆ bridge_complete_join()

static void bridge_complete_join ( struct ast_bridge bridge)
static

Definition at line 493 of file bridge.c.

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

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

Referenced by bridge_reconfigured().

◆ bridge_dissolve()

void bridge_dissolve ( struct ast_bridge bridge,
int  cause 
)

Definition at line 326 of file bridge.c.

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

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

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

◆ bridge_dissolve_check_stolen()

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

Definition at line 374 of file bridge.c.

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

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

Referenced by ast_bridge_add_channel().

◆ bridge_do_merge()

void bridge_do_merge ( struct ast_bridge dst_bridge,
struct ast_bridge src_bridge,
struct ast_bridge_channel **  kick_me,
unsigned int  num_kick,
unsigned int  optimized 
)

Definition at line 2117 of file bridge.c.

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

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

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

◆ bridge_do_move()

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

Definition at line 2383 of file bridge.c.

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

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

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

◆ bridge_dtmf_hook_sort()

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

Definition at line 3618 of file bridge.c.

3619{
3620 const struct ast_bridge_hook_dtmf *hook_left = obj_left;
3621 const struct ast_bridge_hook_dtmf *hook_right = obj_right;
3622 const char *right_key = obj_right;
3623 int cmp;
3624
3625 switch (flags & (OBJ_POINTER | OBJ_KEY | OBJ_PARTIAL_KEY)) {
3626 default:
3627 case OBJ_POINTER:
3628 right_key = hook_right->dtmf.code;
3629 /* Fall through */
3630 case OBJ_KEY:
3631 cmp = strcasecmp(hook_left->dtmf.code, right_key);
3632 break;
3633 case OBJ_PARTIAL_KEY:
3634 cmp = strncasecmp(hook_left->dtmf.code, right_key, strlen(right_key));
3635 break;
3636 }
3637 return cmp;
3638}
#define OBJ_KEY
Definition: astobj2.h:1151
#define OBJ_POINTER
Definition: astobj2.h:1150
#define OBJ_PARTIAL_KEY
Definition: astobj2.h:1152

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

Referenced by ast_bridge_features_init().

◆ bridge_find_channel()

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

◆ bridge_handle_actions()

static void bridge_handle_actions ( struct ast_bridge bridge)
static

Definition at line 641 of file bridge.c.

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

3219{
3220 struct ast_bridge_hook *hook = vhook;
3221
3222 if (hook->destructor) {
3223 hook->destructor(hook->hook_pvt);
3224 }
3225}

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

3246{
3247 struct ast_bridge_hook *hook;
3248
3249 /* Allocate new hook and setup it's basic variables */
3251 if (hook) {
3252 hook->callback = callback;
3253 hook->destructor = destructor;
3254 hook->hook_pvt = hook_pvt;
3256 }
3257
3258 return hook;
3259}
#define ao2_alloc_options(data_size, destructor_fn, options)
Definition: astobj2.h:404
static void bridge_hook_destroy(void *vhook)
Definition: bridge.c:3218
struct ast_flags remove_flags

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

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

◆ bridge_impart_internal()

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

Definition at line 1846 of file bridge.c.

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

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

5031{
5032 struct bridge_manager_controller *manager;
5033
5034 manager = ao2_alloc(sizeof(*manager), bridge_manager_destroy);
5035 if (!manager) {
5036 /* Well. This isn't good. */
5037 return NULL;
5038 }
5039 ast_cond_init(&manager->cond, NULL);
5041
5042 /* Create the bridge manager thread. */
5043 if (ast_pthread_create(&manager->thread, NULL, bridge_manager_thread, manager)) {
5044 /* Well. This isn't good either. */
5045 manager->thread = AST_PTHREADT_NULL;
5046 ao2_ref(manager, -1);
5047 manager = NULL;
5048 }
5049
5050 return manager;
5051}
static void bridge_manager_destroy(void *obj)
Definition: bridge.c:4998
static void * bridge_manager_thread(void *data)
Definition: bridge.c:4965
#define AST_LIST_HEAD_INIT_NOLOCK(head)
Initializes a list head structure.
Definition: linkedlists.h:681
#define AST_PTHREADT_NULL
Definition: lock.h:73
struct bridge_manager_controller::@313 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 4998 of file bridge.c.

4999{
5000 struct bridge_manager_controller *manager = obj;
5002
5003 if (manager->thread != AST_PTHREADT_NULL) {
5004 /* Stop the manager thread. */
5005 ao2_lock(manager);
5006 manager->stop = 1;
5007 ast_cond_signal(&manager->cond);
5008 ao2_unlock(manager);
5009 ast_debug(1, "Waiting for bridge manager thread to die.\n");
5010 pthread_join(manager->thread, NULL);
5011 }
5012
5013 /* Destroy the service request queue. */
5014 while ((request = AST_LIST_REMOVE_HEAD(&manager->service_requests, node))) {
5015 ao2_ref(request->bridge, -1);
5017 }
5018
5019 ast_cond_destroy(&manager->cond);
5020}
unsigned int stop
Definition: bridge.c:179

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

Referenced by bridge_manager_create().

◆ bridge_manager_service()

static void bridge_manager_service ( struct ast_bridge bridge)
static

Definition at line 4948 of file bridge.c.

4949{
4950 ast_bridge_lock(bridge);
4951 if (bridge->callid) {
4953 }
4954
4955 /* Do any pending bridge actions. */
4956 bridge_handle_actions(bridge);
4957 ast_bridge_unlock(bridge);
4958}
static void bridge_handle_actions(struct ast_bridge *bridge)
Definition: bridge.c:641
int ast_callid_threadassoc_change(ast_callid callid)
Sets what is stored in the thread storage to the given callid if it does not match what is already th...
Definition: logger.c:2277
ast_callid callid
Definition: bridge.h:365

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

Referenced by bridge_manager_thread().

◆ bridge_manager_service_req()

static void bridge_manager_service_req ( struct ast_bridge bridge)
static

Definition at line 197 of file bridge.c.

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

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

Referenced by bridge_queue_action_nodup().

◆ bridge_manager_thread()

static void * bridge_manager_thread ( void *  data)
static

Definition at line 4965 of file bridge.c.

4966{
4967 struct bridge_manager_controller *manager = data;
4969
4970 ao2_lock(manager);
4971 while (!manager->stop) {
4973 if (!request) {
4974 ast_cond_wait(&manager->cond, ao2_object_get_lockaddr(manager));
4975 continue;
4976 }
4977 ao2_unlock(manager);
4978
4979 /* Service the bridge. */
4981 ao2_ref(request->bridge, -1);
4983
4984 ao2_lock(manager);
4985 }
4986 ao2_unlock(manager);
4987
4988 return NULL;
4989}
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:4948

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

Referenced by bridge_manager_create().

◆ bridge_merge_determine_direction()

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

Definition at line 2222 of file bridge.c.

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

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

Referenced by bridge_merge_locked(), and bridges_allow_merge_optimization().

◆ bridge_merge_inhibit_nolock()

void bridge_merge_inhibit_nolock ( struct ast_bridge bridge,
int  request 
)

Definition at line 3070 of file bridge.c.

3071{
3072 int new_request;
3073
3074 new_request = bridge->inhibit_merge + request;
3075 ast_assert(0 <= new_request);
3076 bridge->inhibit_merge = new_request;
3077}

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

Referenced by ast_bridge_channel_merge_inhibit(), and ast_bridge_merge_inhibit().

◆ bridge_merge_locked()

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

Definition at line 2285 of file bridge.c.

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

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

Referenced by ast_bridge_merge().

◆ bridge_move_locked()

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

Definition at line 2468 of file bridge.c.

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

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

Referenced by ast_bridge_add_channel(), and ast_bridge_move().

◆ bridge_other_hook()

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

Definition at line 3310 of file bridge.c.

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

References ao2_link, ao2_ref, bridge_hook_generic(), 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 5593 of file bridge.c.

5594{
5595 struct ast_bridge *bridge = v_obj;
5596
5597 if (!bridge) {
5598 return;
5599 }
5600 prnt(where, "%s %s chans:%u",
5601 bridge->uniqueid, bridge->v_table->name, bridge->num_channels);
5602}

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

Referenced by ast_bridging_init().

◆ bridge_queue_action_nodup()

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

Definition at line 303 of file bridge.c.

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

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

Referenced by ast_bridge_queue_action(), and smart_bridge_operation().

◆ bridge_reconfigured()

void bridge_reconfigured ( struct ast_bridge bridge,
unsigned int  colp_update 
)

Definition at line 1472 of file bridge.c.

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

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

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

◆ bridge_reconfigured_connected_line_update()

static void bridge_reconfigured_connected_line_update ( struct ast_bridge bridge)
static

Definition at line 404 of file bridge.c.

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

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

Referenced by bridge_reconfigured().

◆ bridge_register()

struct ast_bridge * bridge_register ( struct ast_bridge bridge)

Register the new bridge with the system.

Since
12.0.0
Parameters
bridgeWhat to register. (Tolerates a NULL pointer)
struct ast_bridge *ast_bridge_basic_new(uint32_t capabilities, int flags, uint32 dtmf_features)
{
void *bridge;
bridge = bridge_alloc(sizeof(struct ast_bridge_basic), &ast_bridge_basic_v_table);
bridge = bridge_base_init(bridge, capabilities, flags);
bridge = ast_bridge_basic_init(bridge, dtmf_features);
bridge = bridge_register(bridge);
return bridge;
}
struct ast_bridge_methods ast_bridge_basic_v_table
Bridge basic class virtual method table.
struct ast_bridge * ast_bridge_basic_new(void)
Create a new basic class bridge.
struct ast_bridge * bridge_register(struct ast_bridge *bridge)
Register the new bridge with the system.
Definition: bridge.c:713
Note
This must be done after a bridge constructor has completed setting up the new bridge but before it returns.
After a bridge is registered, ast_bridge_destroy() must eventually be called to get rid of the bridge.
Returns
bridge on success.
Return values
NULLon error.

Definition at line 713 of file bridge.c.

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

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

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

◆ bridge_show_specific_print_channel()

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

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

Definition at line 5162 of file bridge.c.

5163{
5164 const char *uniqueid = obj;
5165 struct ast_cli_args *a = arg;
5166 struct ast_channel_snapshot *snapshot;
5167
5168 snapshot = ast_channel_snapshot_get_latest(uniqueid);
5169 if (!snapshot) {
5170 return 0;
5171 }
5172
5173 ast_cli(a->fd, "Channel: %s\n", snapshot->base->name);
5174 ao2_ref(snapshot, -1);
5175
5176 return 0;
5177}
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 5069 of file bridge.c.

5070{
5071 const struct ast_bridge *bridge_left = obj_left;
5072 const struct ast_bridge *bridge_right = obj_right;
5073 const char *right_key = obj_right;
5074 int cmp;
5075
5076 switch (flags & (OBJ_POINTER | OBJ_KEY | OBJ_PARTIAL_KEY)) {
5077 default:
5078 case OBJ_POINTER:
5079 right_key = bridge_right->uniqueid;
5080 /* Fall through */
5081 case OBJ_KEY:
5082 cmp = strcmp(bridge_left->uniqueid, right_key);
5083 break;
5084 case OBJ_PARTIAL_KEY:
5085 cmp = strncmp(bridge_left->uniqueid, right_key, strlen(right_key));
5086 break;
5087 }
5088 return cmp;
5089}

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

4649{
4650 struct ast_bridge_channel *bridged_to_source;
4651
4652 bridged_to_source = ast_bridge_channel_peer(source_bridge_channel);
4653 if (bridged_to_source
4654 && bridged_to_source->state == BRIDGE_CHANNEL_STATE_WAIT
4655 && !ast_test_flag(&bridged_to_source->features->feature_flags,
4657 bridged_to_source->swap = swap_channel;
4658 if (bridge_do_move(dest_bridge, bridged_to_source, 1, 0)) {
4660 }
4661 /* Must kick the source channel out of its bridge. */
4662 ast_bridge_channel_leave_bridge(source_bridge_channel,
4665 } else {
4667 }
4668}

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

Referenced by two_bridge_attended_transfer().

◆ bridge_tech_deferred_destroy()

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

Definition at line 579 of file bridge.c.

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

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

Referenced by bridge_action_bridge().

◆ bridges_allow_merge_optimization()

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

◆ bridges_allow_swap_optimization()

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

Definition at line 2768 of file bridge.c.

2770{
2771 int chan_priority;
2772 int peer_priority;
2773
2774 if (!ast_test_flag(&chan_bridge->feature_flags,
2777 && !ast_test_flag(&peer_bridge->feature_flags,
2780 /*
2781 * Can swap either way. Swap to the higher priority merge
2782 * bridge.
2783 */
2784 chan_priority = chan_bridge->v_table->get_merge_priority(chan_bridge);
2785 peer_priority = peer_bridge->v_table->get_merge_priority(peer_bridge);
2786 if (chan_bridge->num_channels == 2
2787 && chan_priority <= peer_priority) {
2788 return SWAP_TO_PEER_BRIDGE;
2789 } else if (peer_bridge->num_channels == 2
2790 && peer_priority <= chan_priority) {
2791 return SWAP_TO_CHAN_BRIDGE;
2792 }
2793 } else if (chan_bridge->num_channels == 2
2796 /* Can swap optimize only one way. */
2797 return SWAP_TO_PEER_BRIDGE;
2798 } else if (peer_bridge->num_channels == 2
2801 /* Can swap optimize only one way. */
2802 return SWAP_TO_CHAN_BRIDGE;
2803 }
2804
2805 return SWAP_PROHIBITED;
2806}
@ 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 4075 of file bridge.c.

4076{
4077 const struct ast_channel *left = obj;
4078 const struct ast_channel *right = arg;
4079 const char *right_name = arg;
4080 int cmp;
4081
4082 switch (flags & (OBJ_POINTER | OBJ_KEY | OBJ_PARTIAL_KEY)) {
4083 default:
4084 case OBJ_POINTER:
4085 right_name = ast_channel_name(right);
4086 /* Fall through */
4087 case OBJ_KEY:
4088 cmp = strcmp(ast_channel_name(left), right_name);
4089 break;
4090 case OBJ_PARTIAL_KEY:
4091 cmp = strncmp(ast_channel_name(left), right_name, strlen(right_name));
4092 break;
4093 }
4094 return cmp ? 0 : CMP_MATCH;
4095}
@ 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 4052 of file bridge.c.

4053{
4054 const struct ast_channel *chan = obj;
4055 const char *name = obj;
4056 int hash;
4057
4058 switch (flags & (OBJ_POINTER | OBJ_KEY | OBJ_PARTIAL_KEY)) {
4059 default:
4060 case OBJ_POINTER:
4061 name = ast_channel_name(chan);
4062 /* Fall through */
4063 case OBJ_KEY:
4064 hash = ast_str_hash(name);
4065 break;
4066 case OBJ_PARTIAL_KEY:
4067 /* Should never happen in hash callback. */
4068 ast_assert(0);
4069 hash = 0;
4070 break;
4071 }
4072 return hash;
4073}
static force_inline int attribute_pure ast_str_hash(const char *str)
Compute a hash value on a string.
Definition: strings.h:1259

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

Referenced by ast_bridge_peers_nolock().

◆ check_bridge_play_sound()

static void check_bridge_play_sound ( struct ast_bridge_channel bridge_channel)
static

Definition at line 1244 of file bridge.c.

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

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

Referenced by check_bridge_play_sounds().

◆ check_bridge_play_sounds()

static void check_bridge_play_sounds ( struct ast_bridge bridge)
static

Definition at line 1272 of file bridge.c.

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

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

Referenced by bridge_reconfigured().

◆ cleanup_video_mode()

static void cleanup_video_mode ( struct ast_bridge bridge)
static

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

5108{
5111
5112 return NULL;
5113}
static int complete_bridge_live_search(void *obj, void *arg, int flags)
Definition: bridge.c:5096
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 5096 of file bridge.c.

5097{
5098 struct ast_bridge *bridge = obj;
5099
5101 return CMP_STOP;
5102 }
5103
5104 return 0;
5105}
#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:2737

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

5264{
5265 struct ast_bridge *bridge;
5266 struct ast_bridge_channel *bridge_channel;
5267 int wordlen;
5268
5269 bridge = ast_bridge_find_by_id(bridge_name);
5270 if (!bridge) {
5271 return NULL;
5272 }
5273
5274 wordlen = strlen(word);
5275
5277 AST_LIST_TRAVERSE(&bridge->channels, bridge_channel, entry) {
5278 if (!strncasecmp(ast_channel_name(bridge_channel->chan), word, wordlen)) {
5279 if (ast_cli_completion_add(ast_strdup(ast_channel_name(bridge_channel->chan)))) {
5280 break;
5281 }
5282 }
5283 }
5285
5286 ao2_ref(bridge, -1);
5287
5288 return NULL;
5289}

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

Referenced by handle_bridge_kick_channel().

◆ complete_bridge_technology()

static char * complete_bridge_technology ( const char *  word)
static

Definition at line 5412 of file bridge.c.

5413{
5414 struct ast_bridge_technology *cur;
5415 int wordlen;
5416
5417 wordlen = strlen(word);
5420 if (!strncasecmp(cur->name, word, wordlen)) {
5422 break;
5423 }
5424 }
5425 }
5427
5428 return NULL;
5429}
#define AST_RWLIST_RDLOCK(head)
Read locks a list.
Definition: linkedlists.h:78

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

Referenced by handle_bridge_technology_suspend().

◆ destroy_bridge()

static void destroy_bridge ( void *  obj)
static

Definition at line 659 of file bridge.c.

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

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

Referenced by bridge_alloc().

◆ fill_bridgepeer_buf()

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

Definition at line 1338 of file bridge.c.

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

References buf.

Referenced by set_bridge_peer_vars_multiparty().

◆ find_best_technology()

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

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

Definition at line 518 of file bridge.c.

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

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

Referenced by bridge_base_init(), and smart_bridge_operation().

◆ get_transferee()

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

Definition at line 4261 of file bridge.c.

4262{
4263 struct ao2_iterator channel_iter;
4264 struct ast_channel *transferee;
4265
4266 for (channel_iter = ao2_iterator_init(channels, 0);
4267 (transferee = ao2_iterator_next(&channel_iter));
4268 ao2_cleanup(transferee)) {
4269 if (transferee != transferer) {
4270 break;
4271 }
4272 }
4273
4274 ao2_iterator_destroy(&channel_iter);
4275 return transferee;
4276}

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

5292{
5293 static const char * const completions[] = { "all", NULL };
5294 struct ast_bridge *bridge;
5295
5296 switch (cmd) {
5297 case CLI_INIT:
5298 e->command = "bridge kick";
5299 e->usage =
5300 "Usage: bridge kick <bridge-id> <channel-name | all>\n"
5301 " Kick the <channel-name> channel out of the <bridge-id> bridge\n"
5302 " If all is specified as the channel name then all channels will be\n"
5303 " kicked out of the bridge.\n";
5304 return NULL;
5305 case CLI_GENERATE:
5306 if (a->pos == 2) {
5307 return complete_bridge_live(a->word);
5308 }
5309 if (a->pos == 3) {
5310 ast_cli_complete(a->word, completions, -1);
5311 return complete_bridge_participant(a->argv[2], a->word);
5312 }
5313 return NULL;
5314 }
5315
5316 if (a->argc != 4) {
5317 return CLI_SHOWUSAGE;
5318 }
5319
5320 bridge = ast_bridge_find_by_id(a->argv[2]);
5321 if (!bridge) {
5322 ast_cli(a->fd, "Bridge '%s' not found\n", a->argv[2]);
5323 return CLI_SUCCESS;
5324 }
5325
5326 if (!strcasecmp(a->argv[3], "all")) {
5327 struct ast_bridge_channel *bridge_channel;
5328
5329 ast_cli(a->fd, "Kicking all channels from bridge '%s'\n", a->argv[2]);
5330
5332 AST_LIST_TRAVERSE(&bridge->channels, bridge_channel, entry) {
5333 ast_bridge_channel_queue_callback(bridge_channel, 0, kick_it, NULL, 0);
5334 }
5336 } else {
5337 struct ast_channel *chan;
5338
5339 chan = ast_channel_get_by_name_prefix(a->argv[3], strlen(a->argv[3]));
5340 if (!chan) {
5341 ast_cli(a->fd, "Channel '%s' not found\n", a->argv[3]);
5342 ao2_ref(bridge, -1);
5343 return CLI_SUCCESS;
5344 }
5345
5346 ast_cli(a->fd, "Kicking channel '%s' from bridge '%s'\n",
5347 ast_channel_name(chan), a->argv[2]);
5348 ast_bridge_kick(bridge, chan);
5349 ast_channel_unref(chan);
5350 }
5351
5352 ao2_ref(bridge, -1);
5353 return CLI_SUCCESS;
5354}
int ast_bridge_kick(struct ast_bridge *bridge, struct ast_channel *chan)
Kick a channel from a bridge.
Definition: bridge.c:2048
static char * complete_bridge_live(const char *word)
Definition: bridge.c:5107
static char * complete_bridge_participant(const char *bridge_name, const char *word)
Definition: bridge.c:5263
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:1381
#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:1823
@ CLI_INIT
Definition: cli.h:152
@ CLI_GENERATE
Definition: cli.h:153
char * command
Definition: cli.h:186
const char * usage
Definition: cli.h:177

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

◆ handle_bridge_show_all()

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

Definition at line 5115 of file bridge.c.

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

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

◆ handle_bridge_show_specific()

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

Definition at line 5179 of file bridge.c.

5180{
5181 struct ast_bridge_snapshot *snapshot;
5182 char print_time[32];
5183
5184 switch (cmd) {
5185 case CLI_INIT:
5186 e->command = "bridge show";
5187 e->usage =
5188 "Usage: bridge show <bridge-id>\n"
5189 " Show information about the <bridge-id> bridge\n";
5190 return NULL;
5191 case CLI_GENERATE:
5192 if (a->pos == 2) {
5193 return complete_bridge_live(a->word);
5194 }
5195 return NULL;
5196 }
5197
5198 if (a->argc != 3) {
5199 return CLI_SHOWUSAGE;
5200 }
5201
5202 snapshot = ast_bridge_get_snapshot_by_uniqueid(a->argv[2]);
5203 if (!snapshot) {
5204 ast_cli(a->fd, "Bridge '%s' not found\n", a->argv[2]);
5205 return CLI_SUCCESS;
5206 }
5207
5208 ast_format_duration_hh_mm_ss(ast_tvnow().tv_sec - snapshot->creationtime.tv_sec, print_time, sizeof(print_time));
5209
5210 ast_cli(a->fd, "Id: %s\n", snapshot->uniqueid);
5211 ast_cli(a->fd, "Type: %s\n", S_OR(snapshot->subclass, "<unknown>"));
5212 ast_cli(a->fd, "Technology: %s\n", S_OR(snapshot->technology, "<unknown>"));
5213 ast_cli(a->fd, "Subclass: %s\n", snapshot->subclass);
5214 ast_cli(a->fd, "Creator: %s\n", snapshot->creator);
5215 ast_cli(a->fd, "Name: %s\n", snapshot->name);
5216 ast_cli(a->fd, "Video-Mode: %s\n", ast_bridge_video_mode_to_string(snapshot->video_mode));
5217 ast_cli(a->fd, "Video-Source-Id: %s\n", snapshot->video_source_id);
5218 ast_cli(a->fd, "Num-Channels: %u\n", snapshot->num_channels);
5219 ast_cli(a->fd, "Num-Active: %u\n", snapshot->num_active);
5220 ast_cli(a->fd, "Duration: %s\n", print_time);
5222 ao2_ref(snapshot, -1);
5223
5224 return CLI_SUCCESS;
5225}
@ 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:4030
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:5162
struct ast_bridge_snapshot * ast_bridge_get_snapshot_by_uniqueid(const char *bridge_id)
Returns the current snapshot for the bridge.
enum ast_bridge_video_mode_type video_mode
Definition: bridge.h:345
unsigned int num_active
Definition: bridge.h:343
const ast_string_field video_source_id
Definition: bridge.h:332
const ast_string_field creator
Definition: bridge.h:332
const ast_string_field uniqueid
Definition: bridge.h:332
const ast_string_field name
Definition: bridge.h:332
struct ao2_container * channels
Definition: bridge.h:335

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

◆ handle_bridge_technology_show()

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

Definition at line 5377 of file bridge.c.

5378{
5379#define FORMAT_HDR "%-20s %-20s %8s %s\n"
5380#define FORMAT_ROW "%-20s %-20s %8u %s\n"
5381
5382 struct ast_bridge_technology *cur;
5383
5384 switch (cmd) {
5385 case CLI_INIT:
5386 e->command = "bridge technology show";
5387 e->usage =
5388 "Usage: bridge technology show\n"
5389 " List registered bridge technologies\n";
5390 return NULL;
5391 case CLI_GENERATE:
5392 return NULL;
5393 }
5394
5395 ast_cli(a->fd, FORMAT_HDR, "Name", "Type", "Priority", "Suspended");
5398 const char *type;
5399
5400 /* Decode type for display */
5402
5403 ast_cli(a->fd, FORMAT_ROW, cur->name, type, cur->preference,
5404 AST_CLI_YESNO(cur->suspended));
5405 }
5407 return CLI_SUCCESS;
5408
5409#undef FORMAT
5410}
static const char * tech_capability2str(uint32_t capabilities)
Definition: bridge.c:5357
#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 5431 of file bridge.c.

5432{
5433 struct ast_bridge_technology *cur;
5434 int suspend;
5435 int successful;
5436
5437 switch (cmd) {
5438 case CLI_INIT:
5439 e->command = "bridge technology {suspend|unsuspend}";
5440 e->usage =
5441 "Usage: bridge technology {suspend|unsuspend} <technology-name>\n"
5442 " Suspend or unsuspend a bridge technology.\n";
5443 return NULL;
5444 case CLI_GENERATE:
5445 if (a->pos == 3) {
5446 return complete_bridge_technology(a->word);
5447 }
5448 return NULL;
5449 }
5450
5451 if (a->argc != 4) {
5452 return CLI_SHOWUSAGE;
5453 }
5454
5455 suspend = !strcasecmp(a->argv[2], "suspend");
5456 successful = 0;
5459 if (!strcasecmp(cur->name, a->argv[3])) {
5460 successful = 1;
5461 if (suspend) {
5463 } else {
5465 }
5466 break;
5467 }
5468 }
5470
5471 if (successful) {
5472 if (suspend) {
5473 ast_cli(a->fd, "Suspended bridge technology '%s'\n", a->argv[3]);
5474 } else {
5475 ast_cli(a->fd, "Unsuspended bridge technology '%s'\n", a->argv[3]);
5476 }
5477 } else {
5478 ast_cli(a->fd, "Bridge technology '%s' not found\n", a->argv[3]);
5479 }
5480
5481 return CLI_SUCCESS;
5482}
void ast_bridge_technology_unsuspend(struct ast_bridge_technology *technology)
Unsuspend a bridge technology.
Definition: bridge.c:3131
void ast_bridge_technology_suspend(struct ast_bridge_technology *technology)
Suspend a bridge technology from consideration.
Definition: bridge.c:3126
static char * complete_bridge_technology(const char *word)
Definition: bridge.c:5412
static void suspend(struct cc_core_instance *core_instance)
Definition: ccss.c:3166

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

◆ handle_manager_bridge_tech_suspend()

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

Definition at line 5496 of file bridge.c.

5497{
5498 const char *name = astman_get_header(m, "BridgeTechnology");
5499 struct ast_bridge_technology *cur;
5500 int successful = 0;
5501
5502 if (ast_strlen_zero(name)) {
5503 astman_send_error(s, m, "BridgeTechnology must be provided");
5504 return 0;
5505 }
5506
5509
5510 if (!strcasecmp(cur->name, name)) {
5511 successful = 1;
5512 if (suspend) {
5514 } else {
5516 }
5517 break;
5518 }
5519 }
5521 if (!successful) {
5522 astman_send_error(s, m, "BridgeTechnology not found");
5523 return 0;
5524 }
5525
5526 astman_send_ack(s, m, (suspend ? "Suspended bridge technology" : "Unsuspended bridge technology"));
5527 return 0;
5528}
void astman_send_error(struct mansession *s, const struct message *m, char *error)
Send error in manager transaction.
Definition: manager.c:1982
void astman_send_ack(struct mansession *s, const struct message *m, char *msg)
Send ack in manager transaction.
Definition: manager.c:2014
const char * astman_get_header(const struct message *m, char *var)
Get header from manager transaction.
Definition: manager.c:1643

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

3525{
3526 struct ast_bridge_hook *hook = obj;
3528
3529 if (ast_test_flag(&hook->remove_flags, *remove_flags)) {
3530 return CMP_MATCH;
3531 } else {
3532 return 0;
3533 }
3534}
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 3544 of file bridge.c.

3545{
3547 hook_remove_match, &remove_flags);
3548}
@ 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:3524

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

3559{
3560 struct ast_bridge_hook *hook;
3561 int changed;
3562
3563 ast_heap_wrlock(hooks);
3564 do {
3565 int idx;
3566
3567 changed = 0;
3568 for (idx = ast_heap_size(hooks); idx; --idx) {
3569 hook = ast_heap_peek(hooks, idx);
3571 ast_heap_remove(hooks, hook);
3572 ao2_ref(hook, -1);
3573 changed = 1;
3574 }
3575 }
3576 } while (changed);
3577 ast_heap_unlock(hooks);
3578}
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 3587 of file bridge.c.

3588{
3589 struct ast_bridge_hook_timer *hook_a = a;
3590 struct ast_bridge_hook_timer *hook_b = b;
3591 int cmp;
3592
3593 cmp = ast_tvcmp(hook_b->timer.trip_time, hook_a->timer.trip_time);
3594 if (cmp) {
3595 return cmp;
3596 }
3597
3598 cmp = hook_b->timer.seqno - hook_a->timer.seqno;
3599 return cmp;
3600}
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 3648 of file bridge.c.

3649{
3650 struct ast_bridge_hook_timer *hook = obj;
3651
3652 return hook->generic.callback(bridge_channel, hook->generic.hook_pvt);
3653}

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

3657{
3658 ao2_cleanup(obj);
3659}

References ao2_cleanup.

Referenced by wrap_hook().

◆ kick_it()

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

Definition at line 2043 of file bridge.c.

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

References ast_bridge_channel_kick(), and AST_CAUSE_NORMAL_CLEARING.

Referenced by ast_bridge_kick(), and handle_bridge_kick_channel().

◆ manager_bridge_tech_list()

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

Definition at line 5540 of file bridge.c.

5541{
5542 const char *id = astman_get_header(m, "ActionID");
5543 RAII_VAR(struct ast_str *, id_text, ast_str_create(128), ast_free);
5544 struct ast_bridge_technology *cur;
5545 int num_items = 0;
5546
5547 if (!id_text) {
5548 astman_send_error(s, m, "Internal error");
5549 return -1;
5550 }
5551
5552 if (!ast_strlen_zero(id)) {
5553 ast_str_set(&id_text, 0, "ActionID: %s\r\n", id);
5554 }
5555
5556 astman_send_listack(s, m, "Bridge technology listing will follow", "start");
5557
5560 const char *type;
5561
5563
5564 astman_append(s,
5565 "Event: BridgeTechnologyListItem\r\n"
5566 "BridgeTechnology: %s\r\n"
5567 "BridgeType: %s\r\n"
5568 "BridgePriority: %u\r\n"
5569 "BridgeSuspended: %s\r\n"
5570 "%s"
5571 "\r\n",
5572 cur->name, type, cur->preference, AST_YESNO(cur->suspended),
5573 ast_str_buffer(id_text));
5574 ++num_items;
5575 }
5577
5578 astman_send_list_complete_start(s, m, "BridgeTechnologyListComplete", num_items);
5580
5581 return 0;
5582}
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:2024
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:2060
void astman_send_list_complete_end(struct mansession *s)
End the list complete event.
Definition: manager.c:2068
void astman_append(struct mansession *s, const char *fmt,...)
Definition: manager.c:1903
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 5530 of file bridge.c.

5531{
5532 return handle_manager_bridge_tech_suspend(s, m, 1);
5533}
static int handle_manager_bridge_tech_suspend(struct mansession *s, const struct message *m, int suspend)
Definition: bridge.c:5496

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

5536{
5537 return handle_manager_bridge_tech_suspend(s, m, 0);
5538}

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

3642{
3643 ao2_link(data, obj);
3644 return 0;
3645}

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

2659{
2660 struct ast_bridge *bridge;
2661 struct ast_bridge_channel *bridge_channel;
2662
2664 return NULL;
2665 }
2667 return NULL;
2668 }
2670 /* Channel has an active monitor, audiohook, or framehook. */
2671 return NULL;
2672 }
2673 bridge_channel = ast_channel_internal_bridge_channel(chan);
2674 if (!bridge_channel || ast_bridge_channel_trylock(bridge_channel)) {
2675 return NULL;
2676 }
2677 bridge = bridge_channel->bridge;
2678 if (bridge_channel->activity != BRIDGE_CHANNEL_THREAD_SIMPLE
2679 || bridge_channel->state != BRIDGE_CHANNEL_STATE_WAIT
2681 ast_bridge_channel_unlock(bridge_channel);
2682 return NULL;
2683 }
2684 if (!bridge_channel_internal_allows_optimization(bridge_channel) ||
2687 ast_bridge_channel_unlock(bridge_channel);
2688 return NULL;
2689 }
2690 return bridge;
2691}
#define ast_bridge_trylock(bridge)
Try locking the bridge.
Definition: bridge.h:463
#define ast_bridge_channel_trylock(bridge_channel)
Try locking the bridge_channel.
@ BRIDGE_CHANNEL_THREAD_SIMPLE
int bridge_channel_internal_allows_optimization(struct ast_bridge_channel *bridge_channel)
@ AST_FLAG_EMULATE_DTMF
Definition: channel.h:1024
struct ast_readq_list * ast_channel_readq(struct ast_channel *chan)
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:2488
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 2703 of file bridge.c.

2704{
2705 struct ast_bridge *bridge;
2706 struct ast_bridge_channel *bridge_channel;
2707
2708 if (ast_channel_trylock(peer)) {
2709 return NULL;
2710 }
2711 if (!AST_LIST_EMPTY(ast_channel_readq(peer))) {
2712 ast_channel_unlock(peer);
2713 return NULL;
2714 }
2716 ast_channel_unlock(peer);
2717 return NULL;
2718 }
2720 /* Peer has an active monitor, audiohook, or framehook. */
2721 ast_channel_unlock(peer);
2722 return NULL;
2723 }
2724 bridge_channel = ast_channel_internal_bridge_channel(peer);
2725 if (!bridge_channel || ast_bridge_channel_trylock(bridge_channel)) {
2726 ast_channel_unlock(peer);
2727 return NULL;
2728 }
2729 bridge = bridge_channel->bridge;
2730 if (bridge_channel->activity != BRIDGE_CHANNEL_THREAD_IDLE
2731 || bridge_channel->state != BRIDGE_CHANNEL_STATE_WAIT
2733 ast_bridge_channel_unlock(bridge_channel);
2734 ast_channel_unlock(peer);
2735 return NULL;
2736 }
2740 ast_bridge_channel_unlock(bridge_channel);
2741 ast_channel_unlock(peer);
2742 return NULL;
2743 }
2744 return bridge;
2745}
@ BRIDGE_CHANNEL_THREAD_IDLE
#define ast_channel_trylock(chan)
Definition: channel.h:2974

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

Referenced by ast_bridge_unreal_optimize_out().

◆ set_bridge_peer_vars()

static void set_bridge_peer_vars ( struct ast_bridge bridge)
static

Definition at line 1455 of file bridge.c.

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

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

Referenced by bridge_reconfigured().

◆ set_bridge_peer_vars_2party()

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

Definition at line 1300 of file bridge.c.

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

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

Referenced by set_bridge_peer_vars().

◆ set_bridge_peer_vars_holding()

static void set_bridge_peer_vars_holding ( struct ast_bridge bridge)
static

Definition at line 1435 of file bridge.c.

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

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

Referenced by set_bridge_peer_vars().

◆ set_bridge_peer_vars_multiparty()

static void set_bridge_peer_vars_multiparty ( struct ast_bridge bridge)
static

Definition at line 1375 of file bridge.c.

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

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

Referenced by set_bridge_peer_vars().

◆ set_transfer_variables_all()

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

Definition at line 4462 of file bridge.c.

4463{
4464 struct ao2_iterator iter;
4465 struct ast_channel *chan;
4466 const char *transferer_name;
4467 const char *transferer_bridgepeer;
4468
4469 ast_channel_lock(transferer);
4470 transferer_name = ast_strdupa(ast_channel_name(transferer));
4471 transferer_bridgepeer = ast_strdupa(S_OR(pbx_builtin_getvar_helper(transferer, "BRIDGEPEER"), ""));
4472 ast_channel_unlock(transferer);
4473
4474 for (iter = ao2_iterator_init(channels, 0);
4475 (chan = ao2_iterator_next(&iter));
4476 ao2_cleanup(chan)) {
4477 if (chan == transferer) {
4478 ast_bridge_set_transfer_variables(chan, transferer_bridgepeer, is_attended);
4479 } else {
4480 ast_bridge_set_transfer_variables(chan, transferer_name, is_attended);
4481 }
4482 }
4483
4484 ao2_iterator_destroy(&iter);
4485}
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:4431

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

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

◆ smart_bridge_operation()

static int smart_bridge_operation ( struct ast_bridge bridge)
static

Definition at line 1041 of file bridge.c.

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

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

Referenced by bridge_reconfigured().

◆ tech_capability2str()

static const char * tech_capability2str ( uint32_t  capabilities)
static

Bridge technology capabilities to string.

Definition at line 5357 of file bridge.c.

5358{
5359 const char *type;
5360
5361 if (capabilities & AST_BRIDGE_CAPABILITY_HOLDING) {
5362 type = "Holding";
5363 } else if (capabilities & AST_BRIDGE_CAPABILITY_EARLY) {
5364 type = "Early";
5365 } else if (capabilities & AST_BRIDGE_CAPABILITY_NATIVE) {
5366 type = "Native";
5367 } else if (capabilities & AST_BRIDGE_CAPABILITY_1TO1MIX) {
5368 type = "1to1Mix";
5369 } else if (capabilities & AST_BRIDGE_CAPABILITY_MULTIMIX) {
5370 type = "MultiMix";
5371 } else {
5372 type = "<Unknown>";
5373 }
5374 return type;
5375}
@ AST_BRIDGE_CAPABILITY_EARLY
Definition: bridge.h:92

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

Referenced by handle_bridge_technology_show(), and manager_bridge_tech_list().

◆ try_merge_optimize_out()

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

Definition at line 2948 of file bridge.c.

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

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

Referenced by ast_bridge_unreal_optimize_out().

◆ try_parking()

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

Definition at line 4405 of file bridge.c.

4408{
4409 RAII_VAR(struct ast_bridge_channel *, transferer_bridge_channel, NULL, ao2_cleanup);
4410
4413 }
4414
4415 ast_channel_lock(transferer);
4416 transferer_bridge_channel = ast_channel_get_bridge_channel(transferer);
4417 ast_channel_unlock(transferer);
4418
4419 if (!transferer_bridge_channel) {
4421 }
4422
4423 if (ast_parking_blind_transfer_park(transferer_bridge_channel,
4424 context, exten, new_channel_cb, user_data_wrapper)) {
4426 }
4427
4429}
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 2824 of file bridge.c.

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

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

4696{
4697 struct ast_bridge_channel *kick_me[] = {
4698 to_transferee_bridge_channel,
4699 to_target_bridge_channel,
4700 };
4701 enum ast_transfer_result res;
4702 struct ast_bridge *final_bridge = NULL;
4704
4705 channels = ast_bridge_peers_nolock(to_transferee_bridge);
4706
4707 if (!channels) {
4709 goto end;
4710 }
4711
4712 set_transfer_variables_all(to_transferee, channels, 1);
4713
4714 switch (ast_bridges_allow_optimization(to_transferee_bridge, to_target_bridge)) {
4716 final_bridge = to_transferee_bridge;
4717 res = bridge_swap_attended_transfer(to_transferee_bridge, to_target_bridge_channel, to_transferee);
4718 goto end;
4720 final_bridge = to_target_bridge;
4721 res = bridge_swap_attended_transfer(to_target_bridge, to_transferee_bridge_channel, to_transfer_target);
4722 goto end;
4724 final_bridge = to_transferee_bridge;
4725 bridge_do_merge(to_transferee_bridge, to_target_bridge, kick_me, ARRAY_LEN(kick_me), 0);
4727 goto end;
4729 final_bridge = to_target_bridge;
4730 bridge_do_merge(to_target_bridge, to_transferee_bridge, kick_me, ARRAY_LEN(kick_me), 0);
4732 goto end;
4734 default:
4735 /* Just because optimization wasn't doable doesn't necessarily mean
4736 * that we can actually perform the transfer. Some reasons for non-optimization
4737 * indicate bridge invalidity, so let's check those before proceeding.
4738 */
4739 if (to_transferee_bridge->inhibit_merge || to_transferee_bridge->dissolved ||
4740 to_target_bridge->inhibit_merge || to_target_bridge->dissolved) {
4742 }
4743
4744 return attended_transfer_bridge(to_transferee, to_transfer_target,
4745 to_transferee_bridge, to_target_bridge, transfer_msg);
4746 }
4747
4748end:
4749 if (res == AST_BRIDGE_TRANSFER_SUCCESS) {
4750 ast_attended_transfer_message_add_merge(transfer_msg, final_bridge);
4751 }
4752
4753 return res;
4754}
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:4647
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:3039
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 3662 of file bridge.c.

3663{
3664 /* Break out of the current wrapper if it exists to avoid multiple layers */
3665 if (hook->generic.callback == interval_wrapper_cb) {
3666 hook = hook->generic.hook_pvt;
3667 }
3668
3669 ast_bridge_interval_hook(features, hook->timer.flags, hook->timer.interval,
3671 hook->generic.remove_flags.flags);
3672}
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:3398
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:3648
static void interval_wrapper_pvt_dtor(void *obj)
Destructor for the hook wrapper.
Definition: bridge.c:3656

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

Referenced by ast_bridge_features_merge().

Variable Documentation

◆ ast_bridge_base_v_table

struct ast_bridge_methods ast_bridge_base_v_table

◆ bridge_channel_impart_ds_info

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

Definition at line 1601 of file bridge.c.

Referenced by bridge_channel_impart_add(), and bridge_channel_impart_signal().

◆ bridge_cli

struct ast_cli_entry bridge_cli[]
static

Definition at line 5484 of file bridge.c.

Referenced by ast_bridging_init(), and bridge_cleanup().

◆ bridge_init_lock

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

Definition at line 136 of file bridge.c.

Referenced by bridge_base_init(), and bridge_register().

◆ bridge_manager

struct bridge_manager_controller* bridge_manager
static

Bridge manager controller.

Definition at line 183 of file bridge.c.

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

◆ bridge_technologies

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

◆ bridges

struct ao2_container* bridges
static

◆ builtin_features_dtmf

char builtin_features_dtmf[AST_BRIDGE_BUILTIN_END][MAXIMUM_DTMF_FEATURE_STRING]
static

Default DTMF keys for built in features

Definition at line 155 of file bridge.c.

Referenced by ast_bridge_features_enable(), and ast_bridge_features_register().

◆ builtin_features_handlers

ast_bridge_hook_callback builtin_features_handlers[AST_BRIDGE_BUILTIN_END]
static

Function handlers for the built in features

Definition at line 158 of file bridge.c.

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

◆ builtin_interval_handlers

Function handlers for built in interval features

Definition at line 161 of file bridge.c.

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

◆ optimization_id

unsigned int optimization_id
static

Definition at line 138 of file bridge.c.

Referenced by try_merge_optimize_out(), and try_swap_optimize_out().