Asterisk - The Open Source Telephony Project GIT-master-6144b6b
Loading...
Searching...
No Matches
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 BV_NAME_CMP(var_str, name)   !strcmp(var_str, name)
 Compare a bridge variable name with a given name.
 
#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.
 
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.
 
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.
 
int ast_bridge_depart (struct ast_channel *chan)
 Depart a channel from a bridge.
 
int ast_bridge_destroy (struct ast_bridge *bridge, int cause)
 Destroy a bridge.
 
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.
 
void ast_bridge_features_cleanup (struct ast_bridge_features *features)
 Clean up the contents of a bridge features structure.
 
void ast_bridge_features_destroy (struct ast_bridge_features *features)
 Destroy an allocated bridge features struct.
 
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.
 
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.
 
int ast_bridge_features_init (struct ast_bridge_features *features)
 Initialize bridge features structure.
 
int ast_bridge_features_limits_construct (struct ast_bridge_features_limits *limits)
 Constructor function for ast_bridge_features_limits.
 
void ast_bridge_features_limits_destroy (struct ast_bridge_features_limits *limits)
 Destructor function for ast_bridge_features_limits.
 
void ast_bridge_features_merge (struct ast_bridge_features *into, const struct ast_bridge_features *from)
 Merge one ast_bridge_features into another.
 
struct ast_bridge_featuresast_bridge_features_new (void)
 Allocate a new bridge features struct.
 
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.
 
void ast_bridge_features_remove (struct ast_bridge_features *features, enum ast_bridge_hook_remove_flags remove_flags)
 Remove marked bridge channel feature hooks.
 
void ast_bridge_features_set_flag (struct ast_bridge_features *features, unsigned int flag)
 Set a flag on a bridge channel features structure.
 
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.
 
int ast_bridge_features_unregister (enum ast_bridge_builtin_feature feature)
 Unregister a handler for a built in feature.
 
struct ast_bridgeast_bridge_find_by_id (const char *bridge_id)
 Find bridge by id.
 
struct varsheadast_bridge_get_ari_reportable_variables (struct ast_bridge *bridge)
 Get a list of variables that should be included in ARI events for this bridge.
 
const char * ast_bridge_get_variable (const struct ast_bridge *bridge, const char *name)
 Get value a variable from the bridge by name.
 
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.
 
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)
 
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.
 
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.
 
int ast_bridge_interval_unregister (enum ast_bridge_builtin_interval interval)
 Unregisters a handler for a built in interval feature.
 
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.
 
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)
 
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.
 
int ast_bridge_kick (struct ast_bridge *bridge, struct ast_channel *chan)
 Kick a channel from a bridge.
 
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.
 
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.
 
void ast_bridge_merge_inhibit (struct ast_bridge *bridge, int request)
 Adjust the bridge merge inhibit request count.
 
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.
 
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.
 
void ast_bridge_notify_masquerade (struct ast_channel *chan)
 Notify bridging that this channel was just masqueraded.
 
int ast_bridge_number_video_src (struct ast_bridge *bridge)
 Returns the number of video sources currently active in the bridge.
 
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.
 
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.
 
struct ao2_containerast_bridge_peers (struct ast_bridge *bridge)
 Get a container of all channels in the bridge.
 
struct ao2_containerast_bridge_peers_nolock (struct ast_bridge *bridge)
 Get a container of all channels in the bridge.
 
int ast_bridge_queue_action (struct ast_bridge *bridge, struct ast_frame *action)
 Put an action onto the specified bridge.
 
int ast_bridge_remove (struct ast_bridge *bridge, struct ast_channel *chan)
 Remove a channel from a bridge.
 
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.
 
void ast_bridge_set_binaural_active (struct ast_bridge *bridge, unsigned int binaural_active)
 Activates the use of binaural signals in a conference bridge.
 
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.
 
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.
 
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.
 
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.
 
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.
 
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.
 
void ast_bridge_set_sfu_video_mode (struct ast_bridge *bridge)
 Set the bridge to be a selective forwarding unit.
 
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.
 
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.
 
void ast_bridge_set_transfer_variables (struct ast_channel *chan, const char *value, int attended)
 Set the relevant transfer variables for a single channel.
 
int ast_bridge_set_variable (struct ast_bridge *bridge, const char *name, const char *value, int report_events)
 Set a variable on the bridge.
 
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.
 
int ast_bridge_suspend (struct ast_bridge *bridge, struct ast_channel *chan)
 Suspend a channel temporarily from a bridge.
 
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.
 
void ast_bridge_technology_suspend (struct ast_bridge_technology *technology)
 Suspend a bridge technology from consideration.
 
int ast_bridge_technology_unregister (struct ast_bridge_technology *technology)
 Unregister a bridge technology from use.
 
void ast_bridge_technology_unsuspend (struct ast_bridge_technology *technology)
 Unsuspend a bridge technology.
 
struct ast_bridgeast_bridge_transfer_acquire_bridge (struct ast_channel *chan)
 Acquire the channel's bridge for transfer purposes.
 
enum ast_transfer_result ast_bridge_transfer_attended (struct ast_channel *to_transferee, struct ast_channel *to_transfer_target)
 Attended transfer.
 
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.
 
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.
 
int ast_bridge_unsuspend (struct ast_bridge *bridge, struct ast_channel *chan)
 Unsuspend a channel from a bridge.
 
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.
 
void ast_bridge_vars_set (struct ast_channel *chan, const char *name, const char *pvtid)
 Sets BRIDGECHANNEL and BRIDGEPVTCALLID for a channel.
 
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.
 
struct ao2_containerast_bridges (void)
 Returns the global bridges container.
 
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.
 
int ast_bridging_init (void)
 Initialize the bridging system.
 
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.
 
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.
 
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.
 
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.
 
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.
 
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.
 
static int bridge_set_ari_var_reportable (struct ast_bridge *bridge, const char *variable, int report_events)
 
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.
 
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.
 
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.
 
static void interval_wrapper_pvt_dtor (void *obj)
 Destructor for the hook wrapper.
 
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.
 
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.
 

Variables

struct ast_bridge_methods ast_bridge_base_v_table
 Bridge base class virtual method table.
 
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 = AST_MUTEX_INIT_VALUE
 
static struct bridge_manager_controllerbridge_manager
 
static struct bridge_technologies bridge_technologies = AST_RWLIST_HEAD_INIT_VALUE
 
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 
)

◆ BV_NAME_CMP

#define BV_NAME_CMP (   var_str,
  name 
)    !strcmp(var_str, name)

Compare a bridge variable name with a given name.

Parameters
var_strThe variable name to compare.
nameThe name to compare against.
Return values
0if the names do not match.
1if the names match.

Definition at line 161 of file bridge.c.

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

3020 {
3021 /*! Bridge properties prohibit merge optimization */
3023 /*! Merge optimization cannot occur because the source bridge has too few channels */
3025 /*! Merge optimization cannot occur because multimix capability could not be requested */
3027 /*! Merge optimization allowed between bridges */
3029};
@ MERGE_ALLOWED
Definition bridge.c:3028
@ MERGE_NOT_ENOUGH_CHANNELS
Definition bridge.c:3024
@ MERGE_NO_MULTIMIX
Definition bridge.c:3026
@ MERGE_PROHIBITED
Definition bridge.c:3022

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

2881 {
2882 /*! Bridges cannot allow for a swap optimization to occur */
2884 /*! Bridge swap optimization can occur into the chan_bridge */
2886 /*! Bridge swap optimization can occur into the peer_bridge */
2888};
@ SWAP_PROHIBITED
Definition bridge.c:2883
@ SWAP_TO_PEER_BRIDGE
Definition bridge.c:2887
@ SWAP_TO_CHAN_BRIDGE
Definition bridge.c:2885

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

235{
237
238 /* Perform a sanity check to make sure the bridge technology conforms to our needed requirements */
239 if (ast_strlen_zero(technology->name)
240 || !technology->capabilities
241 || !technology->write) {
242 ast_log(LOG_WARNING, "Bridge technology %s failed registration sanity check.\n",
243 technology->name);
244 return -1;
245 }
246
248
249 /* Look for duplicate bridge technology already using this name, or already registered */
251 if ((!strcasecmp(current->name, technology->name)) || (current == technology)) {
252 ast_log(LOG_WARNING, "A bridge technology of %s already claims to exist in our world.\n",
253 technology->name);
255 return -1;
256 }
257 }
258
259 /* Copy module pointer so reference counting can keep the module from unloading */
260 technology->mod = module;
261
262 /* Find the correct position to insert the technology. */
264 /* Put the highest preference tech's first in the list. */
265 if (technology->preference >= current->preference) {
266 AST_RWLIST_INSERT_BEFORE_CURRENT(technology, entry);
267
268 break;
269 }
270 }
272
273 if (!current) {
274 /* Insert our new bridge technology to the end of the list. */
275 AST_RWLIST_INSERT_TAIL(&bridge_technologies, technology, entry);
276 }
277
279
280 ast_verb(5, "Registered bridge technology %s\n", technology->name);
281
282 return 0;
283}
#define ast_log
Definition astobj2.c:42
size_t current
#define ast_verb(level,...)
#define LOG_WARNING
#define AST_RWLIST_TRAVERSE_SAFE_BEGIN
#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.
#define AST_RWLIST_TRAVERSE_SAFE_END
#define AST_RWLIST_TRAVERSE
#define AST_RWLIST_INSERT_TAIL
#define AST_RWLIST_INSERT_BEFORE_CURRENT
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.
int(* start)(struct ast_bridge *bridge)
Request a bridge technology instance start operations.
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, ast_bridge_technology::start, 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 2670 of file bridge.c.

2672{
2673 RAII_VAR(struct ast_bridge *, chan_bridge, NULL, ao2_cleanup);
2674 RAII_VAR(struct ast_channel *, yanked_chan, NULL, ao2_cleanup);
2675
2676 ast_moh_stop(chan);
2677
2678 ast_channel_lock(chan);
2679 chan_bridge = ast_channel_get_bridge(chan);
2680 ast_channel_unlock(chan);
2681
2682 if (chan_bridge) {
2683 struct ast_bridge_channel *bridge_channel;
2684
2685 /* The channel is in a bridge so it is not getting any new features. */
2687
2688 ast_bridge_lock_both(bridge, chan_bridge);
2689 bridge_channel = bridge_find_channel(chan_bridge, chan);
2690
2691 if (bridge_move_locked(bridge, chan_bridge, chan, NULL, 1)) {
2692 ast_bridge_unlock(chan_bridge);
2694 return -1;
2695 }
2696
2697 /*
2698 * bridge_move_locked() will implicitly ensure that
2699 * bridge_channel is not NULL.
2700 */
2701 ast_assert(bridge_channel != NULL);
2702
2703 /*
2704 * Additional checks if the channel we just stole dissolves the
2705 * original bridge.
2706 */
2707 bridge_dissolve_check_stolen(chan_bridge, bridge_channel);
2708 ast_bridge_unlock(chan_bridge);
2710 } else {
2711 int noanswer;
2712 const char *value;
2713 /* Slightly less easy case. We need to yank channel A from
2714 * where he currently is and impart him into our bridge.
2715 */
2716 yanked_chan = ast_channel_yank(chan);
2717 if (!yanked_chan) {
2718 ast_log(LOG_WARNING, "Could not gain control of channel %s\n", ast_channel_name(chan));
2720 return -1;
2721 }
2722
2724 value = pbx_builtin_getvar_helper(chan, "BRIDGE_NOANSWER");
2725 noanswer = !ast_strlen_zero(value) ? 1 : 0;
2727 if (noanswer) {
2728 ast_debug(3, "Skipping answer on bridge target channel %s\n", ast_channel_name(chan));
2729 } else if (ast_channel_state(yanked_chan) != AST_STATE_UP) {
2730 ast_answer(yanked_chan);
2731 }
2732
2733 ast_channel_ref(yanked_chan);
2734 if (ast_bridge_impart(bridge, yanked_chan, NULL, features,
2736 /* It is possible for us to yank a channel and have some other
2737 * thread start a PBX on the channel after we yanked it. In particular,
2738 * this can theoretically happen on the ;2 of a Local channel if we
2739 * yank it prior to the ;1 being answered. Make sure that it isn't
2740 * executing a PBX before hanging it up.
2741 */
2742 if (ast_channel_pbx(yanked_chan)) {
2743 ast_channel_unref(yanked_chan);
2744 } else {
2745 ast_hangup(yanked_chan);
2746 }
2747 return -1;
2748 }
2749 }
2750
2751 if (play_tone && !ast_strlen_zero(xfersound)) {
2752 struct ast_channel *play_chan = yanked_chan ?: chan;
2753 RAII_VAR(struct ast_bridge_channel *, play_bridge_channel, NULL, ao2_cleanup);
2754
2755 ast_channel_lock(play_chan);
2756 play_bridge_channel = ast_channel_get_bridge_channel(play_chan);
2757 ast_channel_unlock(play_chan);
2758
2759 if (!play_bridge_channel) {
2760 ast_log(LOG_WARNING, "Unable to play tone for channel %s. No longer in a bridge.\n",
2761 ast_channel_name(play_chan));
2762 } else {
2763 ast_bridge_channel_queue_playfile(play_bridge_channel, NULL, xfersound, NULL);
2764 }
2765 }
2766 return 0;
2767}
@ 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:2077
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:2598
struct ast_bridge_channel * bridge_find_channel(struct ast_bridge *bridge, struct ast_channel *chan)
Definition bridge.c:1628
void ast_bridge_features_destroy(struct ast_bridge_features *features)
Destroy an allocated bridge features struct.
Definition bridge.c:3883
static void bridge_dissolve_check_stolen(struct ast_bridge *bridge, struct ast_bridge_channel *bridge_channel)
Definition bridge.c:385
#define ast_bridge_lock_both(bridge1, bridge2)
Lock two bridges.
Definition bridge.h:498
#define ast_bridge_unlock(bridge)
Unlock the bridge.
Definition bridge.h:491
@ AST_BRIDGE_IMPART_CHAN_INDEPENDENT
Definition bridge.h:600
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:2540
#define ast_channel_lock(chan)
Definition channel.h:2983
struct ast_channel * ast_channel_yank(struct ast_channel *yankee)
Gain control of a channel in the system.
Definition channel.c:10773
#define ast_channel_ref(c)
Increase channel reference count.
Definition channel.h:3008
struct ast_bridge * ast_channel_get_bridge(const struct ast_channel *chan)
Get the bridge associated with a channel.
Definition channel.c:10714
#define ast_channel_unref(c)
Decrease channel reference count.
Definition channel.h:3019
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:10762
struct ast_pbx * ast_channel_pbx(const struct ast_channel *chan)
int ast_answer(struct ast_channel *chan)
Answer a channel.
Definition channel.c:2805
#define ast_channel_unlock(chan)
Definition channel.h:2984
ast_channel_state
ast_channel states
@ AST_STATE_UP
#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:7812
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:355
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:981
#define ast_assert(a)
Definition utils.h:779

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

1020{
1021 void *bridge;
1022
1023 bridge = bridge_alloc(sizeof(struct ast_bridge), &ast_bridge_base_v_table);
1024 bridge = bridge_base_init(bridge, capabilities, flags, creator, name, id);
1025 bridge = bridge_register(bridge);
1026 return bridge;
1027}
struct ast_bridge_methods ast_bridge_base_v_table
Bridge base class virtual method table.
Definition bridge.c:1008
struct ast_bridge * bridge_register(struct ast_bridge *bridge)
Register the new bridge with the system.
Definition bridge.c:731
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:803
struct ast_bridge * bridge_alloc(size_t size, const struct ast_bridge_methods *v_table)
Definition bridge.c:765
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(), AST_TEST_DEFINE(), 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:2105

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

2106{
2107 struct ast_bridge_channel *bridge_channel;
2108 int departable;
2109 SCOPE_TRACE(1, "%s\n", ast_channel_name(chan));
2110
2112 bridge_channel = ast_channel_internal_bridge_channel(chan);
2113 departable = bridge_channel && bridge_channel->depart_wait;
2115 if (!departable) {
2116 ast_log(LOG_ERROR, "Channel %s cannot be departed.\n",
2118 /*
2119 * Should never happen. It likely means that
2120 * ast_bridge_depart() is called by two threads for the same
2121 * channel, the channel was never imparted to be departed, or it
2122 * has already been departed.
2123 */
2124 ast_assert(0);
2125 return -1;
2126 }
2127
2128 /*
2129 * We are claiming the bridge_channel reference held by
2130 * bridge_channel_depart_thread().
2131 */
2132
2133 ast_bridge_channel_leave_bridge(bridge_channel,
2135
2136 /* Wait for the depart thread to die */
2137 ast_debug(1, "Waiting for %p(%s) bridge thread to die.\n",
2138 bridge_channel, ast_channel_name(bridge_channel->chan));
2139 pthread_join(bridge_channel->thread, NULL);
2140
2144
2145 /* We can get rid of the bridge_channel after the depart thread has died. */
2146 ao2_ref(bridge_channel, -1);
2147 return 0;
2148}
#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(), AST_TEST_DEFINE(), AST_TEST_DEFINE(), AST_TEST_DEFINE(), AST_TEST_DEFINE(), AST_TEST_DEFINE(), AST_TEST_DEFINE(), AST_TEST_DEFINE(), AST_TEST_DEFINE(), AST_TEST_DEFINE(), AST_TEST_DEFINE(), AST_TEST_DEFINE(), 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:1029

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

1030{
1031 ast_debug(1, "Bridge " BRIDGE_PRINTF_SPEC ": destroying. current refcount: %d\n",
1032 BRIDGE_PRINTF_VARS(bridge), ao2_ref(bridge, 0));
1033 ast_bridge_lock(bridge);
1034 bridge_dissolve(bridge, cause);
1035 ast_bridge_unlock(bridge);
1036
1037 ast_debug(1, "Bridge " BRIDGE_PRINTF_SPEC ": unreffing. current refcount: %d\n",
1038 BRIDGE_PRINTF_VARS(bridge), ao2_ref(bridge, 0));
1039
1040 ao2_ref(bridge, -1);
1041
1042 return 0;
1043}
void bridge_dissolve(struct ast_bridge *bridge, int cause)
Definition bridge.c:337
#define ast_bridge_lock(bridge)
Lock the bridge.
Definition bridge.h:480
#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(), safe_bridge_destroy(), safe_bridge_destroy(), safe_bridge_destroy(), 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:3829
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:3391
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 3391 of file bridge.c.

3397{
3398 struct ast_bridge_hook_dtmf *hook;
3399 int res;
3400
3401 /* Allocate new hook and setup it's various variables */
3402 hook = (struct ast_bridge_hook_dtmf *) bridge_hook_generic(sizeof(*hook), callback,
3403 hook_pvt, destructor, remove_flags);
3404 if (!hook) {
3405 return -1;
3406 }
3408 ast_copy_string(hook->dtmf.code, dtmf, sizeof(hook->dtmf.code));
3409
3410 /* Once done we put it in the container. */
3411 res = ao2_link(features->dtmf_hooks, hook) ? 0 : -1;
3412 if (res) {
3413 /*
3414 * Could not link the hook into the container.
3415 *
3416 * Remove the hook_pvt destructor call from the hook since we
3417 * are returning failure to install the hook.
3418 */
3419 hook->generic.destructor = NULL;
3420 }
3421 ao2_ref(hook, -1);
3422
3423 return res;
3424}
#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:3371
@ 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, int rdlock)
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:3862

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

3863{
3864 struct ast_bridge_hook_timer *hook;
3865
3866 /* Destroy the interval hooks heap. */
3867 if (features->interval_hooks) {
3868 while ((hook = ast_heap_pop(features->interval_hooks))) {
3869 ao2_ref(hook, -1);
3870 }
3871 features->interval_hooks = ast_heap_destroy(features->interval_hooks);
3872 }
3873
3874 /* Destroy the miscellaneous other hooks container. */
3875 ao2_cleanup(features->other_hooks);
3876 features->other_hooks = NULL;
3877
3878 /* Destroy the DTMF hooks container. */
3879 ao2_cleanup(features->dtmf_hooks);
3880 features->dtmf_hooks = NULL;
3881}
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(), 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:3892
void ast_bridge_features_destroy(struct ast_bridge_features *features)
Destroy an allocated bridge features struct.
Definition bridge.c:3883

Definition at line 3883 of file bridge.c.

3884{
3885 if (!features) {
3886 return;
3887 }
3889 ast_free(features);
3890}
#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:3862

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

Definition at line 3299 of file bridge.c.

3300{
3302
3303 if (ARRAY_LEN(builtin_features_handlers) <= feature) {
3304 return -1;
3305 }
3306
3308 if (!callback) {
3309 return -1;
3310 }
3311 callback(bridge_channel, hook_pvt);
3312
3313 return 0;
3314}
static ast_bridge_hook_callback builtin_features_handlers[AST_BRIDGE_BUILTIN_END]
Definition bridge.c:169
int(* ast_bridge_hook_callback)(struct ast_bridge_channel *bridge_channel, void *hook_pvt)
Hook callback type.
#define ARRAY_LEN(a)
Definition utils.h:706

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

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

3580{
3581 if (ARRAY_LEN(builtin_features_handlers) <= feature
3582 || !builtin_features_handlers[feature]) {
3583 return -1;
3584 }
3585
3586 /* If no alternate DTMF stream was provided use the default one */
3587 if (ast_strlen_zero(dtmf)) {
3588 dtmf = builtin_features_dtmf[feature];
3589 /* If no DTMF is still available (ie: it has been disabled) then error out now */
3590 if (ast_strlen_zero(dtmf)) {
3591 ast_debug(1, "Failed to enable built in feature %u on %p, no DTMF string is available for it.\n",
3592 feature, features);
3593 return -1;
3594 }
3595 }
3596
3597 /*
3598 * The rest is basically pretty easy. We create another hook
3599 * using the built in feature's DTMF callback. Easy as pie.
3600 */
3601 return ast_bridge_dtmf_hook(features, dtmf, builtin_features_handlers[feature],
3602 config, destructor, remove_flags);
3603}
static char builtin_features_dtmf[AST_BRIDGE_BUILTIN_END][MAXIMUM_DTMF_FEATURE_STRING]
Definition bridge.c:166
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:3391
static const char config[]

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

3830{
3831 /* Zero out the structure */
3832 memset(features, 0, sizeof(*features));
3833
3834 /* Initialize the DTMF hooks container */
3837 if (!features->dtmf_hooks) {
3838 return -1;
3839 }
3840
3841 /* Initialize the miscellaneous other hooks container */
3843 NULL);
3844 if (!features->other_hooks) {
3845 return -1;
3846 }
3847
3848 /* Initialize the interval hooks heap */
3850 offsetof(struct ast_bridge_hook_timer, timer.heap_index));
3851 if (!features->interval_hooks) {
3852 return -1;
3853 }
3854
3855 features->dtmf_passthrough = 1;
3856 features->text_messaging = 1;
3857
3858 return 0;
3859}
@ 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:3717
static int bridge_dtmf_hook_sort(const void *obj_left, const void *obj_right, int flags)
Definition bridge.c:3748
static struct ast_timer * timer
Definition chan_iax2.c:401
#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(), 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 3605 of file bridge.c.

3606{
3607 memset(limits, 0, sizeof(*limits));
3608
3609 if (ast_string_field_init(limits, 256)) {
3610 return -1;
3611 }
3612
3613 return 0;
3614}
#define ast_string_field_init(x, size)
Initialize a field pool and fields.

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

3617{
3619}
#define ast_string_field_free_memory(x)
free all memory - to be called before destroying the object

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

3805{
3806 struct ast_bridge_hook_timer *hook;
3807 int idx;
3808
3809 /* Merge hook containers */
3812
3813 /* Merge hook heaps */
3815 for (idx = 1; (hook = ast_heap_peek(from->interval_hooks, idx)); idx++) {
3816 wrap_hook(into, hook);
3817 }
3819
3820 /* Merge feature flags */
3821 into->feature_flags.flags |= from->feature_flags.flags;
3822 into->usable |= from->usable;
3823
3824 into->mute |= from->mute;
3825 into->dtmf_passthrough |= from->dtmf_passthrough;
3826}
#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:3771
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:3792
#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:221

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

3893{
3894 struct ast_bridge_features *features;
3895
3896 features = ast_malloc(sizeof(*features));
3897 if (features) {
3898 if (ast_bridge_features_init(features)) {
3900 features = NULL;
3901 }
3902 }
3903
3904 return features;
3905}
#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:3829

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

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

Definition at line 3271 of file bridge.c.

3272{
3273 if (ARRAY_LEN(builtin_features_handlers) <= feature
3274 || builtin_features_handlers[feature]) {
3275 return -1;
3276 }
3277
3278 if (!ast_strlen_zero(dtmf)) {
3279 ast_copy_string(builtin_features_dtmf[feature], dtmf, sizeof(builtin_features_dtmf[feature]));
3280 }
3281
3283
3284 return 0;
3285}

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

3711{
3712 hooks_remove_container(features->dtmf_hooks, remove_flags);
3713 hooks_remove_container(features->other_hooks, remove_flags);
3714 hooks_remove_heap(features->interval_hooks, remove_flags);
3715}
static void hooks_remove_heap(struct ast_heap *hooks, enum ast_bridge_hook_remove_flags remove_flags)
Definition bridge.c:3688
static void hooks_remove_container(struct ao2_container *hooks, enum ast_bridge_hook_remove_flags remove_flags)
Definition bridge.c:3674

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

3637{
3638 ast_set_flag(&features->feature_flags, flag);
3639 features->usable = 1;
3640}
long int flag
Definition f2c.h:83
#define ast_set_flag(p, flag)
Definition utils.h:71

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:3621
int ast_bridge_features_limits_construct(struct ast_bridge_features_limits *limits)
Constructor function for ast_bridge_features_limits.
Definition bridge.c:3605
void ast_bridge_features_limits_destroy(struct ast_bridge_features_limits *limits)
Destructor function for ast_bridge_features_limits.
Definition bridge.c:3616
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 3621 of file bridge.c.

3624{
3627
3629 return callback(features, limits, remove_flags);
3630 }
3631
3632 ast_log(LOG_ERROR, "Attempted to set limits without an AST_BRIDGE_BUILTIN_INTERVAL_LIMITS callback registered.\n");
3633 return -1;
3634}
static ast_bridge_builtin_set_limits_fn builtin_interval_handlers[AST_BRIDGE_BUILTIN_INTERVAL_END]
Definition bridge.c:172
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:3287

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

Definition at line 3287 of file bridge.c.

3288{
3289 if (ARRAY_LEN(builtin_features_handlers) <= feature
3290 || !builtin_features_handlers[feature]) {
3291 return -1;
3292 }
3293
3295
3296 return 0;
3297}

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

5222{
5223 return ao2_find(bridges, bridge_id, OBJ_SEARCH_KEY);
5224}
#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_get_ari_reportable_variables()

struct varshead * ast_bridge_get_ari_reportable_variables ( struct ast_bridge bridge)

Get a list of variables that should be included in ARI events for this bridge.

Since
20.20.0
22.10.0
23.4.0
Precondition
Bridge is locked
Parameters
bridgeBridge to operate on.
Note
The returned list must be freed by the caller.
Return values
Apointer to the head of a linked list of variables to include in ARI events on success.
NULLon failure or if no variables are set to be reported.

Definition at line 1385 of file bridge.c.

1386{
1387 struct varshead *ret;
1388 char *var_str;
1389 size_t i;
1390
1392 return NULL;
1393 }
1394
1395 ret = ast_var_list_create();
1396 if (!ret) {
1397 return NULL;
1398 }
1399
1400 for (i = 0; i < AST_VECTOR_SIZE(&bridge->ari_reportable_variable_names); ++i) {
1401 const char *val = NULL;
1402 struct ast_var_t *var;
1403
1404 var_str = AST_VECTOR_GET(&bridge->ari_reportable_variable_names, i);
1405 val = ast_bridge_get_variable(bridge, var_str);
1406
1407 var = ast_var_assign(var_str, val ? val : "");
1408 if (!var) {
1410 return NULL;
1411 }
1412
1414 }
1415
1416 return ret;
1417}
#define var
Definition ast_expr2f.c:605
const char * ast_bridge_get_variable(const struct ast_bridge *bridge, const char *name)
Get value a variable from the bridge by name.
Definition bridge.c:1380
void ast_var_list_destroy(struct varshead *head)
Definition chanvars.c:109
#define ast_var_assign(name, value)
Definition chanvars.h:40
struct varshead * ast_var_list_create(void)
Definition chanvars.c:97
#define AST_LIST_INSERT_TAIL(head, elm, field)
Appends a list entry to the tail of a list.
struct ast_bridge::@200 ari_reportable_variable_names
struct ast_var_t::@221 entries
#define AST_VECTOR_SIZE(vec)
Get the number of elements in a vector.
Definition vector.h:620
#define AST_VECTOR_GET(vec, idx)
Get an element from a vector.
Definition vector.h:691

References ast_bridge::ari_reportable_variable_names, ast_bridge_get_variable(), AST_LIST_INSERT_TAIL, ast_var_assign, ast_var_list_create(), ast_var_list_destroy(), AST_VECTOR_GET, AST_VECTOR_SIZE, ast_var_t::entries, NULL, and var.

Referenced by ast_bridge_snapshot_create().

◆ ast_bridge_get_variable()

const char * ast_bridge_get_variable ( const struct ast_bridge bridge,
const char *  name 
)

Get value a variable from the bridge by name.

Since
20.20.0
22.10.0
23.4.0
Precondition
Bridge is locked
Parameters
bridgeBridge to operate on.
nameName of variable to get.
Return values
Valueof the variable on success.
NULLon failure.

Definition at line 1380 of file bridge.c.

1381{
1382 return ast_var_find(&bridge->bridgevars, name);
1383}
char * ast_var_find(const struct varshead *head, const char *name)
Definition chanvars.c:85
struct varshead bridgevars
Definition bridge.h:416

References ast_var_find(), ast_bridge::bridgevars, and name.

Referenced by ast_ari_bridges_get_bridge_var(), ast_ari_bridges_get_bridge_vars(), and ast_bridge_get_ari_reportable_variables().

◆ 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:3474

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

3479{
3480 return bridge_other_hook(features, callback, hook_pvt, destructor, remove_flags,
3482}
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:3440
@ 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:2077

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

2082{
2084 .done = 0,
2085 };
2086 int res;
2087 SCOPE_TRACE(1, "%s Bridge: %s\n", ast_channel_name(chan), bridge->uniqueid);
2088
2089 ast_mutex_init(&cond.lock);
2090 ast_cond_init(&cond.cond, NULL);
2091
2092 res = bridge_impart_internal(bridge, chan, swap, features, flags, &cond);
2093 if (res) {
2094 /* Impart failed. Signal any other waiting impart threads */
2097 }
2098
2099 ast_cond_destroy(&cond.cond);
2100 ast_mutex_destroy(&cond.lock);
2101
2102 return res;
2103}
ast_cond_t cond
Definition app_sla.c:336
void bridge_channel_impart_signal(struct ast_channel *chan)
Definition bridge.c:1781
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:1976
void ast_bridge_discard_after_callback(struct ast_channel *chan, enum ast_bridge_after_cb_reason reason)
Run discarding any after bridge callbacks.
@ AST_BRIDGE_AFTER_CB_REASON_IMPART_FAILED
#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:407
Internal bridge impart wait condition and associated conditional.
Definition bridge.c:1674

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, bridge_channel_impart_cond::done, 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_TEST_DEFINE(), AST_TEST_DEFINE(), AST_TEST_DEFINE(), AST_TEST_DEFINE(), AST_TEST_DEFINE(), AST_TEST_DEFINE(), AST_TEST_DEFINE(), AST_TEST_DEFINE(), AST_TEST_DEFINE(), AST_TEST_DEFINE(), AST_TEST_DEFINE(), 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:3528

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

3535{
3536 struct ast_bridge_hook_timer *hook;
3537 int res;
3538
3539 if (!features ||!interval || !callback) {
3540 return -1;
3541 }
3542
3543 /* Allocate new hook and setup it's various variables */
3544 hook = (struct ast_bridge_hook_timer *) bridge_hook_generic(sizeof(*hook), callback,
3545 hook_pvt, destructor, remove_flags);
3546 if (!hook) {
3547 return -1;
3548 }
3550 hook->timer.interval = interval;
3551 hook->timer.trip_time = ast_tvadd(ast_tvnow(), ast_samp2tv(interval, 1000));
3552 hook->timer.seqno = ast_atomic_fetchadd_int((int *) &features->interval_sequence, +1);
3553 hook->timer.flags = flags;
3554
3555 ast_debug(1, "Putting interval hook %p with interval %u in the heap on features %p\n",
3556 hook, hook->timer.interval, features);
3558 res = ast_heap_push(features->interval_hooks, hook);
3560 if (res) {
3561 /*
3562 * Could not push the hook into the heap
3563 *
3564 * Remove the hook_pvt destructor call from the hook since we
3565 * are returning failure to install the hook.
3566 */
3567 hook->generic.destructor = NULL;
3568 ao2_ref(hook, -1);
3569 }
3570
3571 return res ? -1 : 0;
3572}
@ 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:3316

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

Definition at line 3316 of file bridge.c.

3317{
3318 if (ARRAY_LEN(builtin_interval_handlers) <= interval
3319 || builtin_interval_handlers[interval]) {
3320 return -1;
3321 }
3322
3324
3325 return 0;
3326}

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

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

Definition at line 3328 of file bridge.c.

3329{
3330 if (ARRAY_LEN(builtin_interval_handlers) <= interval
3331 || !builtin_interval_handlers[interval]) {
3332 return -1;
3333 }
3334
3335 builtin_interval_handlers[interval] = NULL;
3336
3337 return 0;
3338
3339}

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

4101{
4102 int res = 0;
4103
4104 ast_bridge_lock(bridge);
4105 switch (bridge->softmix.video_mode.mode) {
4107 break;
4110 res = 1;
4111 }
4112 break;
4115 res = 1;
4116 } else if (bridge->softmix.video_mode.mode_data.talker_src_data.chan_old_vsrc == chan) {
4117 res = 2;
4118 }
4120 break;
4121 }
4122 ast_bridge_unlock(bridge);
4123 return res;
4124}
@ AST_BRIDGE_VIDEO_MODE_SINGLE_SRC
Definition bridge.h:106
@ AST_BRIDGE_VIDEO_MODE_TALKER_SRC
Definition bridge.h:109
@ AST_BRIDGE_VIDEO_MODE_NONE
Definition bridge.h:104
@ AST_BRIDGE_VIDEO_MODE_SFU
Definition bridge.h:113
struct ast_bridge_video_mode video_mode
Definition bridge.h:283
struct ast_bridge_video_single_src_data single_src_data
Definition bridge.h:167
struct ast_bridge_video_talker_src_data talker_src_data
Definition bridge.h:168
union ast_bridge_video_mode::@198 mode_data
enum ast_bridge_video_mode_type mode
Definition bridge.h:164
struct ast_channel * chan_vsrc
Definition bridge.h:120
struct ast_channel * chan_old_vsrc
Definition bridge.h:131
struct ast_channel * chan_vsrc
Definition bridge.h:127
struct ast_bridge_softmix softmix
Definition bridge.h:373

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:1820
@ AST_BRIDGE_JOIN_PASS_REFERENCE
Definition bridge.h:545

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

1826{
1827 struct ast_bridge_channel *bridge_channel;
1828 int res = 0;
1829 SCOPE_TRACE(1, "%s Bridge: %s\n", ast_channel_name(chan), bridge->uniqueid);
1830
1831 bridge_channel = bridge_channel_internal_alloc(bridge);
1832 if (flags & AST_BRIDGE_JOIN_PASS_REFERENCE) {
1833 ao2_ref(bridge, -1);
1834 }
1835 if (!bridge_channel) {
1836 ao2_t_cleanup(swap, "Error exit: bridge_channel alloc failed");
1837 res = -1;
1838 goto join_exit;
1839 }
1840/* 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. */
1842 if (!features) {
1843 ao2_ref(bridge_channel, -1);
1844 ao2_t_cleanup(swap, "Error exit: features is NULL");
1845 res = -1;
1846 goto join_exit;
1847 }
1848 if (tech_args) {
1849 bridge_channel->tech_args = *tech_args;
1850 }
1851
1854 res = -1;
1855 } else {
1857 }
1859 bridge_channel->thread = pthread_self();
1860 bridge_channel->chan = chan;
1861 bridge_channel->swap = swap;
1862 bridge_channel->features = features;
1863 bridge_channel->inhibit_colp = !!(flags & AST_BRIDGE_JOIN_INHIBIT_JOIN_COLP);
1864
1865 /* allow subclass to peek at upcoming push operation */
1866 if (bridge->v_table->push_peek && !res) {
1867 struct ast_bridge_channel *bcswap = NULL;
1868
1870 if (bridge_channel->swap) {
1871 bcswap = bridge_find_channel(bridge, bridge_channel->swap);
1872 }
1873 res = bridge->v_table->push_peek(bridge, bridge_channel, bcswap);
1875 }
1876
1877 if (!res) {
1878 res = bridge_channel_internal_join(bridge_channel);
1879 }
1880
1881 /* Cleanup all the data in the bridge channel after it leaves the bridge. */
1885 /* Due to a race condition, we lock the bridge channel here for ast_bridge_channel_get_chan */
1886 ao2_lock(bridge_channel);
1887 bridge_channel->chan = NULL;
1888 ao2_unlock(bridge_channel);
1889 /* If bridge_channel->swap is not NULL then the join failed. */
1890 ao2_t_cleanup(bridge_channel->swap, "Bridge complete: join failed");
1891 bridge_channel->swap = NULL;
1892 bridge_channel->features = NULL;
1893
1894 ao2_ref(bridge_channel, -1);
1895
1896join_exit:
1901 /* Claim the after bridge goto is an async goto destination. */
1905 }
1906 return res;
1907}
#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:547
int ast_bridge_setup_after_goto(struct ast_channel *chan)
Setup any after bridge goto location to begin execution.
void ast_bridge_run_after_callback(struct ast_channel *chan)
Run any after bridge callback.
struct ast_bridge_channel * bridge_channel_internal_alloc(struct ast_bridge *bridge)
int bridge_channel_internal_join(struct ast_bridge_channel *bridge_channel)
@ AST_FLAG_ZOMBIE
Definition channel.h:1007
struct ast_flags * ast_channel_flags(struct ast_channel *chan)
@ 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:2449
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:357
#define ast_test_flag(p, flag)
Definition utils.h:64

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

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

3489{
3490 return bridge_other_hook(features, callback, hook_pvt, destructor, remove_flags,
3492}
@ 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:2178

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

2179{
2180 struct ast_bridge_channel *bridge_channel;
2181 int res;
2182
2184
2185 /* Try to find the channel that we want to kick. */
2186 if (!(bridge_channel = bridge_find_channel(bridge, chan))) {
2188 return -1;
2189 }
2190
2191 res = ast_bridge_channel_queue_callback(bridge_channel, 0, kick_it, NULL, 0);
2192
2194
2195 return res;
2196}
static void kick_it(struct ast_bridge_channel *bridge_channel, const void *payload, size_t payload_size)
Definition bridge.c:2173
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:3494

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

3499{
3500 return bridge_other_hook(features, callback, hook_pvt, destructor, remove_flags,
3502}
@ 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:2499

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

Definition at line 2499 of file bridge.c.

2500{
2501 int res;
2502
2503 /* Sanity check. */
2504 ast_assert(dst_bridge && src_bridge);
2505
2506 ast_bridge_lock_both(dst_bridge, src_bridge);
2507 res = bridge_merge_locked(dst_bridge, src_bridge, merge_best_direction, kick_me, num_kick);
2508 ast_bridge_unlock(src_bridge);
2509 ast_bridge_unlock(dst_bridge);
2510 return res;
2511}
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:2415

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

3210{
3211 ast_bridge_lock(bridge);
3213 ast_bridge_unlock(bridge);
3214}
void bridge_merge_inhibit_nolock(struct ast_bridge *bridge, int request)
Definition bridge.c:3200
static int request(void *obj)

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

2660{
2661 int res;
2662
2663 ast_bridge_lock_both(dst_bridge, src_bridge);
2664 res = bridge_move_locked(dst_bridge, src_bridge, chan, swap, attempt_recovery);
2665 ast_bridge_unlock(src_bridge);
2666 ast_bridge_unlock(dst_bridge);
2667 return res;
2668}

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

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

3521{
3523
3524 return bridge_other_hook(features, hook_cb, hook_pvt, destructor, remove_flags,
3526}
@ AST_BRIDGE_HOOK_TYPE_MOVE
static int hook_cb(struct ast_config *cfg)

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

1642{
1643 struct ast_bridge_channel *bridge_channel;
1644 struct ast_bridge *bridge;
1645
1646 /* Safely get the bridge_channel pointer for the chan. */
1647 ast_channel_lock(chan);
1648 bridge_channel = ast_channel_get_bridge_channel(chan);
1649 ast_channel_unlock(chan);
1650 if (!bridge_channel) {
1651 /* Not in a bridge */
1652 return;
1653 }
1654
1655 ast_bridge_channel_lock_bridge(bridge_channel);
1656 bridge = bridge_channel->bridge;
1657 if (bridge_channel == bridge_find_channel(bridge, chan)) {
1658/*
1659 * XXX ASTERISK-22366 this needs more work. The channels need
1660 * to be made compatible again if the formats change. The
1661 * bridge_channel thread needs to monitor for this case.
1662 */
1663 /* The channel we want to notify is still in a bridge. */
1664 bridge->v_table->notify_masquerade(bridge, bridge_channel);
1665 bridge_reconfigured(bridge, 1);
1666 }
1667 ast_bridge_unlock(bridge);
1668 ao2_ref(bridge_channel, -1);
1669}
void bridge_reconfigured(struct ast_bridge *bridge, unsigned int colp_update)
Definition bridge.c:1602
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 4284 of file bridge.c.

4285{
4286 struct ast_channel *peer;
4287
4289 peer = ast_bridge_peer_nolock(bridge, chan);
4291
4292 return peer;
4293}
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:4256
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 4256 of file bridge.c.

4257{
4258 struct ast_channel *peer = NULL;
4259 struct ast_bridge_channel *iter;
4260
4261 /* Asking for the peer channel only makes sense on a two-party bridge. */
4262 if (bridge->num_channels == 2
4265 int in_bridge = 0;
4266
4268 if (iter->chan != chan) {
4269 peer = iter->chan;
4270 } else {
4271 in_bridge = 1;
4272 }
4273 }
4274 if (in_bridge && peer) {
4275 ast_channel_ref(peer);
4276 } else {
4277 peer = NULL;
4278 }
4279 }
4280
4281 return peer;
4282}
@ AST_BRIDGE_CAPABILITY_NATIVE
Definition bridge.h:94
#define AST_LIST_TRAVERSE(head, var, field)
Loops over (traverses) the entries in a list.
struct ast_bridge_channel::@201 entry
unsigned int in_bridge
struct ast_bridge_channels_list channels
Definition bridge.h:369
unsigned int num_channels
Definition bridge.h:379
struct ast_bridge_technology * technology
Definition bridge.h:361

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

4246{
4247 struct ao2_container *channels;
4248
4249 ast_bridge_lock(bridge);
4251 ast_bridge_unlock(bridge);
4252
4253 return channels;
4254}
struct ao2_container * ast_bridge_peers_nolock(struct ast_bridge *bridge)
Get a container of all channels in the bridge.
Definition bridge.c:4227
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 4227 of file bridge.c.

4228{
4229 struct ao2_container *channels;
4230 struct ast_bridge_channel *iter;
4231
4234 if (!channels) {
4235 return NULL;
4236 }
4237
4239 ao2_link(channels, iter->chan);
4240 }
4241
4242 return channels;
4243}
@ 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:4182
static int channel_cmp(void *obj, void *arg, int flags)
Definition bridge.c:4205

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

326{
327 struct ast_frame *dup;
328
329 dup = ast_frdup(action);
330 if (!dup) {
331 return -1;
332 }
333 bridge_queue_action_nodup(bridge, dup);
334 return 0;
335}
static void bridge_queue_action_nodup(struct ast_bridge *bridge, struct ast_frame *action)
Definition bridge.c:314
#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:2150

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

2151{
2152 struct ast_bridge_channel *bridge_channel;
2153
2154 ast_debug(1, "Removing channel %s from bridge %s\n",
2156
2158
2159 /* Try to find the channel that we want to remove */
2160 if (!(bridge_channel = bridge_find_channel(bridge, chan))) {
2162 return -1;
2163 }
2164
2165 ast_bridge_channel_leave_bridge(bridge_channel,
2167
2169
2170 return 0;
2171}

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

4127{
4128 ast_bridge_lock(bridge);
4129 switch (bridge->softmix.video_mode.mode) {
4131 break;
4136 }
4138 }
4139 break;
4144 }
4147 }
4151 }
4153 }
4155 break;
4156 }
4157 ast_bridge_unlock(bridge);
4158}

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

3915{
3916 ast_bridge_lock(bridge);
3917 bridge->softmix.binaural_active = binaural_active;
3918 ast_bridge_unlock(bridge);
3919}
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 3921 of file bridge.c.

3922{
3923 ast_bridge_lock(bridge);
3924 bridge->softmix.internal_sample_rate = sample_rate;
3925 ast_bridge_unlock(bridge);
3926}
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 3928 of file bridge.c.

3929{
3930 ast_bridge_lock(bridge);
3931 bridge->softmix.maximum_sample_rate = sample_rate;
3932 ast_bridge_unlock(bridge);
3933}
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 3907 of file bridge.c.

3908{
3909 ast_bridge_lock(bridge);
3910 bridge->softmix.internal_mixing_interval = mixing_interval;
3911 ast_bridge_unlock(bridge);
3912}
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 4016 of file bridge.c.

4017{
4019
4020 ast_bridge_lock(bridge);
4021 bridge->softmix.video_mode.mode_data.sfu_data.estimated_bitrate = estimated_bitrate;
4022 ast_bridge_unlock(bridge);
4023}
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 3998 of file bridge.c.

3999{
4001
4002 ast_bridge_lock(bridge);
4003 bridge->softmix.video_mode.mode_data.sfu_data.remb_send_interval = remb_send_interval;
4004 ast_bridge_unlock(bridge);
4005}
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 4175 of file bridge.c.

4176{
4177 ast_bridge_lock(bridge);
4178 bridge->softmix.send_sdp_label = send_sdp_label;
4179 ast_bridge_unlock(bridge);
4180}
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 3983 of file bridge.c.

3984{
3985 ast_bridge_lock(bridge);
3986 cleanup_video_mode(bridge);
3988 ast_bridge_unlock(bridge);
3989}
static void cleanup_video_mode(struct ast_bridge *bridge)
Definition bridge.c:3935

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

3959{
3960 ast_bridge_lock(bridge);
3961 cleanup_video_mode(bridge);
3963 if (video_src_chan) {
3965 ast_verb(5, "Video source in bridge '%s' (%s) is now '%s' (%s)\n",
3966 bridge->name, bridge->uniqueid,
3967 ast_channel_name(video_src_chan),
3968 ast_channel_uniqueid(video_src_chan));
3969 ast_indicate(video_src_chan, AST_CONTROL_VIDUPDATE);
3970 }
3972 ast_bridge_unlock(bridge);
3973}
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:4298
@ 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:407

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

3976{
3977 ast_bridge_lock(bridge);
3978 cleanup_video_mode(bridge);
3980 ast_bridge_unlock(bridge);
3981}

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

4562{
4563 char *writevar;
4564 char *erasevar;
4565
4566 if (attended) {
4567 writevar = ATTENDEDTRANSFER;
4568 erasevar = BLINDTRANSFER;
4569 } else {
4570 writevar = BLINDTRANSFER;
4571 erasevar = ATTENDEDTRANSFER;
4572 }
4573
4574 pbx_builtin_setvar_helper(chan, writevar, value);
4575 pbx_builtin_setvar_helper(chan, erasevar, NULL);
4576}
#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_variable()

int ast_bridge_set_variable ( struct ast_bridge bridge,
const char *  name,
const char *  value,
int  report_events 
)

Set a variable on the bridge.

Since
20.20.0
22.10.0
23.4.0
Precondition
Bridge is locked
Parameters
bridgeBridge to operate on.
nameName of variable to set.
valueValue of variable to set. (NULL to delete variable.)
report_eventsIf non-zero, the variable change will be reported in ARI events.
Return values
0on success
-1on failure

Definition at line 1341 of file bridge.c.

1343{
1344 struct ast_var_t *var;
1345
1346 if (ast_strlen_zero(name)) {
1347 return -1;
1348 }
1349
1351 if (!strcmp(ast_var_name(var), name)) {
1354 break;
1355 }
1356 }
1358
1359 if (ast_strlen_zero(value)) {
1360 /* If the value is empty, remove the variable from the reportable list by
1361 forcing report_events to 0 */
1363 return 0;
1364 }
1365
1367 if (!var) {
1368 return -1;
1369 }
1370
1371 if (bridge_set_ari_var_reportable(bridge, name, report_events)) {
1373 return -1;
1374 }
1375
1377 return 0;
1378}
static int bridge_set_ari_var_reportable(struct ast_bridge *bridge, const char *variable, int report_events)
Definition bridge.c:1309
const char * ast_var_name(const struct ast_var_t *var)
Definition chanvars.c:60
void ast_var_delete(struct ast_var_t *var)
Definition extconf.c:2469
#define AST_LIST_TRAVERSE_SAFE_END
Closes a safe loop traversal block.
#define AST_LIST_TRAVERSE_SAFE_BEGIN(head, var, field)
Loops safely over (traverses) the entries in a list.
#define AST_LIST_REMOVE_CURRENT(field)
Removes the current entry from a list during a traversal.

References AST_LIST_INSERT_TAIL, AST_LIST_REMOVE_CURRENT, AST_LIST_TRAVERSE_SAFE_BEGIN, AST_LIST_TRAVERSE_SAFE_END, ast_strlen_zero(), ast_var_assign, ast_var_delete(), ast_var_name(), bridge_set_ari_var_reportable(), ast_bridge::bridgevars, ast_var_t::entries, name, value, and var.

Referenced by ast_ari_bridges_create(), ast_ari_bridges_create_with_id(), and stasis_app_bridge_set_var_reportable().

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

3992{
3993 ast_bridge_lock(bridge);
3994 bridge->softmix.video_mode.video_update_discard = video_update_discard;
3995 ast_bridge_unlock(bridge);
3996}
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:3216

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

3217{
3218 struct ast_bridge_channel *bridge_channel;
3219/* XXX ASTERISK-21271 the case of a dissolved bridge while channel is suspended is not handled. */
3220/* XXX ASTERISK-21271 suspend/unsuspend needs to be rethought. The caller must block until it has successfully suspended the channel for temporary control. */
3221/* 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. */
3222
3224
3225 if (!(bridge_channel = bridge_find_channel(bridge, chan))) {
3227 return -1;
3228 }
3229
3231
3233
3234 return 0;
3235}
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 3504 of file bridge.c.

3509{
3511
3512 return bridge_other_hook(features, hook_cb, hook_pvt, destructor, remove_flags,
3514}
@ 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:3256

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

3257{
3258 technology->suspended = 1;
3259}

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

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

286{
288
290
291 /* Ensure the bridge technology is registered before removing it */
293 if (current == technology) {
295 ast_verb(5, "Unregistered bridge technology %s\n", technology->name);
296 break;
297 }
298 }
300
302
303 return current ? 0 : -1;
304}
#define AST_RWLIST_REMOVE_CURRENT

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(), unload_module(), unload_module(), unload_module(), 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:3261

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

Definition at line 3261 of file bridge.c.

3262{
3263 /*
3264 * XXX We may want the act of unsuspending a bridge technology
3265 * to prod all existing bridges to see if they should start
3266 * using it.
3267 */
3268 technology->suspended = 0;
3269}

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

4618{
4619 struct ast_bridge *bridge;
4620
4621 ast_channel_lock(chan);
4622 bridge = ast_channel_get_bridge(chan);
4623 ast_channel_unlock(chan);
4624
4625 if (bridge && ast_test_flag(&bridge->feature_flags,
4627 ao2_ref(bridge, -1);
4628 bridge = NULL;
4629 }
4630
4631 return bridge;
4632}
@ AST_BRIDGE_FLAG_MASQUERADE_ONLY
@ AST_BRIDGE_FLAG_INVISIBLE
struct ast_flags feature_flags
Definition bridge.h:375

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

4888{
4889 RAII_VAR(struct ast_bridge *, to_transferee_bridge, NULL, ao2_cleanup);
4890 RAII_VAR(struct ast_bridge *, to_target_bridge, NULL, ao2_cleanup);
4891 RAII_VAR(struct ast_bridge_channel *, to_transferee_bridge_channel, NULL, ao2_cleanup);
4892 RAII_VAR(struct ast_bridge_channel *, to_target_bridge_channel, NULL, ao2_cleanup);
4894 RAII_VAR(struct ast_channel *, transferee, NULL, ao2_cleanup);
4895 RAII_VAR(struct ast_attended_transfer_message *, transfer_msg, NULL, ao2_cleanup);
4896 struct ast_bridge *the_bridge = NULL;
4897 struct ast_channel *chan_bridged;
4898 struct ast_channel *chan_unbridged;
4899 int transfer_prohibited;
4900 int do_bridge_transfer;
4901 enum ast_transfer_result res;
4902 const char *app = NULL;
4903 int hangup_target = 0;
4904
4905 to_transferee_bridge = ast_bridge_transfer_acquire_bridge(to_transferee);
4906 to_target_bridge = ast_bridge_transfer_acquire_bridge(to_transfer_target);
4907
4908 transfer_msg = ast_attended_transfer_message_create(1, to_transferee, to_transferee_bridge,
4909 to_transfer_target, to_target_bridge, NULL, NULL);
4910 if (!transfer_msg) {
4911 ast_log(LOG_ERROR, "Unable to create Stasis publication for attended transfer from %s\n",
4912 ast_channel_name(to_transferee));
4914 }
4915
4916 /* They can't both be unbridged, you silly goose! */
4917 if (!to_transferee_bridge && !to_target_bridge) {
4919 goto end;
4920 }
4921
4922 ast_channel_lock(to_transferee);
4923 to_transferee_bridge_channel = ast_channel_get_bridge_channel(to_transferee);
4924 ast_channel_unlock(to_transferee);
4925
4926 ast_channel_lock(to_transfer_target);
4927 to_target_bridge_channel = ast_channel_get_bridge_channel(to_transfer_target);
4928 ast_channel_unlock(to_transfer_target);
4929
4930 if (to_transferee_bridge_channel) {
4931 /* Take off hold if they are on hold. */
4932 if (ast_bridge_channel_write_unhold(to_transferee_bridge_channel)) {
4933 ast_log(LOG_ERROR, "Transferee channel disappeared during transfer!\n");
4935 goto end;
4936 }
4937 }
4938
4939 if (to_target_bridge_channel) {
4940 const char *target_complete_sound;
4941
4942 /* Take off hold if they are on hold. */
4943 if (ast_bridge_channel_write_unhold(to_target_bridge_channel)) {
4944 ast_log(LOG_ERROR, "Target channel disappeared during transfer!\n");
4946 goto end;
4947 }
4948
4949 /* Is there a courtesy sound to play to the target? */
4950 ast_channel_lock(to_transfer_target);
4951 target_complete_sound = pbx_builtin_getvar_helper(to_transfer_target,
4952 "ATTENDED_TRANSFER_COMPLETE_SOUND");
4953 if (!ast_strlen_zero(target_complete_sound)) {
4954 target_complete_sound = ast_strdupa(target_complete_sound);
4955 } else {
4956 target_complete_sound = NULL;
4957 }
4958 ast_channel_unlock(to_transfer_target);
4959 if (!target_complete_sound) {
4960 ast_channel_lock(to_transferee);
4961 target_complete_sound = pbx_builtin_getvar_helper(to_transferee,
4962 "ATTENDED_TRANSFER_COMPLETE_SOUND");
4963 if (!ast_strlen_zero(target_complete_sound)) {
4964 target_complete_sound = ast_strdupa(target_complete_sound);
4965 } else {
4966 target_complete_sound = NULL;
4967 }
4968 ast_channel_unlock(to_transferee);
4969 }
4970 if (target_complete_sound) {
4971 ast_bridge_channel_write_playfile(to_target_bridge_channel, NULL,
4972 target_complete_sound, NULL);
4973 }
4974 }
4975
4976 /* Let's get the easy one out of the way first */
4977 if (to_transferee_bridge && to_target_bridge) {
4978
4979 if (!to_transferee_bridge_channel || !to_target_bridge_channel) {
4981 goto end;
4982 }
4983
4984 ast_bridge_lock_both(to_transferee_bridge, to_target_bridge);
4985 res = two_bridge_attended_transfer(to_transferee, to_transferee_bridge_channel,
4986 to_transfer_target, to_target_bridge_channel,
4987 to_transferee_bridge, to_target_bridge, transfer_msg);
4988 ast_bridge_unlock(to_transferee_bridge);
4989 ast_bridge_unlock(to_target_bridge);
4990
4991 hangup_target = 1;
4992 goto end;
4993 }
4994
4995 the_bridge = to_transferee_bridge ?: to_target_bridge;
4996 chan_bridged = to_transferee_bridge ? to_transferee : to_transfer_target;
4997 chan_unbridged = to_transferee_bridge ? to_transfer_target : to_transferee;
4998
4999 /*
5000 * Race condition makes it possible for app to be NULL, so get the app prior to
5001 * transferring with a fallback of "unknown".
5002 */
5003 app = ast_strdupa(ast_channel_appl(chan_unbridged) ?: "unknown");
5004
5005 {
5006 int chan_count;
5008
5009 channels = ast_bridge_peers_nolock(the_bridge);
5010 if (!channels) {
5012 goto end;
5013 }
5014 chan_count = ao2_container_count(channels);
5015 if (chan_count <= 1) {
5017 goto end;
5018 }
5019 transfer_prohibited = ast_test_flag(&the_bridge->feature_flags,
5021 do_bridge_transfer = ast_test_flag(&the_bridge->feature_flags,
5023 chan_count > 2;
5024 }
5025
5026 if (transfer_prohibited) {
5028 goto end;
5029 }
5030
5031 set_transfer_variables_all(to_transferee, channels, 1);
5032
5033 if (do_bridge_transfer) {
5034 /*
5035 * Hang up the target if it was bridged. Note, if it is not bridged
5036 * it is hung up during the masquerade.
5037 */
5038 hangup_target = chan_bridged == to_transfer_target;
5039 ast_bridge_lock(the_bridge);
5040 res = attended_transfer_bridge(chan_bridged, chan_unbridged, the_bridge, NULL, transfer_msg);
5041 ast_bridge_unlock(the_bridge);
5042 goto end;
5043 }
5044
5045 transferee = get_transferee(channels, chan_bridged);
5046 if (!transferee) {
5048 goto end;
5049 }
5050
5051 if (bridge_channel_internal_queue_attended_transfer(transferee, chan_unbridged)) {
5053 goto end;
5054 }
5055
5056 ast_bridge_remove(the_bridge, chan_bridged);
5057
5060
5061end:
5062 if ((res == AST_BRIDGE_TRANSFER_SUCCESS && hangup_target) || res == AST_BRIDGE_TRANSFER_FAIL) {
5063 ast_softhangup(to_transfer_target, AST_SOFTHANGUP_DEV);
5064 }
5065
5066 transfer_msg->result = res;
5068 return res;
5069}
static const char app[]
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:4391
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:4820
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:4430
struct ast_bridge * ast_bridge_transfer_acquire_bridge(struct ast_channel *chan)
Acquire the channel's bridge for transfer purposes.
Definition bridge.c:4617
int ast_bridge_remove(struct ast_bridge *bridge, struct ast_channel *chan)
Remove a channel from a bridge.
Definition bridge.c:2150
static void set_transfer_variables_all(struct ast_channel *transferer, struct ao2_container *channels, int is_attended)
Definition bridge.c:4592
ast_transfer_result
Definition bridge.h:1159
@ AST_BRIDGE_TRANSFER_NOT_PERMITTED
Definition bridge.h:1163
@ AST_BRIDGE_TRANSFER_SUCCESS
Definition bridge.h:1161
@ AST_BRIDGE_TRANSFER_INVALID
Definition bridge.h:1165
@ AST_BRIDGE_TRANSFER_FAIL
Definition bridge.h:1167
int ast_bridge_channel_write_unhold(struct ast_bridge_channel *bridge_channel)
Write an unhold frame into the bridge.
int ast_bridge_channel_write_playfile(struct ast_bridge_channel *bridge_channel, ast_bridge_custom_play_fn custom_play, const char *playfile, const char *moh_class)
Write a bridge action play file frame into the bridge.
int bridge_channel_internal_queue_attended_transfer(struct ast_channel *transferee, struct ast_channel *unbridged_chan)
@ AST_BRIDGE_FLAG_TRANSFER_BRIDGE_ONLY
@ AST_BRIDGE_FLAG_TRANSFER_PROHIBITED
const char * ast_channel_appl(const struct ast_channel *chan)
int ast_softhangup(struct ast_channel *chan, int cause)
Softly hangup up a channel.
Definition channel.c:2462
@ AST_SOFTHANGUP_DEV
Definition channel.h:1141
char * end
Definition eagi_proxy.c:73
#define SCOPED_LOCK(varname, lock, lockfunc, unlockfunc)
Scoped Locks.
Definition lock.h: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(), 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 4634 of file bridge.c.

4637{
4638 RAII_VAR(struct ast_bridge *, bridge, NULL, ao2_cleanup);
4639 RAII_VAR(struct ast_bridge_channel *, bridge_channel, NULL, ao2_cleanup);
4641 RAII_VAR(struct ast_channel *, transferee, NULL, ast_channel_cleanup);
4642 RAII_VAR(struct transfer_channel_data *, user_data_wrapper, NULL, ao2_cleanup);
4643 RAII_VAR(struct ast_blind_transfer_message *, transfer_message, NULL, ao2_cleanup);
4644 int do_bridge_transfer;
4645 int transfer_prohibited;
4646 enum ast_transfer_result transfer_result;
4647
4648 transfer_message = ast_blind_transfer_message_create(is_external, transferer, exten, context);
4649 if (!transfer_message) {
4650 /* Out of memory. Not even possible to publish a Stasis message about the
4651 * failure
4652 */
4653 ast_log(LOG_ERROR, "Unable to allocate memory for blind transfer publication from %s\n",
4654 ast_channel_name(transferer));
4656 }
4657
4658 bridge = ast_bridge_transfer_acquire_bridge(transferer);
4659 if (!bridge) {
4660 transfer_result = AST_BRIDGE_TRANSFER_INVALID;
4661 goto publish;
4662 }
4663
4664 ast_bridge_lock(bridge);
4665 transfer_message->bridge = ast_bridge_snapshot_create(bridge);
4666 ast_bridge_unlock(bridge);
4667 if (!transfer_message->bridge) {
4668 transfer_result = AST_BRIDGE_TRANSFER_FAIL;
4669 goto publish;
4670 }
4671
4672 transferee = ast_bridge_peer(bridge, transferer);
4673 if (transferee) {
4674 transfer_message->transferee = ast_channel_snapshot_get_latest(ast_channel_uniqueid(transferee));
4675 if (!transfer_message->transferee) {
4676 transfer_result = AST_BRIDGE_TRANSFER_FAIL;
4677 goto publish;
4678 }
4679 }
4680
4681 ast_channel_lock(transferer);
4682 bridge_channel = ast_channel_get_bridge_channel(transferer);
4683 ast_channel_unlock(transferer);
4684 if (!bridge_channel) {
4685 transfer_result = AST_BRIDGE_TRANSFER_INVALID;
4686 goto publish;
4687 }
4688
4689 user_data_wrapper = ao2_alloc(sizeof(*user_data_wrapper), NULL);
4690 if (!user_data_wrapper) {
4691 transfer_result = AST_BRIDGE_TRANSFER_FAIL;
4692 goto publish;
4693 }
4694
4695 user_data_wrapper->data = user_data;
4696
4697 /* Take off hold if they are on hold. */
4698 ast_bridge_channel_write_unhold(bridge_channel);
4699
4700 transfer_result = try_parking(transferer, context, exten, new_channel_cb, user_data_wrapper);
4701 if (transfer_result == AST_BRIDGE_TRANSFER_SUCCESS) {
4702 goto publish;
4703 }
4704
4705 /* Since parking didn't take control of the user_data_wrapper, we are just going to raise the completed flag now. */
4706 user_data_wrapper->completed = 1;
4707
4708 {
4710
4712 if (!channels) {
4713 transfer_result = AST_BRIDGE_TRANSFER_FAIL;
4714 goto publish;
4715 }
4716 if (ao2_container_count(channels) <= 1) {
4717 transfer_result = AST_BRIDGE_TRANSFER_INVALID;
4718 goto publish;
4719 }
4720 transfer_prohibited = ast_test_flag(&bridge->feature_flags,
4722 do_bridge_transfer = ast_test_flag(&bridge->feature_flags,
4725 }
4726
4727 if (transfer_prohibited) {
4728 transfer_result = AST_BRIDGE_TRANSFER_NOT_PERMITTED;
4729 goto publish;
4730 }
4731
4732 set_transfer_variables_all(transferer, channels, 0);
4733
4734 if (do_bridge_transfer) {
4735 transfer_result = blind_transfer_bridge(is_external, transferer, bridge,
4736 exten, context, transferee, new_channel_cb, user_data_wrapper, transfer_message);
4737 goto publish;
4738 }
4739
4740 /* Reaching this portion means that we're dealing with a two-party bridge */
4741
4742 if (!transferee) {
4743 transfer_result = AST_BRIDGE_TRANSFER_FAIL;
4744 goto publish;
4745 }
4746
4747 if (bridge_channel_internal_queue_blind_transfer(transferee, exten, context,
4748 new_channel_cb, user_data_wrapper)) {
4749 transfer_result = AST_BRIDGE_TRANSFER_FAIL;
4750 goto publish;
4751 }
4752
4753 ast_bridge_remove(bridge, transferer);
4754 transfer_result = AST_BRIDGE_TRANSFER_SUCCESS;
4755
4756publish:
4757 transfer_message->result = transfer_result;
4758 ast_bridge_publish_blind_transfer(transfer_message);
4759 return transfer_result;
4760}
#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:4284
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:4535
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:4320
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:3030
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
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:1180

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

3130{
3131 struct ast_bridge *chan_bridge;
3132 struct ast_bridge *peer_bridge;
3133 struct ast_bridge_channel *chan_bridge_channel;
3134 struct ast_bridge_channel *peer_bridge_channel;
3135 int res = 0;
3136
3137 chan_bridge = optimize_lock_chan_stack(chan);
3138 if (!chan_bridge) {
3139 return res;
3140 }
3141 chan_bridge_channel = ast_channel_internal_bridge_channel(chan);
3142
3143 peer_bridge = optimize_lock_peer_stack(peer);
3144 if (peer_bridge) {
3145 peer_bridge_channel = ast_channel_internal_bridge_channel(peer);
3146
3147 res = try_swap_optimize_out(chan_bridge, chan_bridge_channel,
3148 peer_bridge, peer_bridge_channel, pvt);
3149 if (!res) {
3150 res = try_merge_optimize_out(chan_bridge, chan_bridge_channel,
3151 peer_bridge, peer_bridge_channel, pvt);
3152 } else if (0 < res) {
3153 res = 0;
3154 }
3155
3156 /* Release peer locks. */
3157 ast_bridge_unlock(peer_bridge);
3158 ast_bridge_channel_unlock(peer_bridge_channel);
3159 ast_channel_unlock(peer);
3160 }
3161
3162 /* Release chan locks. */
3163 ast_bridge_unlock(chan_bridge);
3164 ast_bridge_channel_unlock(chan_bridge_channel);
3165
3166 return res;
3167}
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:3078
static struct ast_bridge * optimize_lock_chan_stack(struct ast_channel *chan)
Definition bridge.c:2788
static struct ast_bridge * optimize_lock_peer_stack(struct ast_channel *peer)
Definition bridge.c:2833
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:2954
#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:3237

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

3238{
3239 struct ast_bridge_channel *bridge_channel;
3240/* XXX ASTERISK-21271 the case of a dissolved bridge while channel is suspended is not handled. */
3241
3243
3244 if (!(bridge_channel = bridge_find_channel(bridge, chan))) {
3246 return -1;
3247 }
3248
3250
3252
3253 return 0;
3254}
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 4025 of file bridge.c.

4026{
4028
4029 /* If the channel doesn't support video, we don't care about it */
4031 return;
4032 }
4033
4034 ast_bridge_lock(bridge);
4036
4037 if (data->chan_vsrc == chan) {
4038 data->average_talking_energy = talker_energy;
4039 } else if ((data->average_talking_energy < talker_energy) && is_keyframe) {
4040 if (data->chan_old_vsrc) {
4042 }
4043 if (data->chan_vsrc) {
4044 data->chan_old_vsrc = data->chan_vsrc;
4046 }
4047 data->chan_vsrc = ast_channel_ref(chan);
4048 data->average_talking_energy = talker_energy;
4049 ast_verb(5, "Video source in bridge '%s' (%s) is now '%s' (%s)\n",
4050 bridge->name, bridge->uniqueid,
4055 } else if ((data->average_talking_energy < talker_energy) && !is_keyframe) {
4057 } else if (!data->chan_vsrc && is_keyframe) {
4058 data->chan_vsrc = ast_channel_ref(chan);
4059 data->average_talking_energy = talker_energy;
4060 ast_verb(5, "Video source in bridge '%s' (%s) is now '%s' (%s)\n",
4061 bridge->name, bridge->uniqueid,
4066 } else if (!data->chan_old_vsrc && is_keyframe) {
4067 data->chan_old_vsrc = ast_channel_ref(chan);
4069 }
4070 ast_bridge_unlock(bridge);
4071}
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 1301 of file bridge.c.

1302{
1304 pbx_builtin_setvar_helper(chan, "BRIDGEPEER", name);
1305 pbx_builtin_setvar_helper(chan, "BRIDGEPVTCALLID", pvtid);
1307}
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 4160 of file bridge.c.

4161{
4162 switch (video_mode) {
4164 return "talker";
4166 return "single";
4168 return "sfu";
4170 default:
4171 return "none";
4172 }
4173}

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

197{
198 return ao2_bump(bridges);
199}
#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 3169 of file bridge.c.

3171{
3172 struct merge_direction merge;
3173
3174 if (!bridge_allows_optimization(chan_bridge) || !bridge_allows_optimization(peer_bridge)) {
3176 }
3177
3178 switch (bridges_allow_swap_optimization(chan_bridge, peer_bridge)) {
3183 case SWAP_PROHIBITED:
3184 default:
3185 break;
3186 }
3187
3188 /* Two channels will be kicked from the bridges, the unreal;1 and unreal;2 channels */
3189 if (bridges_allow_merge_optimization(chan_bridge, peer_bridge, 2, &merge) != MERGE_ALLOWED) {
3191 }
3192
3193 if (merge.dest == chan_bridge) {
3195 } else {
3197 }
3198}
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:3044
static enum bridge_allow_swap bridges_allow_swap_optimization(struct ast_bridge *chan_bridge, struct ast_bridge *peer_bridge)
Definition bridge.c:2898
static int bridge_allows_optimization(struct ast_bridge *bridge)
Definition bridge.c:2769
@ AST_BRIDGE_OPTIMIZE_PROHIBITED
Definition bridge.h:945
@ AST_BRIDGE_OPTIMIZE_MERGE_TO_CHAN_BRIDGE
Definition bridge.h:941
@ AST_BRIDGE_OPTIMIZE_SWAP_TO_PEER_BRIDGE
Definition bridge.h:939
@ AST_BRIDGE_OPTIMIZE_MERGE_TO_PEER_BRIDGE
Definition bridge.h:943
@ AST_BRIDGE_OPTIMIZE_SWAP_TO_CHAN_BRIDGE
Definition bridge.h:937

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

5754{
5756
5758 return -1;
5759 }
5760
5762 if (!bridge_manager) {
5763 return -1;
5764 }
5765
5768 if (!bridges) {
5769 return -1;
5770 }
5772
5774
5776
5777 ast_manager_register_xml_core("BridgeTechnologyList", 0, manager_bridge_tech_list);
5778 ast_manager_register_xml_core("BridgeTechnologySuspend", 0, manager_bridge_tech_suspend);
5779 ast_manager_register_xml_core("BridgeTechnologyUnsuspend", 0, manager_bridge_tech_unsuspend);
5780
5781 return 0;
5782}
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:194
static int manager_bridge_tech_list(struct mansession *s, const struct message *m)
Definition bridge.c:5670
static int manager_bridge_tech_suspend(struct mansession *s, const struct message *m)
Definition bridge.c:5660
static int manager_bridge_tech_unsuspend(struct mansession *s, const struct message *m)
Definition bridge.c:5665
static struct ast_cli_entry bridge_cli[]
Definition bridge.c:5614
static int bridge_sort_cmp(const void *obj_left, const void *obj_right, int flags)
Definition bridge.c:5199
static void bridge_prnt_obj(void *v_obj, void *where, ao2_prnt_fn *prnt)
Definition bridge.c:5723
static void bridge_cleanup(void)
Definition bridge.c:5739
static struct bridge_manager_controller * bridge_manager_create(void)
Definition bridge.c:5160
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:204
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 4007 of file bridge.c.

4008{
4010
4011 ast_bridge_lock(bridge);
4013 ast_bridge_unlock(bridge);
4014}
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 4430 of file bridge.c.

4433{
4434#define BRIDGE_LOCK_ONE_OR_BOTH(b1, b2) \
4435 do { \
4436 if (b2) { \
4437 ast_bridge_lock_both(b1, b2); \
4438 } else { \
4439 ast_bridge_lock(b1); \
4440 } \
4441 } while (0)
4442
4443 static const char *dest = "_attended@transfer/m";
4444 struct ast_channel *local_chan;
4445 int cause;
4446 int res;
4447 const char *app = NULL;
4448 struct ast_format_cap *caps;
4449
4450 ast_channel_lock(chan1);
4451 caps = ao2_bump(ast_channel_nativeformats(chan1));
4452 ast_channel_unlock(chan1);
4453
4454 local_chan = ast_request("Local", caps, NULL, chan1, dest, &cause);
4455
4456 ao2_cleanup(caps);
4457
4458 if (!local_chan) {
4460 }
4461
4462 ast_channel_lock_both(local_chan, chan1);
4465 ast_channel_unlock(local_chan);
4466 ast_channel_unlock(chan1);
4467
4468 if (bridge2) {
4469 res = ast_local_setup_bridge(local_chan, bridge2, chan2, NULL);
4470 } else {
4472 res = ast_local_setup_masquerade(local_chan, chan2);
4473 }
4474
4475 if (res) {
4476 ast_hangup(local_chan);
4478 }
4479
4480 /*
4481 * Since bridges need to be unlocked before entering ast_bridge_impart and
4482 * core_local may call into it then the bridges need to be unlocked here.
4483 */
4484 ast_bridge_unlock(bridge1);
4485 if (bridge2) {
4486 ast_bridge_unlock(bridge2);
4487 }
4488
4489 if (ast_call(local_chan, dest, 0)) {
4490 ast_hangup(local_chan);
4491 BRIDGE_LOCK_ONE_OR_BOTH(bridge1, bridge2);
4493 }
4494
4495 /* Get a ref for use later since this one is being stolen */
4496 ao2_ref(local_chan, +1);
4497 if (ast_bridge_impart(bridge1, local_chan, chan1, NULL,
4499 ast_hangup(local_chan);
4500 ao2_cleanup(local_chan);
4501 BRIDGE_LOCK_ONE_OR_BOTH(bridge1, bridge2);
4503 }
4504 BRIDGE_LOCK_ONE_OR_BOTH(bridge1, bridge2);
4505
4506 if (bridge2) {
4507 void *tech;
4508 struct ast_channel *locals[2];
4509
4510 /* Have to lock everything just in case a hangup comes in early */
4511 ast_local_lock_all(local_chan, &tech, &locals[0], &locals[1]);
4512 if (!locals[0] || !locals[1]) {
4513 ast_log(LOG_ERROR, "Transfer failed probably due to an early hangup - "
4514 "missing other half of '%s'\n", ast_channel_name(local_chan));
4516 ao2_cleanup(local_chan);
4518 }
4519
4520 /* Make sure the peer is properly set */
4521 if (local_chan != locals[0]) {
4522 SWAP(locals[0], locals[1]);
4523 }
4524
4527 } else {
4528 ast_attended_transfer_message_add_app(transfer_msg, app, local_chan);
4529 }
4530
4531 ao2_cleanup(local_chan);
4533}
#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:6480
@ AST_CHANNEL_REQUESTOR_REPLACEMENT
Definition channel.h:1527
#define ast_channel_lock_both(chan1, chan2)
Lock two channels.
Definition channel.h:2990
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:6453
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:6373
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:256

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

4326{
4327 struct ast_channel *local;
4328 char chan_name[AST_MAX_EXTENSION + AST_MAX_CONTEXT + 2];
4329 int cause;
4330 struct ast_format_cap *caps;
4331
4332 ast_channel_lock(transferer);
4333 caps = ao2_bump(ast_channel_nativeformats(transferer));
4334 ast_channel_unlock(transferer);
4335
4336 snprintf(chan_name, sizeof(chan_name), "%s@%s", exten, context);
4337 local = ast_request("Local", caps, NULL, transferer,
4338 chan_name, &cause);
4339
4340 ao2_cleanup(caps);
4341
4342 if (!local) {
4344 }
4345
4346 ast_channel_lock_both(local, transferer);
4348
4350 if (!transfer_message->replace_channel) {
4351 ast_hangup(local);
4353 }
4354
4356 ast_channel_unlock(local);
4357 ast_channel_unlock(transferer);
4358
4359 if (new_channel_cb) {
4360 new_channel_cb(local, user_data_wrapper, AST_BRIDGE_TRANSFER_MULTI_PARTY);
4361 }
4362
4363 if (ast_call(local, chan_name, 0)) {
4364 ast_hangup(local);
4366 }
4367
4368 if (ast_bridge_impart(bridge, local, transferer, NULL,
4370 ast_hangup(local);
4372 }
4373
4375}
@ AST_BRIDGE_TRANSFER_MULTI_PARTY
Definition bridge.h:1174
#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, 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 618 of file bridge.c.

619{
620#if 0 /* In case we need to know when the destructor is calling us. */
621 int in_destructor = !ao2_ref(bridge, 0);
622#endif
623
624 switch (action->subclass.integer) {
626 ast_bridge_unlock(bridge);
627 bridge_tech_deferred_destroy(bridge, action);
628 ast_bridge_lock(bridge);
629 break;
631 ast_bridge_unlock(bridge);
632 bridge->v_table->dissolving(bridge);
633 ast_bridge_lock(bridge);
634 break;
635 default:
636 /* Unexpected deferred action type. Should never happen. */
637 ast_assert(0);
638 break;
639 }
640}
static void bridge_tech_deferred_destroy(struct ast_bridge *bridge, struct ast_frame *action)
Definition bridge.c:590
@ 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 765 of file bridge.c.

766{
767 struct ast_bridge *bridge;
768
769 /* Check v_table that all methods are present. */
770 if (!v_table
771 || !v_table->name
772 || !v_table->destroy
774 || !v_table->push
775 || !v_table->pull
778 ast_log(LOG_ERROR, "Virtual method table for bridge class %s not complete.\n",
779 v_table && v_table->name ? v_table->name : "<unknown>");
780 ast_assert(0);
781 return NULL;
782 }
783
784 bridge = ao2_alloc(size, destroy_bridge);
785 if (!bridge) {
786 return NULL;
787 }
788
789 if (ast_string_field_init(bridge, 80)) {
790 ao2_cleanup(bridge);
791 return NULL;
792 }
793
794 bridge->v_table = v_table;
795
799
800 return bridge;
801}
static void destroy_bridge(void *obj)
Definition bridge.c:670
@ AST_MEDIA_TYPE_END
Definition codec.h:36
#define AST_LIST_HEAD_INIT_NOLOCK(head)
Initializes a list head structure.
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:410
#define AST_VECTOR_INIT(vec, size)
Initialize a vector.
Definition vector.h:124

References ao2_alloc, ao2_cleanup, ast_bridge::ari_reportable_variable_names, ast_assert, AST_LIST_HEAD_INIT_NOLOCK, ast_log, AST_MEDIA_TYPE_END, ast_string_field_init, AST_VECTOR_INIT, ast_bridge::bridgevars, 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 2769 of file bridge.c.

2770{
2771 return !(bridge->inhibit_merge
2772 || bridge->dissolved
2774}
unsigned int dissolved
Definition bridge.h:396
unsigned int inhibit_merge
Count of the active temporary requests to inhibit bridge merges. Zero if merges are allowed.
Definition bridge.h:390

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

901{
902 ast_debug(1, "Bridge " BRIDGE_PRINTF_SPEC ": destroying bridge (noop)\n",
903 BRIDGE_PRINTF_VARS(self));
904}

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

914{
915 ast_debug(1, "Bridge " BRIDGE_PRINTF_SPEC ": unlinking bridge. Refcount: %d\n",
916 BRIDGE_PRINTF_VARS(self), ao2_ref(self, 0));
917 ao2_unlink(bridges, self);
918 ast_debug(1, "Bridge " BRIDGE_PRINTF_SPEC ": unlinked bridge. Refcount: %d\n",
919 BRIDGE_PRINTF_VARS(self), ao2_ref(self, 0));
920}
#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 983 of file bridge.c.

984{
985 return 0;
986}

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

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

Definition at line 803 of file bridge.c.

804{
805 char uuid_hold[AST_UUID_STR_LEN];
806
807 if (!self) {
808 return NULL;
809 }
810
811 {
812 /*
813 * We need to ensure that another bridge with the same uniqueid
814 * doesn't get created before the previous bridge's destructor
815 * has run and deleted the existing topic.
816 */
818 if (!ast_strlen_zero(id)) {
819 if (ast_bridge_topic_exists(id)) {
820 ast_log(LOG_WARNING, "Bridge " BRIDGE_PRINTF_SPEC ": already registered\n",
821 BRIDGE_PRINTF_VARS(self));
822 ast_bridge_destroy(self, 0);
823 return NULL;
824 }
825 ast_string_field_set(self, uniqueid, id);
826 } else {
828 ast_string_field_set(self, uniqueid, uuid_hold);
829 }
830 if (!(flags & AST_BRIDGE_FLAG_INVISIBLE)) {
831 if (bridge_topics_init(self) != 0) {
832 ast_log(LOG_WARNING, "Bridge " BRIDGE_PRINTF_SPEC ": Could not initialize topics\n",
833 BRIDGE_PRINTF_VARS(self));
834 ao2_ref(self, -1);
835 return NULL;
836 }
837 }
838 }
839
840 ast_string_field_set(self, creator, creator);
841 if (!ast_strlen_zero(creator)) {
843 }
844 ast_debug(1, "Bridge " BRIDGE_PRINTF_SPEC ": base_init\n",
845 BRIDGE_PRINTF_VARS(self));
846
847 ast_set_flag(&self->feature_flags, flags);
848 self->allowed_capabilities = capabilities;
849
850 /* Use our helper function to find the "best" bridge technology. */
851 self->technology = find_best_technology(capabilities, self);
852 if (!self->technology) {
853 ast_log(LOG_WARNING, "Bridge %s: Could not create class %s. No technology to support it.\n",
854 self->uniqueid, self->v_table->name);
855 ao2_ref(self, -1);
856 return NULL;
857 }
858
859 /* Pass off the bridge to the technology to manipulate if needed */
860 ast_debug(1, "Bridge %s: calling %s technology constructor\n",
861 self->uniqueid, self->technology->name);
862 if (self->technology->create && self->technology->create(self)) {
863 ast_log(LOG_WARNING, "Bridge %s: failed to setup bridge technology %s\n",
864 self->uniqueid, self->technology->name);
865 ao2_ref(self, -1);
866 return NULL;
867 }
868 ast_debug(1, "Bridge %s: calling %s technology start\n",
869 self->uniqueid, self->technology->name);
870 if (self->technology->start && self->technology->start(self)) {
871 ast_log(LOG_WARNING, "Bridge %s: failed to start bridge technology %s\n",
872 self->uniqueid, self->technology->name);
873 ao2_ref(self, -1);
874 return NULL;
875 }
876
877 if (!(flags & AST_BRIDGE_FLAG_INVISIBLE)) {
878 if (!ast_bridge_topic(self)) {
879 ao2_ref(self, -1);
880 return NULL;
881 }
882 }
883
884 self->creationtime = ast_tvnow();
885 ast_debug(1, "Bridge " BRIDGE_PRINTF_SPEC ": base_init complete\n",
886 BRIDGE_PRINTF_VARS(self));
887
888 return self;
889}
int ast_bridge_destroy(struct ast_bridge *bridge, int cause)
Destroy a bridge.
Definition bridge.c:1029
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:529
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.
int(* create)(struct ast_bridge *bridge)
Create a bridge technology instance for a bridge.
struct timeval creationtime
Definition bridge.h:414
uint32_t allowed_capabilities
Definition bridge.h:377
#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 967 of file bridge.c.

968{
969 self->reconfigured = 1;
970}
unsigned int reconfigured
Definition bridge.h:394

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

953{
955}
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:3710
@ 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 937 of file bridge.c.

938{
939 return 0;
940}

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

1004{
1005 return 0;
1006}

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

2207{
2208 struct ast_bridge *old_bridge;
2209
2210 ao2_ref(new_bridge, +1);
2211 ast_bridge_channel_lock(bridge_channel);
2212 ast_channel_lock(bridge_channel->chan);
2213 old_bridge = bridge_channel->bridge;
2214 bridge_channel->bridge = new_bridge;
2215 ast_channel_internal_bridge_set(bridge_channel->chan, new_bridge);
2216 ast_channel_unlock(bridge_channel->chan);
2217 ast_bridge_channel_unlock(bridge_channel);
2218 ao2_ref(old_bridge, -1);
2219}
#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 463 of file bridge.c.

464{
465 /* Tell the bridge technology we are joining so they set us up */
466 ast_debug(1, "Bridge %s: %p(%s) is joining %s technology\n",
467 bridge->uniqueid, bridge_channel, ast_channel_name(bridge_channel->chan),
468 bridge->technology->name);
469 if (bridge->technology->join
470 && bridge->technology->join(bridge, bridge_channel)) {
471 /* We cannot leave the channel partially in the bridge so we must kick it out */
472 ast_debug(1, "Bridge %s: %p(%s) failed to join %s technology (Kicking it out)\n",
473 bridge->uniqueid, bridge_channel, ast_channel_name(bridge_channel->chan),
474 bridge->technology->name);
475 bridge_channel->just_joined = 1;
477 return;
478 }
479
480 bridge_channel->just_joined = 0;
481
482 /*
483 * When a channel joins the bridge its streams need to be mapped to the bridge's
484 * media types vector. This way all streams map to the same media type index for
485 * a given channel.
486 */
487 if (bridge_channel->bridge->technology->stream_topology_changed) {
488 bridge_channel->bridge->technology->stream_topology_changed(
489 bridge_channel->bridge, bridge_channel);
490 } else {
491 ast_bridge_channel_stream_map(bridge_channel);
492 }
493}
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 1910 of file bridge.c.

1911{
1912 struct ast_bridge_channel *bridge_channel = data;
1913 int res = 0;
1914
1915 if (bridge_channel->callid) {
1916 ast_callid_threadassoc_add(bridge_channel->callid);
1917 }
1918
1919 res = bridge_channel_internal_join(bridge_channel);
1920
1921 /*
1922 * cleanup
1923 *
1924 * If bridge_channel->swap is not NULL then the join failed.
1925 */
1926 ao2_t_cleanup(bridge_channel->swap, "Bridge complete: Departable impart join failed");
1927 bridge_channel->swap = NULL;
1928 ast_bridge_features_destroy(bridge_channel->features);
1929 bridge_channel->features = NULL;
1930
1933 /* If join failed there will be impart threads waiting. */
1934 bridge_channel_impart_signal(bridge_channel->chan);
1935 ast_bridge_discard_after_goto(bridge_channel->chan);
1936
1937 return NULL;
1938}
@ AST_BRIDGE_AFTER_CB_REASON_DEPART
void ast_bridge_discard_after_goto(struct ast_channel *chan)
Discard channel after bridge goto location.
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 1748 of file bridge.c.

1749{
1750 struct ast_datastore *datastore;
1751 struct bridge_channel_impart_ds_head *ds_head;
1752
1753 ast_channel_lock(chan);
1754
1756 if (!datastore) {
1758 if (!datastore) {
1759 ast_channel_unlock(chan);
1760 return -1;
1761 }
1762 ds_head = ast_calloc(1, sizeof(*ds_head));
1763 if (!ds_head) {
1764 ast_channel_unlock(chan);
1765 ast_datastore_free(datastore);
1766 return -1;
1767 }
1768 datastore->data = ds_head;
1769 ast_channel_datastore_add(chan, datastore);
1770 } else {
1771 ds_head = datastore->data;
1772 ast_assert(ds_head != NULL);
1773 }
1774
1775 AST_LIST_INSERT_TAIL(ds_head, cond, node);
1776
1777 ast_channel_unlock(chan);
1778 return 0;
1779}
#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:1731
int ast_channel_datastore_add(struct ast_channel *chan, struct ast_datastore *datastore)
Add a datastore to a channel.
Definition channel.c:2376
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:2390
#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
Structure for a data store object.
Definition datastore.h:64
void * data
Definition datastore.h:66

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

1708{
1710 ast_free(doomed);
1711}
static void bridge_channel_impart_ds_head_signal(struct bridge_channel_impart_ds_head *ds_head)
Definition bridge.c:1693

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

1723{
1724 /*
1725 * Signal any waiting impart threads. The masquerade is going to kill
1726 * old_chan and we don't need to be waiting on new_chan.
1727 */
1729}

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

1694{
1695 if (ds_head) {
1697
1698 while ((cond = AST_LIST_REMOVE_HEAD(ds_head, node))) {
1699 ast_mutex_lock(&cond->lock);
1700 cond->done = 1;
1701 ast_cond_signal(&cond->cond);
1702 ast_mutex_unlock(&cond->lock);
1703 }
1704 }
1705}
#define AST_LIST_REMOVE_HEAD(head, field)
Removes and returns the head entry from a list.
#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 1800 of file bridge.c.

1801{
1802 ast_mutex_lock(&cond->lock);
1803 while (!cond->done) {
1804 ast_cond_wait(&cond->cond, &cond->lock);
1805 }
1806 ast_mutex_unlock(&cond->lock);
1807}
#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 1941 of file bridge.c.

1942{
1943 struct ast_bridge_channel *bridge_channel = data;
1944 struct ast_channel *chan;
1945
1946 if (bridge_channel->callid) {
1948 }
1949
1951 chan = bridge_channel->chan;
1952
1953 /* cleanup */
1954 ast_channel_lock(chan);
1956 ast_channel_unlock(chan);
1957 /* Lock here for ast_bridge_channel_get_chan */
1961 /* If bridge_channel->swap is not NULL then the join failed. */
1962 ao2_t_cleanup(bridge_channel->swap, "Bridge complete: Independent impart join failed");
1966
1968
1970 /* If join failed there will be impart threads waiting. */
1973 return NULL;
1974}
void ast_bridge_run_after_goto(struct ast_channel *chan)
Run a PBX on any after bridge goto location.
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 2221 of file bridge.c.

2222{
2223 struct ast_bridge_features *features = bridge_channel->features;
2224 struct ast_bridge_hook *hook;
2225 struct ao2_iterator iter;
2226
2227 /* Run any moving hooks. */
2228 iter = ao2_iterator_init(features->other_hooks, 0);
2229 for (; (hook = ao2_iterator_next(&iter)); ao2_ref(hook, -1)) {
2230 int remove_me;
2232
2233 if (hook->type != AST_BRIDGE_HOOK_TYPE_MOVE) {
2234 continue;
2235 }
2237 remove_me = move_cb(bridge_channel, hook->hook_pvt, src, dst);
2238 if (remove_me) {
2239 ast_debug(1, "Move detection hook %p is being removed from %p(%s)\n",
2240 hook, bridge_channel, ast_channel_name(bridge_channel->chan));
2241 ao2_unlink(features->other_hooks, hook);
2242 }
2243 }
2244 ao2_iterator_destroy(&iter);
2245}
#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 5739 of file bridge.c.

5740{
5741 ast_manager_unregister("BridgeTechnologyList");
5742 ast_manager_unregister("BridgeTechnologySuspend");
5743 ast_manager_unregister("BridgeTechnologyUnsuspend");
5745 ao2_container_unregister("bridges");
5746
5748 bridges = NULL;
5751}
void ast_cli_unregister_multiple(void)
Definition ael_main.c:408
void ao2_container_unregister(const char *name)
Unregister a container for CLI stats and integrity check.
int ast_manager_unregister(const char *action)
Unregister a registered manager command.
Definition manager.c:7716

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

505{
506 struct ast_bridge_channel *bridge_channel;
507
508 if (bridge->dissolved) {
509 /*
510 * No sense in completing the join on channels for a dissolved
511 * bridge. They are just going to be removed soon anyway.
512 * However, we do have reason to abort here because the bridge
513 * technology may not be able to handle the number of channels
514 * still in the bridge.
515 */
516 return;
517 }
518
519 AST_LIST_TRAVERSE(&bridge->channels, bridge_channel, entry) {
521 if (!bridge_channel->just_joined) {
522 continue;
523 }
524 bridge_channel_complete_join(bridge, bridge_channel);
525 }
526}
static void bridge_channel_complete_join(struct ast_bridge *bridge, struct ast_bridge_channel *bridge_channel)
Definition bridge.c:463
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 337 of file bridge.c.

338{
339 struct ast_bridge_channel *bridge_channel;
340 struct ast_frame action = {
343 };
344
345 if (bridge->dissolved) {
346 ast_debug(1, "Bridge " BRIDGE_PRINTF_SPEC ": already dissolved\n",
347 BRIDGE_PRINTF_VARS(bridge));
348 return;
349 }
350 bridge->dissolved = 1;
351
352 if (cause <= 0) {
354 }
355 bridge->cause = cause;
356
357 ast_debug(1, "Bridge " BRIDGE_PRINTF_SPEC ": dissolving with cause %d(%s)\n",
358 BRIDGE_PRINTF_VARS(bridge), cause, ast_cause2str(cause));
359
360 AST_LIST_TRAVERSE(&bridge->channels, bridge_channel, entry) {
361 ast_debug(1, "Bridge " BRIDGE_PRINTF_SPEC ": kicking channel %s\n",
362 BRIDGE_PRINTF_VARS(bridge),
363 ast_channel_name(bridge_channel->chan));
364 ast_bridge_channel_leave_bridge(bridge_channel,
366 }
367
368 /* Must defer dissolving bridge because it is already locked. */
369 ast_bridge_queue_action(bridge, &action);
370 ast_debug(1, "Bridge " BRIDGE_PRINTF_SPEC ": DEFERRED_DISSOLVING queued. current refcound: %d\n",
371 BRIDGE_PRINTF_VARS(bridge), ao2_ref(bridge, 0));
372
373}
int ast_bridge_queue_action(struct ast_bridge *bridge, struct ast_frame *action)
Put an action onto the specified bridge.
Definition bridge.c:325
const char * ast_cause2str(int cause) attribute_pure
Gives the string form of a given cause code.
Definition channel.c:613
@ AST_FRAME_BRIDGE_ACTION
int cause
Definition bridge.h:392
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 385 of file bridge.c.

386{
387 if (bridge->dissolved) {
388 return;
389 }
390
391 if (bridge_channel->features->usable
392 && ast_test_flag(&bridge_channel->features->feature_flags,
394 /* The stolen channel controlled the bridge it was stolen from. */
395 bridge_dissolve(bridge, 0);
396 return;
397 }
398 if (bridge->num_channels < 2
400 /*
401 * The stolen channel has not left enough channels to keep the
402 * bridge alive. Assume the stolen channel hung up.
403 */
404 bridge_dissolve(bridge, 0);
405 return;
406 }
407}

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

2249{
2250 struct ast_bridge_channel *bridge_channel;
2251 unsigned int idx;
2252
2253 ast_debug(1, "Merging bridge %s into bridge %s\n",
2254 src_bridge->uniqueid, dst_bridge->uniqueid);
2255
2256 ast_bridge_publish_merge(dst_bridge, src_bridge);
2257
2258 /*
2259 * Move channels from src_bridge over to dst_bridge.
2260 *
2261 * We must use AST_LIST_TRAVERSE_SAFE_BEGIN() because
2262 * bridge_channel_internal_pull() alters the list we are traversing.
2263 */
2264 AST_LIST_TRAVERSE_SAFE_BEGIN(&src_bridge->channels, bridge_channel, entry) {
2265 if (bridge_channel->state != BRIDGE_CHANNEL_STATE_WAIT) {
2266 /*
2267 * The channel is already leaving let it leave normally because
2268 * pulling it may delete hooks that should run for this channel.
2269 */
2270 continue;
2271 }
2272 if (ast_test_flag(&bridge_channel->features->feature_flags,
2274 continue;
2275 }
2276
2277 if (kick_me) {
2278 for (idx = 0; idx < num_kick; ++idx) {
2279 if (bridge_channel == kick_me[idx]) {
2280 ast_bridge_channel_leave_bridge(bridge_channel,
2282 break;
2283 }
2284 }
2285 }
2286 bridge_channel_internal_pull(bridge_channel);
2287 if (bridge_channel->state != BRIDGE_CHANNEL_STATE_WAIT) {
2288 /*
2289 * The channel died as a result of being pulled or it was
2290 * kicked. Leave it pointing to the original bridge.
2291 */
2292 continue;
2293 }
2294
2295 bridge_channel_moving(bridge_channel, bridge_channel->bridge, dst_bridge);
2296
2297 /* Point to new bridge.*/
2298 bridge_channel_change_bridge(bridge_channel, dst_bridge);
2299
2300 if (bridge_channel_internal_push(bridge_channel)) {
2301 ast_bridge_features_remove(bridge_channel->features,
2303 ast_bridge_channel_leave_bridge(bridge_channel,
2305 }
2306 }
2308
2309 if (kick_me) {
2310 /*
2311 * Now we can kick any channels in the dst_bridge without
2312 * potentially dissolving the bridge.
2313 */
2314 for (idx = 0; idx < num_kick; ++idx) {
2315 bridge_channel = kick_me[idx];
2316 ast_bridge_channel_lock(bridge_channel);
2317 if (bridge_channel->state == BRIDGE_CHANNEL_STATE_WAIT) {
2320 bridge_channel_internal_pull(bridge_channel);
2321 }
2322 ast_bridge_channel_unlock(bridge_channel);
2323 }
2324 }
2325
2326 bridge_reconfigured(dst_bridge, !optimized);
2327 bridge_reconfigured(src_bridge, !optimized);
2328
2329 ast_debug(1, "Merged bridge %s into bridge %s\n",
2330 src_bridge->uniqueid, dst_bridge->uniqueid);
2331}
static void bridge_channel_change_bridge(struct ast_bridge_channel *bridge_channel, struct ast_bridge *new_bridge)
Definition bridge.c:2206
static void bridge_channel_moving(struct ast_bridge_channel *bridge_channel, struct ast_bridge *src, struct ast_bridge *dst)
Definition bridge.c:2221
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
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 2513 of file bridge.c.

2515{
2516 struct ast_bridge *orig_bridge;
2517 int was_in_bridge;
2518 int res = 0;
2519
2520 if (bridge_channel->swap) {
2521 ast_debug(1, "Moving %p(%s) into bridge %s swapping with %s\n",
2522 bridge_channel, ast_channel_name(bridge_channel->chan), dst_bridge->uniqueid,
2523 ast_channel_name(bridge_channel->swap));
2524 } else {
2525 ast_debug(1, "Moving %p(%s) into bridge %s\n",
2526 bridge_channel, ast_channel_name(bridge_channel->chan), dst_bridge->uniqueid);
2527 }
2528
2529 orig_bridge = bridge_channel->bridge;
2530 was_in_bridge = bridge_channel->in_bridge;
2531
2532 bridge_channel_internal_pull(bridge_channel);
2533 if (bridge_channel->state != BRIDGE_CHANNEL_STATE_WAIT) {
2534 /*
2535 * The channel died as a result of being pulled. Leave it
2536 * pointing to the original bridge.
2537 *
2538 * Clear out the swap channel pointer. A ref is not held
2539 * by bridge_channel->swap at this point.
2540 */
2541 bridge_channel->swap = NULL;
2542 bridge_reconfigured(orig_bridge, 0);
2543 return -1;
2544 }
2545
2546 /* Point to new bridge.*/
2547 ao2_ref(orig_bridge, +1);/* Keep a ref in case the push fails. */
2548 bridge_channel_change_bridge(bridge_channel, dst_bridge);
2549
2550 bridge_channel_moving(bridge_channel, orig_bridge, dst_bridge);
2551
2552 if (bridge_channel_internal_push_full(bridge_channel, optimized)) {
2553 /* Try to put the channel back into the original bridge. */
2554 ast_bridge_features_remove(bridge_channel->features,
2556 if (attempt_recovery && was_in_bridge) {
2557 /* Point back to original bridge. */
2558 bridge_channel_change_bridge(bridge_channel, orig_bridge);
2559
2560 if (bridge_channel_internal_push(bridge_channel)) {
2561 ast_bridge_features_remove(bridge_channel->features,
2563 ast_bridge_channel_leave_bridge(bridge_channel,
2565 }
2566 } else {
2567 ast_bridge_channel_leave_bridge(bridge_channel,
2569 bridge_channel_settle_owed_events(orig_bridge, bridge_channel);
2570 }
2571 res = -1;
2572 } else if (!optimized) {
2573 bridge_channel_settle_owed_events(orig_bridge, bridge_channel);
2574 }
2575
2576 bridge_reconfigured(dst_bridge, !optimized);
2577 bridge_reconfigured(orig_bridge, !optimized);
2578 ao2_ref(orig_bridge, -1);
2579 return res;
2580}
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 3748 of file bridge.c.

3749{
3750 const struct ast_bridge_hook_dtmf *hook_left = obj_left;
3751 const struct ast_bridge_hook_dtmf *hook_right = obj_right;
3752 const char *right_key = obj_right;
3753 int cmp;
3754
3755 switch (flags & (OBJ_POINTER | OBJ_KEY | OBJ_PARTIAL_KEY)) {
3756 default:
3757 case OBJ_POINTER:
3758 right_key = hook_right->dtmf.code;
3759 /* Fall through */
3760 case OBJ_KEY:
3761 cmp = strcasecmp(hook_left->dtmf.code, right_key);
3762 break;
3763 case OBJ_PARTIAL_KEY:
3764 cmp = strncasecmp(hook_left->dtmf.code, right_key, strlen(right_key));
3765 break;
3766 }
3767 return cmp;
3768}
#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 652 of file bridge.c.

653{
654 struct ast_frame *action;
655
656 while ((action = AST_LIST_REMOVE_HEAD(&bridge->action_queue, frame_list))) {
657 switch (action->frametype) {
659 bridge_action_bridge(bridge, action);
660 break;
661 default:
662 /* Unexpected deferred frame type. Should never happen. */
663 ast_assert(0);
664 break;
665 }
666 ast_frfree(action);
667 }
668}
static void bridge_action_bridge(struct ast_bridge *bridge, struct ast_frame *action)
Definition bridge.c:618
#define ast_frfree(fr)
struct ast_bridge::@199 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 3348 of file bridge.c.

3349{
3350 struct ast_bridge_hook *hook = vhook;
3351
3352 if (hook->destructor) {
3353 hook->destructor(hook->hook_pvt);
3354 }
3355}

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

3376{
3377 struct ast_bridge_hook *hook;
3378
3379 /* Allocate new hook and setup it's basic variables */
3381 if (hook) {
3382 hook->callback = callback;
3383 hook->destructor = destructor;
3384 hook->hook_pvt = hook_pvt;
3386 }
3387
3388 return hook;
3389}
#define ao2_alloc_options(data_size, destructor_fn, options)
Definition astobj2.h:404
static void bridge_hook_destroy(void *vhook)
Definition bridge.c:3348
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 1976 of file bridge.c.

1982{
1983 int res = 0;
1984 struct ast_bridge_channel *bridge_channel;
1985
1986 /* Imparted channels cannot have a PBX. */
1987 if (ast_channel_pbx(chan)) {
1988 ast_log(AST_LOG_WARNING, "Channel %s has a PBX thread and cannot be imparted into bridge %s\n",
1991 return -1;
1992 }
1993
1994 /* Supply an empty features structure if the caller did not. */
1995 if (!features) {
1997 if (!features) {
1998 return -1;
1999 }
2000 }
2001
2002 /* Try to allocate a structure for the bridge channel */
2003 bridge_channel = bridge_channel_internal_alloc(bridge);
2004 if (!bridge_channel) {
2006 return -1;
2007 }
2008
2011 ast_log(AST_LOG_NOTICE, "Channel %s is a zombie and cannot be imparted into bridge %s\n",
2013 res = -1;
2014 } else {
2016 }
2018 bridge_channel->chan = chan;
2019 bridge_channel->swap = ao2_t_bump(swap, "Setting up bridge impart");
2020 bridge_channel->features = features;
2021 bridge_channel->inhibit_colp = !!(flags & AST_BRIDGE_IMPART_INHIBIT_JOIN_COLP);
2022 bridge_channel->depart_wait =
2024 bridge_channel->callid = ast_read_threadstorage_callid();
2025
2026 /* allow subclass to peek at swap channel before it can hangup */
2027 if (bridge->v_table->push_peek && !res) {
2028 struct ast_bridge_channel *bcswap = NULL;
2029
2031 if (bridge_channel->swap) {
2032 bcswap = bridge_find_channel(bridge, bridge_channel->swap);
2033 }
2034 res = bridge->v_table->push_peek(bridge, bridge_channel, bcswap);
2036 }
2037
2038 /* Actually create the thread that will handle the channel */
2039 if (!res) {
2041 }
2042 if (!res) {
2044 res = ast_pthread_create_detached(&bridge_channel->thread, NULL,
2045 bridge_channel_ind_thread, bridge_channel);
2046 } else {
2047 res = ast_pthread_create(&bridge_channel->thread, NULL,
2048 bridge_channel_depart_thread, bridge_channel);
2049 }
2050
2051 if (!res) {
2053 }
2054 }
2055
2056 if (res) {
2057 /* cleanup */
2061 /* Lock here for ast_bridge_channel_get_chan */
2062 ao2_lock(bridge_channel);
2063 bridge_channel->chan = NULL;
2064 ao2_unlock(bridge_channel);
2065 ao2_t_cleanup(bridge_channel->swap, "Bridge complete: Impart failed");
2066 bridge_channel->swap = NULL;
2067 ast_bridge_features_destroy(bridge_channel->features);
2068 bridge_channel->features = NULL;
2069
2070 ao2_ref(bridge_channel, -1);
2071 return -1;
2072 }
2073
2074 return 0;
2075}
#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:1800
struct ast_bridge_features * ast_bridge_features_new(void)
Allocate a new bridge features struct.
Definition bridge.c:3892
static void * bridge_channel_depart_thread(void *data)
Thread responsible for imparted bridged channels to be departed.
Definition bridge.c:1910
static int bridge_channel_impart_add(struct ast_channel *chan, struct bridge_channel_impart_cond *cond)
Definition bridge.c:1748
static void * bridge_channel_ind_thread(void *data)
Thread responsible for independent imparted bridged channels.
Definition bridge.c:1941
@ AST_BRIDGE_IMPART_CHAN_DEPARTABLE
Definition bridge.h:598
@ AST_BRIDGE_IMPART_CHAN_MASK
Definition bridge.h:596
@ AST_BRIDGE_IMPART_INHIBIT_JOIN_COLP
Definition bridge.h:602
#define AST_LOG_WARNING
ast_callid ast_read_threadstorage_callid(void)
extracts the callid from the thread
Definition logger.c:2268
#define AST_LOG_NOTICE
#define ast_pthread_create(a, b, c, d)
Definition utils.h:624
#define ast_pthread_create_detached(a, b, c, d)
Definition utils.h:628

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

5161{
5162 struct bridge_manager_controller *manager;
5163
5164 manager = ao2_alloc(sizeof(*manager), bridge_manager_destroy);
5165 if (!manager) {
5166 /* Well. This isn't good. */
5167 return NULL;
5168 }
5169 ast_cond_init(&manager->cond, NULL);
5171
5172 /* Create the bridge manager thread. */
5173 if (ast_pthread_create(&manager->thread, NULL, bridge_manager_thread, manager)) {
5174 /* Well. This isn't good either. */
5175 manager->thread = AST_PTHREADT_NULL;
5176 ao2_ref(manager, -1);
5177 manager = NULL;
5178 }
5179
5180 return manager;
5181}
static void bridge_manager_destroy(void *obj)
Definition bridge.c:5128
static void * bridge_manager_thread(void *data)
Definition bridge.c:5095
#define AST_PTHREADT_NULL
Definition lock.h:73
struct bridge_manager_controller::@328 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 5128 of file bridge.c.

5129{
5130 struct bridge_manager_controller *manager = obj;
5132
5133 if (manager->thread != AST_PTHREADT_NULL) {
5134 /* Stop the manager thread. */
5135 ao2_lock(manager);
5136 manager->stop = 1;
5137 ast_cond_signal(&manager->cond);
5138 ao2_unlock(manager);
5139 ast_debug(1, "Waiting for bridge manager thread to die.\n");
5140 pthread_join(manager->thread, NULL);
5141 }
5142
5143 /* Destroy the service request queue. */
5144 while ((request = AST_LIST_REMOVE_HEAD(&manager->service_requests, node))) {
5145 ao2_ref(request->bridge, -1);
5147 }
5148
5149 ast_cond_destroy(&manager->cond);
5150}

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

5079{
5080 ast_bridge_lock(bridge);
5081 if (bridge->callid) {
5083 }
5084
5085 /* Do any pending bridge actions. */
5086 bridge_handle_actions(bridge);
5087 ast_bridge_unlock(bridge);
5088}
static void bridge_handle_actions(struct ast_bridge *bridge)
Definition bridge.c:652
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:367

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

209{
211
213 if (bridge_manager->stop) {
215 return;
216 }
217
218 /* Create the service request. */
219 request = ast_calloc(1, sizeof(*request));
220 if (!request) {
221 /* Well. This isn't good. */
223 return;
224 }
225 ao2_ref(bridge, +1);
226 request->bridge = bridge;
227
228 /* Put request into the queue and wake the bridge manager. */
232}
struct ast_bridge * bridge
Definition bridge.c:179

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

5096{
5097 struct bridge_manager_controller *manager = data;
5099
5100 ao2_lock(manager);
5101 while (!manager->stop) {
5103 if (!request) {
5104 ast_cond_wait(&manager->cond, ao2_object_get_lockaddr(manager));
5105 continue;
5106 }
5107 ao2_unlock(manager);
5108
5109 /* Service the bridge. */
5111 ao2_ref(request->bridge, -1);
5113
5114 ao2_lock(manager);
5115 }
5116 ao2_unlock(manager);
5117
5118 return NULL;
5119}
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:5078

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

2353{
2354 struct merge_direction merge = { NULL, NULL };
2355 int bridge1_priority;
2356 int bridge2_priority;
2357
2358 if (!ast_test_flag(&bridge1->feature_flags,
2360 && !ast_test_flag(&bridge2->feature_flags,
2362 /*
2363 * Can merge either way. Merge to the higher priority merge
2364 * bridge. Otherwise merge to the larger bridge.
2365 */
2366 bridge1_priority = bridge1->v_table->get_merge_priority(bridge1);
2367 bridge2_priority = bridge2->v_table->get_merge_priority(bridge2);
2368 if (bridge2_priority < bridge1_priority) {
2369 merge.dest = bridge1;
2370 merge.src = bridge2;
2371 } else if (bridge1_priority < bridge2_priority) {
2372 merge.dest = bridge2;
2373 merge.src = bridge1;
2374 } else {
2375 /* Merge to the larger bridge. */
2376 if (bridge2->num_channels <= bridge1->num_channels) {
2377 merge.dest = bridge1;
2378 merge.src = bridge2;
2379 } else {
2380 merge.dest = bridge2;
2381 merge.src = bridge1;
2382 }
2383 }
2386 /* Can merge only one way. */
2387 merge.dest = bridge1;
2388 merge.src = bridge2;
2391 /* Can merge only one way. */
2392 merge.dest = bridge2;
2393 merge.src = bridge1;
2394 }
2395
2396 return merge;
2397}
@ AST_BRIDGE_FLAG_MERGE_INHIBIT_TO
@ AST_BRIDGE_FLAG_MERGE_INHIBIT_FROM
struct ast_bridge * src
Definition bridge.c:2337
struct ast_bridge * dest
Definition bridge.c:2335

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

3201{
3202 int new_request;
3203
3204 new_request = bridge->inhibit_merge + request;
3205 ast_assert(0 <= new_request);
3206 bridge->inhibit_merge = new_request;
3207}

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

2416{
2417 struct merge_direction merge;
2418 struct ast_bridge_channel **kick_them = NULL;
2419
2420 /* Sanity check. */
2421 ast_assert(dst_bridge && src_bridge && dst_bridge != src_bridge && (!num_kick || kick_me));
2422
2423 if (dst_bridge->dissolved || src_bridge->dissolved) {
2424 ast_debug(1, "Can't merge bridges %s and %s, at least one bridge is dissolved.\n",
2425 src_bridge->uniqueid, dst_bridge->uniqueid);
2426 return -1;
2427 }
2430 ast_debug(1, "Can't merge bridges %s and %s, masquerade only.\n",
2431 src_bridge->uniqueid, dst_bridge->uniqueid);
2432 return -1;
2433 }
2434 if (dst_bridge->inhibit_merge || src_bridge->inhibit_merge) {
2435 ast_debug(1, "Can't merge bridges %s and %s, merging temporarily inhibited.\n",
2436 src_bridge->uniqueid, dst_bridge->uniqueid);
2437 return -1;
2438 }
2439
2440 if (merge_best_direction) {
2441 merge = bridge_merge_determine_direction(dst_bridge, src_bridge);
2442 } else {
2443 merge.dest = dst_bridge;
2444 merge.src = src_bridge;
2445 }
2446
2447 if (!merge.dest
2448 || ast_test_flag(&merge.dest->feature_flags, AST_BRIDGE_FLAG_MERGE_INHIBIT_TO)
2449 || ast_test_flag(&merge.src->feature_flags, AST_BRIDGE_FLAG_MERGE_INHIBIT_FROM)) {
2450 ast_debug(1, "Can't merge bridges %s and %s, merging inhibited.\n",
2451 src_bridge->uniqueid, dst_bridge->uniqueid);
2452 return -1;
2453 }
2454 if (merge.src->num_channels < 2) {
2455 /*
2456 * For a two party bridge, a channel may be temporarily removed
2457 * from the source bridge or the initial bridge members have not
2458 * joined yet.
2459 */
2460 ast_debug(1, "Can't merge bridge %s into bridge %s, not enough channels in source bridge.\n",
2461 merge.src->uniqueid, merge.dest->uniqueid);
2462 return -1;
2463 }
2464 if (2 + num_kick < merge.dest->num_channels + merge.src->num_channels
2465 && !(merge.dest->technology->capabilities & AST_BRIDGE_CAPABILITY_MULTIMIX)
2466 && (!ast_test_flag(&merge.dest->feature_flags, AST_BRIDGE_FLAG_SMART)
2467 || !(merge.dest->allowed_capabilities & AST_BRIDGE_CAPABILITY_MULTIMIX))) {
2468 ast_debug(1, "Can't merge bridge %s into bridge %s, multimix is needed and it cannot be acquired.\n",
2469 merge.src->uniqueid, merge.dest->uniqueid);
2470 return -1;
2471 }
2472
2473 if (num_kick) {
2474 unsigned int num_to_kick = 0;
2475 unsigned int idx;
2476
2477 kick_them = ast_alloca(num_kick * sizeof(*kick_them));
2478 for (idx = 0; idx < num_kick; ++idx) {
2479 kick_them[num_to_kick] = bridge_find_channel(merge.src, kick_me[idx]);
2480 if (!kick_them[num_to_kick]) {
2481 kick_them[num_to_kick] = bridge_find_channel(merge.dest, kick_me[idx]);
2482 }
2483 if (kick_them[num_to_kick]) {
2484 ++num_to_kick;
2485 }
2486 }
2487
2488 if (num_to_kick != num_kick) {
2489 ast_debug(1, "Can't merge bridge %s into bridge %s, at least one kicked channel is not in either bridge.\n",
2490 merge.src->uniqueid, merge.dest->uniqueid);
2491 return -1;
2492 }
2493 }
2494
2495 bridge_do_merge(merge.dest, merge.src, kick_them, num_kick, 0);
2496 return 0;
2497}
#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:2247
static struct merge_direction bridge_merge_determine_direction(struct ast_bridge *bridge1, struct ast_bridge *bridge2)
Definition bridge.c:2352
@ 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 2598 of file bridge.c.

2599{
2600 struct ast_bridge_channel *bridge_channel;
2601
2602 if (dst_bridge->dissolved || src_bridge->dissolved) {
2603 ast_debug(1, "Can't move channel %s from bridge %s into bridge %s, at least one bridge is dissolved.\n",
2604 ast_channel_name(chan), src_bridge->uniqueid, dst_bridge->uniqueid);
2605 return -1;
2606 }
2609 ast_debug(1, "Can't move channel %s from bridge %s into bridge %s, masquerade only.\n",
2610 ast_channel_name(chan), src_bridge->uniqueid, dst_bridge->uniqueid);
2611 return -1;
2612 }
2613 if (dst_bridge->inhibit_merge || src_bridge->inhibit_merge) {
2614 ast_debug(1, "Can't move channel %s from bridge %s into bridge %s, temporarily inhibited.\n",
2615 ast_channel_name(chan), src_bridge->uniqueid, dst_bridge->uniqueid);
2616 return -1;
2617 }
2618
2619 bridge_channel = bridge_find_channel(src_bridge, chan);
2620 if (!bridge_channel) {
2621 ast_debug(1, "Can't move channel %s from bridge %s into bridge %s, channel not in bridge.\n",
2622 ast_channel_name(chan), src_bridge->uniqueid, dst_bridge->uniqueid);
2623 return -1;
2624 }
2625 if (bridge_channel->state != BRIDGE_CHANNEL_STATE_WAIT) {
2626 ast_debug(1, "Can't move channel %s from bridge %s into bridge %s, channel leaving bridge.\n",
2627 ast_channel_name(chan), src_bridge->uniqueid, dst_bridge->uniqueid);
2628 return -1;
2629 }
2630 if (ast_test_flag(&bridge_channel->features->feature_flags,
2632 ast_debug(1, "Can't move channel %s from bridge %s into bridge %s, channel immovable.\n",
2633 ast_channel_name(chan), src_bridge->uniqueid, dst_bridge->uniqueid);
2634 return -1;
2635 }
2636
2637 if (swap) {
2638 struct ast_bridge_channel *bridge_channel_swap;
2639
2640 bridge_channel_swap = bridge_find_channel(dst_bridge, swap);
2641 if (!bridge_channel_swap) {
2642 ast_debug(1, "Can't move channel %s from bridge %s into bridge %s, swap channel %s not in bridge.\n",
2643 ast_channel_name(chan), src_bridge->uniqueid, dst_bridge->uniqueid,
2645 return -1;
2646 }
2647 if (bridge_channel_swap->state != BRIDGE_CHANNEL_STATE_WAIT) {
2648 ast_debug(1, "Can't move channel %s from bridge %s into bridge %s, swap channel %s leaving bridge.\n",
2649 ast_channel_name(chan), src_bridge->uniqueid, dst_bridge->uniqueid,
2651 return -1;
2652 }
2653 }
2654
2655 bridge_channel->swap = swap;
2656 return bridge_do_move(dst_bridge, bridge_channel, attempt_recovery, 0);
2657}
int bridge_do_move(struct ast_bridge *dst_bridge, struct ast_bridge_channel *bridge_channel, int attempt_recovery, unsigned int optimized)
Definition bridge.c:2513

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

3446{
3447 struct ast_bridge_hook *hook;
3448 int res;
3449
3450 /* Allocate new hook and setup it's various variables */
3451 hook = bridge_hook_generic(sizeof(*hook), callback, hook_pvt, destructor,
3452 remove_flags);
3453 if (!hook) {
3454 return -1;
3455 }
3456 hook->type = type;
3457
3458 /* Once done we put it in the container. */
3459 res = ao2_link(features->other_hooks, hook) ? 0 : -1;
3460 if (res) {
3461 /*
3462 * Could not link the hook into the container.
3463 *
3464 * Remove the hook_pvt destructor call from the hook since we
3465 * are returning failure to install the hook.
3466 */
3467 hook->destructor = NULL;
3468 }
3469 ao2_ref(hook, -1);
3470
3471 return res;
3472}
static const char type[]

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

5724{
5725 struct ast_bridge *bridge = v_obj;
5726
5727 if (!bridge) {
5728 return;
5729 }
5730 prnt(where, "%s %s chans:%u",
5731 bridge->uniqueid, bridge->v_table->name, bridge->num_channels);
5732}

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

315{
316 ast_debug(1, "Bridge %s: queueing action type:%u sub:%d\n",
317 bridge->uniqueid, action->frametype, action->subclass.integer);
318
319 ast_bridge_lock(bridge);
321 ast_bridge_unlock(bridge);
323}
static void bridge_manager_service_req(struct ast_bridge *bridge)
Definition bridge.c:208

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

1603{
1604 if (!bridge->reconfigured) {
1605 return;
1606 }
1607 bridge->reconfigured = 0;
1609 && smart_bridge_operation(bridge)) {
1610 /* Smart bridge failed. */
1611 bridge_dissolve(bridge, 0);
1612 return;
1613 }
1614 bridge_complete_join(bridge);
1615
1616 if (bridge->dissolved) {
1617 return;
1618 }
1620 set_bridge_peer_vars(bridge);
1622
1623 if (colp_update) {
1625 }
1626}
static void check_bridge_play_sounds(struct ast_bridge *bridge)
Definition bridge.c:1292
static int smart_bridge_operation(struct ast_bridge *bridge)
Definition bridge.c:1061
static void bridge_reconfigured_connected_line_update(struct ast_bridge *bridge)
Definition bridge.c:415
static void bridge_complete_join(struct ast_bridge *bridge)
Definition bridge.c:504
static void set_bridge_peer_vars(struct ast_bridge *bridge)
Definition bridge.c:1585

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

416{
418 struct ast_bridge_channel *bridge_channel = AST_LIST_FIRST(&bridge->channels), *peer;
419 unsigned char data[1024];
420 size_t datalen;
421
422 if (!bridge_channel ||
424 !(peer = ast_bridge_channel_peer(bridge_channel)) ||
427 ast_check_hangup_locked(bridge_channel->chan) ||
428 ast_check_hangup_locked(peer->chan)) {
429 return;
430 }
431
433
434 ast_channel_lock(bridge_channel->chan);
436 ast_channel_unlock(bridge_channel->chan);
437
438 if ((datalen = ast_connected_line_build_data(data, sizeof(data), &connected, NULL)) != (size_t) -1) {
440 }
441
442 ast_channel_lock(peer->chan);
444 ast_channel_unlock(peer->chan);
445
446 if ((datalen = ast_connected_line_build_data(data, sizeof(data), &connected, NULL)) != (size_t) -1) {
448 }
449
451}
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.
static int connected
Definition cdr_pgsql.c:73
void ast_party_connected_line_free(struct ast_party_connected_line *doomed)
Destroy the connected line information contents.
Definition channel.c:2059
int ast_check_hangup_locked(struct ast_channel *chan)
Definition channel.c:460
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:8873
void ast_party_connected_line_init(struct ast_party_connected_line *init)
Initialize the given connected line structure.
Definition channel.c:2009
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:8469
struct ast_party_caller * ast_channel_caller(struct ast_channel *chan)
@ AST_CONTROL_CONNECTED_LINE
#define AST_LIST_FIRST(head)
Returns the first entry contained in a list.
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:731
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 731 of file bridge.c.

732{
733 if (bridge) {
735 /*
736 * Although bridge_base_init() should have already checked for
737 * an existing bridge with the same uniqueid, bridge_base_init()
738 * and bridge_register() are two separate public APIs so we need
739 * to check again here.
740 */
741 struct ast_bridge *existing = ast_bridge_find_by_id(bridge->uniqueid);
742 if (existing) {
743 ast_log(LOG_WARNING, "Bridge " BRIDGE_PRINTF_SPEC ": already registered\n",
744 BRIDGE_PRINTF_VARS(bridge));
745 ao2_ref(existing, -1);
746 ast_bridge_destroy(bridge, 0);
747 return NULL;
748 }
749 ast_debug(1, "Bridge " BRIDGE_PRINTF_SPEC ": registering\n",
750 BRIDGE_PRINTF_VARS(bridge));
751 bridge->construction_completed = 1;
752 ast_bridge_lock(bridge);
754 ast_bridge_unlock(bridge);
755 if (!ao2_link(bridges, bridge)) {
756 ast_log(LOG_WARNING, "Bridge " BRIDGE_PRINTF_SPEC ": failed to link\n",
757 BRIDGE_PRINTF_VARS(bridge));
758 ast_bridge_destroy(bridge, 0);
759 bridge = NULL;
760 }
761 }
762 return bridge;
763}
struct ast_bridge * ast_bridge_find_by_id(const char *bridge_id)
Find bridge by id.
Definition bridge.c:5221
unsigned int construction_completed
Definition bridge.h:398

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_set_ari_var_reportable()

static int bridge_set_ari_var_reportable ( struct ast_bridge bridge,
const char *  variable,
int  report_events 
)
static

Definition at line 1309 of file bridge.c.

1311{
1312 char *var_str;
1313
1314 if (ast_strlen_zero(variable)) {
1315 return -1;
1316 }
1317
1318 if (!report_events) {
1321 return 0;
1322 }
1323
1325 return 0; /* already present */
1326 }
1327
1328 var_str = ast_strdup(variable);
1329 if (!var_str) {
1330 return -1;
1331 }
1332
1333 if (AST_VECTOR_APPEND(&bridge->ari_reportable_variable_names, var_str)) {
1334 ast_free(var_str);
1335 return -1;
1336 }
1337
1338 return 0;
1339}
#define ast_strdup(str)
A wrapper for strdup()
Definition astmm.h:241
#define BV_NAME_CMP(var_str, name)
Compare a bridge variable name with a given name.
Definition bridge.c:161
#define AST_VECTOR_REMOVE_CMP_UNORDERED(vec, value, cmp, cleanup)
Remove an element from a vector that matches the given comparison.
Definition vector.h:499
#define AST_VECTOR_GET_CMP(vec, value, cmp)
Get an element from a vector that matches the given comparison.
Definition vector.h:742
#define AST_VECTOR_APPEND(vec, elem)
Append an element to a vector, growing the vector if needed.
Definition vector.h:267

References ast_bridge::ari_reportable_variable_names, ast_free, ast_strdup, ast_strlen_zero(), AST_VECTOR_APPEND, AST_VECTOR_GET_CMP, AST_VECTOR_REMOVE_CMP_UNORDERED, ast_bridge_channel::bridge, and BV_NAME_CMP.

Referenced by ast_bridge_set_variable().

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

5293{
5294 const char *uniqueid = obj;
5295 struct ast_cli_args *a = arg;
5296 struct ast_channel_snapshot *snapshot;
5297
5298 snapshot = ast_channel_snapshot_get_latest(uniqueid);
5299 if (!snapshot) {
5300 return 0;
5301 }
5302
5303 ast_cli(a->fd, "Channel: %s\n", snapshot->base->name);
5304 ao2_ref(snapshot, -1);
5305
5306 return 0;
5307}
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 5199 of file bridge.c.

5200{
5201 const struct ast_bridge *bridge_left = obj_left;
5202 const struct ast_bridge *bridge_right = obj_right;
5203 const char *right_key = obj_right;
5204 int cmp;
5205
5206 switch (flags & (OBJ_POINTER | OBJ_KEY | OBJ_PARTIAL_KEY)) {
5207 default:
5208 case OBJ_POINTER:
5209 right_key = bridge_right->uniqueid;
5210 /* Fall through */
5211 case OBJ_KEY:
5212 cmp = strcmp(bridge_left->uniqueid, right_key);
5213 break;
5214 case OBJ_PARTIAL_KEY:
5215 cmp = strncmp(bridge_left->uniqueid, right_key, strlen(right_key));
5216 break;
5217 }
5218 return cmp;
5219}

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

4779{
4780 struct ast_bridge_channel *bridged_to_source;
4781
4782 bridged_to_source = ast_bridge_channel_peer(source_bridge_channel);
4783 if (bridged_to_source
4784 && bridged_to_source->state == BRIDGE_CHANNEL_STATE_WAIT
4785 && !ast_test_flag(&bridged_to_source->features->feature_flags,
4787 bridged_to_source->swap = swap_channel;
4788 if (bridge_do_move(dest_bridge, bridged_to_source, 1, 0)) {
4790 }
4791 /* Must kick the source channel out of its bridge. */
4792 ast_bridge_channel_leave_bridge(source_bridge_channel,
4795 } else {
4797 }
4798}

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

591{
592 struct tech_deferred_destroy *deferred = action->data.ptr;
593 struct ast_bridge dummy_bridge = {
594 .technology = deferred->tech,
595 .tech_pvt = deferred->tech_pvt,
596 .creator = bridge->creator,
597 .name = bridge->name,
598 .uniqueid = bridge->uniqueid,
599 };
600
601 ast_debug(1, "Bridge %s: calling %s technology destructor (deferred, dummy)\n",
602 dummy_bridge.uniqueid, dummy_bridge.technology->name);
603 dummy_bridge.technology->destroy(&dummy_bridge);
604 ast_module_unref(dummy_bridge.technology->mod);
605}
#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:407
union ast_frame::@237 data
struct ast_bridge_technology * tech
Definition bridge.c:576

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

2900{
2901 int chan_priority;
2902 int peer_priority;
2903
2904 if (!ast_test_flag(&chan_bridge->feature_flags,
2907 && !ast_test_flag(&peer_bridge->feature_flags,
2910 /*
2911 * Can swap either way. Swap to the higher priority merge
2912 * bridge.
2913 */
2914 chan_priority = chan_bridge->v_table->get_merge_priority(chan_bridge);
2915 peer_priority = peer_bridge->v_table->get_merge_priority(peer_bridge);
2916 if (chan_bridge->num_channels == 2
2917 && chan_priority <= peer_priority) {
2918 return SWAP_TO_PEER_BRIDGE;
2919 } else if (peer_bridge->num_channels == 2
2920 && peer_priority <= chan_priority) {
2921 return SWAP_TO_CHAN_BRIDGE;
2922 }
2923 } else if (chan_bridge->num_channels == 2
2926 /* Can swap optimize only one way. */
2927 return SWAP_TO_PEER_BRIDGE;
2928 } else if (peer_bridge->num_channels == 2
2931 /* Can swap optimize only one way. */
2932 return SWAP_TO_CHAN_BRIDGE;
2933 }
2934
2935 return SWAP_PROHIBITED;
2936}
@ 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 4205 of file bridge.c.

4206{
4207 const struct ast_channel *left = obj;
4208 const struct ast_channel *right = arg;
4209 const char *right_name = arg;
4210 int cmp;
4211
4212 switch (flags & (OBJ_POINTER | OBJ_KEY | OBJ_PARTIAL_KEY)) {
4213 default:
4214 case OBJ_POINTER:
4215 right_name = ast_channel_name(right);
4216 /* Fall through */
4217 case OBJ_KEY:
4218 cmp = strcmp(ast_channel_name(left), right_name);
4219 break;
4220 case OBJ_PARTIAL_KEY:
4221 cmp = strncmp(ast_channel_name(left), right_name, strlen(right_name));
4222 break;
4223 }
4224 return cmp ? 0 : CMP_MATCH;
4225}
@ 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 4182 of file bridge.c.

4183{
4184 const struct ast_channel *chan = obj;
4185 const char *name = obj;
4186 int hash;
4187
4188 switch (flags & (OBJ_POINTER | OBJ_KEY | OBJ_PARTIAL_KEY)) {
4189 default:
4190 case OBJ_POINTER:
4191 name = ast_channel_name(chan);
4192 /* Fall through */
4193 case OBJ_KEY:
4194 hash = ast_str_hash(name);
4195 break;
4196 case OBJ_PARTIAL_KEY:
4197 /* Should never happen in hash callback. */
4198 ast_assert(0);
4199 hash = 0;
4200 break;
4201 }
4202 return hash;
4203}
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 1264 of file bridge.c.

1265{
1266 const char *play_file;
1267
1268 ast_channel_lock(bridge_channel->chan);
1269 play_file = pbx_builtin_getvar_helper(bridge_channel->chan, "BRIDGE_PLAY_SOUND");
1270 if (!ast_strlen_zero(play_file)) {
1272 pbx_builtin_setvar_helper(bridge_channel->chan, "BRIDGE_PLAY_SOUND", NULL);
1273 } else {
1274 play_file = NULL;
1275 }
1276 ast_channel_unlock(bridge_channel->chan);
1277
1278 if (play_file) {
1280 }
1281}
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 1292 of file bridge.c.

1293{
1294 struct ast_bridge_channel *bridge_channel;
1295
1296 AST_LIST_TRAVERSE(&bridge->channels, bridge_channel, entry) {
1297 check_bridge_play_sound(bridge_channel);
1298 }
1299}
static void check_bridge_play_sound(struct ast_bridge_channel *bridge_channel)
Definition bridge.c:1264

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

5238{
5241
5242 return NULL;
5243}
static int complete_bridge_live_search(void *obj, void *arg, int flags)
Definition bridge.c:5226
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 5226 of file bridge.c.

5227{
5228 struct ast_bridge *bridge = obj;
5229
5231 return CMP_STOP;
5232 }
5233
5234 return 0;
5235}
@ 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:2845

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

5394{
5395 struct ast_bridge *bridge;
5396 struct ast_bridge_channel *bridge_channel;
5397 int wordlen;
5398
5399 bridge = ast_bridge_find_by_id(bridge_name);
5400 if (!bridge) {
5401 return NULL;
5402 }
5403
5404 wordlen = strlen(word);
5405
5407 AST_LIST_TRAVERSE(&bridge->channels, bridge_channel, entry) {
5408 if (!strncasecmp(ast_channel_name(bridge_channel->chan), word, wordlen)) {
5409 if (ast_cli_completion_add(ast_strdup(ast_channel_name(bridge_channel->chan)))) {
5410 break;
5411 }
5412 }
5413 }
5415
5416 ao2_ref(bridge, -1);
5417
5418 return NULL;
5419}

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

5543{
5544 struct ast_bridge_technology *cur;
5545 int wordlen;
5546
5547 wordlen = strlen(word);
5550 if (!strncasecmp(cur->name, word, wordlen)) {
5552 break;
5553 }
5554 }
5555 }
5557
5558 return NULL;
5559}
#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, NULL, and ast_bridge_technology::start.

Referenced by handle_bridge_technology_suspend().

◆ destroy_bridge()

static void destroy_bridge ( void *  obj)
static

Definition at line 670 of file bridge.c.

671{
672 struct ast_bridge *bridge = obj;
673 struct ast_var_t *var;
674
675 ast_debug(1, "Bridge " BRIDGE_PRINTF_SPEC ": actually destroying %s bridge, nobody wants it anymore\n",
676 BRIDGE_PRINTF_VARS(bridge), bridge->v_table->name);
677
678 if (bridge->construction_completed) {
679 bridge_topics_destroy(bridge);
680 }
681
682 /* Do any pending actions in the context of destruction. */
683 ast_bridge_lock(bridge);
684 bridge_handle_actions(bridge);
685 ast_bridge_unlock(bridge);
686
687 /* There should not be any channels left in the bridge. */
689
690 ast_debug(1, "Bridge %s: calling %s bridge destructor\n",
691 bridge->uniqueid, bridge->v_table->name);
692 bridge->v_table->destroy(bridge);
693
694 /* Pass off the bridge to the technology to destroy if needed */
695 if (bridge->technology) {
696 ast_debug(1, "Bridge %s: calling %s technology stop\n",
697 bridge->uniqueid, bridge->technology->name);
698 if (bridge->technology->stop) {
699 ast_bridge_lock(bridge);
700 bridge->technology->stop(bridge);
701 ast_bridge_unlock(bridge);
702 }
703 ast_debug(1, "Bridge %s: calling %s technology destructor\n",
704 bridge->uniqueid, bridge->technology->name);
705 if (bridge->technology->destroy) {
706 bridge->technology->destroy(bridge);
707 }
709 bridge->technology = NULL;
710 }
711
713
714 bridge->callid = 0;
715
716 cleanup_video_mode(bridge);
717
718 ast_debug(1, "Bridge " BRIDGE_PRINTF_SPEC ": destroyed\n",
719 BRIDGE_PRINTF_VARS(bridge));
722 bridge->current_snapshot = NULL;
723 while ((var = AST_LIST_REMOVE_HEAD(&bridge->bridgevars, entries))) {
725 }
729}
#define AST_LIST_EMPTY(head)
Checks whether the specified list contains any entries.
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:412
#define AST_VECTOR_RESET(vec, cleanup)
Reset vector.
Definition vector.h:636
#define AST_VECTOR_FREE(vec)
Deallocates this vector.
Definition vector.h:185

References ao2_cleanup, ast_bridge::ari_reportable_variable_names, ast_assert, ast_bridge_lock, ast_bridge_unlock, ast_debug, ast_free, AST_LIST_EMPTY, AST_LIST_HEAD_INIT_NOLOCK, AST_LIST_REMOVE_HEAD, ast_module_unref, ast_string_field_free_memory, ast_var_delete(), AST_VECTOR_FREE, AST_VECTOR_RESET, bridge_handle_actions(), BRIDGE_PRINTF_SPEC, BRIDGE_PRINTF_VARS, bridge_topics_destroy(), ast_bridge::bridgevars, 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_var_t::entries, 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, ast_bridge::v_table, and var.

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

1469{
1470 int need_separator = 0;
1471 unsigned int idx;
1472 const char *src;
1473 char *pos;
1474
1475 pos = buf;
1476 for (idx = 0; idx < num_names; ++idx) {
1477 if (idx == cur_idx) {
1478 continue;
1479 }
1480
1481 if (need_separator) {
1482 *pos++ = ',';
1483 }
1484 need_separator = 1;
1485
1486 /* Copy name into buffer. */
1487 src = names[idx];
1488 while (*src) {
1489 *pos++ = *src++;
1490 }
1491 }
1492 *pos = '\0';
1493}
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 529 of file bridge.c.

530{
533
536 if (current->suspended) {
537 ast_debug(2, "Bridge technology %s is suspended. Skipping.\n",
538 current->name);
539 continue;
540 }
541 if (!(current->capabilities & capabilities)) {
542 ast_debug(2, "Bridge technology %s does not have any capabilities we want.\n",
543 current->name);
544 continue;
545 }
546 if (best && current->preference <= best->preference) {
547 ast_debug(2, "Bridge technology %s has less preference than %s (%u <= %u). Skipping.\n",
548 current->name, best->name, current->preference, best->preference);
549 continue;
550 }
551 if (current->compatible && !current->compatible(bridge)) {
552 ast_debug(2, "Bridge technology %s is not compatible with properties of existing bridge.\n",
553 current->name);
554 continue;
555 }
556 if (!ast_module_running_ref(current->mod)) {
557 ast_debug(2, "Bridge technology %s is not running, skipping.\n", current->name);
558 continue;
559 }
560 if (best) {
562 }
563 best = current;
564 }
565
566 if (best) {
567 ast_debug(1, "Chose bridge technology %s\n", best->name);
568 }
569
571
572 return best;
573}
#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, NULL, and ast_bridge_technology::start.

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

4392{
4393 struct ao2_iterator channel_iter;
4394 struct ast_channel *transferee;
4395
4396 for (channel_iter = ao2_iterator_init(channels, 0);
4397 (transferee = ao2_iterator_next(&channel_iter));
4398 ao2_cleanup(transferee)) {
4399 if (transferee != transferer) {
4400 break;
4401 }
4402 }
4403
4404 ao2_iterator_destroy(&channel_iter);
4405 return transferee;
4406}

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

5422{
5423 static const char * const completions[] = { "all", NULL };
5424 struct ast_bridge *bridge;
5425
5426 switch (cmd) {
5427 case CLI_INIT:
5428 e->command = "bridge kick";
5429 e->usage =
5430 "Usage: bridge kick <bridge-id> <channel-name | all>\n"
5431 " Kick the <channel-name> channel out of the <bridge-id> bridge\n"
5432 " If all is specified as the channel name then all channels will be\n"
5433 " kicked out of the bridge.\n";
5434 return NULL;
5435 case CLI_GENERATE:
5436 if (a->pos == 2) {
5437 return complete_bridge_live(a->word);
5438 }
5439 if (a->pos == 3) {
5440 ast_cli_complete(a->word, completions, -1);
5441 return complete_bridge_participant(a->argv[2], a->word);
5442 }
5443 return NULL;
5444 }
5445
5446 if (a->argc != 4) {
5447 return CLI_SHOWUSAGE;
5448 }
5449
5450 bridge = ast_bridge_find_by_id(a->argv[2]);
5451 if (!bridge) {
5452 ast_cli(a->fd, "Bridge '%s' not found\n", a->argv[2]);
5453 return CLI_SUCCESS;
5454 }
5455
5456 if (!strcasecmp(a->argv[3], "all")) {
5457 struct ast_bridge_channel *bridge_channel;
5458
5459 ast_cli(a->fd, "Kicking all channels from bridge '%s'\n", a->argv[2]);
5460
5462 AST_LIST_TRAVERSE(&bridge->channels, bridge_channel, entry) {
5463 ast_bridge_channel_queue_callback(bridge_channel, 0, kick_it, NULL, 0);
5464 }
5466 } else {
5467 struct ast_channel *chan;
5468
5469 chan = ast_channel_get_by_name_prefix(a->argv[3], strlen(a->argv[3]));
5470 if (!chan) {
5471 ast_cli(a->fd, "Channel '%s' not found\n", a->argv[3]);
5472 ao2_ref(bridge, -1);
5473 return CLI_SUCCESS;
5474 }
5475
5476 ast_cli(a->fd, "Kicking channel '%s' from bridge '%s'\n",
5477 ast_channel_name(chan), a->argv[2]);
5478 ast_bridge_kick(bridge, chan);
5479 ast_channel_unref(chan);
5480 }
5481
5482 ao2_ref(bridge, -1);
5483 return CLI_SUCCESS;
5484}
int ast_bridge_kick(struct ast_bridge *bridge, struct ast_channel *chan)
Kick a channel from a bridge.
Definition bridge.c:2178
static char * complete_bridge_live(const char *word)
Definition bridge.c:5237
static char * complete_bridge_participant(const char *bridge_name, const char *word)
Definition bridge.c:5393
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:1400
#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:1931
@ 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 5245 of file bridge.c.

5246{
5247#define FORMAT_HDR "%-36s %-36s %5s %-15s %-15s %s\n"
5248#define FORMAT_ROW "%-36s %-36s %5u %-15s %-15s %s\n"
5249
5250 struct ao2_iterator iter;
5251 struct ast_bridge *bridge;
5252
5253 switch (cmd) {
5254 case CLI_INIT:
5255 e->command = "bridge show all";
5256 e->usage =
5257 "Usage: bridge show all\n"
5258 " List all bridges\n";
5259 return NULL;
5260 case CLI_GENERATE:
5261 return NULL;
5262 }
5263
5264 ast_cli(a->fd, FORMAT_HDR, "Bridge-ID", "Name", "Chans", "Type", "Technology", "Duration");
5265
5266 iter = ao2_iterator_init(bridges, 0);
5267 for (; (bridge = ao2_iterator_next(&iter)); ao2_ref(bridge, -1)) {
5268 struct ast_bridge_snapshot *snapshot = ast_bridge_get_snapshot(bridge);
5269 char print_time[32];
5270
5271 if (snapshot) {
5272 ast_format_duration_hh_mm_ss(ast_tvnow().tv_sec - snapshot->creationtime.tv_sec, print_time, sizeof(print_time));
5273 ast_cli(a->fd, FORMAT_ROW,
5274 bridge->uniqueid,
5275 S_OR(bridge->name, "<unknown>"),
5276 snapshot->num_channels,
5277 S_OR(snapshot->subclass, "<unknown>"),
5278 S_OR(snapshot->technology, "<unknown>"),
5279 print_time);
5280 ao2_ref(snapshot, -1);
5281 }
5282 }
5283 ao2_iterator_destroy(&iter);
5284
5285 return CLI_SUCCESS;
5286
5287#undef FORMAT_HDR
5288#undef FORMAT_ROW
5289}
#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:2331

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

5310{
5311 struct ast_bridge_snapshot *snapshot;
5312 char print_time[32];
5313
5314 switch (cmd) {
5315 case CLI_INIT:
5316 e->command = "bridge show";
5317 e->usage =
5318 "Usage: bridge show <bridge-id>\n"
5319 " Show information about the <bridge-id> bridge\n";
5320 return NULL;
5321 case CLI_GENERATE:
5322 if (a->pos == 2) {
5323 return complete_bridge_live(a->word);
5324 }
5325 return NULL;
5326 }
5327
5328 if (a->argc != 3) {
5329 return CLI_SHOWUSAGE;
5330 }
5331
5332 snapshot = ast_bridge_get_snapshot_by_uniqueid(a->argv[2]);
5333 if (!snapshot) {
5334 ast_cli(a->fd, "Bridge '%s' not found\n", a->argv[2]);
5335 return CLI_SUCCESS;
5336 }
5337
5338 ast_format_duration_hh_mm_ss(ast_tvnow().tv_sec - snapshot->creationtime.tv_sec, print_time, sizeof(print_time));
5339
5340 ast_cli(a->fd, "Id: %s\n", snapshot->uniqueid);
5341 ast_cli(a->fd, "Type: %s\n", S_OR(snapshot->subclass, "<unknown>"));
5342 ast_cli(a->fd, "Technology: %s\n", S_OR(snapshot->technology, "<unknown>"));
5343 ast_cli(a->fd, "Subclass: %s\n", snapshot->subclass);
5344 ast_cli(a->fd, "Creator: %s\n", snapshot->creator);
5345 ast_cli(a->fd, "Name: %s\n", snapshot->name);
5346 ast_cli(a->fd, "Video-Mode: %s\n", ast_bridge_video_mode_to_string(snapshot->video_mode));
5347 ast_cli(a->fd, "Video-Source-Id: %s\n", snapshot->video_source_id);
5348 ast_cli(a->fd, "Num-Channels: %u\n", snapshot->num_channels);
5349 ast_cli(a->fd, "Num-Active: %u\n", snapshot->num_active);
5350 ast_cli(a->fd, "Duration: %s\n", print_time);
5352 ao2_ref(snapshot, -1);
5353
5354 return CLI_SUCCESS;
5355}
@ 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:4160
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:5292
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 5507 of file bridge.c.

5508{
5509#define FORMAT_HDR "%-20s %-20s %8s %s\n"
5510#define FORMAT_ROW "%-20s %-20s %8u %s\n"
5511
5512 struct ast_bridge_technology *cur;
5513
5514 switch (cmd) {
5515 case CLI_INIT:
5516 e->command = "bridge technology show";
5517 e->usage =
5518 "Usage: bridge technology show\n"
5519 " List registered bridge technologies\n";
5520 return NULL;
5521 case CLI_GENERATE:
5522 return NULL;
5523 }
5524
5525 ast_cli(a->fd, FORMAT_HDR, "Name", "Type", "Priority", "Suspended");
5528 const char *type;
5529
5530 /* Decode type for display */
5532
5533 ast_cli(a->fd, FORMAT_ROW, cur->name, type, cur->preference,
5534 AST_CLI_YESNO(cur->suspended));
5535 }
5537 return CLI_SUCCESS;
5538
5539#undef FORMAT
5540}
static const char * tech_capability2str(uint32_t capabilities)
Definition bridge.c:5487
#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 5561 of file bridge.c.

5562{
5563 struct ast_bridge_technology *cur;
5564 int suspend;
5565 int successful;
5566
5567 switch (cmd) {
5568 case CLI_INIT:
5569 e->command = "bridge technology {suspend|unsuspend}";
5570 e->usage =
5571 "Usage: bridge technology {suspend|unsuspend} <technology-name>\n"
5572 " Suspend or unsuspend a bridge technology.\n";
5573 return NULL;
5574 case CLI_GENERATE:
5575 if (a->pos == 3) {
5576 return complete_bridge_technology(a->word);
5577 }
5578 return NULL;
5579 }
5580
5581 if (a->argc != 4) {
5582 return CLI_SHOWUSAGE;
5583 }
5584
5585 suspend = !strcasecmp(a->argv[2], "suspend");
5586 successful = 0;
5589 if (!strcasecmp(cur->name, a->argv[3])) {
5590 successful = 1;
5591 if (suspend) {
5593 } else {
5595 }
5596 break;
5597 }
5598 }
5600
5601 if (successful) {
5602 if (suspend) {
5603 ast_cli(a->fd, "Suspended bridge technology '%s'\n", a->argv[3]);
5604 } else {
5605 ast_cli(a->fd, "Unsuspended bridge technology '%s'\n", a->argv[3]);
5606 }
5607 } else {
5608 ast_cli(a->fd, "Bridge technology '%s' not found\n", a->argv[3]);
5609 }
5610
5611 return CLI_SUCCESS;
5612}
void ast_bridge_technology_unsuspend(struct ast_bridge_technology *technology)
Unsuspend a bridge technology.
Definition bridge.c:3261
void ast_bridge_technology_suspend(struct ast_bridge_technology *technology)
Suspend a bridge technology from consideration.
Definition bridge.c:3256
static char * complete_bridge_technology(const char *word)
Definition bridge.c:5542
static void suspend(struct cc_core_instance *core_instance)
Definition ccss.c:3211

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, ast_bridge_technology::start, 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 5626 of file bridge.c.

5627{
5628 const char *name = astman_get_header(m, "BridgeTechnology");
5629 struct ast_bridge_technology *cur;
5630 int successful = 0;
5631
5632 if (ast_strlen_zero(name)) {
5633 astman_send_error(s, m, "BridgeTechnology must be provided");
5634 return 0;
5635 }
5636
5639
5640 if (!strcasecmp(cur->name, name)) {
5641 successful = 1;
5642 if (suspend) {
5644 } else {
5646 }
5647 break;
5648 }
5649 }
5651 if (!successful) {
5652 astman_send_error(s, m, "BridgeTechnology not found");
5653 return 0;
5654 }
5655
5656 astman_send_ack(s, m, (suspend ? "Suspended bridge technology" : "Unsuspended bridge technology"));
5657 return 0;
5658}
void astman_send_error(struct mansession *s, const struct message *m, char *error)
Send error in manager transaction.
Definition manager.c:2000
void astman_send_ack(struct mansession *s, const struct message *m, char *msg)
Send ack in manager transaction.
Definition manager.c:2032
const char * astman_get_header(const struct message *m, char *var)
Get header from manager transaction.
Definition manager.c:1661

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, ast_bridge_technology::start, 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 3654 of file bridge.c.

3655{
3656 struct ast_bridge_hook *hook = obj;
3658
3659 if (ast_test_flag(&hook->remove_flags, *remove_flags)) {
3660 return CMP_MATCH;
3661 } else {
3662 return 0;
3663 }
3664}
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 3674 of file bridge.c.

3675{
3677 hook_remove_match, &remove_flags);
3678}
@ 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:3654

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

3689{
3690 struct ast_bridge_hook *hook;
3691 int changed;
3692
3693 ast_heap_wrlock(hooks);
3694 do {
3695 int idx;
3696
3697 changed = 0;
3698 for (idx = ast_heap_size(hooks); idx; --idx) {
3699 hook = ast_heap_peek(hooks, idx);
3701 ast_heap_remove(hooks, hook);
3702 ao2_ref(hook, -1);
3703 changed = 1;
3704 }
3705 }
3706 } while (changed);
3707 ast_heap_unlock(hooks);
3708}
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 3717 of file bridge.c.

3718{
3719 struct ast_bridge_hook_timer *hook_a = a;
3720 struct ast_bridge_hook_timer *hook_b = b;
3721 int cmp;
3722
3723 cmp = ast_tvcmp(hook_b->timer.trip_time, hook_a->timer.trip_time);
3724 if (cmp) {
3725 return cmp;
3726 }
3727
3728 cmp = hook_b->timer.seqno - hook_a->timer.seqno;
3729 return cmp;
3730}
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 3778 of file bridge.c.

3779{
3780 struct ast_bridge_hook_timer *hook = obj;
3781
3782 return hook->generic.callback(bridge_channel, hook->generic.hook_pvt);
3783}

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

3787{
3788 ao2_cleanup(obj);
3789}

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

2174{
2176}
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 5670 of file bridge.c.

5671{
5672 const char *id = astman_get_header(m, "ActionID");
5673 RAII_VAR(struct ast_str *, id_text, ast_str_create(128), ast_free);
5674 struct ast_bridge_technology *cur;
5675 int num_items = 0;
5676
5677 if (!id_text) {
5678 astman_send_error(s, m, "Internal error");
5679 return -1;
5680 }
5681
5682 if (!ast_strlen_zero(id)) {
5683 ast_str_set(&id_text, 0, "ActionID: %s\r\n", id);
5684 }
5685
5686 astman_send_listack(s, m, "Bridge technology listing will follow", "start");
5687
5690 const char *type;
5691
5693
5694 astman_append(s,
5695 "Event: BridgeTechnologyListItem\r\n"
5696 "BridgeTechnology: %s\r\n"
5697 "BridgeType: %s\r\n"
5698 "BridgePriority: %u\r\n"
5699 "BridgeSuspended: %s\r\n"
5700 "%s"
5701 "\r\n",
5702 cur->name, type, cur->preference, AST_YESNO(cur->suspended),
5703 ast_str_buffer(id_text));
5704 ++num_items;
5705 }
5707
5708 astman_send_list_complete_start(s, m, "BridgeTechnologyListComplete", num_items);
5710
5711 return 0;
5712}
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:2042
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:2078
void astman_send_list_complete_end(struct mansession *s)
End the list complete event.
Definition manager.c:2086
void astman_append(struct mansession *s, const char *fmt,...)
Definition manager.c:1921
#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
char *attribute_pure ast_str_buffer(const struct ast_str *buf)
Returns the string buffer within the ast_str buf.
Definition strings.h:761
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::start, 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 5660 of file bridge.c.

5661{
5662 return handle_manager_bridge_tech_suspend(s, m, 1);
5663}
static int handle_manager_bridge_tech_suspend(struct mansession *s, const struct message *m, int suspend)
Definition bridge.c:5626

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

5666{
5667 return handle_manager_bridge_tech_suspend(s, m, 0);
5668}

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

3772{
3773 ao2_link(data, obj);
3774 return 0;
3775}

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

2789{
2790 struct ast_bridge *bridge;
2791 struct ast_bridge_channel *bridge_channel;
2792
2794 return NULL;
2795 }
2797 return NULL;
2798 }
2800 /* Channel has an active monitor, audiohook, or framehook. */
2801 return NULL;
2802 }
2803 bridge_channel = ast_channel_internal_bridge_channel(chan);
2804 if (!bridge_channel || ast_bridge_channel_trylock(bridge_channel)) {
2805 return NULL;
2806 }
2807 bridge = bridge_channel->bridge;
2808 if (bridge_channel->activity != BRIDGE_CHANNEL_THREAD_SIMPLE
2809 || bridge_channel->state != BRIDGE_CHANNEL_STATE_WAIT
2811 ast_bridge_channel_unlock(bridge_channel);
2812 return NULL;
2813 }
2814 if (!bridge_channel_internal_allows_optimization(bridge_channel) ||
2817 ast_bridge_channel_unlock(bridge_channel);
2818 return NULL;
2819 }
2820 return bridge;
2821}
#define ast_bridge_trylock(bridge)
Try locking the bridge.
Definition bridge.h:469
#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:2517
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 2833 of file bridge.c.

2834{
2835 struct ast_bridge *bridge;
2836 struct ast_bridge_channel *bridge_channel;
2837
2838 if (ast_channel_trylock(peer)) {
2839 return NULL;
2840 }
2841 if (!AST_LIST_EMPTY(ast_channel_readq(peer))) {
2842 ast_channel_unlock(peer);
2843 return NULL;
2844 }
2846 ast_channel_unlock(peer);
2847 return NULL;
2848 }
2850 /* Peer has an active monitor, audiohook, or framehook. */
2851 ast_channel_unlock(peer);
2852 return NULL;
2853 }
2854 bridge_channel = ast_channel_internal_bridge_channel(peer);
2855 if (!bridge_channel || ast_bridge_channel_trylock(bridge_channel)) {
2856 ast_channel_unlock(peer);
2857 return NULL;
2858 }
2859 bridge = bridge_channel->bridge;
2860 if (bridge_channel->activity != BRIDGE_CHANNEL_THREAD_IDLE
2861 || bridge_channel->state != BRIDGE_CHANNEL_STATE_WAIT
2863 ast_bridge_channel_unlock(bridge_channel);
2864 ast_channel_unlock(peer);
2865 return NULL;
2866 }
2870 ast_bridge_channel_unlock(bridge_channel);
2871 ast_channel_unlock(peer);
2872 return NULL;
2873 }
2874 return bridge;
2875}
@ BRIDGE_CHANNEL_THREAD_IDLE
#define ast_channel_trylock(chan)
Definition channel.h:2985

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

1586{
1589 return;
1590 }
1591 if (bridge->num_channels < 2) {
1592 return;
1593 }
1594 if (bridge->num_channels == 2) {
1596 AST_LIST_LAST(&bridge->channels)->chan);
1597 } else {
1599 }
1600}
static void set_bridge_peer_vars_2party(struct ast_channel *c0, struct ast_channel *c1)
Definition bridge.c:1430
static void set_bridge_peer_vars_multiparty(struct ast_bridge *bridge)
Definition bridge.c:1505
static void set_bridge_peer_vars_holding(struct ast_bridge *bridge)
Definition bridge.c:1565
@ AST_BRIDGE_CAPABILITY_HOLDING
Definition bridge.h:90
#define AST_LIST_LAST(head)
Returns the last entry contained in a list.

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

1431{
1432 const char *c0_name;
1433 const char *c1_name;
1434 const char *c0_pvtid = NULL;
1435 const char *c1_pvtid = NULL;
1436#define UPDATE_BRIDGE_VARS_GET(chan, name, pvtid) \
1437 do { \
1438 name = ast_strdupa(ast_channel_name(chan)); \
1439 if (ast_channel_tech(chan)->get_pvt_uniqueid) { \
1440 pvtid = ast_strdupa(ast_channel_tech(chan)->get_pvt_uniqueid(chan)); \
1441 } \
1442 } while (0)
1443
1444 ast_channel_lock(c1);
1445 UPDATE_BRIDGE_VARS_GET(c1, c1_name, c1_pvtid);
1447
1448 ast_channel_lock(c0);
1449 ast_bridge_vars_set(c0, c1_name, c1_pvtid);
1450 UPDATE_BRIDGE_VARS_GET(c0, c0_name, c0_pvtid);
1452
1453 ast_channel_lock(c1);
1454 ast_bridge_vars_set(c1, c0_name, c0_pvtid);
1456}
#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:1301

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

1566{
1567 struct ast_bridge_channel *bridge_channel;
1568
1569 AST_LIST_TRAVERSE(&bridge->channels, bridge_channel, entry) {
1570 ast_channel_lock(bridge_channel->chan);
1571 ast_bridge_vars_set(bridge_channel->chan, NULL, NULL);
1572 ast_channel_unlock(bridge_channel->chan);
1573 }
1574}

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

1506{
1507/*
1508 * Set a maximum number of channel names for the BRIDGEPEER
1509 * list. The plus one is for the current channel which is not
1510 * put in the list.
1511 */
1512#define MAX_BRIDGEPEER_CHANS (10 + 1)
1513
1514 unsigned int idx;
1515 unsigned int num_names;
1516 unsigned int len;
1517 const char **names;
1518 char *buf;
1519 struct ast_bridge_channel *bridge_channel;
1520
1521 /* Get first MAX_BRIDGEPEER_CHANS channel names. */
1523 names = ast_alloca(num_names * sizeof(*names));
1524 idx = 0;
1525 AST_LIST_TRAVERSE(&bridge->channels, bridge_channel, entry) {
1526 if (num_names <= idx) {
1527 break;
1528 }
1529 ast_channel_lock(bridge_channel->chan);
1530 names[idx++] = ast_strdupa(ast_channel_name(bridge_channel->chan));
1531 ast_channel_unlock(bridge_channel->chan);
1532 }
1533
1534 /* Determine maximum buf size needed. */
1535 len = num_names;
1536 for (idx = 0; idx < num_names; ++idx) {
1537 len += strlen(names[idx]);
1538 }
1539 buf = ast_alloca(len);
1540
1541 /* Set the bridge channel variables. */
1542 idx = 0;
1543 buf[0] = '\0';
1544 AST_LIST_TRAVERSE(&bridge->channels, bridge_channel, entry) {
1545 if (idx < num_names) {
1546 fill_bridgepeer_buf(buf, idx, names, num_names);
1547 }
1548 ++idx;
1549
1550 ast_channel_lock(bridge_channel->chan);
1551 ast_bridge_vars_set(bridge_channel->chan, buf, NULL);
1552 ast_channel_unlock(bridge_channel->chan);
1553 }
1554}
static void fill_bridgepeer_buf(char *buf, unsigned int cur_idx, const char *names[], unsigned int num_names)
Definition bridge.c:1468
#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:252

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

4593{
4594 struct ao2_iterator iter;
4595 struct ast_channel *chan;
4596 const char *transferer_name;
4597 const char *transferer_bridgepeer;
4598
4599 ast_channel_lock(transferer);
4600 transferer_name = ast_strdupa(ast_channel_name(transferer));
4601 transferer_bridgepeer = ast_strdupa(S_OR(pbx_builtin_getvar_helper(transferer, "BRIDGEPEER"), ""));
4602 ast_channel_unlock(transferer);
4603
4604 for (iter = ao2_iterator_init(channels, 0);
4605 (chan = ao2_iterator_next(&iter));
4606 ao2_cleanup(chan)) {
4607 if (chan == transferer) {
4608 ast_bridge_set_transfer_variables(chan, transferer_bridgepeer, is_attended);
4609 } else {
4610 ast_bridge_set_transfer_variables(chan, transferer_name, is_attended);
4611 }
4612 }
4613
4614 ao2_iterator_destroy(&iter);
4615}
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:4561

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

1062{
1063 uint32_t new_capabilities;
1066 struct ast_bridge_channel *bridge_channel;
1067 struct ast_frame *deferred_action;
1068 struct ast_bridge dummy_bridge = {
1069 .technology = bridge->technology,
1070 .tech_pvt = bridge->tech_pvt,
1071 .creator = bridge->creator,
1072 .name = bridge->name,
1073 .uniqueid = bridge->uniqueid,
1074 };
1075
1076 if (bridge->dissolved) {
1077 ast_debug(1, "Bridge %s is dissolved, not performing smart bridge operation.\n",
1078 bridge->uniqueid);
1079 return 0;
1080 }
1081
1082 /* Determine new bridge technology capabilities needed. */
1083 if (2 < bridge->num_channels) {
1084 new_capabilities = AST_BRIDGE_CAPABILITY_MULTIMIX;
1085 new_capabilities &= bridge->allowed_capabilities;
1086 } else {
1088 new_capabilities &= bridge->allowed_capabilities;
1089 if (!new_capabilities
1091 /* Allow switching between different multimix bridge technologies. */
1092 new_capabilities = AST_BRIDGE_CAPABILITY_MULTIMIX;
1093 }
1094 }
1095
1096 /* Find a bridge technology to satisfy the new capabilities. */
1097 new_technology = find_best_technology(new_capabilities, bridge);
1098 if (!new_technology) {
1099 int is_compatible = 0;
1100
1101 if (old_technology->compatible) {
1102 is_compatible = old_technology->compatible(bridge);
1103 } else if (old_technology->capabilities & AST_BRIDGE_CAPABILITY_MULTIMIX) {
1104 is_compatible = 1;
1105 } else if (bridge->num_channels <= 2
1106 && (old_technology->capabilities & AST_BRIDGE_CAPABILITY_1TO1MIX)) {
1107 is_compatible = 1;
1108 }
1109
1110 if (is_compatible) {
1111 ast_debug(1, "Bridge %s could not get a new technology, staying with old technology.\n",
1112 bridge->uniqueid);
1113 return 0;
1114 }
1115 ast_log(LOG_WARNING, "Bridge %s has no technology available to support it.\n",
1116 bridge->uniqueid);
1117 return -1;
1118 }
1119 if (new_technology == old_technology) {
1120 ast_debug(1, "Bridge %s is already using the new technology.\n",
1121 bridge->uniqueid);
1122 ast_module_unref(old_technology->mod);
1123 return 0;
1124 }
1125
1126 if (old_technology->destroy) {
1127 struct tech_deferred_destroy deferred_tech_destroy = {
1128 .tech = dummy_bridge.technology,
1129 .tech_pvt = dummy_bridge.tech_pvt,
1130 };
1131 struct ast_frame action = {
1134 .data.ptr = &deferred_tech_destroy,
1135 .datalen = sizeof(deferred_tech_destroy),
1136 };
1137
1138 /*
1139 * We need to defer the bridge technology destroy callback
1140 * because we have the bridge locked.
1141 */
1142 deferred_action = ast_frdup(&action);
1143 if (!deferred_action) {
1144 ast_module_unref(new_technology->mod);
1145 return -1;
1146 }
1147 } else {
1149 }
1150
1151 /*
1152 * We are now committed to changing the bridge technology. We
1153 * must not release the bridge lock until we have installed the
1154 * new bridge technology.
1155 */
1156 ast_verb(4, "Bridge %s: switching from %s technology to %s\n",
1157 bridge->uniqueid, old_technology->name, new_technology->name);
1158
1159 /*
1160 * Since we are soon going to pass this bridge to a new
1161 * technology we need to NULL out the tech_pvt pointer but
1162 * don't worry as it still exists in dummy_bridge, ditto for the
1163 * old technology.
1164 */
1165 bridge->tech_pvt = NULL;
1166 bridge->technology = new_technology;
1167
1168 /* Setup the new bridge technology. */
1169 ast_debug(1, "Bridge %s: calling %s technology constructor\n",
1170 bridge->uniqueid, new_technology->name);
1171 if (new_technology->create && new_technology->create(bridge)) {
1172 ast_log(LOG_WARNING, "Bridge %s: failed to setup bridge technology %s\n",
1173 bridge->uniqueid, new_technology->name);
1174 bridge->tech_pvt = dummy_bridge.tech_pvt;
1175 bridge->technology = dummy_bridge.technology;
1176 ast_module_unref(new_technology->mod);
1177 return -1;
1178 }
1179
1180 /* To ensure that things are sane for the old technology move the channels it
1181 * expects to the dummy bridge
1182 */
1183 AST_LIST_TRAVERSE_SAFE_BEGIN(&bridge->channels, bridge_channel, entry) {
1184 if (bridge_channel->just_joined) {
1185 continue;
1186 }
1187 ast_debug(1, "Bridge %s: moving %p(%s) to dummy bridge temporarily\n",
1188 bridge->uniqueid, bridge_channel, ast_channel_name(bridge_channel->chan));
1190 AST_LIST_INSERT_TAIL(&dummy_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 /* Take all the channels out of the old technology */
1202 AST_LIST_TRAVERSE_SAFE_BEGIN(&dummy_bridge.channels, bridge_channel, entry) {
1203 ast_debug(1, "Bridge %s: %p(%s) is leaving %s technology (dummy)\n",
1204 dummy_bridge.uniqueid, bridge_channel, ast_channel_name(bridge_channel->chan),
1205 old_technology->name);
1206 if (old_technology->leave) {
1207 old_technology->leave(&dummy_bridge, bridge_channel);
1208 }
1210 AST_LIST_INSERT_TAIL(&bridge->channels, bridge_channel, entry);
1211 dummy_bridge.num_channels--;
1213 dummy_bridge.num_lonely--;
1214 }
1215 if (!bridge_channel->suspended) {
1216 dummy_bridge.num_active--;
1217 }
1218 }
1220
1221 ast_debug(1, "Bridge %s: calling %s technology stop\n",
1222 dummy_bridge.uniqueid, old_technology->name);
1223 if (old_technology->stop) {
1224 old_technology->stop(&dummy_bridge);
1225 }
1226
1227 /* Add any new channels or re-add existing channels to the bridge. */
1228 AST_LIST_TRAVERSE(&bridge->channels, bridge_channel, entry) {
1229 bridge_channel_complete_join(bridge, bridge_channel);
1230 }
1231
1232 ast_debug(1, "Bridge %s: calling %s technology start\n",
1233 bridge->uniqueid, new_technology->name);
1234 if (new_technology->start && new_technology->start(bridge)) {
1235 ast_log(LOG_WARNING, "Bridge %s: failed to start bridge technology %s\n",
1236 bridge->uniqueid, new_technology->name);
1237 }
1238
1239 /*
1240 * Now that all the channels have been moved over we need to get
1241 * rid of all the information the old technology may have left
1242 * around.
1243 */
1244 if (old_technology->destroy) {
1245 ast_debug(1, "Bridge %s: deferring %s technology destructor\n",
1246 dummy_bridge.uniqueid, old_technology->name);
1248 } else {
1249 ast_debug(1, "Bridge %s: calling %s technology destructor\n",
1250 dummy_bridge.uniqueid, old_technology->name);
1251 ast_module_unref(old_technology->mod);
1252 }
1253
1254 return 0;
1255}
@ AST_BRIDGE_CHANNEL_FLAG_LONELY
static void deferred_action(struct ast_bridge_channel *bridge_channel, const void *payload, size_t payload_size)
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:363
unsigned int num_active
Definition bridge.h:381
unsigned int num_lonely
Definition bridge.h:383

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

5488{
5489 const char *type;
5490
5491 if (capabilities & AST_BRIDGE_CAPABILITY_HOLDING) {
5492 type = "Holding";
5493 } else if (capabilities & AST_BRIDGE_CAPABILITY_EARLY) {
5494 type = "Early";
5495 } else if (capabilities & AST_BRIDGE_CAPABILITY_NATIVE) {
5496 type = "Native";
5497 } else if (capabilities & AST_BRIDGE_CAPABILITY_1TO1MIX) {
5498 type = "1to1Mix";
5499 } else if (capabilities & AST_BRIDGE_CAPABILITY_MULTIMIX) {
5500 type = "MultiMix";
5501 } else {
5502 type = "<Unknown>";
5503 }
5504 return type;
5505}
@ 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 3078 of file bridge.c.

3082{
3083 struct merge_direction merge;
3084 struct ast_bridge_channel *kick_me[] = {
3085 chan_bridge_channel,
3086 peer_bridge_channel,
3087 };
3088 unsigned int id;
3089
3090 switch (bridges_allow_merge_optimization(chan_bridge, peer_bridge, ARRAY_LEN(kick_me), &merge)) {
3091 case MERGE_ALLOWED:
3092 break;
3093 case MERGE_PROHIBITED:
3094 return 0;
3096 ast_debug(4, "Can't optimize %s -- %s out, not enough channels in bridge %s.\n",
3097 ast_channel_name(chan_bridge_channel->chan),
3098 ast_channel_name(peer_bridge_channel->chan),
3099 merge.src->uniqueid);
3100 return 0;
3101 case MERGE_NO_MULTIMIX:
3102 ast_debug(4, "Can't optimize %s -- %s out, multimix is needed and it cannot be acquired.\n",
3103 ast_channel_name(chan_bridge_channel->chan),
3104 ast_channel_name(peer_bridge_channel->chan));
3105 return 0;
3106 }
3107
3108 ast_verb(4, "Merge optimizing %s -- %s out.\n",
3109 ast_channel_name(chan_bridge_channel->chan),
3110 ast_channel_name(peer_bridge_channel->chan));
3111
3112 id = ast_atomic_fetchadd_int((int *) &optimization_id, +1);
3113
3114 if (pvt && !ast_test_flag(pvt, AST_UNREAL_OPTIMIZE_BEGUN) && pvt->callbacks
3118 id);
3120 }
3121 bridge_do_merge(merge.dest, merge.src, kick_me, ARRAY_LEN(kick_me), 1);
3122 if (pvt && pvt->callbacks && pvt->callbacks->optimization_finished) {
3123 pvt->callbacks->optimization_finished(pvt, 1, id);
3124 }
3125
3126 return -1;
3127}
enum queue_result id
Definition app_queue.c:1790
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
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 4535 of file bridge.c.

4538{
4539 RAII_VAR(struct ast_bridge_channel *, transferer_bridge_channel, NULL, ao2_cleanup);
4540
4543 }
4544
4545 ast_channel_lock(transferer);
4546 transferer_bridge_channel = ast_channel_get_bridge_channel(transferer);
4547 ast_channel_unlock(transferer);
4548
4549 if (!transferer_bridge_channel) {
4551 }
4552
4553 if (ast_parking_blind_transfer_park(transferer_bridge_channel,
4554 context, exten, new_channel_cb, user_data_wrapper)) {
4556 }
4557
4559}
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(), ast_channel::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 2954 of file bridge.c.

2958{
2959 struct ast_bridge *dst_bridge;
2960 struct ast_bridge_channel *dst_bridge_channel;
2961 struct ast_bridge_channel *src_bridge_channel;
2962 struct ast_bridge_channel *other;
2963 int res = 1;
2964
2965 switch (bridges_allow_swap_optimization(chan_bridge, peer_bridge)) {
2967 dst_bridge = chan_bridge;
2968 dst_bridge_channel = chan_bridge_channel;
2969 src_bridge_channel = peer_bridge_channel;
2970 break;
2972 dst_bridge = peer_bridge;
2973 dst_bridge_channel = peer_bridge_channel;
2974 src_bridge_channel = chan_bridge_channel;
2975 break;
2976 case SWAP_PROHIBITED:
2977 default:
2978 return 0;
2979 }
2980
2981 other = ast_bridge_channel_peer(src_bridge_channel);
2982 if (other && other->state == BRIDGE_CHANNEL_STATE_WAIT) {
2983 unsigned int id;
2984
2985 if (ast_channel_trylock(other->chan)) {
2986 return 1;
2987 }
2988
2989 id = ast_atomic_fetchadd_int((int *) &optimization_id, +1);
2990
2991 ast_verb(4, "Move-swap optimizing %s <-- %s.\n",
2992 ast_channel_name(dst_bridge_channel->chan),
2993 ast_channel_name(other->chan));
2994
2995 if (pvt && !ast_test_flag(pvt, AST_UNREAL_OPTIMIZE_BEGUN) && pvt->callbacks
2997 pvt->callbacks->optimization_started(pvt, other->chan,
2998 dst_bridge_channel->chan == pvt->owner ? AST_UNREAL_OWNER : AST_UNREAL_CHAN,
2999 id);
3001 }
3002 other->swap = dst_bridge_channel->chan;
3003 if (!bridge_do_move(dst_bridge, other, 1, 1)) {
3004 ast_bridge_channel_leave_bridge(src_bridge_channel,
3006 res = -1;
3007 }
3008 if (pvt && pvt->callbacks && pvt->callbacks->optimization_finished) {
3009 pvt->callbacks->optimization_finished(pvt, res == 1, id);
3010 }
3011 ast_channel_unlock(other->chan);
3012 }
3013 return res;
3014}

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

4826{
4827 struct ast_bridge_channel *kick_me[] = {
4828 to_transferee_bridge_channel,
4829 to_target_bridge_channel,
4830 };
4831 enum ast_transfer_result res;
4832 struct ast_bridge *final_bridge = NULL;
4834
4835 channels = ast_bridge_peers_nolock(to_transferee_bridge);
4836
4837 if (!channels) {
4839 goto end;
4840 }
4841
4842 set_transfer_variables_all(to_transferee, channels, 1);
4843
4844 switch (ast_bridges_allow_optimization(to_transferee_bridge, to_target_bridge)) {
4846 final_bridge = to_transferee_bridge;
4847 res = bridge_swap_attended_transfer(to_transferee_bridge, to_target_bridge_channel, to_transferee);
4848 goto end;
4850 final_bridge = to_target_bridge;
4851 res = bridge_swap_attended_transfer(to_target_bridge, to_transferee_bridge_channel, to_transfer_target);
4852 goto end;
4854 final_bridge = to_transferee_bridge;
4855 bridge_do_merge(to_transferee_bridge, to_target_bridge, kick_me, ARRAY_LEN(kick_me), 0);
4857 goto end;
4859 final_bridge = to_target_bridge;
4860 bridge_do_merge(to_target_bridge, to_transferee_bridge, kick_me, ARRAY_LEN(kick_me), 0);
4862 goto end;
4864 default:
4865 /* Just because optimization wasn't doable doesn't necessarily mean
4866 * that we can actually perform the transfer. Some reasons for non-optimization
4867 * indicate bridge invalidity, so let's check those before proceeding.
4868 */
4869 if (to_transferee_bridge->inhibit_merge || to_transferee_bridge->dissolved ||
4870 to_target_bridge->inhibit_merge || to_target_bridge->dissolved) {
4872 }
4873
4874 return attended_transfer_bridge(to_transferee, to_transfer_target,
4875 to_transferee_bridge, to_target_bridge, transfer_msg);
4876 }
4877
4878end:
4879 if (res == AST_BRIDGE_TRANSFER_SUCCESS) {
4880 ast_attended_transfer_message_add_merge(transfer_msg, final_bridge);
4881 }
4882
4883 return res;
4884}
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:4777
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:3169
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 3792 of file bridge.c.

3793{
3794 /* Break out of the current wrapper if it exists to avoid multiple layers */
3795 if (hook->generic.callback == interval_wrapper_cb) {
3796 hook = hook->generic.hook_pvt;
3797 }
3798
3799 ast_bridge_interval_hook(features, hook->timer.flags, hook->timer.interval,
3801 hook->generic.remove_flags.flags);
3802}
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:3528
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:3778
static void interval_wrapper_pvt_dtor(void *obj)
Destructor for the hook wrapper.
Definition bridge.c:3786

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 base class virtual method table.

Definition at line 1008 of file bridge.c.

1008 {
1009 .name = "base",
1010 .destroy = bridge_base_destroy,
1011 .dissolving = bridge_base_dissolving,
1012 .push = bridge_base_push,
1013 .pull = bridge_base_pull,
1014 .notify_masquerade = bridge_base_notify_masquerade,
1015 .get_merge_priority = bridge_base_get_merge_priority,
1016 .push_peek = bridge_base_push_peek,
1017};
static int bridge_base_push_peek(struct ast_bridge *self, struct ast_bridge_channel *bridge_channel, struct ast_bridge_channel *swap)
Definition bridge.c:1003
static void bridge_base_dissolving(struct ast_bridge *self)
Definition bridge.c:913
static int bridge_base_push(struct ast_bridge *self, struct ast_bridge_channel *bridge_channel, struct ast_bridge_channel *swap)
Definition bridge.c:937
static int bridge_base_get_merge_priority(struct ast_bridge *self)
Definition bridge.c:983
static void bridge_base_destroy(struct ast_bridge *self)
Definition bridge.c:900
static void bridge_base_pull(struct ast_bridge *self, struct ast_bridge_channel *bridge_channel)
Definition bridge.c:952
static void bridge_base_notify_masquerade(struct ast_bridge *self, struct ast_bridge_channel *bridge_channel)
Definition bridge.c:967

Referenced by ast_bridge_base_new(), ast_bridging_init_basic(), bridge_agent_hold_dissolving(), bridge_agent_hold_pull(), bridge_agent_hold_push(), bridge_basic_destroy(), bridge_basic_pull(), bridge_basic_push(), bridge_init_agent_hold(), bridge_parking_destroy(), bridge_parking_dissolving(), bridge_parking_get_merge_priority(), bridge_parking_notify_masquerade(), bridge_parking_pull(), bridge_parking_push(), bridge_stasis_init(), bridge_stasis_pull(), bridge_stasis_push(), and bridge_stasis_push_peek().

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

Definition at line 1731 of file bridge.c.

1731 {
1732 .type = "bridge-impart-ds",
1735};

Referenced by bridge_channel_impart_add(), and bridge_channel_impart_signal().

◆ bridge_cli

struct ast_cli_entry bridge_cli[]
static

Definition at line 5614 of file bridge.c.

5614 {
5615 AST_CLI_DEFINE(handle_bridge_show_all, "List all bridges"),
5616 AST_CLI_DEFINE(handle_bridge_show_specific, "Show information about a bridge"),
5617#ifdef AST_DEVMODE
5618 AST_CLI_DEFINE(handle_bridge_destroy_specific, "Destroy a bridge"),
5619#endif
5620 AST_CLI_DEFINE(handle_bridge_kick_channel, "Kick a channel from a bridge"),
5621 AST_CLI_DEFINE(handle_bridge_technology_show, "List registered bridge technologies"),
5622 AST_CLI_DEFINE(handle_bridge_technology_suspend, "Suspend/unsuspend a bridge technology"),
5623};
static char * handle_bridge_technology_suspend(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
Definition bridge.c:5561
static char * handle_bridge_technology_show(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
Definition bridge.c:5507
static char * handle_bridge_kick_channel(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
Definition bridge.c:5421
static char * handle_bridge_show_all(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
Definition bridge.c:5245
static char * handle_bridge_show_specific(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
Definition bridge.c:5309
#define AST_CLI_DEFINE(fn, txt,...)
Definition cli.h:197

Referenced by ast_bridging_init(), and bridge_cleanup().

◆ bridge_init_lock

ast_mutex_t bridge_init_lock = AST_MUTEX_INIT_VALUE
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 194 of file bridge.c.

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

◆ bridge_technologies

◆ 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 166 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 169 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 172 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().