Asterisk - The Open Source Telephony Project  18.5.0
Data Structures | Macros | Enumerations | Functions | Variables
bridge.c File Reference

Bridging API. More...

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

Go to the source code of this file.

Data Structures

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

Macros

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

Enumerations

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

Functions

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

Variables

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

Detailed Description

Bridging API.

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

Definition in file bridge.c.

Macro Definition Documentation

◆ ATTENDEDTRANSFER

#define ATTENDEDTRANSFER   "ATTENDEDTRANSFER"

Definition at line 139 of file bridge.c.

Referenced by ast_bridge_set_transfer_variables(), and attended_transfer_bridge().

◆ BLINDTRANSFER

#define BLINDTRANSFER   "BLINDTRANSFER"

Definition at line 136 of file bridge.c.

Referenced by ast_bridge_set_transfer_variables(), and blind_transfer_bridge().

◆ BRIDGE_ARRAY_GROW

#define BRIDGE_ARRAY_GROW   32

Definition at line 133 of file bridge.c.

◆ BRIDGE_ARRAY_START

#define BRIDGE_ARRAY_START   128

Definition at line 130 of file bridge.c.

◆ BRIDGE_LOCK_ONE_OR_BOTH

#define BRIDGE_LOCK_ONE_OR_BOTH (   b1,
  b2 
)

◆ FORMAT_HDR [1/2]

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

◆ FORMAT_HDR [2/2]

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

◆ FORMAT_ROW [1/2]

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

◆ FORMAT_ROW [2/2]

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

◆ MAX_BRIDGEPEER_CHANS

#define MAX_BRIDGEPEER_CHANS   (10 + 1)

◆ UPDATE_BRIDGE_VARS_GET

#define UPDATE_BRIDGE_VARS_GET (   chan,
  name,
  pvtid 
)

Enumeration Type Documentation

◆ bridge_allow_merge

Enumerator
MERGE_PROHIBITED 

Bridge properties prohibit merge optimization

MERGE_NOT_ENOUGH_CHANNELS 

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

MERGE_NO_MULTIMIX 

Merge optimization cannot occur because multimix capability could not be requested

MERGE_ALLOWED 

Merge optimization allowed between bridges

Definition at line 2859 of file bridge.c.

2859  {
2860  /*! Bridge properties prohibit merge optimization */
2862  /*! Merge optimization cannot occur because the source bridge has too few channels */
2864  /*! Merge optimization cannot occur because multimix capability could not be requested */
2866  /*! Merge optimization allowed between bridges */
2867  MERGE_ALLOWED,
2868 };

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

2720  {
2721  /*! Bridges cannot allow for a swap optimization to occur */
2723  /*! Bridge swap optimization can occur into the chan_bridge */
2725  /*! Bridge swap optimization can occur into the peer_bridge */
2727 };

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);

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

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, LOG_WARNING, ast_bridge_technology::mod, ast_bridge_technology::name, ast_bridge_technology::preference, and ast_bridge_technology::write.

215 {
216  struct ast_bridge_technology *current;
217 
218  /* Perform a sanity check to make sure the bridge technology conforms to our needed requirements */
219  if (ast_strlen_zero(technology->name)
220  || !technology->capabilities
221  || !technology->write) {
222  ast_log(LOG_WARNING, "Bridge technology %s failed registration sanity check.\n",
223  technology->name);
224  return -1;
225  }
226 
228 
229  /* Look for duplicate bridge technology already using this name, or already registered */
231  if ((!strcasecmp(current->name, technology->name)) || (current == technology)) {
232  ast_log(LOG_WARNING, "A bridge technology of %s already claims to exist in our world.\n",
233  technology->name);
235  return -1;
236  }
237  }
238 
239  /* Copy module pointer so reference counting can keep the module from unloading */
240  technology->mod = module;
241 
242  /* Find the correct position to insert the technology. */
244  /* Put the highest preference tech's first in the list. */
245  if (technology->preference >= current->preference) {
247 
248  break;
249  }
250  }
252 
253  if (!current) {
254  /* Insert our new bridge technology to the end of the list. */
256  }
257 
259 
260  ast_verb(2, "Registered bridge technology %s\n", technology->name);
261 
262  return 0;
263 }
#define AST_RWLIST_WRLOCK(head)
Write locks a list.
Definition: linkedlists.h:51
#define LOG_WARNING
Definition: logger.h:274
#define AST_RWLIST_UNLOCK(head)
Attempts to unlock a read/write based list.
Definition: linkedlists.h:150
#define ast_verb(level,...)
Definition: logger.h:463
#define ast_strlen_zero(foo)
Definition: strings.h:52
#define ast_log
Definition: astobj2.c:42
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
#define AST_RWLIST_TRAVERSE
Definition: linkedlists.h:493
#define AST_RWLIST_INSERT_BEFORE_CURRENT
Definition: linkedlists.h:609
#define AST_RWLIST_TRAVERSE_SAFE_BEGIN
Definition: linkedlists.h:544
struct ast_module * mod
#define AST_RWLIST_INSERT_TAIL
Definition: linkedlists.h:740
Structure that is the essence of a bridge technology.
Definition: search.h:40
#define AST_RWLIST_TRAVERSE_SAFE_END
Definition: linkedlists.h:616

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

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

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

2521 {
2522  RAII_VAR(struct ast_bridge *, chan_bridge, NULL, ao2_cleanup);
2523  RAII_VAR(struct ast_channel *, yanked_chan, NULL, ao2_cleanup);
2524 
2525  ast_moh_stop(chan);
2526 
2527  ast_channel_lock(chan);
2528  chan_bridge = ast_channel_get_bridge(chan);
2529  ast_channel_unlock(chan);
2530 
2531  if (chan_bridge) {
2532  struct ast_bridge_channel *bridge_channel;
2533 
2534  /* The channel is in a bridge so it is not getting any new features. */
2535  ast_bridge_features_destroy(features);
2536 
2537  ast_bridge_lock_both(bridge, chan_bridge);
2538  bridge_channel = bridge_find_channel(chan_bridge, chan);
2539 
2540  if (bridge_move_locked(bridge, chan_bridge, chan, NULL, 1)) {
2541  ast_bridge_unlock(chan_bridge);
2542  ast_bridge_unlock(bridge);
2543  return -1;
2544  }
2545 
2546  /*
2547  * bridge_move_locked() will implicitly ensure that
2548  * bridge_channel is not NULL.
2549  */
2550  ast_assert(bridge_channel != NULL);
2551 
2552  /*
2553  * Additional checks if the channel we just stole dissolves the
2554  * original bridge.
2555  */
2556  bridge_dissolve_check_stolen(chan_bridge, bridge_channel);
2557  ast_bridge_unlock(chan_bridge);
2558  ast_bridge_unlock(bridge);
2559  } else {
2560  /* Slightly less easy case. We need to yank channel A from
2561  * where he currently is and impart him into our bridge.
2562  */
2563  yanked_chan = ast_channel_yank(chan);
2564  if (!yanked_chan) {
2565  ast_log(LOG_WARNING, "Could not gain control of channel %s\n", ast_channel_name(chan));
2566  ast_bridge_features_destroy(features);
2567  return -1;
2568  }
2569  if (ast_channel_state(yanked_chan) != AST_STATE_UP) {
2570  ast_answer(yanked_chan);
2571  }
2572  ast_channel_ref(yanked_chan);
2573  if (ast_bridge_impart(bridge, yanked_chan, NULL, features,
2575  /* It is possible for us to yank a channel and have some other
2576  * thread start a PBX on the channl after we yanked it. In particular,
2577  * this can theoretically happen on the ;2 of a Local channel if we
2578  * yank it prior to the ;1 being answered. Make sure that it isn't
2579  * executing a PBX before hanging it up.
2580  */
2581  if (ast_channel_pbx(yanked_chan)) {
2582  ast_channel_unref(yanked_chan);
2583  } else {
2584  ast_hangup(yanked_chan);
2585  }
2586  return -1;
2587  }
2588  }
2589 
2590  if (play_tone && !ast_strlen_zero(xfersound)) {
2591  struct ast_channel *play_chan = yanked_chan ?: chan;
2592  RAII_VAR(struct ast_bridge_channel *, play_bridge_channel, NULL, ao2_cleanup);
2593 
2594  ast_channel_lock(play_chan);
2595  play_bridge_channel = ast_channel_get_bridge_channel(play_chan);
2596  ast_channel_unlock(play_chan);
2597 
2598  if (!play_bridge_channel) {
2599  ast_log(LOG_WARNING, "Unable to play tone for channel %s. No longer in a bridge.\n",
2600  ast_channel_name(play_chan));
2601  } else {
2602  ast_bridge_channel_queue_playfile(play_bridge_channel, NULL, xfersound, NULL);
2603  }
2604  }
2605  return 0;
2606 }
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:2447
#define ast_channel_lock(chan)
Definition: channel.h:2945
Main Channel structure associated with a channel.
#define ast_bridge_lock_both(bridge1, bridge2)
Lock two bridges.
Definition: bridge.h:500
#define ast_channel_unref(c)
Decrease channel reference count.
Definition: channel.h:2981
#define LOG_WARNING
Definition: logger.h:274
struct ast_bridge_channel * bridge_find_channel(struct ast_bridge *bridge, struct ast_channel *chan)
Definition: bridge.c:1469
ast_channel_state
ast_channel states
Definition: channelstate.h:35
struct ast_channel * ast_channel_yank(struct ast_channel *yankee)
Gain control of a channel in the system.
Definition: channel.c:10794
#define ast_assert(a)
Definition: utils.h:695
static void bridge_dissolve_check_stolen(struct ast_bridge *bridge, struct ast_bridge_channel *bridge_channel)
Definition: bridge.c:361
#define NULL
Definition: resample.c:96
void ast_moh_stop(struct ast_channel *chan)
Turn off music on hold on a given channel.
Definition: channel.c:7876
#define ast_strlen_zero(foo)
Definition: strings.h:52
#define ast_log
Definition: astobj2.c:42
struct ast_bridge * ast_channel_get_bridge(const struct ast_channel *chan)
Get the bridge associated with a channel.
Definition: channel.c:10735
#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:911
struct ast_pbx * ast_channel_pbx(const struct ast_channel *chan)
Structure that contains information about a bridge.
Definition: bridge.h:357
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:1924
#define ast_channel_unlock(chan)
Definition: channel.h:2946
#define ast_bridge_unlock(bridge)
Unlock the bridge.
Definition: bridge.h:493
void ast_bridge_features_destroy(struct ast_bridge_features *features)
Destroy an allocated bridge features struct.
Definition: bridge.c:3741
void ast_hangup(struct ast_channel *chan)
Hang up a channel.
Definition: channel.c:2548
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:10783
Structure that contains information regarding a channel in a bridge.
#define ast_channel_ref(c)
Increase channel reference count.
Definition: channel.h:2970
#define ao2_cleanup(obj)
Definition: astobj2.h:1958
const char * ast_channel_name(const struct ast_channel *chan)
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.
int ast_answer(struct ast_channel *chan)
Answer a channel.
Definition: channel.c:2814

◆ 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)
Return values
apointer to a new bridge on success
NULLon failure

Example usage:

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

Definition at line 960 of file bridge.c.

References bridge_manager_request::bridge, bridge_alloc(), bridge_base_init(), and bridge_register().

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

961 {
962  void *bridge;
963 
964  bridge = bridge_alloc(sizeof(struct ast_bridge), &ast_bridge_base_v_table);
965  bridge = bridge_base_init(bridge, capabilities, flags, creator, name, id);
966  bridge = bridge_register(bridge);
967  return bridge;
968 }
struct ast_bridge * bridge_alloc(size_t size, const struct ast_bridge_methods *v_table)
Definition: bridge.c:724
struct ast_bridge_methods ast_bridge_base_v_table
Bridge base class virtual method table.
Definition: bridge.c:949
struct ast_bridge * bridge_register(struct ast_bridge *bridge)
Register the new bridge with the system.
Definition: bridge.c:709
Structure that contains information about a bridge.
Definition: bridge.h:357
static const char name[]
Definition: cdr_mysql.c:74
const ast_string_field creator
Definition: bridge.h:409
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:760

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

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

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

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

1953 {
1954  struct ast_bridge_channel *bridge_channel;
1955  int departable;
1956  SCOPE_TRACE(1, "%s\n", ast_channel_name(chan));
1957 
1958  ast_channel_lock(chan);
1959  bridge_channel = ast_channel_internal_bridge_channel(chan);
1960  departable = bridge_channel && bridge_channel->depart_wait;
1961  ast_channel_unlock(chan);
1962  if (!departable) {
1963  ast_log(LOG_ERROR, "Channel %s cannot be departed.\n",
1964  ast_channel_name(chan));
1965  /*
1966  * Should never happen. It likely means that
1967  * ast_bridge_depart() is called by two threads for the same
1968  * channel, the channel was never imparted to be departed, or it
1969  * has already been departed.
1970  */
1971  ast_assert(0);
1972  return -1;
1973  }
1974 
1975  /*
1976  * We are claiming the bridge_channel reference held by
1977  * bridge_channel_depart_thread().
1978  */
1979 
1980  ast_bridge_channel_leave_bridge(bridge_channel,
1982 
1983  /* Wait for the depart thread to die */
1984  ast_debug(1, "Waiting for %p(%s) bridge thread to die.\n",
1985  bridge_channel, ast_channel_name(bridge_channel->chan));
1986  pthread_join(bridge_channel->thread, NULL);
1987 
1988  ast_channel_lock(chan);
1990  ast_channel_unlock(chan);
1991 
1992  /* We can get rid of the bridge_channel after the depart thread has died. */
1993  ao2_ref(bridge_channel, -1);
1994  return 0;
1995 }
void ast_channel_internal_bridge_channel_set(struct ast_channel *chan, struct ast_bridge_channel *value)
#define ast_channel_lock(chan)
Definition: channel.h:2945
#define ast_assert(a)
Definition: utils.h:695
#define NULL
Definition: resample.c:96
#define ast_debug(level,...)
Log a DEBUG message.
Definition: logger.h:452
#define ast_log
Definition: astobj2.c:42
#define AST_CAUSE_NORMAL_CLEARING
Definition: causes.h:105
#define ao2_ref(o, delta)
Definition: astobj2.h:464
struct ast_bridge_channel * ast_channel_internal_bridge_channel(const struct ast_channel *chan)
#define LOG_ERROR
Definition: logger.h:285
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_channel_unlock(chan)
Definition: channel.h:2946
struct ast_channel * chan
Structure that contains information regarding a channel in a bridge.
#define SCOPE_TRACE(level,...)
Print a trace message with details when a scope is entered or existed.
Definition: logger.h:749
const char * ast_channel_name(const struct ast_channel *chan)
unsigned int depart_wait

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

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

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

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

971 {
972  ast_debug(1, "Bridge %s: telling all channels to leave the party\n", bridge->uniqueid);
973  ast_bridge_lock(bridge);
974  bridge_dissolve(bridge, cause);
975  ast_bridge_unlock(bridge);
976 
977  ao2_ref(bridge, -1);
978 
979  return 0;
980 }
const ast_string_field uniqueid
Definition: bridge.h:409
void bridge_dissolve(struct ast_bridge *bridge, int cause)
Definition: bridge.c:319
#define ast_debug(level,...)
Log a DEBUG message.
Definition: logger.h:452
#define ao2_ref(o, delta)
Definition: astobj2.h:464
#define ast_bridge_unlock(bridge)
Unlock the bridge.
Definition: bridge.h:493
#define ast_bridge_lock(bridge)
Lock the bridge.
Definition: bridge.h:480

◆ 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);

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

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

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

3251 {
3252  struct ast_bridge_hook_dtmf *hook;
3253  int res;
3254 
3255  /* Allocate new hook and setup it's various variables */
3256  hook = (struct ast_bridge_hook_dtmf *) bridge_hook_generic(sizeof(*hook), callback,
3257  hook_pvt, destructor, remove_flags);
3258  if (!hook) {
3259  return -1;
3260  }
3262  ast_copy_string(hook->dtmf.code, dtmf, sizeof(hook->dtmf.code));
3263 
3264  /* Once done we put it in the container. */
3265  res = ao2_link(features->dtmf_hooks, hook) ? 0 : -1;
3266  if (res) {
3267  /*
3268  * Could not link the hook into the container.
3269  *
3270  * Remove the hook_pvt destructor call from the hook since we
3271  * are returning failure to install the hook.
3272  */
3273  hook->generic.destructor = NULL;
3274  }
3275  ao2_ref(hook, -1);
3276 
3277  return res;
3278 }
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:3225
ast_bridge_hook_pvt_destructor destructor
struct ao2_container * dtmf_hooks
#define NULL
Definition: resample.c:96
enum ast_bridge_hook_type type
#define ao2_ref(o, delta)
Definition: astobj2.h:464
struct ast_bridge_hook_dtmf_parms dtmf
struct ast_bridge_hook generic
void ast_copy_string(char *dst, const char *src, size_t size)
Size-limited null-terminating string copy.
Definition: strings.h:401
char code[MAXIMUM_DTMF_FEATURE_STRING]
#define ao2_link(container, obj)
Definition: astobj2.h:1549

◆ 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
Returns
Nothing

Example usage:

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

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

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

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

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

Returns
Nothing

Definition at line 3741 of file bridge.c.

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

3742 {
3743  if (!features) {
3744  return;
3745  }
3746  ast_bridge_features_cleanup(features);
3747  ast_free(features);
3748 }
#define ast_free(a)
Definition: astmm.h:182
void ast_bridge_features_cleanup(struct ast_bridge_features *features)
Clean up the contents of a bridge features structure.
Definition: bridge.c:3720

◆ 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);

Definition at line 3151 of file bridge.c.

References ARRAY_LEN, and builtin_features_handlers.

Referenced by agent_connect_caller().

3152 {
3153  ast_bridge_hook_callback callback;
3154 
3155  if (ARRAY_LEN(builtin_features_handlers) <= feature) {
3156  return -1;
3157  }
3158 
3159  callback = builtin_features_handlers[feature];
3160  if (!callback) {
3161  return -1;
3162  }
3163  callback(bridge_channel, hook_pvt);
3164 
3165  return 0;
3166 }
#define ARRAY_LEN(a)
Definition: isdn_lib.c:42
static ast_bridge_hook_callback builtin_features_handlers[AST_BRIDGE_BUILTIN_END]
Definition: bridge.c:147
int(* ast_bridge_hook_callback)(struct ast_bridge_channel *bridge_channel, void *hook_pvt)
Hook callback type.

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

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

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

Referenced by builtin_features_helper().

3434 {
3435  if (ARRAY_LEN(builtin_features_handlers) <= feature
3436  || !builtin_features_handlers[feature]) {
3437  return -1;
3438  }
3439 
3440  /* If no alternate DTMF stream was provided use the default one */
3441  if (ast_strlen_zero(dtmf)) {
3442  dtmf = builtin_features_dtmf[feature];
3443  /* If no DTMF is still available (ie: it has been disabled) then error out now */
3444  if (ast_strlen_zero(dtmf)) {
3445  ast_debug(1, "Failed to enable built in feature %u on %p, no DTMF string is available for it.\n",
3446  feature, features);
3447  return -1;
3448  }
3449  }
3450 
3451  /*
3452  * The rest is basically pretty easy. We create another hook
3453  * using the built in feature's DTMF callback. Easy as pie.
3454  */
3455  return ast_bridge_dtmf_hook(features, dtmf, builtin_features_handlers[feature],
3456  config, destructor, remove_flags);
3457 }
#define ARRAY_LEN(a)
Definition: isdn_lib.c:42
char * config
Definition: conf2ael.c:66
static ast_bridge_hook_callback builtin_features_handlers[AST_BRIDGE_BUILTIN_END]
Definition: bridge.c:147
static char builtin_features_dtmf[AST_BRIDGE_BUILTIN_END][MAXIMUM_DTMF_FEATURE_STRING]
Definition: bridge.c:144
#define ast_strlen_zero(foo)
Definition: strings.h:52
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:3245
#define ast_debug(level,...)
Log a DEBUG message.
Definition: logger.h:452

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

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

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

3688 {
3689  /* Zero out the structure */
3690  memset(features, 0, sizeof(*features));
3691 
3692  /* Initialize the DTMF hooks container */
3695  if (!features->dtmf_hooks) {
3696  return -1;
3697  }
3698 
3699  /* Initialize the miscellaneous other hooks container */
3701  NULL);
3702  if (!features->other_hooks) {
3703  return -1;
3704  }
3705 
3706  /* Initialize the interval hooks heap */
3708  offsetof(struct ast_bridge_hook_timer, timer.heap_index));
3709  if (!features->interval_hooks) {
3710  return -1;
3711  }
3712 
3713  features->dtmf_passthrough = 1;
3714  features->text_messaging = 1;
3715 
3716  return 0;
3717 }
#define ao2_container_alloc_list(ao2_options, container_options, sort_fn, cmp_fn)
Definition: astobj2.h:1335
static int bridge_dtmf_hook_sort(const void *obj_left, const void *obj_right, int flags)
Definition: bridge.c:3606
struct ao2_container * dtmf_hooks
#define NULL
Definition: resample.c:96
unsigned int text_messaging
struct ast_heap * interval_hooks
unsigned int dtmf_passthrough
static int interval_hook_time_cmp(void *a, void *b)
Definition: bridge.c:3575
#define ast_heap_create(init_height, cmp_fn, index_offset)
Definition: heap.h:102
Replace objects with duplicate keys in container.
Definition: astobj2.h:1215
struct ao2_container * other_hooks
static struct ast_timer * timer
Definition: chan_iax2.c:360

◆ 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 allocted, but not initialized
Return values
0on success
-1on failure

Definition at line 3459 of file bridge.c.

References ast_string_field_init.

Referenced by bridge_builtin_set_limits(), and pre_bridge_setup().

3460 {
3461  memset(limits, 0, sizeof(*limits));
3462 
3463  if (ast_string_field_init(limits, 256)) {
3464  return -1;
3465  }
3466 
3467  return 0;
3468 }
#define ast_string_field_init(x, size)
Initialize a field pool and fields.
Definition: stringfields.h:353

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

References ast_string_field_free_memory.

Referenced by bridge_features_limits_dtor(), and pre_bridge_setup().

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

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

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

3663 {
3664  struct ast_bridge_hook_timer *hook;
3665  int idx;
3666 
3667  /* Merge hook containers */
3670 
3671  /* Merge hook heaps */
3673  for (idx = 1; (hook = ast_heap_peek(from->interval_hooks, idx)); idx++) {
3674  wrap_hook(into, hook);
3675  }
3677 
3678  /* Merge feature flags */
3679  into->feature_flags.flags |= from->feature_flags.flags;
3680  into->usable |= from->usable;
3681 
3682  into->mute |= from->mute;
3683  into->dtmf_passthrough |= from->dtmf_passthrough;
3684 }
#define ast_heap_unlock(h)
Definition: heap.h:248
#define ao2_callback(c, flags, cb_fn, arg)
Definition: astobj2.h:1716
unsigned int flags
Definition: utils.h:200
struct ao2_container * dtmf_hooks
static int merge_container_cb(void *obj, void *data, int flags)
Callback for merging hook ao2_containers.
Definition: bridge.c:3629
struct ast_flags feature_flags
struct ast_heap * interval_hooks
unsigned int dtmf_passthrough
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:3650
struct ao2_container * other_hooks
void * ast_heap_peek(struct ast_heap *h, unsigned int index)
Peek at an element on a heap.
Definition: heap.c:267
#define ast_heap_wrlock(h)
Definition: heap.h:246

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

Return values
featuresNew allocated features struct.
NULLon error.

Definition at line 3750 of file bridge.c.

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

3751 {
3752  struct ast_bridge_features *features;
3753 
3754  features = ast_malloc(sizeof(*features));
3755  if (features) {
3756  if (ast_bridge_features_init(features)) {
3757  ast_bridge_features_destroy(features);
3758  features = NULL;
3759  }
3760  }
3761 
3762  return features;
3763 }
Structure that contains features information.
#define NULL
Definition: resample.c:96
#define ast_malloc(len)
A wrapper for malloc()
Definition: astmm.h:193
int ast_bridge_features_init(struct ast_bridge_features *features)
Initialize bridge features structure.
Definition: bridge.c:3687
void ast_bridge_features_destroy(struct ast_bridge_features *features)
Destroy an allocated bridge features struct.
Definition: bridge.c:3741

◆ 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");

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

Definition at line 3123 of file bridge.c.

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

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

3124 {
3125  if (ARRAY_LEN(builtin_features_handlers) <= feature
3126  || builtin_features_handlers[feature]) {
3127  return -1;
3128  }
3129 
3130  if (!ast_strlen_zero(dtmf)) {
3131  ast_copy_string(builtin_features_dtmf[feature], dtmf, sizeof(builtin_features_dtmf[feature]));
3132  }
3133 
3134  builtin_features_handlers[feature] = callback;
3135 
3136  return 0;
3137 }
#define ARRAY_LEN(a)
Definition: isdn_lib.c:42
static ast_bridge_hook_callback builtin_features_handlers[AST_BRIDGE_BUILTIN_END]
Definition: bridge.c:147
static char builtin_features_dtmf[AST_BRIDGE_BUILTIN_END][MAXIMUM_DTMF_FEATURE_STRING]
Definition: bridge.c:144
#define ast_strlen_zero(foo)
Definition: strings.h:52
void ast_copy_string(char *dst, const char *src, size_t size)
Size-limited null-terminating string copy.
Definition: strings.h:401

◆ 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.
Returns
Nothing

Definition at line 3568 of file bridge.c.

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

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

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

◆ 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
Returns
Nothing

Example usage:

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

Definition at line 3490 of file bridge.c.

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

3491 {
3492  ast_set_flag(&features->feature_flags, flag);
3493  features->usable = 1;
3494 }
#define ast_set_flag(p, flag)
Definition: utils.h:70
struct ast_flags feature_flags
long int flag
Definition: f2c.h:83

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

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

References AST_BRIDGE_BUILTIN_INTERVAL_LIMITS, ast_log, builtin_interval_handlers, and LOG_ERROR.

Referenced by pre_bridge_setup().

3478 {
3481 
3483  return callback(features, limits, remove_flags);
3484  }
3485 
3486  ast_log(LOG_ERROR, "Attempted to set limits without an AST_BRIDGE_BUILTIN_INTERVAL_LIMITS callback registered.\n");
3487  return -1;
3488 }
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.
static ast_bridge_builtin_set_limits_fn builtin_interval_handlers[AST_BRIDGE_BUILTIN_INTERVAL_END]
Definition: bridge.c:150
#define ast_log
Definition: astobj2.c:42
#define LOG_ERROR
Definition: logger.h:285

◆ 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);

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

Definition at line 3139 of file bridge.c.

References ARRAY_LEN, builtin_features_handlers, and NULL.

Referenced by unload_module(), and unload_parking_bridge_features().

3140 {
3141  if (ARRAY_LEN(builtin_features_handlers) <= feature
3142  || !builtin_features_handlers[feature]) {
3143  return -1;
3144  }
3145 
3146  builtin_features_handlers[feature] = NULL;
3147 
3148  return 0;
3149 }
#define ARRAY_LEN(a)
Definition: isdn_lib.c:42
static ast_bridge_hook_callback builtin_features_handlers[AST_BRIDGE_BUILTIN_END]
Definition: bridge.c:147
#define NULL
Definition: resample.c:96

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

References ao2_find, and OBJ_SEARCH_KEY.

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

5071 {
5072  return ao2_find(bridges, bridge_id, OBJ_SEARCH_KEY);
5073 }
The arg parameter is a search key, but is not an object.
Definition: astobj2.h:1105
static struct ao2_container * bridges
Definition: bridge.c:123
#define ao2_find(container, arg, flags)
Definition: astobj2.h:1756

◆ 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);

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

References AST_BRIDGE_HOOK_TYPE_HANGUP, and bridge_other_hook().

Referenced by add_normal_hooks(), and bridge_personality_atxfer_push().

3333 {
3334  return bridge_other_hook(features, callback, hook_pvt, destructor, remove_flags,
3336 }
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:3294

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

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

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(), bridge_channel_impart_cond::cond, bridge_channel_impart_cond::done, bridge_channel_impart_cond::lock, NULL, SCOPE_TRACE, and ast_bridge::uniqueid.

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

1929 {
1930  struct bridge_channel_impart_cond cond = {
1931  .done = 0,
1932  };
1933  int res;
1934  SCOPE_TRACE(1, "%s Bridge: %s\n", ast_channel_name(chan), bridge->uniqueid);
1935 
1936  ast_mutex_init(&cond.lock);
1937  ast_cond_init(&cond.cond, NULL);
1938 
1939  res = bridge_impart_internal(bridge, chan, swap, features, flags, &cond);
1940  if (res) {
1941  /* Impart failed. Signal any other waiting impart threads */
1944  }
1945 
1946  ast_cond_destroy(&cond.cond);
1947  ast_mutex_destroy(&cond.lock);
1948 
1949  return res;
1950 }
Internal bridge impart wait condition and associated conditional.
Definition: bridge.c:1515
const ast_string_field uniqueid
Definition: bridge.h:409
void bridge_channel_impart_signal(struct ast_channel *chan)
Signal imparting threads to wake up.
Definition: bridge.c:1626
#define ast_cond_init(cond, attr)
Definition: lock.h:199
#define NULL
Definition: resample.c:96
void ast_bridge_discard_after_callback(struct ast_channel *chan, enum ast_bridge_after_cb_reason reason)
Run discarding any after bridge callbacks.
Definition: bridge_after.c:247
ast_cond_t cond
Definition: app_meetme.c:1090
#define ast_cond_destroy(cond)
Definition: lock.h:200
#define SCOPE_TRACE(level,...)
Print a trace message with details when a scope is entered or existed.
Definition: logger.h:749
const char * ast_channel_name(const struct ast_channel *chan)
#define ast_mutex_init(pmutex)
Definition: lock.h:184
#define ast_mutex_destroy(a)
Definition: lock.h:186
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:1823

◆ 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);

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

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

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

3389 {
3390  struct ast_bridge_hook_timer *hook;
3391  int res;
3392 
3393  if (!features ||!interval || !callback) {
3394  return -1;
3395  }
3396 
3397  /* Allocate new hook and setup it's various variables */
3398  hook = (struct ast_bridge_hook_timer *) bridge_hook_generic(sizeof(*hook), callback,
3399  hook_pvt, destructor, remove_flags);
3400  if (!hook) {
3401  return -1;
3402  }
3404  hook->timer.interval = interval;
3405  hook->timer.trip_time = ast_tvadd(ast_tvnow(), ast_samp2tv(interval, 1000));
3406  hook->timer.seqno = ast_atomic_fetchadd_int((int *) &features->interval_sequence, +1);
3407  hook->timer.flags = flags;
3408 
3409  ast_debug(1, "Putting interval hook %p with interval %u in the heap on features %p\n",
3410  hook, hook->timer.interval, features);
3411  ast_heap_wrlock(features->interval_hooks);
3412  res = ast_heap_push(features->interval_hooks, hook);
3413  ast_heap_unlock(features->interval_hooks);
3414  if (res) {
3415  /*
3416  * Could not push the hook into the heap
3417  *
3418  * Remove the hook_pvt destructor call from the hook since we
3419  * are returning failure to install the hook.
3420  */
3421  hook->generic.destructor = NULL;
3422  ao2_ref(hook, -1);
3423  }
3424 
3425  return res ? -1 : 0;
3426 }
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:3225
#define ast_heap_unlock(h)
Definition: heap.h:248
struct ast_bridge_hook generic
ast_bridge_hook_pvt_destructor destructor
struct timeval ast_tvnow(void)
Returns current timeval. Meant to replace calls to gettimeofday().
Definition: time.h:150
#define NULL
Definition: resample.c:96
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:755
#define ast_debug(level,...)
Log a DEBUG message.
Definition: logger.h:452
#define ast_heap_push(h, elm)
Definition: heap.h:126
enum ast_bridge_hook_type type
#define ao2_ref(o, delta)
Definition: astobj2.h:464
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:238
struct ast_heap * interval_hooks
struct timeval ast_tvadd(struct timeval a, struct timeval b)
Returns the sum of two timevals a + b.
Definition: extconf.c:2283
struct ast_bridge_hook_timer_parms timer
unsigned int interval_sequence
#define ast_heap_wrlock(h)
Definition: heap.h:246

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

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

Definition at line 3168 of file bridge.c.

References ARRAY_LEN, and builtin_interval_handlers.

Referenced by load_module().

3169 {
3170  if (ARRAY_LEN(builtin_interval_handlers) <= interval
3171  || builtin_interval_handlers[interval]) {
3172  return -1;
3173  }
3174 
3175  builtin_interval_handlers[interval] = callback;
3176 
3177  return 0;
3178 }
#define ARRAY_LEN(a)
Definition: isdn_lib.c:42
static ast_bridge_builtin_set_limits_fn builtin_interval_handlers[AST_BRIDGE_BUILTIN_INTERVAL_END]
Definition: bridge.c:150

◆ ast_bridge_interval_unregister()

int ast_bridge_interval_unregister ( enum ast_bridge_builtin_interval  interval)

Definition at line 3180 of file bridge.c.

References ARRAY_LEN, builtin_interval_handlers, and NULL.

Referenced by unload_module().

3181 {
3182  if (ARRAY_LEN(builtin_interval_handlers) <= interval
3183  || !builtin_interval_handlers[interval]) {
3184  return -1;
3185  }
3186 
3187  builtin_interval_handlers[interval] = NULL;
3188 
3189  return 0;
3190 
3191 }
#define ARRAY_LEN(a)
Definition: isdn_lib.c:42
#define NULL
Definition: resample.c:96
static ast_bridge_builtin_set_limits_fn builtin_interval_handlers[AST_BRIDGE_BUILTIN_INTERVAL_END]
Definition: bridge.c:150

◆ 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.
None0, is 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 3958 of file bridge.c.

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

3959 {
3960  int res = 0;
3961 
3962  ast_bridge_lock(bridge);
3963  switch (bridge->softmix.video_mode.mode) {
3965  break;
3967  if (bridge->softmix.video_mode.mode_data.single_src_data.chan_vsrc == chan) {
3968  res = 1;
3969  }
3970  break;
3972  if (bridge->softmix.video_mode.mode_data.talker_src_data.chan_vsrc == chan) {
3973  res = 1;
3974  } else if (bridge->softmix.video_mode.mode_data.talker_src_data.chan_old_vsrc == chan) {
3975  res = 2;
3976  }
3978  break;
3979  }
3980  ast_bridge_unlock(bridge);
3981  return res;
3982 }
struct ast_bridge_video_mode video_mode
Definition: bridge.h:287
struct ast_channel * chan_old_vsrc
Definition: bridge.h:127
struct ast_channel * chan_vsrc
Definition: bridge.h:116
struct ast_bridge_softmix softmix
Definition: bridge.h:375
union ast_bridge_video_mode::@227 mode_data
struct ast_bridge_video_talker_src_data talker_src_data
Definition: bridge.h:164
struct ast_bridge_video_single_src_data single_src_data
Definition: bridge.h:163
#define ast_bridge_unlock(bridge)
Unlock the bridge.
Definition: bridge.h:493
#define ast_bridge_lock(bridge)
Lock the bridge.
Definition: bridge.h:480
struct ast_channel * chan_vsrc
Definition: bridge.h:123
enum ast_bridge_video_mode_type mode
Definition: bridge.h:160

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

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

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, 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().

1673 {
1674  struct ast_bridge_channel *bridge_channel;
1675  int res = 0;
1676  SCOPE_TRACE(1, "%s Bridge: %s\n", ast_channel_name(chan), bridge->uniqueid);
1677 
1678  bridge_channel = bridge_channel_internal_alloc(bridge);
1679  if (flags & AST_BRIDGE_JOIN_PASS_REFERENCE) {
1680  ao2_ref(bridge, -1);
1681  }
1682  if (!bridge_channel) {
1683  ao2_t_cleanup(swap, "Error exit: bridge_channel alloc failed");
1684  res = -1;
1685  goto join_exit;
1686  }
1687 /* 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. */
1688  ast_assert(features != NULL);
1689  if (!features) {
1690  ao2_ref(bridge_channel, -1);
1691  ao2_t_cleanup(swap, "Error exit: features is NULL");
1692  res = -1;
1693  goto join_exit;
1694  }
1695  if (tech_args) {
1696  bridge_channel->tech_args = *tech_args;
1697  }
1698 
1699  ast_channel_lock(chan);
1701  res = -1;
1702  } else {
1703  ast_channel_internal_bridge_channel_set(chan, bridge_channel);
1704  }
1705  ast_channel_unlock(chan);
1706  bridge_channel->thread = pthread_self();
1707  bridge_channel->chan = chan;
1708  bridge_channel->swap = swap;
1709  bridge_channel->features = features;
1710  bridge_channel->inhibit_colp = !!(flags & AST_BRIDGE_JOIN_INHIBIT_JOIN_COLP);
1711 
1712  /* allow subclass to peek at upcoming push operation */
1713  if (bridge->v_table->push_peek && !res) {
1714  struct ast_bridge_channel *bcswap = NULL;
1715 
1716  ast_bridge_lock(bridge);
1717  if (bridge_channel->swap) {
1718  bcswap = bridge_find_channel(bridge, bridge_channel->swap);
1719  }
1720  res = bridge->v_table->push_peek(bridge, bridge_channel, bcswap);
1721  ast_bridge_unlock(bridge);
1722  }
1723 
1724  if (!res) {
1725  res = bridge_channel_internal_join(bridge_channel);
1726  }
1727 
1728  /* Cleanup all the data in the bridge channel after it leaves the bridge. */
1729  ast_channel_lock(chan);
1731  ast_channel_unlock(chan);
1732  /* Due to a race condition, we lock the bridge channel here for ast_bridge_channel_get_chan */
1733  ao2_lock(bridge_channel);
1734  bridge_channel->chan = NULL;
1735  ao2_unlock(bridge_channel);
1736  /* If bridge_channel->swap is not NULL then the join failed. */
1737  ao2_t_cleanup(bridge_channel->swap, "Bridge complete: join failed");
1738  bridge_channel->swap = NULL;
1739  bridge_channel->features = NULL;
1740 
1741  ao2_ref(bridge_channel, -1);
1742 
1743 join_exit:
1747  && !ast_bridge_setup_after_goto(chan)) {
1748  /* Claim the after bridge goto is an async goto destination. */
1749  ast_channel_lock(chan);
1750  ast_softhangup_nolock(chan, AST_SOFTHANGUP_ASYNCGOTO);
1751  ast_channel_unlock(chan);
1752  }
1753  return res;
1754 }
void ast_channel_internal_bridge_channel_set(struct ast_channel *chan, struct ast_bridge_channel *value)
#define ast_channel_lock(chan)
Definition: channel.h:2945
#define ao2_t_cleanup(obj, tag)
Definition: astobj2.h:1959
const ast_string_field uniqueid
Definition: bridge.h:409
struct ast_bridge_features * features
#define ast_test_flag(p, flag)
Definition: utils.h:63
void bridge_channel_impart_signal(struct ast_channel *chan)
Signal imparting threads to wake up.
Definition: bridge.c:1626
struct ast_bridge_channel * bridge_find_channel(struct ast_bridge *bridge, struct ast_channel *chan)
Definition: bridge.c:1469
#define ast_assert(a)
Definition: utils.h:695
#define ao2_unlock(a)
Definition: astobj2.h:730
#define NULL
Definition: resample.c:96
#define ao2_ref(o, delta)
Definition: astobj2.h:464
#define ao2_lock(a)
Definition: astobj2.h:718
const struct ast_bridge_methods * v_table
Definition: bridge.h:359
struct ast_bridge_tech_optimizations tech_args
int ast_softhangup_nolock(struct ast_channel *chan, int reason)
Softly hangup up a channel (no channel lock)
Definition: channel.c:2463
#define ast_channel_unlock(chan)
Definition: channel.h:2946
#define ast_bridge_unlock(bridge)
Unlock the bridge.
Definition: bridge.h:493
void ast_bridge_run_after_callback(struct ast_channel *chan)
Run any after bridge callback.
Definition: bridge_after.c:220
unsigned int inhibit_colp
struct ast_channel * swap
#define ast_bridge_lock(bridge)
Lock the bridge.
Definition: bridge.h:480
int ast_channel_softhangup_internal_flag(struct ast_channel *chan)
struct ast_channel * chan
Structure that contains information regarding a channel in a bridge.
ast_bridge_push_channel_fn push_peek
Definition: bridge.h:281
#define SCOPE_TRACE(level,...)
Print a trace message with details when a scope is entered or existed.
Definition: logger.h:749
struct ast_bridge_channel * bridge_channel_internal_alloc(struct ast_bridge *bridge)
const char * ast_channel_name(const struct ast_channel *chan)
int bridge_channel_internal_join(struct ast_bridge_channel *bridge_channel)
struct ast_flags * ast_channel_flags(struct ast_channel *chan)
int ast_bridge_setup_after_goto(struct ast_channel *chan)
Setup any after bridge goto location to begin execution.
Definition: bridge_after.c:447

◆ 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 
)

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)
/endcode
This unregisters the function that is handling the built in duration limit feature.
/
/*!
* \brief Attach a bridge channel join hook to a bridge features structure
* \param features Bridge features structure
* \param callback Function to execute upon activation
* \param hook_pvt Unique data
* \param destructor Optional destructor callback for hook_pvt data
* \param remove_flags Dictates what situations the hook should be removed.
* \retval 0 on success
* \retval -1 on failure (The caller must cleanup any hook_pvt resources.)
* Example usage:
* \code
* struct ast_bridge_features features;
* ast_bridge_features_init(&features);
* ast_bridge_join_hook(&features, join_callback, NULL, NULL, 0);
*

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

References AST_BRIDGE_HOOK_TYPE_JOIN, and bridge_other_hook().

Referenced by agent_request_exec(), and confbridge_exec().

3343 {
3344  return bridge_other_hook(features, callback, hook_pvt, destructor, remove_flags,
3346 }
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:3294

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

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

References ast_bridge_channel_queue_callback(), ast_bridge_lock, ast_bridge_unlock, bridge_find_channel(), kick_it(), and NULL.

Referenced by handle_bridge_kick_channel(), and manager_bridge_kick().

2026 {
2027  struct ast_bridge_channel *bridge_channel;
2028  int res;
2029 
2030  ast_bridge_lock(bridge);
2031 
2032  /* Try to find the channel that we want to kick. */
2033  if (!(bridge_channel = bridge_find_channel(bridge, chan))) {
2034  ast_bridge_unlock(bridge);
2035  return -1;
2036  }
2037 
2038  res = ast_bridge_channel_queue_callback(bridge_channel, 0, kick_it, NULL, 0);
2039 
2040  ast_bridge_unlock(bridge);
2041 
2042  return res;
2043 }
struct ast_bridge_channel * bridge_find_channel(struct ast_bridge *bridge, struct ast_channel *chan)
Definition: bridge.c:1469
static void kick_it(struct ast_bridge_channel *bridge_channel, const void *payload, size_t payload_size)
Definition: bridge.c:2020
#define NULL
Definition: resample.c:96
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.
#define ast_bridge_unlock(bridge)
Unlock the bridge.
Definition: bridge.h:493
#define ast_bridge_lock(bridge)
Lock the bridge.
Definition: bridge.h:480
Structure that contains information regarding a channel in a bridge.

◆ 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);

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

References AST_BRIDGE_HOOK_TYPE_LEAVE, and bridge_other_hook().

Referenced by confbridge_exec().

3353 {
3354  return bridge_other_hook(features, callback, hook_pvt, destructor, remove_flags,
3356 }
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:3294

◆ 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);

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

Definition at line 2348 of file bridge.c.

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

2349 {
2350  int res;
2351 
2352  /* Sanity check. */
2353  ast_assert(dst_bridge && src_bridge);
2354 
2355  ast_bridge_lock_both(dst_bridge, src_bridge);
2356  res = bridge_merge_locked(dst_bridge, src_bridge, merge_best_direction, kick_me, num_kick);
2357  ast_bridge_unlock(src_bridge);
2358  ast_bridge_unlock(dst_bridge);
2359  return res;
2360 }
#define ast_bridge_lock_both(bridge1, bridge2)
Lock two bridges.
Definition: bridge.h:500
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:2264
#define ast_assert(a)
Definition: utils.h:695
#define ast_bridge_unlock(bridge)
Unlock the bridge.
Definition: bridge.h:493

◆ 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.)
Returns
Nothing

Definition at line 3061 of file bridge.c.

References ast_bridge_lock, ast_bridge_unlock, and bridge_merge_inhibit_nolock().

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

3062 {
3063  ast_bridge_lock(bridge);
3065  ast_bridge_unlock(bridge);
3066 }
void bridge_merge_inhibit_nolock(struct ast_bridge *bridge, int request)
Definition: bridge.c:3052
#define ast_bridge_unlock(bridge)
Unlock the bridge.
Definition: bridge.h:493
static int request(void *obj)
Definition: chan_pjsip.c:2559
#define ast_bridge_lock(bridge)
Lock the bridge.
Definition: bridge.h:480

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

References ast_bridge_lock_both, ast_bridge_unlock, and bridge_move_locked().

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

2509 {
2510  int res;
2511 
2512  ast_bridge_lock_both(dst_bridge, src_bridge);
2513  res = bridge_move_locked(dst_bridge, src_bridge, chan, swap, attempt_recovery);
2514  ast_bridge_unlock(src_bridge);
2515  ast_bridge_unlock(dst_bridge);
2516  return res;
2517 }
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:2447
#define ast_bridge_lock_both(bridge1, bridge2)
Lock two bridges.
Definition: bridge.h:500
#define ast_bridge_unlock(bridge)
Unlock the bridge.
Definition: bridge.h:493

◆ 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);

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

References AST_BRIDGE_HOOK_TYPE_MOVE, bridge_other_hook(), and hook_cb().

Referenced by bridge_stasis_pull().

3375 {
3377 
3378  return bridge_other_hook(features, hook_cb, hook_pvt, destructor, remove_flags,
3380 }
int(* ast_bridge_hook_callback)(struct ast_bridge_channel *bridge_channel, void *hook_pvt)
Hook callback type.
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:3294
static int hook_cb(struct ast_config *cfg)
Definition: test_config.c:875

◆ 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
Returns
Nothing

Definition at line 1482 of file bridge.c.

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_manager_request::bridge, bridge_find_channel(), bridge_reconfigured(), ast_bridge_methods::notify_masquerade, and ast_bridge::v_table.

Referenced by channel_do_masquerade().

1483 {
1484  struct ast_bridge_channel *bridge_channel;
1485  struct ast_bridge *bridge;
1486 
1487  /* Safely get the bridge_channel pointer for the chan. */
1488  ast_channel_lock(chan);
1489  bridge_channel = ast_channel_get_bridge_channel(chan);
1490  ast_channel_unlock(chan);
1491  if (!bridge_channel) {
1492  /* Not in a bridge */
1493  return;
1494  }
1495 
1496  ast_bridge_channel_lock_bridge(bridge_channel);
1497  bridge = bridge_channel->bridge;
1498  if (bridge_channel == bridge_find_channel(bridge, chan)) {
1499 /*
1500  * XXX ASTERISK-22366 this needs more work. The channels need
1501  * to be made compatible again if the formats change. The
1502  * bridge_channel thread needs to monitor for this case.
1503  */
1504  /* The channel we want to notify is still in a bridge. */
1505  bridge->v_table->notify_masquerade(bridge, bridge_channel);
1506  bridge_reconfigured(bridge, 1);
1507  }
1508  ast_bridge_unlock(bridge);
1509  ao2_ref(bridge_channel, -1);
1510 }
#define ast_channel_lock(chan)
Definition: channel.h:2945
struct ast_bridge_channel * bridge_find_channel(struct ast_bridge *bridge, struct ast_channel *chan)
Definition: bridge.c:1469
struct ast_bridge * bridge
Bridge this channel is participating in.
ast_bridge_notify_masquerade_fn notify_masquerade
Definition: bridge.h:277
#define ao2_ref(o, delta)
Definition: astobj2.h:464
const struct ast_bridge_methods * v_table
Definition: bridge.h:359
Structure that contains information about a bridge.
Definition: bridge.h:357
void bridge_reconfigured(struct ast_bridge *bridge, unsigned int colp_update)
Definition: bridge.c:1443
#define ast_channel_unlock(chan)
Definition: channel.h:2946
#define ast_bridge_unlock(bridge)
Unlock the bridge.
Definition: bridge.h:493
struct ast_bridge_channel * ast_channel_get_bridge_channel(struct ast_channel *chan)
Get a reference to the channel&#39;s bridge pointer.
Definition: channel.c:10783
Structure that contains information regarding a channel in a bridge.
void ast_bridge_channel_lock_bridge(struct ast_bridge_channel *bridge_channel)
Lock the bridge associated with the bridge channel.

◆ ast_bridge_number_video_src()

int ast_bridge_number_video_src ( struct ast_bridge bridge)

Returns the number of video sources currently active in the bridge.

Definition at line 3931 of file bridge.c.

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 softmix_bridge_write_video().

3932 {
3933  int res = 0;
3934 
3935  ast_bridge_lock(bridge);
3936  switch (bridge->softmix.video_mode.mode) {
3938  break;
3941  res = 1;
3942  }
3943  break;
3946  res++;
3947  }
3949  res++;
3950  }
3952  break;
3953  }
3954  ast_bridge_unlock(bridge);
3955  return res;
3956 }
struct ast_bridge_video_mode video_mode
Definition: bridge.h:287
struct ast_channel * chan_old_vsrc
Definition: bridge.h:127
struct ast_channel * chan_vsrc
Definition: bridge.h:116
struct ast_bridge_softmix softmix
Definition: bridge.h:375
union ast_bridge_video_mode::@227 mode_data
struct ast_bridge_video_talker_src_data talker_src_data
Definition: bridge.h:164
struct ast_bridge_video_single_src_data single_src_data
Definition: bridge.h:163
#define ast_bridge_unlock(bridge)
Unlock the bridge.
Definition: bridge.h:493
#define ast_bridge_lock(bridge)
Lock the bridge.
Definition: bridge.h:480
struct ast_channel * chan_vsrc
Definition: bridge.h:123
enum ast_bridge_video_mode_type mode
Definition: bridge.h:160

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

References ast_bridge_lock, ast_bridge_peer_nolock(), and ast_bridge_unlock.

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

4143 {
4144  struct ast_channel *peer;
4145 
4146  ast_bridge_lock(bridge);
4147  peer = ast_bridge_peer_nolock(bridge, chan);
4148  ast_bridge_unlock(bridge);
4149 
4150  return peer;
4151 }
Main Channel structure associated with a channel.
struct ast_channel * ast_bridge_peer_nolock(struct ast_bridge *bridge, struct ast_channel *chan)
Get the channel&#39;s bridge peer only if the bridge is two-party.
Definition: bridge.c:4114
#define ast_bridge_unlock(bridge)
Unlock the bridge.
Definition: bridge.h:493
#define ast_bridge_lock(bridge)
Lock the bridge.
Definition: bridge.h:480

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

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

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

4115 {
4116  struct ast_channel *peer = NULL;
4117  struct ast_bridge_channel *iter;
4118 
4119  /* Asking for the peer channel only makes sense on a two-party bridge. */
4120  if (bridge->num_channels == 2
4121  && bridge->technology->capabilities
4123  int in_bridge = 0;
4124 
4125  AST_LIST_TRAVERSE(&bridge->channels, iter, entry) {
4126  if (iter->chan != chan) {
4127  peer = iter->chan;
4128  } else {
4129  in_bridge = 1;
4130  }
4131  }
4132  if (in_bridge && peer) {
4133  ast_channel_ref(peer);
4134  } else {
4135  peer = NULL;
4136  }
4137  }
4138 
4139  return peer;
4140 }
Main Channel structure associated with a channel.
#define NULL
Definition: resample.c:96
struct ast_bridge_technology * technology
Definition: bridge.h:363
#define AST_LIST_TRAVERSE(head, var, field)
Loops over (traverses) the entries in a list.
Definition: linkedlists.h:490
unsigned int in_bridge
struct ast_bridge_channels_list channels
Definition: bridge.h:371
struct ast_channel * chan
Structure that contains information regarding a channel in a bridge.
#define ast_channel_ref(c)
Increase channel reference count.
Definition: channel.h:2970
Definition: search.h:40
unsigned int num_channels
Definition: bridge.h:381

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

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

4104 {
4105  struct ao2_container *channels;
4106 
4107  ast_bridge_lock(bridge);
4108  channels = ast_bridge_peers_nolock(bridge);
4109  ast_bridge_unlock(bridge);
4110 
4111  return channels;
4112 }
static struct channel_usage channels
#define ast_bridge_unlock(bridge)
Unlock the bridge.
Definition: bridge.h:493
struct ao2_container * ast_bridge_peers_nolock(struct ast_bridge *bridge)
Get a container of all channels in the bridge.
Definition: bridge.c:4085
#define ast_bridge_lock(bridge)
Lock the bridge.
Definition: bridge.h:480
Generic container type.

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

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

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

4086 {
4087  struct ao2_container *channels;
4088  struct ast_bridge_channel *iter;
4089 
4091  13, channel_hash, NULL, channel_cmp);
4092  if (!channels) {
4093  return NULL;
4094  }
4095 
4096  AST_LIST_TRAVERSE(&bridge->channels, iter, entry) {
4097  ao2_link(channels, iter->chan);
4098  }
4099 
4100  return channels;
4101 }
static int channel_cmp(void *obj, void *arg, int flags)
Definition: bridge.c:4063
#define NULL
Definition: resample.c:96
static struct channel_usage channels
static int channel_hash(const void *obj, int flags)
Definition: bridge.c:4040
#define ao2_container_alloc_hash(ao2_options, container_options, n_buckets, hash_fn, sort_fn, cmp_fn)
Definition: astobj2.h:1310
#define AST_LIST_TRAVERSE(head, var, field)
Loops over (traverses) the entries in a list.
Definition: linkedlists.h:490
struct ast_bridge_channels_list channels
Definition: bridge.h:371
struct ast_channel * chan
Structure that contains information regarding a channel in a bridge.
Definition: search.h:40
Generic container type.
#define ao2_link(container, obj)
Definition: astobj2.h:1549

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

References ast_frdup, and bridge_queue_action_nodup().

Referenced by bridge_dissolve().

308 {
309  struct ast_frame *dup;
310 
311  dup = ast_frdup(action);
312  if (!dup) {
313  return -1;
314  }
315  bridge_queue_action_nodup(bridge, dup);
316  return 0;
317 }
#define ast_frdup(fr)
Copies a frame.
static void bridge_queue_action_nodup(struct ast_bridge *bridge, struct ast_frame *action)
Definition: bridge.c:296
Data structure associated with a single frame of data.

◆ 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);

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

References ast_bridge_channel_leave_bridge(), ast_bridge_lock, ast_bridge_unlock, AST_CAUSE_NORMAL_CLEARING, ast_channel_name(), ast_debug, BRIDGE_CHANNEL_STATE_END_NO_DISSOLVE, bridge_find_channel(), 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().

1998 {
1999  struct ast_bridge_channel *bridge_channel;
2000 
2001  ast_debug(1, "Removing channel %s from bridge %s\n",
2002  ast_channel_name(chan), bridge->uniqueid);
2003 
2004  ast_bridge_lock(bridge);
2005 
2006  /* Try to find the channel that we want to remove */
2007  if (!(bridge_channel = bridge_find_channel(bridge, chan))) {
2008  ast_bridge_unlock(bridge);
2009  return -1;
2010  }
2011 
2012  ast_bridge_channel_leave_bridge(bridge_channel,
2014 
2015  ast_bridge_unlock(bridge);
2016 
2017  return 0;
2018 }
const ast_string_field uniqueid
Definition: bridge.h:409
struct ast_bridge_channel * bridge_find_channel(struct ast_bridge *bridge, struct ast_channel *chan)
Definition: bridge.c:1469
#define ast_debug(level,...)
Log a DEBUG message.
Definition: logger.h:452
#define AST_CAUSE_NORMAL_CLEARING
Definition: causes.h:105
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_bridge_unlock(bridge)
Unlock the bridge.
Definition: bridge.h:493
#define ast_bridge_lock(bridge)
Lock the bridge.
Definition: bridge.h:480
Structure that contains information regarding a channel in a bridge.
const char * ast_channel_name(const struct ast_channel *chan)

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

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

3985 {
3986  ast_bridge_lock(bridge);
3987  switch (bridge->softmix.video_mode.mode) {
3989  break;
3991  if (bridge->softmix.video_mode.mode_data.single_src_data.chan_vsrc == chan) {
3994  }
3996  }
3997  break;
3999  if (bridge->softmix.video_mode.mode_data.talker_src_data.chan_vsrc == chan) {
4002  }
4005  }
4009  }
4011  }
4013  break;
4014  }
4015  ast_bridge_unlock(bridge);
4016 }
#define ast_channel_unref(c)
Decrease channel reference count.
Definition: channel.h:2981
struct ast_bridge_video_mode video_mode
Definition: bridge.h:287
struct ast_channel * chan_old_vsrc
Definition: bridge.h:127
struct ast_channel * chan_vsrc
Definition: bridge.h:116
#define NULL
Definition: resample.c:96
struct ast_bridge_softmix softmix
Definition: bridge.h:375
union ast_bridge_video_mode::@227 mode_data
struct ast_bridge_video_talker_src_data talker_src_data
Definition: bridge.h:164
struct ast_bridge_video_single_src_data single_src_data
Definition: bridge.h:163
#define ast_bridge_unlock(bridge)
Unlock the bridge.
Definition: bridge.h:493
#define ast_bridge_lock(bridge)
Lock the bridge.
Definition: bridge.h:480
struct ast_channel * chan_vsrc
Definition: bridge.h:123
enum ast_bridge_video_mode_type mode
Definition: bridge.h:160

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

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

Referenced by join_conference_bridge().

3773 {
3774  ast_bridge_lock(bridge);
3775  bridge->softmix.binaural_active = binaural_active;
3776  ast_bridge_unlock(bridge);
3777 }
struct ast_bridge_softmix softmix
Definition: bridge.h:375
#define ast_bridge_unlock(bridge)
Unlock the bridge.
Definition: bridge.h:493
#define ast_bridge_lock(bridge)
Lock the bridge.
Definition: bridge.h:480
unsigned int binaural_active
Definition: bridge.h:303

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

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

Referenced by join_conference_bridge().

3780 {
3781  ast_bridge_lock(bridge);
3782  bridge->softmix.internal_sample_rate = sample_rate;
3783  ast_bridge_unlock(bridge);
3784 }
struct ast_bridge_softmix softmix
Definition: bridge.h:375
#define ast_bridge_unlock(bridge)
Unlock the bridge.
Definition: bridge.h:493
#define ast_bridge_lock(bridge)
Lock the bridge.
Definition: bridge.h:480
unsigned int internal_sample_rate
The internal sample rate softmix uses to mix channels.
Definition: bridge.h:293

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

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

Referenced by join_conference_bridge().

3787 {
3788  ast_bridge_lock(bridge);
3789  bridge->softmix.maximum_sample_rate = sample_rate;
3790  ast_bridge_unlock(bridge);
3791 }
struct ast_bridge_softmix softmix
Definition: bridge.h:375
#define ast_bridge_unlock(bridge)
Unlock the bridge.
Definition: bridge.h:493
#define ast_bridge_lock(bridge)
Lock the bridge.
Definition: bridge.h:480
unsigned int maximum_sample_rate
The maximum sample rate softmix uses to mix channels.
Definition: bridge.h:314

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

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

Referenced by join_conference_bridge().

3766 {
3767  ast_bridge_lock(bridge);
3768  bridge->softmix.internal_mixing_interval = mixing_interval;
3769  ast_bridge_unlock(bridge);
3770 }
unsigned int internal_mixing_interval
The mixing interval indicates how quickly softmix mixing should occur to mix audio.
Definition: bridge.h:301
struct ast_bridge_softmix softmix
Definition: bridge.h:375
#define ast_bridge_unlock(bridge)
Unlock the bridge.
Definition: bridge.h:493
#define ast_bridge_lock(bridge)
Lock the bridge.
Definition: bridge.h:480

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

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

3875 {
3877 
3878  ast_bridge_lock(bridge);
3879  bridge->softmix.video_mode.mode_data.sfu_data.estimated_bitrate = estimated_bitrate;
3880  ast_bridge_unlock(bridge);
3881 }
struct ast_bridge_video_mode video_mode
Definition: bridge.h:287
#define ast_assert(a)
Definition: utils.h:695
struct ast_bridge_softmix softmix
Definition: bridge.h:375
union ast_bridge_video_mode::@227 mode_data
struct ast_bridge_video_sfu_data sfu_data
Definition: bridge.h:165
#define ast_bridge_unlock(bridge)
Unlock the bridge.
Definition: bridge.h:493
#define ast_bridge_lock(bridge)
Lock the bridge.
Definition: bridge.h:480
enum ast_bridge_video_mode_type mode
Definition: bridge.h:160

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

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

3857 {
3859 
3860  ast_bridge_lock(bridge);
3861  bridge->softmix.video_mode.mode_data.sfu_data.remb_send_interval = remb_send_interval;
3862  ast_bridge_unlock(bridge);
3863 }
unsigned int remb_send_interval
Definition: bridge.h:151
struct ast_bridge_video_mode video_mode
Definition: bridge.h:287
#define ast_assert(a)
Definition: utils.h:695
struct ast_bridge_softmix softmix
Definition: bridge.h:375
union ast_bridge_video_mode::@227 mode_data
struct ast_bridge_video_sfu_data sfu_data
Definition: bridge.h:165
#define ast_bridge_unlock(bridge)
Unlock the bridge.
Definition: bridge.h:493
#define ast_bridge_lock(bridge)
Lock the bridge.
Definition: bridge.h:480
enum ast_bridge_video_mode_type mode
Definition: bridge.h:160

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

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

Referenced by join_conference_bridge().

4034 {
4035  ast_bridge_lock(bridge);
4036  bridge->softmix.send_sdp_label = send_sdp_label;
4037  ast_bridge_unlock(bridge);
4038 }
struct ast_bridge_softmix softmix
Definition: bridge.h:375
#define ast_bridge_unlock(bridge)
Unlock the bridge.
Definition: bridge.h:493
unsigned int send_sdp_label
Definition: bridge.h:308
#define ast_bridge_lock(bridge)
Lock the bridge.
Definition: bridge.h:480

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

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

3842 {
3843  ast_bridge_lock(bridge);
3844  cleanup_video_mode(bridge);
3846  ast_bridge_unlock(bridge);
3847 }
struct ast_bridge_video_mode video_mode
Definition: bridge.h:287
static void cleanup_video_mode(struct ast_bridge *bridge)
Definition: bridge.c:3793
struct ast_bridge_softmix softmix
Definition: bridge.h:375
#define ast_bridge_unlock(bridge)
Unlock the bridge.
Definition: bridge.h:493
#define ast_bridge_lock(bridge)
Lock the bridge.
Definition: bridge.h:480
enum ast_bridge_video_mode_type mode
Definition: bridge.h:160

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

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

3817 {
3818  ast_bridge_lock(bridge);
3819  cleanup_video_mode(bridge);
3821  if (video_src_chan) {
3823  ast_verb(5, "Video source in bridge '%s' (%s) is now '%s' (%s)\n",
3824  bridge->name, bridge->uniqueid,
3825  ast_channel_name(video_src_chan),
3826  ast_channel_uniqueid(video_src_chan));
3827  ast_indicate(video_src_chan, AST_CONTROL_VIDUPDATE);
3828  }
3829  ast_bridge_publish_state(bridge);
3830  ast_bridge_unlock(bridge);
3831 }
const ast_string_field uniqueid
Definition: bridge.h:409
int ast_indicate(struct ast_channel *chan, int condition)
Indicates condition of channel.
Definition: channel.c:4322
struct ast_bridge_video_mode video_mode
Definition: bridge.h:287
const ast_string_field name
Definition: bridge.h:409
struct ast_channel * chan_vsrc
Definition: bridge.h:116
static void cleanup_video_mode(struct ast_bridge *bridge)
Definition: bridge.c:3793
struct ast_bridge_softmix softmix
Definition: bridge.h:375
union ast_bridge_video_mode::@227 mode_data
#define ast_verb(level,...)
Definition: logger.h:463
void ast_bridge_publish_state(struct ast_bridge *bridge)
Publish the state of a bridge.
struct ast_bridge_video_single_src_data single_src_data
Definition: bridge.h:163
const char * ast_channel_uniqueid(const struct ast_channel *chan)
#define ast_bridge_unlock(bridge)
Unlock the bridge.
Definition: bridge.h:493
#define ast_bridge_lock(bridge)
Lock the bridge.
Definition: bridge.h:480
#define ast_channel_ref(c)
Increase channel reference count.
Definition: channel.h:2970
const char * ast_channel_name(const struct ast_channel *chan)
enum ast_bridge_video_mode_type mode
Definition: bridge.h:160

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

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

3834 {
3835  ast_bridge_lock(bridge);
3836  cleanup_video_mode(bridge);
3838  ast_bridge_unlock(bridge);
3839 }
struct ast_bridge_video_mode video_mode
Definition: bridge.h:287
static void cleanup_video_mode(struct ast_bridge *bridge)
Definition: bridge.c:3793
struct ast_bridge_softmix softmix
Definition: bridge.h:375
#define ast_bridge_unlock(bridge)
Unlock the bridge.
Definition: bridge.h:493
#define ast_bridge_lock(bridge)
Lock the bridge.
Definition: bridge.h:480
enum ast_bridge_video_mode_type mode
Definition: bridge.h:160

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

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

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

4405 {
4406  char *writevar;
4407  char *erasevar;
4408 
4409  if (attended) {
4410  writevar = ATTENDEDTRANSFER;
4411  erasevar = BLINDTRANSFER;
4412  } else {
4413  writevar = BLINDTRANSFER;
4414  erasevar = ATTENDEDTRANSFER;
4415  }
4416 
4417  pbx_builtin_setvar_helper(chan, writevar, value);
4418  pbx_builtin_setvar_helper(chan, erasevar, NULL);
4419 }
#define ATTENDEDTRANSFER
Definition: bridge.c:139
#define NULL
Definition: resample.c:96
int value
Definition: syslog.c:37
#define BLINDTRANSFER
Definition: bridge.c:136
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...

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

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

3850 {
3851  ast_bridge_lock(bridge);
3852  bridge->softmix.video_mode.video_update_discard = video_update_discard;
3853  ast_bridge_unlock(bridge);
3854 }
struct ast_bridge_video_mode video_mode
Definition: bridge.h:287
struct ast_bridge_softmix softmix
Definition: bridge.h:375
#define ast_bridge_unlock(bridge)
Unlock the bridge.
Definition: bridge.h:493
unsigned int video_update_discard
Definition: bridge.h:168
#define ast_bridge_lock(bridge)
Lock the bridge.
Definition: bridge.h:480

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

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

References ast_bridge_lock, ast_bridge_unlock, bridge_channel_internal_suspend_nolock(), and bridge_find_channel().

Referenced by conf_moh_start(), and conf_moh_stop().

3069 {
3070  struct ast_bridge_channel *bridge_channel;
3071 /* XXX ASTERISK-21271 the case of a disolved bridge while channel is suspended is not handled. */
3072 /* XXX ASTERISK-21271 suspend/unsuspend needs to be rethought. The caller must block until it has successfully suspended the channel for temporary control. */
3073 /* 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. */
3074 
3075  ast_bridge_lock(bridge);
3076 
3077  if (!(bridge_channel = bridge_find_channel(bridge, chan))) {
3078  ast_bridge_unlock(bridge);
3079  return -1;
3080  }
3081 
3083 
3084  ast_bridge_unlock(bridge);
3085 
3086  return 0;
3087 }
void bridge_channel_internal_suspend_nolock(struct ast_bridge_channel *bridge_channel)
struct ast_bridge_channel * bridge_find_channel(struct ast_bridge *bridge, struct ast_channel *chan)
Definition: bridge.c:1469
#define ast_bridge_unlock(bridge)
Unlock the bridge.
Definition: bridge.h:493
#define ast_bridge_lock(bridge)
Lock the bridge.
Definition: bridge.h:480
Structure that contains information regarding a channel in a bridge.

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

References AST_BRIDGE_HOOK_TYPE_TALK, bridge_other_hook(), and hook_cb().

Referenced by confbridge_exec().

3363 {
3365 
3366  return bridge_other_hook(features, hook_cb, hook_pvt, destructor, remove_flags,
3368 }
int(* ast_bridge_hook_callback)(struct ast_bridge_channel *bridge_channel, void *hook_pvt)
Hook callback type.
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:3294
static int hook_cb(struct ast_config *cfg)
Definition: test_config.c:875

◆ 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);

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

References ast_bridge_technology::suspended.

Referenced by handle_bridge_technology_suspend(), and handle_manager_bridge_tech_suspend().

3109 {
3110  technology->suspended = 1;
3111 }

◆ 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);

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

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

Referenced by dahdi_native_unload(), and unload_module().

266 {
267  struct ast_bridge_technology *current;
268 
270 
271  /* Ensure the bridge technology is registered before removing it */
273  if (current == technology) {
275  ast_verb(2, "Unregistered bridge technology %s\n", technology->name);
276  break;
277  }
278  }
280 
282 
283  return current ? 0 : -1;
284 }
#define AST_RWLIST_WRLOCK(head)
Write locks a list.
Definition: linkedlists.h:51
#define AST_RWLIST_UNLOCK(head)
Attempts to unlock a read/write based list.
Definition: linkedlists.h:150
#define ast_verb(level,...)
Definition: logger.h:463
#define AST_RWLIST_REMOVE_CURRENT
Definition: linkedlists.h:569
#define AST_RWLIST_TRAVERSE_SAFE_BEGIN
Definition: linkedlists.h:544
Structure that is the essence of a bridge technology.
Definition: search.h:40
#define AST_RWLIST_TRAVERSE_SAFE_END
Definition: linkedlists.h:616

◆ 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);

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

Definition at line 3113 of file bridge.c.

References ast_bridge_technology::suspended.

Referenced by handle_bridge_technology_suspend(), and handle_manager_bridge_tech_suspend().

3114 {
3115  /*
3116  * XXX We may want the act of unsuspending a bridge technology
3117  * to prod all existing bridges to see if they should start
3118  * using it.
3119  */
3120  technology->suspended = 0;
3121 }

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

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, bridge_manager_request::bridge, ast_bridge::feature_flags, and NULL.

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

4461 {
4462  struct ast_bridge *bridge;
4463 
4464  ast_channel_lock(chan);
4465  bridge = ast_channel_get_bridge(chan);
4466  ast_channel_unlock(chan);
4467 
4468  if (bridge && ast_test_flag(&bridge->feature_flags,
4470  ao2_ref(bridge, -1);
4471  bridge = NULL;
4472  }
4473 
4474  return bridge;
4475 }
#define ast_channel_lock(chan)
Definition: channel.h:2945
struct ast_flags feature_flags
Definition: bridge.h:377
#define ast_test_flag(p, flag)
Definition: utils.h:63
#define NULL
Definition: resample.c:96
struct ast_bridge * ast_channel_get_bridge(const struct ast_channel *chan)
Get the bridge associated with a channel.
Definition: channel.c:10735
#define ao2_ref(o, delta)
Definition: astobj2.h:464
Structure that contains information about a bridge.
Definition: bridge.h:357
#define ast_channel_unlock(chan)
Definition: channel.h:2946

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

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(), local_attended_transfer(), misdn_attempt_transfer(), refer_attended_task(), and skinny_transfer_attended().

4731 {
4732  RAII_VAR(struct ast_bridge *, to_transferee_bridge, NULL, ao2_cleanup);
4733  RAII_VAR(struct ast_bridge *, to_target_bridge, NULL, ao2_cleanup);
4734  RAII_VAR(struct ast_bridge_channel *, to_transferee_bridge_channel, NULL, ao2_cleanup);
4735  RAII_VAR(struct ast_bridge_channel *, to_target_bridge_channel, NULL, ao2_cleanup);
4737  RAII_VAR(struct ast_channel *, transferee, NULL, ao2_cleanup);
4738  RAII_VAR(struct ast_attended_transfer_message *, transfer_msg, NULL, ao2_cleanup);
4739  struct ast_bridge *the_bridge = NULL;
4740  struct ast_channel *chan_bridged;
4741  struct ast_channel *chan_unbridged;
4742  int transfer_prohibited;
4743  int do_bridge_transfer;
4744  enum ast_transfer_result res;
4745  const char *app = NULL;
4746  int hangup_target = 0;
4747 
4748  to_transferee_bridge = ast_bridge_transfer_acquire_bridge(to_transferee);
4749  to_target_bridge = ast_bridge_transfer_acquire_bridge(to_transfer_target);
4750 
4751  transfer_msg = ast_attended_transfer_message_create(1, to_transferee, to_transferee_bridge,
4752  to_transfer_target, to_target_bridge, NULL, NULL);
4753  if (!transfer_msg) {
4754  ast_log(LOG_ERROR, "Unable to create Stasis publication for attended transfer from %s\n",
4755  ast_channel_name(to_transferee));
4756  return AST_BRIDGE_TRANSFER_FAIL;
4757  }
4758 
4759  /* They can't both be unbridged, you silly goose! */
4760  if (!to_transferee_bridge && !to_target_bridge) {
4762  goto end;
4763  }
4764 
4765  ast_channel_lock(to_transferee);
4766  to_transferee_bridge_channel = ast_channel_get_bridge_channel(to_transferee);
4767  ast_channel_unlock(to_transferee);
4768 
4769  ast_channel_lock(to_transfer_target);
4770  to_target_bridge_channel = ast_channel_get_bridge_channel(to_transfer_target);
4771  ast_channel_unlock(to_transfer_target);
4772 
4773  if (to_transferee_bridge_channel) {
4774  /* Take off hold if they are on hold. */
4775  if (ast_bridge_channel_write_unhold(to_transferee_bridge_channel)) {
4776  ast_log(LOG_ERROR, "Transferee channel disappeared during transfer!\n");
4778  goto end;
4779  }
4780  }
4781 
4782  if (to_target_bridge_channel) {
4783  const char *target_complete_sound;
4784 
4785  /* Take off hold if they are on hold. */
4786  if (ast_bridge_channel_write_unhold(to_target_bridge_channel)) {
4787  ast_log(LOG_ERROR, "Target channel disappeared during transfer!\n");
4789  goto end;
4790  }
4791 
4792  /* Is there a courtesy sound to play to the target? */
4793  ast_channel_lock(to_transfer_target);
4794  target_complete_sound = pbx_builtin_getvar_helper(to_transfer_target,
4795  "ATTENDED_TRANSFER_COMPLETE_SOUND");
4796  if (!ast_strlen_zero(target_complete_sound)) {
4797  target_complete_sound = ast_strdupa(target_complete_sound);
4798  } else {
4799  target_complete_sound = NULL;
4800  }
4801  ast_channel_unlock(to_transfer_target);
4802  if (!target_complete_sound) {
4803  ast_channel_lock(to_transferee);
4804  target_complete_sound = pbx_builtin_getvar_helper(to_transferee,
4805  "ATTENDED_TRANSFER_COMPLETE_SOUND");
4806  if (!ast_strlen_zero(target_complete_sound)) {
4807  target_complete_sound = ast_strdupa(target_complete_sound);
4808  } else {
4809  target_complete_sound = NULL;
4810  }
4811  ast_channel_unlock(to_transferee);
4812  }
4813  if (target_complete_sound) {
4814  ast_bridge_channel_write_playfile(to_target_bridge_channel, NULL,
4815  target_complete_sound, NULL);
4816  }
4817  }
4818 
4819  /* Let's get the easy one out of the way first */
4820  if (to_transferee_bridge && to_target_bridge) {
4821 
4822  if (!to_transferee_bridge_channel || !to_target_bridge_channel) {
4824  goto end;
4825  }
4826 
4827  ast_bridge_lock_both(to_transferee_bridge, to_target_bridge);
4828  res = two_bridge_attended_transfer(to_transferee, to_transferee_bridge_channel,
4829  to_transfer_target, to_target_bridge_channel,
4830  to_transferee_bridge, to_target_bridge, transfer_msg);
4831  ast_bridge_unlock(to_transferee_bridge);
4832  ast_bridge_unlock(to_target_bridge);
4833 
4834  hangup_target = 1;
4835  goto end;
4836  }
4837 
4838  the_bridge = to_transferee_bridge ?: to_target_bridge;
4839  chan_bridged = to_transferee_bridge ? to_transferee : to_transfer_target;
4840  chan_unbridged = to_transferee_bridge ? to_transfer_target : to_transferee;
4841 
4842  /*
4843  * Race condition makes it possible for app to be NULL, so get the app prior to
4844  * transferring with a fallback of "unknown".
4845  */
4846  app = ast_strdupa(ast_channel_appl(chan_unbridged) ?: "unknown");
4847 
4848  {
4849  int chan_count;
4851 
4852  channels = ast_bridge_peers_nolock(the_bridge);
4853  if (!channels) {
4855  goto end;
4856  }
4857  chan_count = ao2_container_count(channels);
4858  if (chan_count <= 1) {
4860  goto end;
4861  }
4862  transfer_prohibited = ast_test_flag(&the_bridge->feature_flags,
4864  do_bridge_transfer = ast_test_flag(&the_bridge->feature_flags,
4866  chan_count > 2;
4867  }
4868 
4869  if (transfer_prohibited) {
4871  goto end;
4872  }
4873 
4874  set_transfer_variables_all(to_transferee, channels, 1);
4875 
4876  if (do_bridge_transfer) {
4877  /*
4878  * Hang up the target if it was bridged. Note, if it is not bridged
4879  * it is hung up during the masquerade.
4880  */
4881  hangup_target = chan_bridged == to_transfer_target;
4882  ast_bridge_lock(the_bridge);
4883  res = attended_transfer_bridge(chan_bridged, chan_unbridged, the_bridge, NULL, transfer_msg);
4884  ast_bridge_unlock(the_bridge);
4885  goto end;
4886  }
4887 
4888  transferee = get_transferee(channels, chan_bridged);
4889  if (!transferee) {
4891  goto end;
4892  }
4893 
4894  if (bridge_channel_internal_queue_attended_transfer(transferee, chan_unbridged)) {
4896  goto end;
4897  }
4898 
4899  ast_bridge_remove(the_bridge, chan_bridged);
4900 
4901  ast_attended_transfer_message_add_app(transfer_msg, app, NULL);
4903 
4904 end:
4905  if ((res == AST_BRIDGE_TRANSFER_SUCCESS && hangup_target) || res == AST_BRIDGE_TRANSFER_FAIL) {
4906  ast_softhangup(to_transfer_target, AST_SOFTHANGUP_DEV);
4907  }
4908 
4909  transfer_msg->result = res;
4911  return res;
4912 }
#define ast_channel_lock(chan)
Definition: channel.h:2945
Main Channel structure associated with a channel.
#define ast_bridge_lock_both(bridge1, bridge2)
Lock two bridges.
Definition: bridge.h:500
struct ast_flags feature_flags
Definition: bridge.h:377
int ao2_container_count(struct ao2_container *c)
Returns the number of elements in a container.
struct ast_bridge * ast_bridge_transfer_acquire_bridge(struct ast_channel *chan)
Acquire the channel&#39;s bridge for transfer purposes.
Definition: bridge.c:4460
Message representing attended transfer.
#define ast_test_flag(p, flag)
Definition: utils.h:63
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.
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:4663
#define NULL
Definition: resample.c:96
char * end
Definition: eagi_proxy.c:73
ast_transfer_result
Definition: bridge.h:1115
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 ast_strlen_zero(foo)
Definition: strings.h:52
#define ast_log
Definition: astobj2.c:42
static void set_transfer_variables_all(struct ast_channel *transferer, struct ao2_container *channels, int is_attended)
Definition: bridge.c:4435
#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:911
ast_mutex_t lock
Definition: app_meetme.c:1091
int ast_softhangup(struct ast_channel *chan, int reason)
Softly hangup up a channel.
Definition: channel.c:2476
#define ast_strdupa(s)
duplicate a string in memory from the stack
Definition: astmm.h:300
#define SCOPED_LOCK(varname, lock, lockfunc, unlockfunc)
Scoped Locks.
Definition: lock.h:581
static struct channel_usage channels
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:4280
Structure that contains information about a bridge.
Definition: bridge.h:357
#define LOG_ERROR
Definition: logger.h:285
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.
const char * ast_channel_appl(const struct ast_channel *chan)
#define ast_channel_unlock(chan)
Definition: channel.h:2946
#define ast_bridge_unlock(bridge)
Unlock the bridge.
Definition: bridge.h:493
struct ao2_container * ast_bridge_peers_nolock(struct ast_bridge *bridge)
Get a container of all channels in the bridge.
Definition: bridge.c:4085
struct ast_bridge_channel * ast_channel_get_bridge_channel(struct ast_channel *chan)
Get a reference to the channel&#39;s bridge pointer.
Definition: channel.c:10783
#define ast_bridge_lock(bridge)
Lock the bridge.
Definition: bridge.h:480
Structure that contains information regarding a channel in a bridge.
#define ao2_cleanup(obj)
Definition: astobj2.h:1958
const char * ast_channel_name(const struct ast_channel *chan)
static struct ast_channel * get_transferee(struct ao2_container *channels, struct ast_channel *transferer)
Definition: bridge.c:4241
int bridge_channel_internal_queue_attended_transfer(struct ast_channel *transferee, struct ast_channel *unbridged_chan)
Generic container type.
int ast_bridge_remove(struct ast_bridge *bridge, struct ast_channel *chan)
Remove a channel from a bridge.
Definition: bridge.c:1997
int ast_bridge_channel_write_unhold(struct ast_bridge_channel *bridge_channel)
Write an unhold frame into the bridge.
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.
static const char app[]
Definition: app_mysql.c:62

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

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_manager_request::bridge, bridge_channel_internal_queue_blind_transfer(), channels, ast_bridge::feature_flags, lock, LOG_ERROR, NULL, publish, RAII_VAR, SCOPED_LOCK, set_transfer_variables_all(), and try_parking().

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

4480 {
4481  RAII_VAR(struct ast_bridge *, bridge, NULL, ao2_cleanup);
4482  RAII_VAR(struct ast_bridge_channel *, bridge_channel, NULL, ao2_cleanup);
4484  RAII_VAR(struct ast_channel *, transferee, NULL, ast_channel_cleanup);
4485  RAII_VAR(struct transfer_channel_data *, user_data_wrapper, NULL, ao2_cleanup);
4486  RAII_VAR(struct ast_blind_transfer_message *, transfer_message, NULL, ao2_cleanup);
4487  int do_bridge_transfer;
4488  int transfer_prohibited;
4489  enum ast_transfer_result transfer_result;
4490 
4491  transfer_message = ast_blind_transfer_message_create(is_external, transferer, exten, context);
4492  if (!transfer_message) {
4493  /* Out of memory. Not even possible to publish a Stasis message about the
4494  * failure
4495  */
4496  ast_log(LOG_ERROR, "Unable to allocate memory for blind transfer publication from %s\n",
4497  ast_channel_name(transferer));
4498  return AST_BRIDGE_TRANSFER_FAIL;
4499  }
4500 
4501  bridge = ast_bridge_transfer_acquire_bridge(transferer);
4502  if (!bridge) {
4503  transfer_result = AST_BRIDGE_TRANSFER_INVALID;
4504  goto publish;
4505  }
4506 
4507  ast_bridge_lock(bridge);
4508  transfer_message->bridge = ast_bridge_snapshot_create(bridge);
4509  ast_bridge_unlock(bridge);
4510  if (!transfer_message->bridge) {
4511  transfer_result = AST_BRIDGE_TRANSFER_FAIL;
4512  goto publish;
4513  }
4514 
4515  transferee = ast_bridge_peer(bridge, transferer);
4516  if (transferee) {
4517  transfer_message->transferee = ast_channel_snapshot_get_latest(ast_channel_uniqueid(transferee));
4518  if (!transfer_message->transferee) {
4519  transfer_result = AST_BRIDGE_TRANSFER_FAIL;
4520  goto publish;
4521  }
4522  }
4523 
4524  ast_channel_lock(transferer);
4525  bridge_channel = ast_channel_get_bridge_channel(transferer);
4526  ast_channel_unlock(transferer);
4527  if (!bridge_channel) {
4528  transfer_result = AST_BRIDGE_TRANSFER_INVALID;
4529  goto publish;
4530  }
4531 
4532  user_data_wrapper = ao2_alloc(sizeof(*user_data_wrapper), NULL);
4533  if (!user_data_wrapper) {
4534  transfer_result = AST_BRIDGE_TRANSFER_FAIL;
4535  goto publish;
4536  }
4537 
4538  user_data_wrapper->data = user_data;
4539 
4540  /* Take off hold if they are on hold. */
4541  ast_bridge_channel_write_unhold(bridge_channel);
4542 
4543  transfer_result = try_parking(transferer, context, exten, new_channel_cb, user_data_wrapper);
4544  if (transfer_result == AST_BRIDGE_TRANSFER_SUCCESS) {
4545  goto publish;
4546  }
4547 
4548  /* Since parking didn't take control of the user_data_wrapper, we are just going to raise the completed flag now. */
4549  user_data_wrapper->completed = 1;
4550 
4551  {
4553 
4555  if (!channels) {
4556  transfer_result = AST_BRIDGE_TRANSFER_FAIL;
4557  goto publish;
4558  }
4559  if (ao2_container_count(channels) <= 1) {
4560  transfer_result = AST_BRIDGE_TRANSFER_INVALID;
4561  goto publish;
4562  }
4563  transfer_prohibited = ast_test_flag(&bridge->feature_flags,
4565  do_bridge_transfer = ast_test_flag(&bridge->feature_flags,
4568  }
4569 
4570  if (transfer_prohibited) {
4571  transfer_result = AST_BRIDGE_TRANSFER_NOT_PERMITTED;
4572  goto publish;
4573  }
4574 
4575  set_transfer_variables_all(transferer, channels, 0);
4576 
4577  if (do_bridge_transfer) {
4578  transfer_result = blind_transfer_bridge(is_external, transferer, bridge,
4579  exten, context, transferee, new_channel_cb, user_data_wrapper, transfer_message);
4580  goto publish;
4581  }
4582 
4583  /* Reaching this portion means that we're dealing with a two-party bridge */
4584 
4585  if (!transferee) {
4586  transfer_result = AST_BRIDGE_TRANSFER_FAIL;
4587  goto publish;
4588  }
4589 
4591  new_channel_cb, user_data_wrapper)) {
4592  transfer_result = AST_BRIDGE_TRANSFER_FAIL;
4593  goto publish;
4594  }
4595 
4596  ast_bridge_remove(bridge, transferer);
4597  transfer_result = AST_BRIDGE_TRANSFER_SUCCESS;
4598 
4599 publish:
4600  transfer_message->result = transfer_result;
4601  ast_bridge_publish_blind_transfer(transfer_message);
4602  return transfer_result;
4603 }
#define ast_channel_lock(chan)
Definition: channel.h:2945
static char exten[AST_MAX_EXTENSION]
Definition: chan_alsa.c:118
Main Channel structure associated with a channel.
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.
int ao2_container_count(struct ao2_container *c)
Returns the number of elements in a container.
struct ast_bridge * ast_bridge_transfer_acquire_bridge(struct ast_channel *chan)
Acquire the channel&#39;s bridge for transfer purposes.
Definition: bridge.c:4460
#define ast_test_flag(p, flag)
Definition: utils.h:63
Message published during a blind transfer.
#define NULL
Definition: resample.c:96
ast_transfer_result
Definition: bridge.h:1115
unsigned char publish
Definition: res_corosync.c:241
#define ast_log
Definition: astobj2.c:42
static void set_transfer_variables_all(struct ast_channel *transferer, struct ao2_container *channels, int is_attended)
Definition: bridge.c:4435
#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:911
ast_mutex_t lock
Definition: app_meetme.c:1091
#define ast_channel_cleanup(c)
Cleanup a channel reference.
Definition: channel.h:2992
#define SCOPED_LOCK(varname, lock, lockfunc, unlockfunc)
Scoped Locks.
Definition: lock.h:581
static struct channel_usage channels
const char * ast_channel_uniqueid(const struct ast_channel *chan)
Structure that contains information about a bridge.
Definition: bridge.h:357
#define LOG_ERROR
Definition: logger.h:285
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)
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:4378
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:4178
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...
#define ao2_alloc(data_size, destructor_fn)
Definition: astobj2.h:411
struct ast_channel * ast_bridge_peer(struct ast_bridge *bridge, struct ast_channel *chan)
Get the channel&#39;s bridge peer only if the bridge is two-party.
Definition: bridge.c:4142
#define ast_channel_unlock(chan)
Definition: channel.h:2946
#define ast_bridge_unlock(bridge)
Unlock the bridge.
Definition: bridge.h:493
void ast_bridge_publish_blind_transfer(struct ast_blind_transfer_message *transfer_message)
Publish a blind transfer event.
struct ao2_container * ast_bridge_peers_nolock(struct ast_bridge *bridge)
Get a container of all channels in the bridge.
Definition: bridge.c:4085
struct ast_bridge_channel * ast_channel_get_bridge_channel(struct ast_channel *chan)
Get a reference to the channel&#39;s bridge pointer.
Definition: channel.c:10783
#define ast_bridge_lock(bridge)
Lock the bridge.
Definition: bridge.h:480
Structure that contains information regarding a channel in a bridge.
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...
#define ao2_cleanup(obj)
Definition: astobj2.h:1958
const char * ast_channel_name(const struct ast_channel *chan)
AO2 object that wraps data for transfer_channel_cb.
Definition: bridge.h:1136
Generic container type.
static char context[AST_MAX_CONTEXT]
Definition: chan_alsa.c:116
int ast_bridge_remove(struct ast_bridge *bridge, struct ast_channel *chan)
Remove a channel from a bridge.
Definition: bridge.c:1997
int ast_bridge_channel_write_unhold(struct ast_bridge_channel *bridge_channel)
Write an unhold frame into the bridge.

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

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

Referenced by got_optimized_out().

2969 {
2970  struct ast_bridge *chan_bridge;
2971  struct ast_bridge *peer_bridge;
2972  struct ast_bridge_channel *chan_bridge_channel;
2973  struct ast_bridge_channel *peer_bridge_channel;
2974  int res = 0;
2975 
2976  chan_bridge = optimize_lock_chan_stack(chan);
2977  if (!chan_bridge) {
2978  return res;
2979  }
2980  chan_bridge_channel = ast_channel_internal_bridge_channel(chan);
2981 
2982  peer_bridge = optimize_lock_peer_stack(peer);
2983  if (peer_bridge) {
2984  peer_bridge_channel = ast_channel_internal_bridge_channel(peer);
2985 
2986  res = try_swap_optimize_out(chan_bridge, chan_bridge_channel,
2987  peer_bridge, peer_bridge_channel, pvt);
2988  if (!res) {
2989  res = try_merge_optimize_out(chan_bridge, chan_bridge_channel,
2990  peer_bridge, peer_bridge_channel, pvt);
2991  } else if (0 < res) {
2992  res = 0;
2993  }
2994 
2995  /* Release peer locks. */
2996  ast_bridge_unlock(peer_bridge);
2997  ast_bridge_channel_unlock(peer_bridge_channel);
2998  ast_channel_unlock(peer);
2999  }
3000 
3001  /* Release chan locks. */
3002  ast_bridge_unlock(chan_bridge);
3003  ast_bridge_channel_unlock(chan_bridge_channel);
3004 
3005  return res;
3006 }
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:2793
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:2917
static struct ast_bridge * optimize_lock_peer_stack(struct ast_channel *peer)
Definition: bridge.c:2672
struct ast_bridge_channel * ast_channel_internal_bridge_channel(const struct ast_channel *chan)
#define ast_bridge_channel_unlock(bridge_channel)
Unlock the bridge_channel.
Structure that contains information about a bridge.
Definition: bridge.h:357
#define ast_channel_unlock(chan)
Definition: channel.h:2946
#define ast_bridge_unlock(bridge)
Unlock the bridge.
Definition: bridge.h:493
static struct ast_bridge * optimize_lock_chan_stack(struct ast_channel *chan)
Definition: bridge.c:2627
Structure that contains information regarding a channel in a bridge.

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

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

References ast_bridge_lock, ast_bridge_unlock, bridge_channel_internal_unsuspend_nolock(), and bridge_find_channel().

Referenced by conf_moh_start(), and conf_moh_stop().

3090 {
3091  struct ast_bridge_channel *bridge_channel;
3092 /* XXX ASTERISK-21271 the case of a disolved bridge while channel is suspended is not handled. */
3093 
3094  ast_bridge_lock(bridge);
3095 
3096  if (!(bridge_channel = bridge_find_channel(bridge, chan))) {
3097  ast_bridge_unlock(bridge);
3098  return -1;
3099  }
3100 
3102 
3103  ast_bridge_unlock(bridge);
3104 
3105  return 0;
3106 }
struct ast_bridge_channel * bridge_find_channel(struct ast_bridge *bridge, struct ast_channel *chan)
Definition: bridge.c:1469
void bridge_channel_internal_unsuspend_nolock(struct ast_bridge_channel *bridge_channel)
#define ast_bridge_unlock(bridge)
Unlock the bridge.
Definition: bridge.h:493
#define ast_bridge_lock(bridge)
Lock the bridge.
Definition: bridge.h:480
Structure that contains information regarding a channel in a bridge.

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

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

3884 {
3885  struct ast_bridge_video_talker_src_data *data;
3886 
3887  /* If the channel doesn't support video, we don't care about it */
3889  return;
3890  }
3891 
3892  ast_bridge_lock(bridge);
3893  data = &bridge->softmix.video_mode.mode_data.talker_src_data;
3894 
3895  if (data->chan_vsrc == chan) {
3896  data->average_talking_energy = talker_energy;
3897  } else if ((data->average_talking_energy < talker_energy) && is_keyframe) {
3898  if (data->chan_old_vsrc) {
3900  }
3901  if (data->chan_vsrc) {
3902  data->chan_old_vsrc = data->chan_vsrc;
3904  }
3905  data->chan_vsrc = ast_channel_ref(chan);
3906  data->average_talking_energy = talker_energy;
3907  ast_verb(5, "Video source in bridge '%s' (%s) is now '%s' (%s)\n",
3908  bridge->name, bridge->uniqueid,
3909  ast_channel_name(data->chan_vsrc),
3911  ast_bridge_publish_state(bridge);
3913  } else if ((data->average_talking_energy < talker_energy) && !is_keyframe) {
3915  } else if (!data->chan_vsrc && is_keyframe) {
3916  data->chan_vsrc = ast_channel_ref(chan);
3917  data->average_talking_energy = talker_energy;
3918  ast_verb(5, "Video source in bridge '%s' (%s) is now '%s' (%s)\n",
3919  bridge->name, bridge->uniqueid,
3920  ast_channel_name(data->chan_vsrc),
3922  ast_bridge_publish_state(bridge);
3924  } else if (!data->chan_old_vsrc && is_keyframe) {
3925  data->chan_old_vsrc = ast_channel_ref(chan);
3927  }
3928  ast_bridge_unlock(bridge);
3929 }
const ast_string_field uniqueid
Definition: bridge.h:409
#define ast_channel_unref(c)
Decrease channel reference count.
Definition: channel.h:2981
int ast_indicate(struct ast_channel *chan, int condition)
Indicates condition of channel.
Definition: channel.c:4322
struct ast_bridge_video_mode video_mode
Definition: bridge.h:287
const ast_string_field name
Definition: bridge.h:409
struct ast_channel * chan_old_vsrc
Definition: bridge.h:127
This is used for both SINGLE_SRC_TALKER mode to set what channel should be the current single video f...
Definition: bridge.h:121
struct ast_bridge_softmix softmix
Definition: bridge.h:375
union ast_bridge_video_mode::@227 mode_data
#define ast_verb(level,...)
Definition: logger.h:463
struct ast_bridge_video_talker_src_data talker_src_data
Definition: bridge.h:164
void ast_bridge_publish_state(struct ast_bridge *bridge)
Publish the state of a bridge.
const char * ast_channel_uniqueid(const struct ast_channel *chan)
#define ast_bridge_unlock(bridge)
Unlock the bridge.
Definition: bridge.h:493
struct ast_format_cap * ast_channel_nativeformats(const struct ast_channel *chan)
#define ast_bridge_lock(bridge)
Lock the bridge.
Definition: bridge.h:480
#define ast_channel_ref(c)
Increase channel reference count.
Definition: channel.h:2970
const char * ast_channel_name(const struct ast_channel *chan)
struct ast_channel * chan_vsrc
Definition: bridge.h:123
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:615

◆ 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
namechannel name of the bridged peer
pvtidPrivate CallID of the bridged peer
Returns
nothing

Definition at line 1242 of file bridge.c.

References ast_channel_stage_snapshot(), ast_channel_stage_snapshot_done(), 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().

1243 {
1245  pbx_builtin_setvar_helper(chan, "BRIDGEPEER", name);
1246  pbx_builtin_setvar_helper(chan, "BRIDGEPVTCALLID", pvtid);
1248 }
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.
static const char name[]
Definition: cdr_mysql.c:74
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...

◆ 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
Return values
Astring representation of video_mode

Definition at line 4018 of file bridge.c.

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

4019 {
4020  switch (video_mode) {
4022  return "talker";
4024  return "single";
4026  return "sfu";
4028  default:
4029  return "none";
4030  }
4031 }

◆ ast_bridges()

struct ao2_container* ast_bridges ( void  )

Returns the global bridges container.

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

Definition at line 174 of file bridge.c.

References ao2_bump.

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

175 {
176  return ao2_bump(bridges);
177 }
#define ao2_bump(obj)
Definition: astobj2.h:491
static struct ao2_container * bridges
Definition: bridge.c:123

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

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

3010 {
3011  struct merge_direction merge;
3012 
3013  if (!bridge_allows_optimization(chan_bridge) || !bridge_allows_optimization(peer_bridge)) {
3015  }
3016 
3017  switch (bridges_allow_swap_optimization(chan_bridge, peer_bridge)) {
3018  case SWAP_TO_CHAN_BRIDGE:
3020  case SWAP_TO_PEER_BRIDGE:
3022  case SWAP_PROHIBITED:
3023  default:
3024  break;
3025  }
3026 
3027  /* Two channels will be kicked from the bridges, the unreal;1 and unreal;2 channels */
3028  if (bridges_allow_merge_optimization(chan_bridge, peer_bridge, 2, &merge) != MERGE_ALLOWED) {
3030  }
3031 
3032  if (merge.dest == chan_bridge) {
3034  } else {
3036  }
3037 }
static int bridge_allows_optimization(struct ast_bridge *bridge)
Definition: bridge.c:2608
static enum bridge_allow_swap bridges_allow_swap_optimization(struct ast_bridge *chan_bridge, struct ast_bridge *peer_bridge)
Definition: bridge.c:2737
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:2883

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

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_manager_create(), bridge_prnt_obj(), bridge_sort_cmp(), manager_bridge_tech_list(), manager_bridge_tech_suspend(), manager_bridge_tech_unsuspend(), and NULL.

Referenced by asterisk_daemon().

5606 {
5608 
5609  if (ast_stasis_bridging_init()) {
5610  return -1;
5611  }
5612 
5614  if (!bridge_manager) {
5615  return -1;
5616  }
5617 
5620  if (!bridges) {
5621  return -1;
5622  }
5624 
5626 
5628 
5629  ast_manager_register_xml_core("BridgeTechnologyList", 0, manager_bridge_tech_list);
5630  ast_manager_register_xml_core("BridgeTechnologySuspend", 0, manager_bridge_tech_suspend);
5631  ast_manager_register_xml_core("BridgeTechnologyUnsuspend", 0, manager_bridge_tech_unsuspend);
5632 
5633  return 0;
5634 }
#define ARRAY_LEN(a)
Definition: isdn_lib.c:42
static void bridge_cleanup(void)
Definition: bridge.c:5591
static int manager_bridge_tech_suspend(struct mansession *s, const struct message *m)
Definition: bridge.c:5508
static void bridge_prnt_obj(void *v_obj, void *where, ao2_prnt_fn *prnt)
Definition: bridge.c:5573
#define ast_cli_register_multiple(e, len)
Register multiple commands.
Definition: cli.h:265
static struct bridge_manager_controller * bridge_manager
Definition: bridge.c:172
#define NULL
Definition: resample.c:96
#define ast_manager_register_xml_core(action, authority, func)
Register a manager callback using XML documentation to describe the manager.
Definition: manager.h:197
static int manager_bridge_tech_unsuspend(struct mansession *s, const struct message *m)
Definition: bridge.c:5513
static struct bridge_manager_controller * bridge_manager_create(void)
Definition: bridge.c:5009
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.
int ast_stasis_bridging_init(void)
int ast_register_cleanup(void(*func)(void))
Register a function to be executed before Asterisk gracefully exits.
Definition: clicompat.c:19
static struct ao2_container * bridges
Definition: bridge.c:123
void ast_bridging_init_basic(void)
static int bridge_sort_cmp(const void *obj_left, const void *obj_right, int flags)
Definition: bridge.c:5048
Replace objects with duplicate keys in container.
Definition: astobj2.h:1215
#define ao2_container_alloc_rbtree(ao2_options, container_options, sort_fn, cmp_fn)
Definition: astobj2.h:1358
static int manager_bridge_tech_list(struct mansession *s, const struct message *m)
Definition: bridge.c:5518
static struct ast_cli_entry bridge_cli[]
Definition: bridge.c:5462

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

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

3866 {
3868 
3869  ast_bridge_lock(bridge);
3870  bridge->softmix.video_mode.mode_data.sfu_data.remb_behavior = behavior;
3871  ast_bridge_unlock(bridge);
3872 }
struct ast_bridge_video_mode video_mode
Definition: bridge.h:287
#define ast_assert(a)
Definition: utils.h:695
struct ast_bridge_softmix softmix
Definition: bridge.h:375
union ast_bridge_video_mode::@227 mode_data
enum ast_bridge_video_sfu_remb_behavior remb_behavior
Definition: bridge.h:153
struct ast_bridge_video_sfu_data sfu_data
Definition: bridge.h:165
#define ast_bridge_unlock(bridge)
Unlock the bridge.
Definition: bridge.h:493
#define ast_bridge_lock(bridge)
Lock the bridge.
Definition: bridge.h:480
enum ast_bridge_video_mode_type mode
Definition: bridge.h:160

◆ 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.
publicationData to publish for a stasis attended transfer message.
Return values
AST_BRIDGE_TRANSFER_FAILInternal error occurred
AST_BRIDGE_TRANSFER_SUCCESSSuccesfully transferred the bridge

Definition at line 4280 of file bridge.c.

References 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_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().

4283 {
4284 #define BRIDGE_LOCK_ONE_OR_BOTH(b1, b2) \
4285  do { \
4286  if (b2) { \
4287  ast_bridge_lock_both(b1, b2); \
4288  } else { \
4289  ast_bridge_lock(b1); \
4290  } \
4291  } while (0)
4292 
4293  static const char *dest = "_attended@transfer/m";
4294  struct ast_channel *local_chan;
4295  int cause;
4296  int res;
4297  const char *app = NULL;
4298 
4299  local_chan = ast_request("Local", ast_channel_nativeformats(chan1), NULL, chan1,
4300  dest, &cause);
4301  if (!local_chan) {
4302  return AST_BRIDGE_TRANSFER_FAIL;
4303  }
4304 
4305  ast_channel_lock_both(local_chan, chan1);
4308  ast_channel_unlock(local_chan);
4309  ast_channel_unlock(chan1);
4310 
4311  if (bridge2) {
4312  res = ast_local_setup_bridge(local_chan, bridge2, chan2, NULL);
4313  } else {
4314  app = ast_strdupa(ast_channel_appl(chan2));
4315  res = ast_local_setup_masquerade(local_chan, chan2);
4316  }
4317 
4318  if (res) {
4319  ast_hangup(local_chan);
4320  return AST_BRIDGE_TRANSFER_FAIL;
4321  }
4322 
4323  /*
4324  * Since bridges need to be unlocked before entering ast_bridge_impart and
4325  * core_local may call into it then the bridges need to be unlocked here.
4326  */
4327  ast_bridge_unlock(bridge1);
4328  if (bridge2) {
4329  ast_bridge_unlock(bridge2);
4330  }
4331 
4332  if (ast_call(local_chan, dest, 0)) {
4333  ast_hangup(local_chan);
4334  BRIDGE_LOCK_ONE_OR_BOTH(bridge1, bridge2);
4335  return AST_BRIDGE_TRANSFER_FAIL;
4336  }
4337 
4338  /* Get a ref for use later since this one is being stolen */
4339  ao2_ref(local_chan, +1);
4340  if (ast_bridge_impart(bridge1, local_chan, chan1, NULL,
4342  ast_hangup(local_chan);
4343  ao2_cleanup(local_chan);
4344  BRIDGE_LOCK_ONE_OR_BOTH(bridge1, bridge2);
4345  return AST_BRIDGE_TRANSFER_FAIL;
4346  }
4347  BRIDGE_LOCK_ONE_OR_BOTH(bridge1, bridge2);
4348 
4349  if (bridge2) {
4350  void *tech;
4351  struct ast_channel *locals[2];
4352 
4353  /* Have to lock everything just in case a hangup comes in early */
4354  ast_local_lock_all(local_chan, &tech, &locals[0], &locals[1]);
4355  if (!locals[0] || !locals[1]) {
4356  ast_log(LOG_ERROR, "Transfer failed probably due to an early hangup - "
4357  "missing other half of '%s'\n", ast_channel_name(local_chan));
4358  ast_local_unlock_all(tech, locals[0], locals[1]);
4359  ao2_cleanup(local_chan);
4360  return AST_BRIDGE_TRANSFER_FAIL;
4361  }
4362 
4363  /* Make sure the peer is properly set */
4364  if (local_chan != locals[0]) {
4365  SWAP(locals[0], locals[1]);
4366  }
4367 
4368  ast_attended_transfer_message_add_link(transfer_msg, locals);
4369  ast_local_unlock_all(tech, locals[0], locals[1]);
4370  } else {
4371  ast_attended_transfer_message_add_app(transfer_msg, app, local_chan);
4372  }
4373 
4374  ao2_cleanup(local_chan);
4376 }
Main Channel structure associated with a channel.
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.
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&#39;s private tech, lock the local channel&#39;s private base...
Definition: core_local.c:241
int ast_call(struct ast_channel *chan, const char *addr, int timeout)
Make a call.
Definition: channel.c:6553
#define ATTENDEDTRANSFER
Definition: bridge.c:139
#define SWAP(a, b)
Definition: utils.h:230
#define NULL
Definition: resample.c:96
struct ast_bridge * dest
Definition: bridge.c:2184
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:6444
const struct ast_channel_tech * tech
#define ast_log
Definition: astobj2.c:42
#define ao2_ref(o, delta)
Definition: astobj2.h:464
#define ast_strdupa(s)
duplicate a string in memory from the stack
Definition: astmm.h:300
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:6526
#define LOG_ERROR
Definition: logger.h:285
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:1924
const char * ast_channel_appl(const struct ast_channel *chan)
#define ast_channel_unlock(chan)
Definition: channel.h:2946
#define ast_bridge_unlock(bridge)
Unlock the bridge.
Definition: bridge.h:493
void ast_hangup(struct ast_channel *chan)
Hang up a channel.
Definition: channel.c:2548
struct ast_format_cap * ast_channel_nativeformats(const struct ast_channel *chan)
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...
#define ast_channel_lock_both(chan1, chan2)
Lock two channels.
Definition: channel.h:2952
#define ao2_cleanup(obj)
Definition: astobj2.h:1958
const char * ast_channel_name(const struct ast_channel *chan)
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&#39;s private tech, unlock the given local channel&#39;s privat...
Definition: core_local.c:256
static struct ao2_container * locals
Definition: core_local.c:138
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.
static const char app[]
Definition: app_mysql.c:62
#define BRIDGE_LOCK_ONE_OR_BOTH(b1, b2)
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:641
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:599

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

References 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_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().

4184 {
4185  struct ast_channel *local;
4186  char chan_name[AST_MAX_EXTENSION + AST_MAX_CONTEXT + 2];
4187  int cause;
4188 
4189  snprintf(chan_name, sizeof(chan_name), "%s@%s", exten, context);
4190  local = ast_request("Local", ast_channel_nativeformats(transferer), NULL, transferer,
4191  chan_name, &cause);
4192  if (!local) {
4193  return AST_BRIDGE_TRANSFER_FAIL;
4194  }
4195 
4196  ast_channel_lock_both(local, transferer);
4198 
4200  if (!transfer_message->replace_channel) {
4201  ast_hangup(local);
4202  return AST_BRIDGE_TRANSFER_FAIL;
4203  }
4204 
4206  ast_channel_unlock(local);
4207  ast_channel_unlock(transferer);
4208 
4209  if (new_channel_cb) {
4210  new_channel_cb(local, user_data_wrapper, AST_BRIDGE_TRANSFER_MULTI_PARTY);
4211  }
4212 
4213  if (ast_call(local, chan_name, 0)) {
4214  ast_hangup(local);
4215  return AST_BRIDGE_TRANSFER_FAIL;
4216  }
4217 
4218  if (ast_bridge_impart(bridge, local, transferer, NULL,
4220  ast_hangup(local);
4221  return AST_BRIDGE_TRANSFER_FAIL;
4222  }
4223 
4225 }
static char exten[AST_MAX_EXTENSION]
Definition: chan_alsa.c:118
Main Channel structure associated with a channel.
int ast_call(struct ast_channel *chan, const char *addr, int timeout)
Make a call.
Definition: channel.c:6553
#define NULL
Definition: resample.c:96
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:6444
#define AST_MAX_EXTENSION
Definition: channel.h:135
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:6526
const char * ast_channel_uniqueid(const struct ast_channel *chan)
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:1924
#define ast_channel_unlock(chan)
Definition: channel.h:2946
#define AST_MAX_CONTEXT
Definition: channel.h:136
void ast_hangup(struct ast_channel *chan)
Hang up a channel.
Definition: channel.c:2548
#define BLINDTRANSFER
Definition: bridge.c:136
struct ast_format_cap * ast_channel_nativeformats(const struct ast_channel *chan)
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...
#define ast_channel_lock_both(chan1, chan2)
Lock two channels.
Definition: channel.h:2952
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...
const char * ast_channel_name(const struct ast_channel *chan)
static char context[AST_MAX_CONTEXT]
Definition: chan_alsa.c:116
struct ast_channel_snapshot * replace_channel

◆ bridge_action_bridge()

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

Definition at line 604 of file bridge.c.

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

605 {
606 #if 0 /* In case we need to know when the destructor is calling us. */
607  int in_destructor = !ao2_ref(bridge, 0);
608 #endif
609 
610  switch (action->subclass.integer) {
612  ast_bridge_unlock(bridge);
613  bridge_tech_deferred_destroy(bridge, action);
614  ast_bridge_lock(bridge);
615  break;
617  ast_bridge_unlock(bridge);
618  bridge->v_table->dissolving(bridge);
619  ast_bridge_lock(bridge);
620  break;
621  default:
622  /* Unexpected deferred action type. Should never happen. */
623  ast_assert(0);
624  break;
625  }
626 }
ast_bridge_dissolving_fn dissolving
Definition: bridge.h:271
#define ast_assert(a)
Definition: utils.h:695
struct ast_frame_subclass subclass
#define ao2_ref(o, delta)
Definition: astobj2.h:464
const struct ast_bridge_methods * v_table
Definition: bridge.h:359
#define ast_bridge_unlock(bridge)
Unlock the bridge.
Definition: bridge.h:493
#define ast_bridge_lock(bridge)
Lock the bridge.
Definition: bridge.h:480
static void bridge_tech_deferred_destroy(struct ast_bridge *bridge, struct ast_frame *action)
Definition: bridge.c:574

◆ bridge_alloc()

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

Definition at line 724 of file bridge.c.

References ao2_alloc, ao2_cleanup, ast_assert, ast_log, AST_MEDIA_TYPE_END, ast_string_field_init, AST_VECTOR_INIT, bridge_manager_request::bridge, 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().

725 {
726  struct ast_bridge *bridge;
727 
728  /* Check v_table that all methods are present. */
729  if (!v_table
730  || !v_table->name
731  || !v_table->destroy
732  || !v_table->dissolving
733  || !v_table->push
734  || !v_table->pull
735  || !v_table->notify_masquerade
736  || !v_table->get_merge_priority) {
737  ast_log(LOG_ERROR, "Virtual method table for bridge class %s not complete.\n",
738  v_table && v_table->name ? v_table->name : "<unknown>");
739  ast_assert(0);
740  return NULL;
741  }
742 
743  bridge = ao2_alloc(size, destroy_bridge);
744  if (!bridge) {
745  return NULL;
746  }
747 
748  if (ast_string_field_init(bridge, 80)) {
749  ao2_cleanup(bridge);
750  return NULL;
751  }
752 
753  bridge->v_table = v_table;
754 
756 
757  return bridge;
758 }
static void destroy_bridge(void *obj)
Definition: bridge.c:658
const char * name
Definition: bridge.h:267
ast_bridge_dissolving_fn dissolving
Definition: bridge.h:271
#define ast_assert(a)
Definition: utils.h:695
#define NULL
Definition: resample.c:96
#define ast_log
Definition: astobj2.c:42
#define AST_VECTOR_INIT(vec, size)
Initialize a vector.
Definition: vector.h:113
ast_bridge_notify_masquerade_fn notify_masquerade
Definition: bridge.h:277
#define ast_string_field_init(x, size)
Initialize a field pool and fields.
Definition: stringfields.h:353
const struct ast_bridge_methods * v_table
Definition: bridge.h:359
Structure that contains information about a bridge.
Definition: bridge.h:357
#define LOG_ERROR
Definition: logger.h:285
#define ao2_alloc(data_size, destructor_fn)
Definition: astobj2.h:411
ast_bridge_merge_priority_fn get_merge_priority
Definition: bridge.h:279
#define ao2_cleanup(obj)
Definition: astobj2.h:1958
struct ast_vector_int media_types
Definition: bridge.h:412
ast_bridge_pull_channel_fn pull
Definition: bridge.h:275
ast_bridge_destructor_fn destroy
Definition: bridge.h:269
ast_bridge_push_channel_fn push
Definition: bridge.h:273

◆ bridge_allows_optimization()

static int bridge_allows_optimization ( struct ast_bridge bridge)
static

Definition at line 2608 of file bridge.c.

References AST_BRIDGE_FLAG_MASQUERADE_ONLY, ast_test_flag, 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().

2609 {
2610  return !(bridge->inhibit_merge
2611  || bridge->dissolved
2613 }
struct ast_flags feature_flags
Definition: bridge.h:377
#define ast_test_flag(p, flag)
Definition: utils.h:63
unsigned int dissolved
Definition: bridge.h:398
unsigned int inhibit_merge
Count of the active temporary requests to inhibit bridge merges. Zero if merges are allowed...
Definition: bridge.h:392

◆ bridge_base_destroy()

static void bridge_base_destroy ( struct ast_bridge self)
static

Definition at line 841 of file bridge.c.

842 {
843 }

◆ bridge_base_dissolving()

static void bridge_base_dissolving ( struct ast_bridge self)
static

Definition at line 854 of file bridge.c.

References ao2_unlink.

855 {
856  ao2_unlink(bridges, self);
857 }
#define ao2_unlink(container, obj)
Definition: astobj2.h:1598
static struct ao2_container * bridges
Definition: bridge.c:123

◆ bridge_base_get_merge_priority()

static int bridge_base_get_merge_priority ( struct ast_bridge self)
static

Definition at line 924 of file bridge.c.

925 {
926  return 0;
927 }

◆ 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)
Return values
selfon success
NULLon failure, self is already destroyed

Example usage:

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

Definition at line 760 of file bridge.c.

References ao2_ref, AST_BRIDGE_FLAG_INVISIBLE, ast_bridge_topic(), ast_debug, ast_log, ast_set_flag, ast_string_field_set, ast_strlen_zero, ast_tvnow(), ast_uuid_generate_str(), AST_UUID_STR_LEN, bridge_topics_init(), find_best_technology(), LOG_WARNING, NULL, 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().

761 {
762  char uuid_hold[AST_UUID_STR_LEN];
763 
764  if (!self) {
765  return NULL;
766  }
767 
768  if (!ast_strlen_zero(id)) {
769  ast_string_field_set(self, uniqueid, id);
770  } else {
772  ast_string_field_set(self, uniqueid, uuid_hold);
773  }
775  if (!ast_strlen_zero(creator)) {
777  }
778 
779  ast_set_flag(&self->feature_flags, flags);
780  self->allowed_capabilities = capabilities;
781 
782  if (!(flags & AST_BRIDGE_FLAG_INVISIBLE)) {
783  if (bridge_topics_init(self) != 0) {
784  ast_log(LOG_WARNING, "Bridge %s: Could not initialize topics\n",
785  self->uniqueid);
786  ao2_ref(self, -1);
787  return NULL;
788  }
789  }
790 
791  /* Use our helper function to find the "best" bridge technology. */
792  self->technology = find_best_technology(capabilities, self);
793  if (!self->technology) {
794  ast_log(LOG_WARNING, "Bridge %s: Could not create class %s. No technology to support it.\n",
795  self->uniqueid, self->v_table->name);
796  ao2_ref(self, -1);
797  return NULL;
798  }
799 
800  /* Pass off the bridge to the technology to manipulate if needed */
801  ast_debug(1, "Bridge %s: calling %s technology constructor\n",
802  self->uniqueid, self->technology->name);
803  if (self->technology->create && self->technology->create(self)) {
804  ast_log(LOG_WARNING, "Bridge %s: failed to setup bridge technology %s\n",
805  self->uniqueid, self->technology->name);
806  ao2_ref(self, -1);
807  return NULL;
808  }
809  ast_debug(1, "Bridge %s: calling %s technology start\n",
810  self->uniqueid, self->technology->name);
811  if (self->technology->start && self->technology->start(self)) {
812  ast_log(LOG_WARNING, "Bridge %s: failed to start bridge technology %s\n",
813  self->uniqueid, self->technology->name);
814  ao2_ref(self, -1);
815  return NULL;
816  }
817 
818  if (!(flags & AST_BRIDGE_FLAG_INVISIBLE)) {
819  if (!ast_bridge_topic(self)) {
820  ao2_ref(self, -1);
821  return NULL;
822  }
823  }
824 
825  self->creationtime = ast_tvnow();
826 
827  return self;
828 }
struct ast_flags feature_flags
Definition: bridge.h:377
const ast_string_field uniqueid
Definition: bridge.h:409
#define AST_UUID_STR_LEN
Definition: uuid.h:27
const char * name
Definition: bridge.h:267
#define ast_set_flag(p, flag)
Definition: utils.h:70
#define LOG_WARNING
Definition: logger.h:274
int(* start)(struct ast_bridge *bridge)
Request a bridge technology instance start operations.
int bridge_topics_init(struct ast_bridge *bridge)
struct timeval ast_tvnow(void)
Returns current timeval. Meant to replace calls to gettimeofday().
Definition: time.h:150
#define NULL
Definition: resample.c:96
#define ast_strlen_zero(foo)
Definition: strings.h:52
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:511
struct ast_bridge_technology * technology
Definition: bridge.h:363
#define ast_debug(level,...)
Log a DEBUG message.
Definition: logger.h:452
#define ast_log
Definition: astobj2.c:42
#define ao2_ref(o, delta)
Definition: astobj2.h:464
const struct ast_bridge_methods * v_table
Definition: bridge.h:359
static const char name[]
Definition: cdr_mysql.c:74
char * ast_uuid_generate_str(char *buf, size_t size)
Generate a UUID string.
Definition: uuid.c:143
struct stasis_topic * ast_bridge_topic(struct ast_bridge *bridge)
A topic which publishes the events for a particular bridge.
int(* create)(struct ast_bridge *bridge)
Create a bridge technology instance for a bridge.
const ast_string_field creator
Definition: bridge.h:409
#define ast_string_field_set(x, field, data)
Set a field to a simple string value.
Definition: stringfields.h:514

◆ bridge_base_notify_masquerade()

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

Definition at line 908 of file bridge.c.

909 {
910  self->reconfigured = 1;
911 }

◆ bridge_base_pull()

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

Definition at line 891 of file bridge.c.

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

892 {
894 }
struct ast_bridge_features * features
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:3568

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

875 {
876  return 0;
877 }

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

945 {
946  return 0;
947 }

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

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

2056 {
2057  struct ast_bridge *old_bridge;
2058 
2059  ao2_ref(new_bridge, +1);
2060  ast_bridge_channel_lock(bridge_channel);
2061  ast_channel_lock(bridge_channel->chan);
2062  old_bridge = bridge_channel->bridge;
2063  bridge_channel->bridge = new_bridge;
2064  ast_channel_internal_bridge_set(bridge_channel->chan, new_bridge);
2065  ast_channel_unlock(bridge_channel->chan);
2066  ast_bridge_channel_unlock(bridge_channel);
2067  ao2_ref(old_bridge, -1);
2068 }
#define ast_channel_lock(chan)
Definition: channel.h:2945
struct ast_bridge * bridge
Bridge this channel is participating in.
#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)
#define ao2_ref(o, delta)
Definition: astobj2.h:464
#define ast_bridge_channel_unlock(bridge_channel)
Unlock the bridge_channel.
Structure that contains information about a bridge.
Definition: bridge.h:357
#define ast_channel_unlock(chan)
Definition: channel.h:2946
struct ast_channel * chan

◆ bridge_channel_complete_join()

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

Definition at line 443 of file bridge.c.

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

444 {
445  /* Tell the bridge technology we are joining so they set us up */
446  ast_debug(1, "Bridge %s: %p(%s) is joining %s technology\n",
447  bridge->uniqueid, bridge_channel, ast_channel_name(bridge_channel->chan),
448  bridge->technology->name);
449  if (bridge->technology->join
450  && bridge->technology->join(bridge, bridge_channel)) {
451  /* We cannot leave the channel partially in the bridge so we must kick it out */
452  ast_debug(1, "Bridge %s: %p(%s) failed to join %s technology (Kicking it out)\n",
453  bridge->uniqueid, bridge_channel, ast_channel_name(bridge_channel->chan),
454  bridge->technology->name);
455  bridge_channel->just_joined = 1;
457  return;
458  }
459 
460  bridge_channel->just_joined = 0;
461 
462  /*
463  * When a channel joins the bridge its streams need to be mapped to the bridge's
464  * media types vector. This way all streams map to the same media type index for
465  * a given channel.
466  */
467  if (bridge_channel->bridge->technology->stream_topology_changed) {
468  bridge_channel->bridge->technology->stream_topology_changed(
469  bridge_channel->bridge, bridge_channel);
470  } else {
471  ast_bridge_channel_stream_map(bridge_channel);
472  }
473 }
const ast_string_field uniqueid
Definition: bridge.h:409
void(* stream_topology_changed)(struct ast_bridge *bridge, struct ast_bridge_channel *bridge_channel)
Callback for when a stream topology changes on the channel.
struct ast_bridge * bridge
Bridge this channel is participating in.
struct ast_bridge_technology * technology
Definition: bridge.h:363
#define ast_debug(level,...)
Log a DEBUG message.
Definition: logger.h:452
unsigned int just_joined
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).
int(* join)(struct ast_bridge *bridge, struct ast_bridge_channel *bridge_channel)
Add a channel to a bridging technology instance for a bridge.
struct ast_channel * chan
const char * ast_channel_name(const struct ast_channel *chan)
void ast_bridge_channel_stream_map(struct ast_bridge_channel *bridge_channel)
Maps a channel&#39;s stream topology to and from the bridge.

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

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

1758 {
1759  struct ast_bridge_channel *bridge_channel = data;
1760  int res = 0;
1761 
1762  if (bridge_channel->callid) {
1763  ast_callid_threadassoc_add(bridge_channel->callid);
1764  }
1765 
1766  res = bridge_channel_internal_join(bridge_channel);
1767 
1768  /*
1769  * cleanup
1770  *
1771  * If bridge_channel->swap is not NULL then the join failed.
1772  */
1773  ao2_t_cleanup(bridge_channel->swap, "Bridge complete: Departable impart join failed");
1774  bridge_channel->swap = NULL;
1775  ast_bridge_features_destroy(bridge_channel->features);
1776  bridge_channel->features = NULL;
1777 
1778  ast_bridge_discard_after_callback(bridge_channel->chan,
1780  /* If join failed there will be impart threads waiting. */
1781  bridge_channel_impart_signal(bridge_channel->chan);
1782  ast_bridge_discard_after_goto(bridge_channel->chan);
1783 
1784  return NULL;
1785 }
#define ao2_t_cleanup(obj, tag)
Definition: astobj2.h:1959
struct ast_bridge_features * features
void bridge_channel_impart_signal(struct ast_channel *chan)
Signal imparting threads to wake up.
Definition: bridge.c:1626
#define NULL
Definition: resample.c:96
void ast_bridge_discard_after_callback(struct ast_channel *chan, enum ast_bridge_after_cb_reason reason)
Run discarding any after bridge callbacks.
Definition: bridge_after.c:247
int ast_callid_threadassoc_add(ast_callid callid)
Adds a known callid to thread storage of the calling thread.
Definition: logger.c:1984
void ast_bridge_discard_after_goto(struct ast_channel *chan)
Discard channel after bridge goto location.
Definition: bridge_after.c:396
void ast_bridge_features_destroy(struct ast_bridge_features *features)
Destroy an allocated bridge features struct.
Definition: bridge.c:3741
struct ast_channel * swap
struct ast_channel * chan
Structure that contains information regarding a channel in a bridge.
int bridge_channel_internal_join(struct ast_bridge_channel *bridge_channel)

◆ bridge_channel_impart_add()

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

Definition at line 1593 of file bridge.c.

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

Referenced by bridge_impart_internal().

1594 {
1595  struct ast_datastore *datastore;
1596  struct bridge_channel_impart_ds_head *ds_head;
1597 
1598  ast_channel_lock(chan);
1599 
1601  if (!datastore) {
1603  if (!datastore) {
1604  ast_channel_unlock(chan);
1605  return -1;
1606  }
1607  ds_head = ast_calloc(1, sizeof(*ds_head));
1608  if (!ds_head) {
1609  ast_channel_unlock(chan);
1610  ast_datastore_free(datastore);
1611  return -1;
1612  }
1613  datastore->data = ds_head;
1614  ast_channel_datastore_add(chan, datastore);
1615  } else {
1616  ds_head = datastore->data;
1617  ast_assert(ds_head != NULL);
1618  }
1619 
1620  AST_LIST_INSERT_TAIL(ds_head, cond, node);
1621 
1622  ast_channel_unlock(chan);
1623  return 0;
1624 }
#define ast_channel_lock(chan)
Definition: channel.h:2945
Definition: test_heap.c:38
static const struct ast_datastore_info bridge_channel_impart_ds_info
Definition: bridge.c:1576
#define ast_assert(a)
Definition: utils.h:695
Structure for a data store object.
Definition: datastore.h:68
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:2404
#define NULL
Definition: resample.c:96
int ast_datastore_free(struct ast_datastore *datastore)
Free a data store object.
Definition: datastore.c:68
#define AST_LIST_INSERT_TAIL(head, elm, field)
Appends a list entry to the tail of a list.
Definition: linkedlists.h:730
#define ast_channel_unlock(chan)
Definition: channel.h:2946
#define ast_calloc(num, len)
A wrapper for calloc()
Definition: astmm.h:204
void * data
Definition: datastore.h:70
#define ast_datastore_alloc(info, uid)
Definition: datastore.h:89
int ast_channel_datastore_add(struct ast_channel *chan, struct ast_datastore *datastore)
Add a datastore to a channel.
Definition: channel.c:2390

◆ bridge_channel_impart_ds_head_dtor()

static void bridge_channel_impart_ds_head_dtor ( void *  doomed)
static

Definition at line 1550 of file bridge.c.

References ast_free, and bridge_channel_impart_ds_head_signal().

1551 {
1553  ast_free(doomed);
1554 }
static void bridge_channel_impart_ds_head_signal(struct bridge_channel_impart_ds_head *ds_head)
Definition: bridge.c:1536
#define ast_free(a)
Definition: astmm.h:182

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

References bridge_channel_impart_ds_head_signal().

1568 {
1569  /*
1570  * Signal any waiting impart threads. The masquerade is going to kill
1571  * old_chan and we don't need to be waiting on new_chan.
1572  */
1574 }
static void bridge_channel_impart_ds_head_signal(struct bridge_channel_impart_ds_head *ds_head)
Definition: bridge.c:1536

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

References ast_cond_signal, AST_LIST_REMOVE_HEAD, ast_mutex_lock, ast_mutex_unlock, cond, bridge_channel_impart_cond::cond, bridge_channel_impart_cond::done, and bridge_channel_impart_cond::lock.

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

1537 {
1538  if (ds_head) {
1540 
1541  while ((cond = AST_LIST_REMOVE_HEAD(ds_head, node))) {
1542  ast_mutex_lock(&cond->lock);
1543  cond->done = 1;
1544  ast_cond_signal(&cond->cond);
1545  ast_mutex_unlock(&cond->lock);
1546  }
1547  }
1548 }
Internal bridge impart wait condition and associated conditional.
Definition: bridge.c:1515
Definition: test_heap.c:38
#define ast_mutex_lock(a)
Definition: lock.h:187
#define ast_cond_signal(cond)
Definition: lock.h:201
ast_cond_t cond
Definition: app_meetme.c:1090
#define AST_LIST_REMOVE_HEAD(head, field)
Removes and returns the head entry from a list.
Definition: linkedlists.h:832
#define ast_mutex_unlock(a)
Definition: lock.h:188

◆ bridge_channel_impart_signal()

void bridge_channel_impart_signal ( struct ast_channel chan)

Signal imparting threads to wake up.

Since
13.9.0
Parameters
chanChannel imparted that we need to signal.
Returns
Nothing

Definition at line 1626 of file bridge.c.

References ast_channel_datastore_find(), ast_channel_lock, ast_channel_unlock, bridge_channel_impart_ds_head_signal(), ast_datastore::data, and NULL.

Referenced by ast_bridge_impart(), ast_bridge_join(), bridge_channel_depart_thread(), bridge_channel_ind_thread(), and bridge_channel_internal_join().

1627 {
1628  struct ast_datastore *datastore;
1629 
1630  ast_channel_lock(chan);
1632  if (datastore) {
1634  }
1635  ast_channel_unlock(chan);
1636 }
#define ast_channel_lock(chan)
Definition: channel.h:2945
static void bridge_channel_impart_ds_head_signal(struct bridge_channel_impart_ds_head *ds_head)
Definition: bridge.c:1536
static const struct ast_datastore_info bridge_channel_impart_ds_info
Definition: bridge.c:1576
Structure for a data store object.
Definition: datastore.h:68
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:2404
#define NULL
Definition: resample.c:96
#define ast_channel_unlock(chan)
Definition: channel.h:2946
void * data
Definition: datastore.h:70

◆ bridge_channel_impart_wait()

static void bridge_channel_impart_wait ( struct bridge_channel_impart_cond cond)
static

Definition at line 1647 of file bridge.c.

References ast_cond_wait, ast_mutex_lock, ast_mutex_unlock, bridge_channel_impart_cond::cond, bridge_channel_impart_cond::done, and bridge_channel_impart_cond::lock.

Referenced by bridge_impart_internal().

1648 {
1649  ast_mutex_lock(&cond->lock);
1650  while (!cond->done) {
1651  ast_cond_wait(&cond->cond, &cond->lock);
1652  }
1653  ast_mutex_unlock(&cond->lock);
1654 }
#define ast_cond_wait(cond, mutex)
Definition: lock.h:203
#define ast_mutex_lock(a)
Definition: lock.h:187
#define ast_mutex_unlock(a)
Definition: lock.h:188

◆ bridge_channel_ind_thread()

static void* bridge_channel_ind_thread ( void *  data)
static

Thread responsible for independent imparted bridged channels.

Definition at line 1788 of file bridge.c.

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, 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().

1789 {
1790  struct ast_bridge_channel *bridge_channel = data;
1791  struct ast_channel *chan;
1792 
1793  if (bridge_channel->callid) {
1794  ast_callid_threadassoc_add(bridge_channel->callid);
1795  }
1796 
1797  bridge_channel_internal_join(bridge_channel);
1798  chan = bridge_channel->chan;
1799 
1800  /* cleanup */
1801  ast_channel_lock(chan);
1803  ast_channel_unlock(chan);
1804  /* Lock here for ast_bridge_channel_get_chan */
1805  ao2_lock(bridge_channel);
1806  bridge_channel->chan = NULL;
1807  ao2_unlock(bridge_channel);
1808  /* If bridge_channel->swap is not NULL then the join failed. */
1809  ao2_t_cleanup(bridge_channel->swap, "Bridge complete: Independent impart join failed");
1810  bridge_channel->swap = NULL;
1811  ast_bridge_features_destroy(bridge_channel->features);
1812  bridge_channel->features = NULL;
1813 
1814  ao2_ref(bridge_channel, -1);
1815 
1817  /* If join failed there will be impart threads waiting. */
1820  return NULL;
1821 }
void ast_channel_internal_bridge_channel_set(struct ast_channel *chan, struct ast_bridge_channel *value)
#define ast_channel_lock(chan)
Definition: channel.h:2945
Main Channel structure associated with a channel.
#define ao2_t_cleanup(obj, tag)
Definition: astobj2.h:1959
void ast_bridge_run_after_goto(struct ast_channel *chan)
Run a PBX on any after bridge goto location.
Definition: bridge_after.c:537
struct ast_bridge_features * features
void bridge_channel_impart_signal(struct ast_channel *chan)
Signal imparting threads to wake up.
Definition: bridge.c:1626
#define ao2_unlock(a)
Definition: astobj2.h:730
#define NULL
Definition: resample.c:96
int ast_callid_threadassoc_add(ast_callid callid)
Adds a known callid to thread storage of the calling thread.
Definition: logger.c:1984
#define ao2_ref(o, delta)
Definition: astobj2.h:464
#define ao2_lock(a)
Definition: astobj2.h:718
#define ast_channel_unlock(chan)
Definition: channel.h:2946
void ast_bridge_features_destroy(struct ast_bridge_features *features)
Destroy an allocated bridge features struct.
Definition: bridge.c:3741
void ast_bridge_run_after_callback(struct ast_channel *chan)
Run any after bridge callback.
Definition: bridge_after.c:220
struct ast_channel * swap
struct ast_channel * chan
Structure that contains information regarding a channel in a bridge.
int bridge_channel_internal_join(struct ast_bridge_channel *bridge_channel)

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

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

2071 {
2072  struct ast_bridge_features *features = bridge_channel->features;
2073  struct ast_bridge_hook *hook;
2074  struct ao2_iterator iter;
2075 
2076  /* Run any moving hooks. */
2077  iter = ao2_iterator_init(features->other_hooks, 0);
2078  for (; (hook = ao2_iterator_next(&iter)); ao2_ref(hook, -1)) {
2079  int remove_me;
2081 
2082  if (hook->type != AST_BRIDGE_HOOK_TYPE_MOVE) {
2083  continue;
2084  }
2085  move_cb = (ast_bridge_move_indicate_callback) hook->callback;
2086  remove_me = move_cb(bridge_channel, hook->hook_pvt, src, dst);
2087  if (remove_me) {
2088  ast_debug(1, "Move detection hook %p is being removed from %p(%s)\n",
2089  hook, bridge_channel, ast_channel_name(bridge_channel->chan));
2090  ao2_unlink(features->other_hooks, hook);
2091  }
2092  }
2093  ao2_iterator_destroy(&iter);
2094 }
struct ast_bridge_features * features
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.
Structure that contains features information.
void ao2_iterator_destroy(struct ao2_iterator *iter)
Destroy a container iterator.
#define ast_debug(level,...)
Log a DEBUG message.
Definition: logger.h:452
enum ast_bridge_hook_type type
#define ao2_ref(o, delta)
Definition: astobj2.h:464
#define ao2_unlink(container, obj)
Definition: astobj2.h:1598
ast_bridge_hook_callback callback
#define ao2_iterator_next(iter)
Definition: astobj2.h:1933
struct ast_channel * chan
When we need to walk through a container, we use an ao2_iterator to keep track of the current positio...
Definition: astobj2.h:1841
struct ao2_container * other_hooks
const char * ast_channel_name(const struct ast_channel *chan)
struct ao2_iterator ao2_iterator_init(struct ao2_container *c, int flags) attribute_warn_unused_result
Create an iterator for a container.
Structure that is the essence of a feature hook.

◆ bridge_cleanup()

static void bridge_cleanup ( void  )
static

Definition at line 5591 of file bridge.c.

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

Referenced by ast_bridging_init().

5592 {
5593  ast_manager_unregister("BridgeTechnologyList");
5594  ast_manager_unregister("BridgeTechnologySuspend");
5595  ast_manager_unregister("BridgeTechnologyUnsuspend");
5597  ao2_container_unregister("bridges");
5598 
5600  bridges = NULL;
5602  bridge_manager = NULL;
5603 }
#define ARRAY_LEN(a)
Definition: isdn_lib.c:42
int ast_cli_unregister_multiple(struct ast_cli_entry *e, int len)
Unregister multiple commands.
Definition: clicompat.c:30
static struct bridge_manager_controller * bridge_manager
Definition: bridge.c:172
#define NULL
Definition: resample.c:96
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:7258
static struct ao2_container * bridges
Definition: bridge.c:123
#define ao2_cleanup(obj)
Definition: astobj2.h:1958
static struct ast_cli_entry bridge_cli[]
Definition: bridge.c:5462

◆ bridge_complete_join()

static void bridge_complete_join ( struct ast_bridge bridge)
static

Definition at line 486 of file bridge.c.

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

Referenced by bridge_reconfigured().

487 {
488  struct ast_bridge_channel *bridge_channel;
489 
490  if (bridge->dissolved) {
491  /*
492  * No sense in completing the join on channels for a dissolved
493  * bridge. They are just going to be removed soon anyway.
494  * However, we do have reason to abort here because the bridge
495  * technology may not be able to handle the number of channels
496  * still in the bridge.
497  */
498  return;
499  }
500 
501  AST_LIST_TRAVERSE(&bridge->channels, bridge_channel, entry) {
502  bridge_channel_queue_deferred_frames(bridge_channel);
503  if (!bridge_channel->just_joined) {
504  continue;
505  }
506  bridge_channel_complete_join(bridge, bridge_channel);
507  }
508 }
unsigned int dissolved
Definition: bridge.h:398
static void bridge_channel_complete_join(struct ast_bridge *bridge, struct ast_bridge_channel *bridge_channel)
Definition: bridge.c:443
void bridge_channel_queue_deferred_frames(struct ast_bridge_channel *bridge_channel)
unsigned int just_joined
#define AST_LIST_TRAVERSE(head, var, field)
Loops over (traverses) the entries in a list.
Definition: linkedlists.h:490
struct ast_bridge_channels_list channels
Definition: bridge.h:371
Structure that contains information regarding a channel in a bridge.
Definition: search.h:40

◆ bridge_dissolve()

void bridge_dissolve ( struct ast_bridge bridge,
int  cause 
)

Definition at line 319 of file bridge.c.

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

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

320 {
321  struct ast_bridge_channel *bridge_channel;
322  struct ast_frame action = {
324  .subclass.integer = BRIDGE_CHANNEL_ACTION_DEFERRED_DISSOLVING,
325  };
326 
327  if (bridge->dissolved) {
328  return;
329  }
330  bridge->dissolved = 1;
331 
332  if (cause <= 0) {
334  }
335  bridge->cause = cause;
336 
337  ast_debug(1, "Bridge %s: dissolving bridge with cause %d(%s)\n",
338  bridge->uniqueid, cause, ast_cause2str(cause));
339 
340  AST_LIST_TRAVERSE(&bridge->channels, bridge_channel, entry) {
341  ast_bridge_channel_leave_bridge(bridge_channel,
343  }
344 
345  /* Must defer dissolving bridge because it is already locked. */
346  ast_bridge_queue_action(bridge, &action);
347 }
const ast_string_field uniqueid
Definition: bridge.h:409
unsigned int dissolved
Definition: bridge.h:398
int ast_bridge_queue_action(struct ast_bridge *bridge, struct ast_frame *action)
Put an action onto the specified bridge.
Definition: bridge.c:307
#define ast_debug(level,...)
Log a DEBUG message.
Definition: logger.h:452
#define AST_CAUSE_NORMAL_CLEARING
Definition: causes.h:105
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_LIST_TRAVERSE(head, var, field)
Loops over (traverses) the entries in a list.
Definition: linkedlists.h:490
const char * ast_cause2str(int state) attribute_pure
Gives the string form of a given cause code.
Definition: channel.c:612
int cause
Definition: bridge.h:394
struct ast_bridge_channels_list channels
Definition: bridge.h:371
Structure that contains information regarding a channel in a bridge.
Data structure associated with a single frame of data.
Definition: search.h:40
enum ast_frame_type frametype

◆ bridge_dissolve_check_stolen()

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

Definition at line 361 of file bridge.c.

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

Referenced by ast_bridge_add_channel().

362 {
363  if (bridge->dissolved) {
364  return;
365  }
366 
367  if (bridge_channel->features->usable
368  && ast_test_flag(&bridge_channel->features->feature_flags,
370  /* The stolen channel controlled the bridge it was stolen from. */
371  bridge_dissolve(bridge, 0);
372  return;
373  }
374  if (bridge->num_channels < 2
376  /*
377  * The stolen channel has not left enough channels to keep the
378  * bridge alive. Assume the stolen channel hung up.
379  */
380  bridge_dissolve(bridge, 0);
381  return;
382  }
383 }
struct ast_flags feature_flags
Definition: bridge.h:377
struct ast_bridge_features * features
#define ast_test_flag(p, flag)
Definition: utils.h:63
unsigned int dissolved
Definition: bridge.h:398
void bridge_dissolve(struct ast_bridge *bridge, int cause)
Definition: bridge.c:319
struct ast_flags feature_flags
unsigned int num_channels
Definition: bridge.h:381

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

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

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

2098 {
2099  struct ast_bridge_channel *bridge_channel;
2100  unsigned int idx;
2101 
2102  ast_debug(1, "Merging bridge %s into bridge %s\n",
2103  src_bridge->uniqueid, dst_bridge->uniqueid);
2104 
2105  ast_bridge_publish_merge(dst_bridge, src_bridge);
2106 
2107  /*
2108  * Move channels from src_bridge over to dst_bridge.
2109  *
2110  * We must use AST_LIST_TRAVERSE_SAFE_BEGIN() because
2111  * bridge_channel_internal_pull() alters the list we are traversing.
2112  */
2113  AST_LIST_TRAVERSE_SAFE_BEGIN(&src_bridge->channels, bridge_channel, entry) {
2114  if (bridge_channel->state != BRIDGE_CHANNEL_STATE_WAIT) {
2115  /*
2116  * The channel is already leaving let it leave normally because
2117  * pulling it may delete hooks that should run for this channel.
2118  */
2119  continue;
2120  }
2121  if (ast_test_flag(&bridge_channel->features->feature_flags,
2123  continue;
2124  }
2125 
2126  if (kick_me) {
2127  for (idx = 0; idx < num_kick; ++idx) {
2128  if (bridge_channel == kick_me[idx]) {
2129  ast_bridge_channel_leave_bridge(bridge_channel,
2131  break;
2132  }
2133  }
2134  }
2135  bridge_channel_internal_pull(bridge_channel);
2136  if (bridge_channel->state != BRIDGE_CHANNEL_STATE_WAIT) {
2137  /*
2138  * The channel died as a result of being pulled or it was
2139  * kicked. Leave it pointing to the original bridge.
2140  */
2141  continue;
2142  }
2143 
2144  bridge_channel_moving(bridge_channel, bridge_channel->bridge, dst_bridge);
2145 
2146  /* Point to new bridge.*/
2147  bridge_channel_change_bridge(bridge_channel, dst_bridge);
2148 
2149  if (bridge_channel_internal_push(bridge_channel)) {
2150  ast_bridge_features_remove(bridge_channel->features,
2152  ast_bridge_channel_leave_bridge(bridge_channel,
2154  }
2155  }
2157 
2158  if (kick_me) {
2159  /*
2160  * Now we can kick any channels in the dst_bridge without
2161  * potentially dissolving the bridge.
2162  */
2163  for (idx = 0; idx < num_kick; ++idx) {
2164  bridge_channel = kick_me[idx];
2165  ast_bridge_channel_lock(bridge_channel);
2166  if (bridge_channel->state == BRIDGE_CHANNEL_STATE_WAIT) {
2169  bridge_channel_internal_pull(bridge_channel);
2170  }
2171  ast_bridge_channel_unlock(bridge_channel);
2172  }
2173  }
2174 
2175  bridge_reconfigured(dst_bridge, !optimized);
2176  bridge_reconfigured(src_bridge, !optimized);
2177 
2178  ast_debug(1, "Merged bridge %s into bridge %s\n",
2179  src_bridge->uniqueid, dst_bridge->uniqueid);
2180 }
const ast_string_field uniqueid
Definition: bridge.h:409
struct ast_bridge_features * features
static void bridge_channel_change_bridge(struct ast_bridge_channel *bridge_channel, struct ast_bridge *new_bridge)
Definition: bridge.c:2055
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).
#define ast_test_flag(p, flag)
Definition: utils.h:63
enum bridge_channel_state state
#define AST_LIST_TRAVERSE_SAFE_END
Closes a safe loop traversal block.
Definition: linkedlists.h:614
struct ast_bridge * bridge
Bridge this channel is participating in.
struct ast_flags feature_flags
#define ast_debug(level,...)
Log a DEBUG message.
Definition: logger.h:452
#define ast_bridge_channel_lock(bridge_channel)
Lock the bridge_channel.
#define AST_CAUSE_NORMAL_CLEARING
Definition: causes.h:105
#define ast_bridge_channel_unlock(bridge_channel)
Unlock the bridge_channel.
static void bridge_channel_moving(struct ast_bridge_channel *bridge_channel, struct ast_bridge *src, struct ast_bridge *dst)
Definition: bridge.c:2070
void bridge_reconfigured(struct ast_bridge *bridge, unsigned int colp_update)
Definition: bridge.c:1443
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).
int cause
Definition: bridge.h:394
int bridge_channel_internal_push(struct ast_bridge_channel *bridge_channel)
struct ast_bridge_channels_list channels
Definition: bridge.h:371
Structure that contains information regarding a channel in a bridge.
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:3568
Definition: search.h:40
#define AST_LIST_TRAVERSE_SAFE_BEGIN(head, var, field)
Loops safely over (traverses) the entries in a list.
Definition: linkedlists.h:528
void bridge_channel_internal_pull(struct ast_bridge_channel *bridge_channel)
void ast_bridge_publish_merge(struct ast_bridge *to, struct ast_bridge *from)
Publish a bridge merge.

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

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

2364 {
2365  struct ast_bridge *orig_bridge;
2366  int was_in_bridge;
2367  int res = 0;
2368 
2369  if (bridge_channel->swap) {
2370  ast_debug(1, "Moving %p(%s) into bridge %s swapping with %s\n",
2371  bridge_channel, ast_channel_name(bridge_channel->chan), dst_bridge->uniqueid,
2372  ast_channel_name(bridge_channel->swap));
2373  } else {
2374  ast_debug(1, "Moving %p(%s) into bridge %s\n",
2375  bridge_channel, ast_channel_name(bridge_channel->chan), dst_bridge->uniqueid);
2376  }
2377 
2378  orig_bridge = bridge_channel->bridge;
2379  was_in_bridge = bridge_channel->in_bridge;
2380 
2381  bridge_channel_internal_pull(bridge_channel);
2382  if (bridge_channel->state != BRIDGE_CHANNEL_STATE_WAIT) {
2383  /*
2384  * The channel died as a result of being pulled. Leave it
2385  * pointing to the original bridge.
2386  *
2387  * Clear out the swap channel pointer. A ref is not held
2388  * by bridge_channel->swap at this point.
2389  */
2390  bridge_channel->swap = NULL;
2391  bridge_reconfigured(orig_bridge, 0);
2392  return -1;
2393  }
2394 
2395  /* Point to new bridge.*/
2396  ao2_ref(orig_bridge, +1);/* Keep a ref in case the push fails. */
2397  bridge_channel_change_bridge(bridge_channel, dst_bridge);
2398 
2399  bridge_channel_moving(bridge_channel, orig_bridge, dst_bridge);
2400 
2401  if (bridge_channel_internal_push_full(bridge_channel, optimized)) {
2402  /* Try to put the channel back into the original bridge. */
2403  ast_bridge_features_remove(bridge_channel->features,
2405  if (attempt_recovery && was_in_bridge) {
2406  /* Point back to original bridge. */
2407  bridge_channel_change_bridge(bridge_channel, orig_bridge);
2408 
2409  if (bridge_channel_internal_push(bridge_channel)) {
2410  ast_bridge_features_remove(bridge_channel->features,
2412  ast_bridge_channel_leave_bridge(bridge_channel,
2414  }
2415  } else {
2416  ast_bridge_channel_leave_bridge(bridge_channel,
2418  bridge_channel_settle_owed_events(orig_bridge, bridge_channel);
2419  }
2420  res = -1;
2421  } else if (!optimized) {
2422  bridge_channel_settle_owed_events(orig_bridge, bridge_channel);
2423  }
2424 
2425  bridge_reconfigured(dst_bridge, !optimized);
2426  bridge_reconfigured(orig_bridge, !optimized);
2427  ao2_ref(orig_bridge, -1);
2428  return res;
2429 }
const ast_string_field uniqueid
Definition: bridge.h:409
struct ast_bridge_features * features
static void bridge_channel_change_bridge(struct ast_bridge_channel *bridge_channel, struct ast_bridge *new_bridge)
Definition: bridge.c:2055
enum bridge_channel_state state
#define NULL
Definition: resample.c:96
void bridge_channel_settle_owed_events(struct ast_bridge *orig_bridge, struct ast_bridge_channel *bridge_channel)
struct ast_bridge * bridge
Bridge this channel is participating in.
#define ast_debug(level,...)
Log a DEBUG message.
Definition: logger.h:452
#define ao2_ref(o, delta)
Definition: astobj2.h:464
static void bridge_channel_moving(struct ast_bridge_channel *bridge_channel, struct ast_bridge *src, struct ast_bridge *dst)
Definition: bridge.c:2070
Structure that contains information about a bridge.
Definition: bridge.h:357
int bridge_channel_internal_push_full(struct ast_bridge_channel *bridge_channel, int optimized)
void bridge_reconfigured(struct ast_bridge *bridge, unsigned int colp_update)
Definition: bridge.c:1443
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).
unsigned int in_bridge
struct ast_channel * swap
int cause
Definition: bridge.h:394
int bridge_channel_internal_push(struct ast_bridge_channel *bridge_channel)
struct ast_channel * chan
const char * ast_channel_name(const struct ast_channel *chan)
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:3568
void bridge_channel_internal_pull(struct ast_bridge_channel *bridge_channel)

◆ bridge_dtmf_hook_sort()

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

Definition at line 3606 of file bridge.c.

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

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

◆ bridge_find_channel()

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

Definition at line 1469 of file bridge.c.

References AST_LIST_TRAVERSE, ast_bridge_channel::chan, and ast_bridge::channels.

Referenced by ast_bridge_add_channel(), ast_bridge_join(), ast_bridge_kick(), ast_bridge_notify_masquerade(), ast_bridge_remove(), ast_bridge_suspend(), ast_bridge_unsuspend(), bridge_channel_internal_push_full(), bridge_impart_internal(), bridge_merge(), bridge_merge_locked(), bridge_move_locked(), and play_uri().

1470 {
1471  struct ast_bridge_channel *bridge_channel;
1472 
1473  AST_LIST_TRAVERSE(&bridge->channels, bridge_channel, entry) {
1474  if (bridge_channel->chan == chan) {
1475  break;
1476  }
1477  }
1478 
1479  return bridge_channel;
1480 }
#define AST_LIST_TRAVERSE(head, var, field)
Loops over (traverses) the entries in a list.
Definition: linkedlists.h:490
struct ast_bridge_channels_list channels
Definition: bridge.h:371
struct ast_channel * chan
Structure that contains information regarding a channel in a bridge.
Definition: search.h:40

◆ bridge_handle_actions()

static void bridge_handle_actions ( struct ast_bridge bridge)
static

Definition at line 640 of file bridge.c.

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

641 {
642  struct ast_frame *action;
643 
644  while ((action = AST_LIST_REMOVE_HEAD(&bridge->action_queue, frame_list))) {
645  switch (action->frametype) {
647  bridge_action_bridge(bridge, action);
648  break;
649  default:
650  /* Unexpected deferred frame type. Should never happen. */
651  ast_assert(0);
652  break;
653  }
654  ast_frfree(action);
655  }
656 }
#define ast_assert(a)
Definition: utils.h:695
struct ast_bridge::@228 action_queue
#define AST_LIST_REMOVE_HEAD(head, field)
Removes and returns the head entry from a list.
Definition: linkedlists.h:832
#define ast_frfree(fr)
Data structure associated with a single frame of data.
static void bridge_action_bridge(struct ast_bridge *bridge, struct ast_frame *action)
Definition: bridge.c:604
enum ast_frame_type frametype

◆ bridge_hook_destroy()

static void bridge_hook_destroy ( void *  vhook)
static

Definition at line 3202 of file bridge.c.

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

Referenced by bridge_hook_generic().

3203 {
3204  struct ast_bridge_hook *hook = vhook;
3205 
3206  if (hook->destructor) {
3207  hook->destructor(hook->hook_pvt);
3208  }
3209 }
ast_bridge_hook_pvt_destructor destructor
Structure that is the essence of a feature hook.

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

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

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

3230 {
3231  struct ast_bridge_hook *hook;
3232 
3233  /* Allocate new hook and setup it's basic variables */
3235  if (hook) {
3236  hook->callback = callback;
3237  hook->destructor = destructor;
3238  hook->hook_pvt = hook_pvt;
3240  }
3241 
3242  return hook;
3243 }
#define ast_set_flag(p, flag)
Definition: utils.h:70
static void bridge_hook_destroy(void *vhook)
Definition: bridge.c:3202
ast_bridge_hook_pvt_destructor destructor
#define ao2_alloc_options(data_size, destructor_fn, options)
Definition: astobj2.h:406
ast_bridge_hook_callback callback
struct ast_flags remove_flags
Structure that is the essence of a feature 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 1823 of file bridge.c.

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, 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, 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().

1829 {
1830  int res = 0;
1831  struct ast_bridge_channel *bridge_channel;
1832 
1833  /* Imparted channels cannot have a PBX. */
1834  if (ast_channel_pbx(chan)) {
1835  ast_log(AST_LOG_WARNING, "Channel %s has a PBX thread and cannot be imparted into bridge %s\n",
1836  ast_channel_name(chan), bridge->uniqueid);
1837  ast_bridge_features_destroy(features);
1838  return -1;
1839  }
1840 
1841  /* Supply an empty features structure if the caller did not. */
1842  if (!features) {
1843  features = ast_bridge_features_new();
1844  if (!features) {
1845  return -1;
1846  }
1847  }
1848 
1849  /* Try to allocate a structure for the bridge channel */
1850  bridge_channel = bridge_channel_internal_alloc(bridge);
1851  if (!bridge_channel) {
1852  ast_bridge_features_destroy(features);
1853  return -1;
1854  }
1855 
1856  ast_channel_lock(chan);
1858  ast_log(AST_LOG_NOTICE, "Channel %s is a zombie and cannot be imparted into bridge %s\n",
1859  ast_channel_name(chan), bridge->uniqueid);
1860  res = -1;
1861  } else {
1862  ast_channel_internal_bridge_channel_set(chan, bridge_channel);
1863  }
1864  ast_channel_unlock(chan);
1865  bridge_channel->chan = chan;
1866  bridge_channel->swap = ao2_t_bump(swap, "Setting up bridge impart");
1867  bridge_channel->features = features;
1868  bridge_channel->inhibit_colp = !!(flags & AST_BRIDGE_IMPART_INHIBIT_JOIN_COLP);
1869  bridge_channel->depart_wait =
1871  bridge_channel->callid = ast_read_threadstorage_callid();
1872 
1873  /* allow subclass to peek at swap channel before it can hangup */
1874  if (bridge->v_table->push_peek && !res) {
1875  struct ast_bridge_channel *bcswap = NULL;
1876 
1877  ast_bridge_lock(bridge);
1878  if (bridge_channel->swap) {
1879  bcswap = bridge_find_channel(bridge, bridge_channel->swap);
1880  }
1881  res = bridge->v_table->push_peek(bridge, bridge_channel, bcswap);
1882  ast_bridge_unlock(bridge);
1883  }
1884 
1885  /* Actually create the thread that will handle the channel */
1886  if (!res) {
1887  res = bridge_channel_impart_add(chan, cond);
1888  }
1889  if (!res) {
1891  res = ast_pthread_create_detached(&bridge_channel->thread, NULL,
1892  bridge_channel_ind_thread, bridge_channel);
1893  } else {
1894  res = ast_pthread_create(&bridge_channel->thread, NULL,
1895  bridge_channel_depart_thread, bridge_channel);
1896  }
1897 
1898  if (!res) {
1900  }
1901  }
1902 
1903  if (res) {
1904  /* cleanup */
1905  ast_channel_lock(chan);
1907  ast_channel_unlock(chan);
1908  /* Lock here for ast_bridge_channel_get_chan */
1909  ao2_lock(bridge_channel);
1910  bridge_channel->chan = NULL;
1911  ao2_unlock(bridge_channel);
1912  ao2_t_cleanup(bridge_channel->swap, "Bridge complete: Impart failed");
1913  bridge_channel->swap = NULL;
1914  ast_bridge_features_destroy(bridge_channel->features);
1915  bridge_channel->features = NULL;
1916 
1917  ao2_ref(bridge_channel, -1);
1918  return -1;
1919  }
1920 
1921  return 0;
1922 }
void ast_channel_internal_bridge_channel_set(struct ast_channel *chan, struct ast_bridge_channel *value)
#define ast_channel_lock(chan)
Definition: channel.h:2945
#define ao2_t_cleanup(obj, tag)
Definition: astobj2.h:1959
const ast_string_field uniqueid
Definition: bridge.h:409
struct ast_bridge_features * features
#define ast_pthread_create_detached(a, b, c, d)
Definition: utils.h:563
#define ast_test_flag(p, flag)
Definition: utils.h:63
struct ast_bridge_features * ast_bridge_features_new(void)
Allocate a new bridge features struct.
Definition: bridge.c:3750
struct ast_bridge_channel * bridge_find_channel(struct ast_bridge *bridge, struct ast_channel *chan)
Definition: bridge.c:1469
#define AST_LOG_WARNING
Definition: logger.h:279
#define ao2_unlock(a)
Definition: astobj2.h:730
#define NULL
Definition: resample.c:96
ast_callid ast_read_threadstorage_callid(void)
extracts the callerid from the thread
Definition: logger.c:1962
#define AST_LOG_NOTICE
Definition: logger.h:268
#define ast_log
Definition: astobj2.c:42
struct ast_pbx * ast_channel_pbx(const struct ast_channel *chan)
#define ao2_ref(o, delta)
Definition: astobj2.h:464
#define ao2_lock(a)
Definition: astobj2.h:718
static void bridge_channel_impart_wait(struct bridge_channel_impart_cond *cond)
Definition: bridge.c:1647
const struct ast_bridge_methods * v_table
Definition: bridge.h:359
static void * bridge_channel_ind_thread(void *data)
Thread responsible for independent imparted bridged channels.
Definition: bridge.c:1788
#define ast_channel_unlock(chan)
Definition: channel.h:2946
#define ast_bridge_unlock(bridge)
Unlock the bridge.
Definition: bridge.h:493
#define ast_pthread_create(a, b, c, d)
Definition: utils.h:559
void ast_bridge_features_destroy(struct ast_bridge_features *features)
Destroy an allocated bridge features struct.
Definition: bridge.c:3741
unsigned int inhibit_colp
struct ast_channel * swap
static int bridge_channel_impart_add(struct ast_channel *chan, struct bridge_channel_impart_cond *cond)
Definition: bridge.c:1593
#define ast_bridge_lock(bridge)
Lock the bridge.
Definition: bridge.h:480
#define ao2_t_bump(obj, tag)
Bump refcount on an AO2 object by one, returning the object.
Definition: astobj2.h:483
struct ast_channel * chan
Structure that contains information regarding a channel in a bridge.
ast_bridge_push_channel_fn push_peek
Definition: bridge.h:281
struct ast_bridge_channel * bridge_channel_internal_alloc(struct ast_bridge *bridge)
const char * ast_channel_name(const struct ast_channel *chan)
unsigned int depart_wait
struct ast_flags * ast_channel_flags(struct ast_channel *chan)
static void * bridge_channel_depart_thread(void *data)
Thread responsible for imparted bridged channels to be departed.
Definition: bridge.c:1757

◆ bridge_manager_create()

static struct bridge_manager_controller* bridge_manager_create ( void  )
static

Definition at line 5009 of file bridge.c.

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

5010 {
5011  struct bridge_manager_controller *manager;
5012 
5013  manager = ao2_alloc(sizeof(*manager), bridge_manager_destroy);
5014  if (!manager) {
5015  /* Well. This isn't good. */
5016  return NULL;
5017  }
5018  ast_cond_init(&manager->cond, NULL);
5020 
5021  /* Create the bridge manager thread. */
5022  if (ast_pthread_create(&manager->thread, NULL, bridge_manager_thread, manager)) {
5023  /* Well. This isn't good either. */
5024  manager->thread = AST_PTHREADT_NULL;
5025  ao2_ref(manager, -1);
5026  manager = NULL;
5027  }
5028 
5029  return manager;
5030 }
static void bridge_manager_destroy(void *obj)
Definition: bridge.c:4977
#define ast_cond_init(cond, attr)
Definition: lock.h:199
#define NULL
Definition: resample.c:96
#define AST_PTHREADT_NULL
Definition: lock.h:66
#define ao2_ref(o, delta)
Definition: astobj2.h:464
#define ao2_alloc(data_size, destructor_fn)
Definition: astobj2.h:411
static void * bridge_manager_thread(void *data)
Definition: bridge.c:4942
#define ast_pthread_create(a, b, c, d)
Definition: utils.h:559
struct bridge_manager_controller::@348 service_requests
#define AST_LIST_HEAD_INIT_NOLOCK(head)
Initializes a list head structure.
Definition: linkedlists.h:680

◆ bridge_manager_destroy()

static void bridge_manager_destroy ( void *  obj)
static

Definition at line 4977 of file bridge.c.

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_request::bridge, 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().

4978 {
4979  struct bridge_manager_controller *manager = obj;
4981 
4982  if (manager->thread != AST_PTHREADT_NULL) {
4983  /* Stop the manager thread. */
4984  ao2_lock(manager);
4985  manager->stop = 1;
4986  ast_cond_signal(&manager->cond);
4987  ao2_unlock(manager);
4988  ast_debug(1, "Waiting for bridge manager thread to die.\n");
4989  pthread_join(manager->thread, NULL);
4990  }
4991 
4992  /* Destroy the service request queue. */
4993  while ((request = AST_LIST_REMOVE_HEAD(&manager->service_requests, node))) {
4994  ao2_ref(request->bridge, -1);
4995  ast_free(request);
4996  }
4997 
4998  ast_cond_destroy(&manager->cond);
4999 }
Definition: test_heap.c:38
unsigned int stop
Definition: bridge.c:168
#define ao2_unlock(a)
Definition: astobj2.h:730
#define NULL
Definition: resample.c:96
#define ast_cond_signal(cond)
Definition: lock.h:201
#define ast_debug(level,...)
Log a DEBUG message.
Definition: logger.h:452
#define AST_PTHREADT_NULL
Definition: lock.h:66
#define ao2_ref(o, delta)
Definition: astobj2.h:464
#define ao2_lock(a)
Definition: astobj2.h:718
#define AST_LIST_REMOVE_HEAD(head, field)
Removes and returns the head entry from a list.
Definition: linkedlists.h:832
struct ast_bridge * bridge
Definition: bridge.c:157
#define ast_cond_destroy(cond)
Definition: lock.h:200
#define ast_free(a)
Definition: astmm.h:182
static int request(void *obj)
Definition: chan_pjsip.c:2559
struct bridge_manager_controller::@348 service_requests

◆ bridge_manager_service()

static void bridge_manager_service ( struct ast_bridge bridge)
static

Definition at line 4923 of file bridge.c.

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

Referenced by bridge_manager_thread().

4924 {
4925  ast_bridge_lock(bridge);
4926  if (bridge->callid) {
4928  }
4929 
4930  /* Do any pending bridge actions. */
4931  bridge_handle_actions(bridge);
4932  ast_bridge_unlock(bridge);
4933 }
ast_callid callid
Definition: bridge.h:369
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:1971
#define ast_bridge_unlock(bridge)
Unlock the bridge.
Definition: bridge.h:493
#define ast_bridge_lock(bridge)
Lock the bridge.
Definition: bridge.h:480
static void bridge_handle_actions(struct ast_bridge *bridge)
Definition: bridge.c:640

◆ bridge_manager_service_req()

static void bridge_manager_service_req ( struct ast_bridge bridge)
static

Definition at line 188 of file bridge.c.

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

Referenced by bridge_queue_action_nodup().

189 {
191 
193  if (bridge_manager->stop) {
195  return;
196  }
197 
198  /* Create the service request. */
199  request = ast_calloc(1, sizeof(*request));
200  if (!request) {
201  /* Well. This isn't good. */
203  return;
204  }
205  ao2_ref(bridge, +1);
206  request->bridge = bridge;
207 
208  /* Put request into the queue and wake the bridge manager. */
212 }
Definition: test_heap.c:38
unsigned int stop
Definition: bridge.c:168
#define ao2_unlock(a)
Definition: astobj2.h:730
static struct bridge_manager_controller * bridge_manager
Definition: bridge.c:172
#define ast_cond_signal(cond)
Definition: lock.h:201
#define ao2_ref(o, delta)
Definition: astobj2.h:464
#define ao2_lock(a)
Definition: astobj2.h:718
#define AST_LIST_INSERT_TAIL(head, elm, field)
Appends a list entry to the tail of a list.
Definition: linkedlists.h:730
struct ast_bridge * bridge
Definition: bridge.c:157
#define ast_calloc(num, len)
A wrapper for calloc()
Definition: astmm.h:204
static int request(void *obj)
Definition: chan_pjsip.c:2559
struct bridge_manager_controller::@348 service_requests

◆ bridge_manager_thread()

static void* bridge_manager_thread ( void *  data)
static

Definition at line 4942 of file bridge.c.

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

Referenced by bridge_manager_create().

4943 {
4944  struct bridge_manager_controller *manager = data;
4946 
4947  ao2_lock(manager);
4948  while (!manager->stop) {
4949  request = AST_LIST_REMOVE_HEAD(&manager->service_requests, node);
4950  if (!request) {
4951  ast_cond_wait(&manager->cond, ao2_object_get_lockaddr(manager));
4952  continue;
4953  }
4954  ao2_unlock(manager);
4955 
4956  /* Service the bridge. */
4957  bridge_manager_service(request->bridge);
4958  ao2_ref(request->bridge, -1);
4959  ast_free(request);
4960 
4961  ao2_lock(manager);
4962  }
4963  ao2_unlock(manager);
4964 
4965  return NULL;
4966 }
Definition: test_heap.c:38
unsigned int stop
Definition: bridge.c:168
static void bridge_manager_service(struct ast_bridge *bridge)
Definition: bridge.c:4923
#define ast_cond_wait(cond, mutex)
Definition: lock.h:203
#define ao2_unlock(a)
Definition: astobj2.h:730
#define NULL
Definition: resample.c:96
void * ao2_object_get_lockaddr(void *obj)
Return the mutex lock address of an object.
Definition: astobj2.c:476
#define ao2_ref(o, delta)
Definition: astobj2.h:464
#define ao2_lock(a)
Definition: astobj2.h:718
#define AST_LIST_REMOVE_HEAD(head, field)
Removes and returns the head entry from a list.
Definition: linkedlists.h:832
struct ast_bridge * bridge
Definition: bridge.c:157
#define ast_free(a)
Definition: astmm.h:182
static int request(void *obj)
Definition: chan_pjsip.c:2559
struct bridge_manager_controller::@348 service_requests

◆ bridge_merge_determine_direction()

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

Definition at line 2201 of file bridge.c.

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

2202 {
2203  struct merge_direction merge = { NULL, NULL };
2204  int bridge1_priority;
2205  int bridge2_priority;
2206 
2207  if (!ast_test_flag(&bridge1->feature_flags,
2209  && !ast_test_flag(&bridge2->feature_flags,
2211  /*
2212  * Can merge either way. Merge to the higher priority merge
2213  * bridge. Otherwise merge to the larger bridge.
2214  */
2215  bridge1_priority = bridge1->v_table->get_merge_priority(bridge1);
2216  bridge2_priority = bridge2->v_table->get_merge_priority(bridge2);
2217  if (bridge2_priority < bridge1_priority) {
2218  merge.dest = bridge1;
2219  merge.src = bridge2;
2220  } else if (bridge1_priority < bridge2_priority) {
2221  merge.dest = bridge2;
2222  merge.src = bridge1;
2223  } else {
2224  /* Merge to the larger bridge. */
2225  if (bridge2->num_channels <= bridge1->num_channels) {
2226  merge.dest = bridge1;
2227  merge.src = bridge2;
2228  } else {
2229  merge.dest = bridge2;
2230  merge.src = bridge1;
2231  }
2232  }
2235  /* Can merge only one way. */
2236  merge.dest = bridge1;
2237  merge.src = bridge2;
2240  /* Can merge only one way. */
2241  merge.dest = bridge2;
2242  merge.src = bridge1;
2243  }
2244 
2245  return merge;
2246 }
struct ast_flags feature_flags
Definition: bridge.h:377
#define ast_test_flag(p, flag)
Definition: utils.h:63
struct ast_bridge * src
Definition: bridge.c:2186
#define NULL
Definition: resample.c:96
struct ast_bridge * dest
Definition: bridge.c:2184
const struct ast_bridge_methods * v_table
Definition: bridge.h:359
ast_bridge_merge_priority_fn get_merge_priority
Definition: bridge.h:279
unsigned int num_channels
Definition: bridge.h:381

◆ bridge_merge_inhibit_nolock()

void bridge_merge_inhibit_nolock ( struct ast_bridge bridge,
int  request 
)

Definition at line 3052 of file bridge.c.

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

Referenced by ast_bridge_channel_merge_inhibit(), and ast_bridge_merge_inhibit().

3053 {
3054  int new_request;
3055 
3056  new_request = bridge->inhibit_merge + request;
3057  ast_assert(0 <= new_request);
3058  bridge->inhibit_merge = new_request;
3059 }
unsigned int inhibit_merge
Count of the active temporary requests to inhibit bridge merges. Zero if merges are allowed...
Definition: bridge.h:392
#define ast_assert(a)
Definition: utils.h:695
static int request(void *obj)
Definition: chan_pjsip.c:2559

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

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

2265 {
2266  struct merge_direction merge;
2267  struct ast_bridge_channel **kick_them = NULL;
2268 
2269  /* Sanity check. */
2270  ast_assert(dst_bridge && src_bridge && dst_bridge != src_bridge && (!num_kick || kick_me));
2271 
2272  if (dst_bridge->dissolved || src_bridge->dissolved) {
2273  ast_debug(1, "Can't merge bridges %s and %s, at least one bridge is dissolved.\n",
2274  src_bridge->uniqueid, dst_bridge->uniqueid);
2275  return -1;
2276  }
2279  ast_debug(1, "Can't merge bridges %s and %s, masquerade only.\n",
2280  src_bridge->uniqueid, dst_bridge->uniqueid);
2281  return -1;
2282  }
2283  if (dst_bridge->inhibit_merge || src_bridge->inhibit_merge) {
2284  ast_debug(1, "Can't merge bridges %s and %s, merging temporarily inhibited.\n",
2285  src_bridge->uniqueid, dst_bridge->uniqueid);
2286  return -1;
2287  }
2288 
2289  if (merge_best_direction) {
2290  merge = bridge_merge_determine_direction(dst_bridge, src_bridge);
2291  } else {
2292  merge.dest = dst_bridge;
2293  merge.src = src_bridge;
2294  }
2295 
2296  if (!merge.dest
2297  || ast_test_flag(&merge.dest->feature_flags, AST_BRIDGE_FLAG_MERGE_INHIBIT_TO)
2298  || ast_test_flag(&merge.src->feature_flags, AST_BRIDGE_FLAG_MERGE_INHIBIT_FROM)) {
2299  ast_debug(1, "Can't merge bridges %s and %s, merging inhibited.\n",
2300  src_bridge->uniqueid, dst_bridge->uniqueid);
2301  return -1;
2302  }
2303  if (merge.src->num_channels < 2) {
2304  /*
2305  * For a two party bridge, a channel may be temporarily removed
2306  * from the source bridge or the initial bridge members have not
2307  * joined yet.
2308  */
2309  ast_debug(1, "Can't merge bridge %s into bridge %s, not enough channels in source bridge.\n",
2310  merge.src->uniqueid, merge.dest->uniqueid);
2311  return -1;
2312  }
2313  if (2 + num_kick < merge.dest->num_channels + merge.src->num_channels
2314  && !(merge.dest->technology->capabilities & AST_BRIDGE_CAPABILITY_MULTIMIX)
2315  && (!ast_test_flag(&merge.dest->feature_flags, AST_BRIDGE_FLAG_SMART)
2316  || !(merge.dest->allowed_capabilities & AST_BRIDGE_CAPABILITY_MULTIMIX))) {
2317  ast_debug(1, "Can't merge bridge %s into bridge %s, multimix is needed and it cannot be acquired.\n",
2318  merge.src->uniqueid, merge.dest->uniqueid);
2319  return -1;
2320  }
2321 
2322  if (num_kick) {
2323  unsigned int num_to_kick = 0;
2324  unsigned int idx;
2325 
2326  kick_them = ast_alloca(num_kick * sizeof(*kick_them));
2327  for (idx = 0; idx < num_kick; ++idx) {
2328  kick_them[num_to_kick] = bridge_find_channel(merge.src, kick_me[idx]);
2329  if (!kick_them[num_to_kick]) {
2330  kick_them[num_to_kick] = bridge_find_channel(merge.dest, kick_me[idx]);
2331  }
2332  if (kick_them[num_to_kick]) {
2333  ++num_to_kick;
2334  }
2335  }
2336 
2337  if (num_to_kick != num_kick) {
2338  ast_debug(1, "Can't merge bridge %s into bridge %s, at least one kicked channel is not in either bridge.\n",
2339  merge.src->uniqueid, merge.dest->uniqueid);
2340  return -1;
2341  }
2342  }
2343 
2344  bridge_do_merge(merge.dest, merge.src, kick_them, num_kick, 0);
2345  return 0;
2346 }
struct ast_flags feature_flags
Definition: bridge.h:377
const ast_string_field uniqueid
Definition: bridge.h:409
#define ast_test_flag(p, flag)
Definition: utils.h:63
struct ast_bridge_channel * bridge_find_channel(struct ast_bridge *bridge, struct ast_channel *chan)
Definition: bridge.c:1469
unsigned int dissolved
Definition: bridge.h:398
static struct merge_direction bridge_merge_determine_direction(struct ast_bridge *bridge1, struct ast_bridge *bridge2)
Definition: bridge.c:2201
unsigned int inhibit_merge
Count of the active temporary requests to inhibit bridge merges. Zero if merges are allowed...
Definition: bridge.h:392
#define ast_assert(a)
Definition: utils.h:695
#define NULL
Definition: resample.c:96
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:2096
#define ast_debug(level,...)
Log a DEBUG message.
Definition: logger.h:452
#define ast_alloca(size)
call __builtin_alloca to ensure we get gcc builtin semantics
Definition: astmm.h:290
Structure that contains information regarding a channel in a bridge.

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

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::dissolved, ast_bridge_features::feature_flags, ast_bridge::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().

2448 {
2449  struct ast_bridge_channel *bridge_channel;
2450 
2451  if (dst_bridge->dissolved || src_bridge->dissolved) {
2452  ast_debug(1, "Can't move channel %s from bridge %s into bridge %s, at least one bridge is dissolved.\n",
2453  ast_channel_name(chan), src_bridge->uniqueid, dst_bridge->uniqueid);
2454  return -1;
2455  }
2458  ast_debug(1, "Can't move channel %s from bridge %s into bridge %s, masquerade only.\n",
2459  ast_channel_name(chan), src_bridge->uniqueid, dst_bridge->uniqueid);
2460  return -1;
2461  }
2462  if (dst_bridge->inhibit_merge || src_bridge->inhibit_merge) {
2463  ast_debug(1, "Can't move channel %s from bridge %s into bridge %s, temporarily inhibited.\n",
2464  ast_channel_name(chan), src_bridge->uniqueid, dst_bridge->uniqueid);
2465  return -1;
2466  }
2467 
2468  bridge_channel = bridge_find_channel(src_bridge, chan);
2469  if (!bridge_channel) {
2470  ast_debug(1, "Can't move channel %s from bridge %s into bridge %s, channel not in bridge.\n",
2471  ast_channel_name(chan), src_bridge->uniqueid, dst_bridge->uniqueid);
2472  return -1;
2473  }
2474  if (bridge_channel->state != BRIDGE_CHANNEL_STATE_WAIT) {
2475  ast_debug(1, "Can't move channel %s from bridge %s into bridge %s, channel leaving bridge.\n",
2476  ast_channel_name(chan), src_bridge->uniqueid, dst_bridge->uniqueid);
2477  return -1;
2478  }
2479  if (ast_test_flag(&bridge_channel->features->feature_flags,
2481  ast_debug(1, "Can't move channel %s from bridge %s into bridge %s, channel immovable.\n",
2482  ast_channel_name(chan), src_bridge->uniqueid, dst_bridge->uniqueid);
2483  return -1;
2484  }
2485 
2486  if (swap) {
2487  struct ast_bridge_channel *bridge_channel_swap;
2488 
2489  bridge_channel_swap = bridge_find_channel(dst_bridge, swap);
2490  if (!bridge_channel_swap) {
2491  ast_debug(1, "Can't move channel %s from bridge %s into bridge %s, swap channel %s not in bridge.\n",
2492  ast_channel_name(chan), src_bridge->uniqueid, dst_bridge->uniqueid,
2493  ast_channel_name(swap));
2494  return -1;
2495  }
2496  if (bridge_channel_swap->state != BRIDGE_CHANNEL_STATE_WAIT) {
2497  ast_debug(1, "Can't move channel %s from bridge %s into bridge %s, swap channel %s leaving bridge.\n",
2498  ast_channel_name(chan), src_bridge->uniqueid, dst_bridge->uniqueid,
2499  ast_channel_name(swap));
2500  return -1;
2501  }
2502  }
2503 
2504  bridge_channel->swap = swap;
2505  return bridge_do_move(dst_bridge, bridge_channel, attempt_recovery, 0);
2506 }
struct ast_flags feature_flags
Definition: bridge.h:377
const ast_string_field uniqueid
Definition: bridge.h:409
struct ast_bridge_features * features
#define ast_test_flag(p, flag)
Definition: utils.h:63
struct ast_bridge_channel * bridge_find_channel(struct ast_bridge *bridge, struct ast_channel *chan)
Definition: bridge.c:1469
unsigned int dissolved
Definition: bridge.h:398
enum bridge_channel_state state
unsigned int inhibit_merge
Count of the active temporary requests to inhibit bridge merges. Zero if merges are allowed...
Definition: bridge.h:392
int bridge_do_move(struct ast_bridge *dst_bridge, struct ast_bridge_channel *bridge_channel, int attempt_recovery, unsigned int optimized)
Definition: bridge.c:2362
struct ast_flags feature_flags
#define ast_debug(level,...)
Log a DEBUG message.
Definition: logger.h:452
struct ast_channel * swap
Structure that contains information regarding a channel in a bridge.
const char * ast_channel_name(const struct ast_channel *chan)

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

References ao2_link, ao2_ref, bridge_hook_generic(), ast_bridge_hook::destructor, NULL, ast_bridge_features::other_hooks, 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().

3300 {
3301  struct ast_bridge_hook *hook;
3302  int res;
3303 
3304  /* Allocate new hook and setup it's various variables */
3305  hook = bridge_hook_generic(sizeof(*hook), callback, hook_pvt, destructor,
3306  remove_flags);
3307  if (!hook) {
3308  return -1;
3309  }
3310  hook->type = type;
3311 
3312  /* Once done we put it in the container. */
3313  res = ao2_link(features->other_hooks, hook) ? 0 : -1;
3314  if (res) {
3315  /*
3316  * Could not link the hook into the container.
3317  *
3318  * Remove the hook_pvt destructor call from the hook since we
3319  * are returning failure to install the hook.
3320  */
3321  hook->destructor = NULL;
3322  }
3323  ao2_ref(hook, -1);
3324 
3325  return res;
3326 }
static const char type[]
Definition: chan_ooh323.c:109
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:3225
ast_bridge_hook_pvt_destructor destructor
#define NULL
Definition: resample.c:96
enum ast_bridge_hook_type type
#define ao2_ref(o, delta)
Definition: astobj2.h:464
ast_bridge_hook_callback callback
struct ao2_container * other_hooks
struct ast_flags remove_flags
Structure that is the essence of a feature hook.
#define ao2_link(container, obj)
Definition: astobj2.h:1549

◆ bridge_prnt_obj()

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

Definition at line 5573 of file bridge.c.

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

Referenced by ast_bridging_init().

5574 {
5575  struct ast_bridge *bridge = v_obj;
5576 
5577  if (!bridge) {
5578  return;
5579  }
5580  prnt(where, "%s %s chans:%u",
5581  bridge->uniqueid, bridge->v_table->name, bridge->num_channels);
5582 }
const ast_string_field uniqueid
Definition: bridge.h:409
const char * name
Definition: bridge.h:267
const struct ast_bridge_methods * v_table
Definition: bridge.h:359
Structure that contains information about a bridge.
Definition: bridge.h:357
unsigned int num_channels
Definition: bridge.h:381

◆ bridge_queue_action_nodup()

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

Definition at line 296 of file bridge.c.

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

297 {
298  ast_debug(1, "Bridge %s: queueing action type:%u sub:%d\n",
299  bridge->uniqueid, action->frametype, action->subclass.integer);
300 
301  ast_bridge_lock(bridge);
302  AST_LIST_INSERT_TAIL(&bridge->action_queue, action, frame_list);
303  ast_bridge_unlock(bridge);
305 }
const ast_string_field uniqueid
Definition: bridge.h:409
static void bridge_manager_service_req(struct ast_bridge *bridge)
Definition: bridge.c:188
struct ast_frame_subclass subclass
#define ast_debug(level,...)
Log a DEBUG message.
Definition: logger.h:452
struct ast_bridge::@228 action_queue
#define AST_LIST_INSERT_TAIL(head, elm, field)
Appends a list entry to the tail of a list.
Definition: linkedlists.h:730
#define ast_bridge_unlock(bridge)
Unlock the bridge.
Definition: bridge.h:493
#define ast_bridge_lock(bridge)
Lock the bridge.
Definition: bridge.h:480
enum ast_frame_type frametype

◆ bridge_reconfigured()

void bridge_reconfigured ( struct ast_bridge bridge,
unsigned int  colp_update 
)

Definition at line 1443 of file bridge.c.

References AST_BRIDGE_FLAG_SMART, ast_bridge_publish_state(), ast_test_flag, 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().

1444 {
1445  if (!bridge->reconfigured) {
1446  return;
1447  }
1448  bridge->reconfigured = 0;
1450  && smart_bridge_operation(bridge)) {
1451  /* Smart bridge failed. */
1452  bridge_dissolve(bridge, 0);
1453  return;
1454  }
1455  bridge_complete_join(bridge);
1456 
1457  if (bridge->dissolved) {
1458  return;
1459  }
1460  check_bridge_play_sounds(bridge);
1461  set_bridge_peer_vars(bridge);
1462  ast_bridge_publish_state(bridge);
1463 
1464  if (colp_update) {
1466  }
1467 }
struct ast_flags feature_flags
Definition: bridge.h:377
static void check_bridge_play_sounds(struct ast_bridge *bridge)
Definition: bridge.c:1233
#define ast_test_flag(p, flag)
Definition: utils.h:63
unsigned int dissolved
Definition: bridge.h:398
unsigned int reconfigured
Definition: bridge.h:396
static void set_bridge_peer_vars(struct ast_bridge *bridge)
Definition: bridge.c:1426
void bridge_dissolve(struct ast_bridge *bridge, int cause)
Definition: bridge.c:319
static void bridge_reconfigured_connected_line_update(struct ast_bridge *bridge)
Definition: bridge.c:393
void ast_bridge_publish_state(struct ast_bridge *bridge)
Publish the state of a bridge.
static int smart_bridge_operation(struct ast_bridge *bridge)
Definition: bridge.c:998
static void bridge_complete_join(struct ast_bridge *bridge)
Definition: bridge.c:486

◆ bridge_reconfigured_connected_line_update()

static void bridge_reconfigured_connected_line_update ( struct ast_bridge bridge)
static

Definition at line 393 of file bridge.c.

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_technology::capabilities, ast_bridge_channel::chan, ast_bridge::channels, NULL, and ast_bridge::technology.

Referenced by bridge_reconfigured().

394 {
396  struct ast_bridge_channel *bridge_channel = AST_LIST_FIRST(&bridge->channels), *peer;
397  unsigned char data[1024];
398  size_t datalen;
399 
400  if (!bridge_channel ||
402  !(peer = ast_bridge_channel_peer(bridge_channel)) ||
405  ast_check_hangup_locked(bridge_channel->chan) ||
406  ast_check_hangup_locked(peer->chan)) {
407  return;
408  }
409 
411 
412  ast_channel_lock(bridge_channel->chan);
414  ast_channel_unlock(bridge_channel->chan);
415 
416  if ((datalen = ast_connected_line_build_data(data, sizeof(data), &connected, NULL)) != (size_t) -1) {
418  }
419 
420  ast_channel_lock(peer->chan);
422  ast_channel_unlock(peer->chan);
423 
424  if ((datalen = ast_connected_line_build_data(data, sizeof(data), &connected, NULL)) != (size_t) -1) {
426  }
427 
429 }
struct ast_party_caller * ast_channel_caller(struct ast_channel *chan)
void ast_party_connected_line_init(struct ast_party_connected_line *init)
Initialize the given connected line structure.
Definition: channel.c:2022
#define ast_channel_lock(chan)
Definition: channel.h:2945
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:8793
#define AST_LIST_FIRST(head)
Returns the first entry contained in a list.
Definition: linkedlists.h:420
#define ast_test_flag(p, flag)
Definition: utils.h:63
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_check_hangup_locked(struct ast_channel *chan)
Definition: channel.c:459
void ast_party_connected_line_free(struct ast_party_connected_line *doomed)
Destroy the connected line information contents.
Definition: channel.c:2072
#define NULL
Definition: resample.c:96
struct ast_bridge_technology * technology
Definition: bridge.h:363
Connected Line/Party information.
Definition: channel.h:457
#define ast_channel_unlock(chan)
Definition: channel.h:2946
struct ast_bridge_channels_list channels
Definition: bridge.h:371
struct ast_channel * chan
Structure that contains information regarding a channel in a bridge.
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:8389
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.
struct ast_flags * ast_channel_flags(struct ast_channel *chan)
char connected
Definition: eagi_proxy.c:82

◆ 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;
}
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.
Return values
bridgeon success.
NULLon error.

Definition at line 709 of file bridge.c.

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

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

710 {
711  if (bridge) {
712  bridge->construction_completed = 1;
713  ast_bridge_lock(bridge);
714  ast_bridge_publish_state(bridge);
715  ast_bridge_unlock(bridge);
716  if (!ao2_link(bridges, bridge)) {
717  ast_bridge_destroy(bridge, 0);
718  bridge = NULL;
719  }
720  }
721  return bridge;
722 }
#define NULL
Definition: resample.c:96
int ast_bridge_destroy(struct ast_bridge *bridge, int cause)
Destroy a bridge.
Definition: bridge.c:970
void ast_bridge_publish_state(struct ast_bridge *bridge)
Publish the state of a bridge.
static struct ao2_container * bridges
Definition: bridge.c:123
#define ast_bridge_unlock(bridge)
Unlock the bridge.
Definition: bridge.h:493
#define ast_bridge_lock(bridge)
Lock the bridge.
Definition: bridge.h:480
unsigned int construction_completed
Definition: bridge.h:400
#define ao2_link(container, obj)
Definition: astobj2.h:1549

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

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

Referenced by handle_bridge_show_specific().

5141 {
5142  const char *uniqueid = obj;
5143  struct ast_cli_args *a = arg;
5144  struct ast_channel_snapshot *snapshot;
5145 
5146  snapshot = ast_channel_snapshot_get_latest(uniqueid);
5147  if (!snapshot) {
5148  return 0;
5149  }
5150 
5151  ast_cli(a->fd, "Channel: %s\n", snapshot->base->name);
5152  ao2_ref(snapshot, -1);
5153 
5154  return 0;
5155 }
struct ast_channel_snapshot_base * base
const ast_string_field uniqueid
Definition: bridge.h:409
Structure representing a snapshot of channel state.
void ast_cli(int fd, const char *fmt,...)
Definition: clicompat.c:6
const int fd
Definition: cli.h:159
#define ao2_ref(o, delta)
Definition: astobj2.h:464
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...
const ast_string_field name
static struct test_val a

◆ bridge_sort_cmp()

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

Definition at line 5048 of file bridge.c.

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

Referenced by ast_bridging_init().

5049 {
5050  const struct ast_bridge *bridge_left = obj_left;
5051  const struct ast_bridge *bridge_right = obj_right;
5052  const char *right_key = obj_right;
5053  int cmp;
5054 
5055  switch (flags & (OBJ_POINTER | OBJ_KEY | OBJ_PARTIAL_KEY)) {
5056  default:
5057  case OBJ_POINTER:
5058  right_key = bridge_right->uniqueid;
5059  /* Fall through */
5060  case OBJ_KEY:
5061  cmp = strcmp(bridge_left->uniqueid, right_key);
5062  break;
5063  case OBJ_PARTIAL_KEY:
5064  cmp = strncmp(bridge_left->uniqueid, right_key, strlen(right_key));
5065  break;
5066  }
5067  return cmp;
5068 }
const ast_string_field uniqueid
Definition: bridge.h:409
#define OBJ_KEY
Definition: astobj2.h:1155
#define OBJ_POINTER
Definition: astobj2.h:1154
#define OBJ_PARTIAL_KEY
Definition: astobj2.h:1156
Structure that contains information about a bridge.
Definition: bridge.h:357

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

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

4622 {
4623  struct ast_bridge_channel *bridged_to_source;
4624 
4625  bridged_to_source = ast_bridge_channel_peer(source_bridge_channel);
4626  if (bridged_to_source
4627  && bridged_to_source->state == BRIDGE_CHANNEL_STATE_WAIT
4628  && !ast_test_flag(&bridged_to_source->features->feature_flags,
4630  bridged_to_source->swap = swap_channel;
4631  if (bridge_do_move(dest_bridge, bridged_to_source, 1, 0)) {
4632  return AST_BRIDGE_TRANSFER_FAIL;
4633  }
4634  /* Must kick the source channel out of its bridge. */
4635  ast_bridge_channel_leave_bridge(source_bridge_channel,
4638  } else {
4640  }
4641 }
struct ast_bridge_features * features
#define ast_test_flag(p, flag)
Definition: utils.h:63
struct ast_bridge_channel * ast_bridge_channel_peer(struct ast_bridge_channel *bridge_channel)
Get the peer bridge channel of a two party bridge.
enum bridge_channel_state state
int bridge_do_move(struct ast_bridge *dst_bridge, struct ast_bridge_channel *bridge_channel, int attempt_recovery, unsigned int optimized)
Definition: bridge.c:2362
struct ast_flags feature_flags
#define AST_CAUSE_NORMAL_CLEARING
Definition: causes.h:105
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).
struct ast_channel * swap
Structure that contains information regarding a channel in a bridge.

◆ bridge_tech_deferred_destroy()

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

Definition at line 574 of file bridge.c.

References ast_debug, ast_module_unref, ast_bridge::creator, ast_frame::data, ast_bridge_technology::destroy, ast_bridge_technology::mod, ast_bridge_technology::name, ast_bridge::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().

575 {
576  struct tech_deferred_destroy *deferred = action->data.ptr;
577  struct ast_bridge dummy_bridge = {
578  .technology = deferred->tech,
579  .tech_pvt = deferred->tech_pvt,
580  .creator = bridge->creator,
581  .name = bridge->name,
582  .uniqueid = bridge->uniqueid,
583  };
584 
585  ast_debug(1, "Bridge %s: calling %s technology destructor (deferred, dummy)\n",
586  dummy_bridge.uniqueid, dummy_bridge.technology->name);
587  dummy_bridge.technology->destroy(&dummy_bridge);
588  ast_module_unref(dummy_bridge.technology->mod);
589 }
const ast_string_field uniqueid
Definition: bridge.h:409
const ast_string_field name
Definition: bridge.h:409
#define ast_module_unref(mod)
Release a reference to the module.
Definition: module.h:469
struct ast_bridge_technology * technology
Definition: bridge.h:363
#define ast_debug(level,...)
Log a DEBUG message.
Definition: logger.h:452
struct ast_bridge_technology * tech
Definition: bridge.c:558
Structure that contains information about a bridge.
Definition: bridge.h:357
void(* destroy)(struct ast_bridge *bridge)
Destroy a bridging technology instance for a bridge.
struct ast_module * mod
union ast_frame::@263 data
const ast_string_field creator
Definition: bridge.h:409

◆ 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

Definition at line 2883 of file bridge.c.

References ast_bridge::allowed_capabilities, AST_BRIDGE_CAPABILITY_MULTIMIX, AST_BRIDGE_FLAG_SMART, ast_test_flag, bridge_merge_determine_direction(), ast_bridge_technology::capabilities, merge_direction::dest, ast_bridge::feature_flags, MERGE_ALLOWED, MERGE_NO_MULTIMIX, MERGE_NOT_ENOUGH_CHANNELS, MERGE_PROHIBITED, ast_bridge::num_channels, merge_direction::src, and ast_bridge::technology.

Referenced by ast_bridges_allow_optimization(), and try_merge_optimize_out().

2885 {
2886  *merge = bridge_merge_determine_direction(chan_bridge, peer_bridge);
2887  if (!merge->dest) {
2888  return MERGE_PROHIBITED;
2889  }
2890  if (merge->src->num_channels < 2) {
2892  } else if ((2 + num_kick_channels) < merge->dest->num_channels + merge->src->num_channels
2896  return MERGE_NO_MULTIMIX;
2897  }
2898 
2899  return MERGE_ALLOWED;
2900 }
struct ast_flags feature_flags
Definition: bridge.h:377
#define ast_test_flag(p, flag)
Definition: utils.h:63
static struct merge_direction bridge_merge_determine_direction(struct ast_bridge *bridge1, struct ast_bridge *bridge2)
Definition: bridge.c:2201
struct ast_bridge * src
Definition: bridge.c:2186
struct ast_bridge * dest
Definition: bridge.c:2184
struct ast_bridge_technology * technology
Definition: bridge.h:363
uint32_t allowed_capabilities
Definition: bridge.h:379
unsigned int num_channels
Definition: bridge.h:381

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

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

2739 {
2740  int chan_priority;
2741  int peer_priority;
2742 
2743  if (!ast_test_flag(&chan_bridge->feature_flags,
2746  && !ast_test_flag(&peer_bridge->feature_flags,
2749  /*
2750  * Can swap either way. Swap to the higher priority merge
2751  * bridge.
2752  */
2753  chan_priority = chan_bridge->v_table->get_merge_priority(chan_bridge);
2754  peer_priority = peer_bridge->v_table->get_merge_priority(peer_bridge);
2755  if (chan_bridge->num_channels == 2
2756  && chan_priority <= peer_priority) {
2757  return SWAP_TO_PEER_BRIDGE;
2758  } else if (peer_bridge->num_channels == 2
2759  && peer_priority <= chan_priority) {
2760  return SWAP_TO_CHAN_BRIDGE;
2761  }
2762  } else if (chan_bridge->num_channels == 2
2765  /* Can swap optimize only one way. */
2766  return SWAP_TO_PEER_BRIDGE;
2767  } else if (peer_bridge->num_channels == 2
2770  /* Can swap optimize only one way. */
2771  return SWAP_TO_CHAN_BRIDGE;
2772  }
2773 
2774  return SWAP_PROHIBITED;
2775 }
struct ast_flags feature_flags
Definition: bridge.h:377
#define ast_test_flag(p, flag)
Definition: utils.h:63
const struct ast_bridge_methods * v_table
Definition: bridge.h:359
ast_bridge_merge_priority_fn get_merge_priority
Definition: bridge.h:279
unsigned int num_channels
Definition: bridge.h:381

◆ channel_cmp()

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

Definition at line 4063 of file bridge.c.

References ast_channel_name(), CMP_MATCH, OBJ_KEY, OBJ_PARTIAL_KEY, and OBJ_POINTER.

Referenced by ast_bridge_peers_nolock().

4064 {
4065  const struct ast_channel *left = obj;
4066  const struct ast_channel *right = arg;
4067  const char *right_name = arg;
4068  int cmp;
4069 
4070  switch (flags & (OBJ_POINTER | OBJ_KEY | OBJ_PARTIAL_KEY)) {
4071  default:
4072  case OBJ_POINTER:
4073  right_name = ast_channel_name(right);
4074  /* Fall through */
4075  case OBJ_KEY:
4076  cmp = strcmp(ast_channel_name(left), right_name);
4077  break;
4078  case OBJ_PARTIAL_KEY:
4079  cmp = strncmp(ast_channel_name(left), right_name, strlen(right_name));
4080  break;
4081  }
4082  return cmp ? 0 : CMP_MATCH;
4083 }
Main Channel structure associated with a channel.
#define OBJ_KEY
Definition: astobj2.h:1155
#define OBJ_POINTER
Definition: astobj2.h:1154
#define OBJ_PARTIAL_KEY
Definition: astobj2.h:1156
const char * ast_channel_name(const struct ast_channel *chan)

◆ channel_hash()

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

Definition at line 4040 of file bridge.c.

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

Referenced by ast_bridge_peers_nolock().

4041 {
4042  const struct ast_channel *chan = obj;
4043  const char *name = obj;
4044  int hash;
4045 
4046  switch (flags & (OBJ_POINTER | OBJ_KEY | OBJ_PARTIAL_KEY)) {
4047  default:
4048  case OBJ_POINTER:
4049  name = ast_channel_name(chan);
4050  /* Fall through */
4051  case OBJ_KEY:
4052  hash = ast_str_hash(name);
4053  break;
4054  case OBJ_PARTIAL_KEY:
4055  /* Should never happen in hash callback. */
4056  ast_assert(0);
4057  hash = 0;
4058  break;
4059  }
4060  return hash;
4061 }
Main Channel structure associated with a channel.
#define OBJ_KEY
Definition: astobj2.h:1155
#define OBJ_POINTER
Definition: astobj2.h:1154
#define ast_assert(a)
Definition: utils.h:695
#define OBJ_PARTIAL_KEY
Definition: astobj2.h:1156
static const char name[]
Definition: cdr_mysql.c:74
const char * ast_channel_name(const struct ast_channel *chan)
static force_inline int attribute_pure ast_str_hash(const char *str)
Compute a hash value on a string.
Definition: strings.h:1206

◆ check_bridge_play_sound()

static void check_bridge_play_sound ( struct ast_bridge_channel bridge_channel)
static

Definition at line 1203 of file bridge.c.

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

1204 {
1205  const char *play_file;
1206 
1207  ast_channel_lock(bridge_channel->chan);
1208  play_file = pbx_builtin_getvar_helper(bridge_channel->chan, "BRIDGE_PLAY_SOUND");
1209  if (!ast_strlen_zero(play_file)) {
1210  play_file = ast_strdupa(play_file);
1211  pbx_builtin_setvar_helper(bridge_channel->chan, "BRIDGE_PLAY_SOUND", NULL);
1212  } else {
1213  play_file = NULL;
1214  }
1215  ast_channel_unlock(bridge_channel->chan);
1216 
1217  if (play_file) {
1218  ast_bridge_channel_queue_playfile(bridge_channel, NULL, play_file, NULL);
1219  }
1220 }
#define ast_channel_lock(chan)
Definition: channel.h:2945
#define NULL
Definition: resample.c:96
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 ast_strlen_zero(foo)
Definition: strings.h:52
#define ast_strdupa(s)
duplicate a string in memory from the stack
Definition: astmm.h:300
#define ast_channel_unlock(chan)
Definition: channel.h:2946
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...
struct ast_channel * chan
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.
static int play_file(struct ast_bridge_channel *bridge_channel, struct ast_channel *channel, const char *filename)

◆ check_bridge_play_sounds()

static void check_bridge_play_sounds ( struct ast_bridge bridge)
static

Definition at line 1233 of file bridge.c.

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

Referenced by bridge_reconfigured().

1234 {
1235  struct ast_bridge_channel *bridge_channel;
1236 
1237  AST_LIST_TRAVERSE(&bridge->channels, bridge_channel, entry) {
1238  check_bridge_play_sound(bridge_channel);
1239  }
1240 }
#define AST_LIST_TRAVERSE(head, var, field)
Loops over (traverses) the entries in a list.
Definition: linkedlists.h:490
struct ast_bridge_channels_list channels
Definition: bridge.h:371
Structure that contains information regarding a channel in a bridge.
Definition: search.h:40
static void check_bridge_play_sound(struct ast_bridge_channel *bridge_channel)
Definition: bridge.c:1203

◆ cleanup_video_mode()

static void cleanup_video_mode ( struct ast_bridge bridge)
static

Definition at line 3793 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().

3794 {
3795  switch (bridge->softmix.video_mode.mode) {
3797  break;
3801  }
3802  break;
3806  }
3809  }
3811  break;
3812  }
3813  memset(&bridge->softmix.video_mode, 0, sizeof(bridge->softmix.video_mode));
3814 }
#define ast_channel_unref(c)
Decrease channel reference count.
Definition: channel.h:2981
struct ast_bridge_video_mode video_mode
Definition: bridge.h:287
struct ast_channel * chan_old_vsrc
Definition: bridge.h:127
struct ast_channel * chan_vsrc
Definition: bridge.h:116
struct ast_bridge_softmix softmix
Definition: bridge.h:375
union ast_bridge_video_mode::@227 mode_data
struct ast_bridge_video_talker_src_data talker_src_data
Definition: bridge.h:164
struct ast_bridge_video_single_src_data single_src_data
Definition: bridge.h:163
struct ast_channel * chan_vsrc
Definition: bridge.h:123
enum ast_bridge_video_mode_type mode
Definition: bridge.h:160

◆ complete_bridge_live()

static char* complete_bridge_live ( const char *  word)
static

Definition at line 5086 of file bridge.c.

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

Referenced by handle_bridge_destroy_specific(), handle_bridge_kick_channel(), and handle_bridge_show_specific().

5087 {
5089  complete_bridge_live_search, (char *) word);
5090 
5091  return NULL;
5092 }
#define ao2_callback(c, flags, cb_fn, arg)
Definition: astobj2.h:1716
#define NULL
Definition: resample.c:96
static int complete_bridge_live_search(void *obj, void *arg, int flags)
Definition: bridge.c:5075
#define OBJ_PARTIAL_KEY
Definition: astobj2.h:1156
#define ast_strlen_zero(foo)
Definition: strings.h:52
static struct ao2_container * bridges
Definition: bridge.c:123
short word

◆ complete_bridge_live_search()

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

Definition at line 5075 of file bridge.c.

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

Referenced by complete_bridge_live().

5076 {
5077  struct ast_bridge *bridge = obj;
5078 
5079  if (ast_cli_completion_add(ast_strdup(bridge->uniqueid))) {
5080  return CMP_STOP;
5081  }
5082 
5083  return 0;
5084 }
const ast_string_field uniqueid
Definition: bridge.h:409
#define ast_strdup(str)
A wrapper for strdup()
Definition: astmm.h:243
Structure that contains information about a bridge.
Definition: bridge.h:357
int ast_cli_completion_add(char *value)
Add a result to a request for completion options.
Definition: main/cli.c:2726

◆ complete_bridge_participant()

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

Definition at line 5241 of file bridge.c.

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, bridge_manager_request::bridge, ast_bridge_channel::chan, ast_bridge::channels, and NULL.

Referenced by handle_bridge_kick_channel().

5242 {
5243  struct ast_bridge *bridge;
5244  struct ast_bridge_channel *bridge_channel;
5245  int wordlen;
5246 
5247  bridge = ast_bridge_find_by_id(bridge_name);
5248  if (!bridge) {
5249  return NULL;
5250  }
5251 
5252  wordlen = strlen(word);
5253 
5254  ast_bridge_lock(bridge);
5255  AST_LIST_TRAVERSE(&bridge->channels, bridge_channel, entry) {
5256  if (!strncasecmp(ast_channel_name(bridge_channel->chan), word, wordlen)) {
5257  if (ast_cli_completion_add(ast_strdup(ast_channel_name(bridge_channel->chan)))) {
5258  break;
5259  }
5260  }
5261  }
5262  ast_bridge_unlock(bridge);
5263 
5264  ao2_ref(bridge, -1);
5265 
5266  return NULL;
5267 }
#define ast_strdup(str)
A wrapper for strdup()
Definition: astmm.h:243
#define NULL
Definition: resample.c:96
struct ast_bridge * ast_bridge_find_by_id(const char *bridge_id)
Find bridge by id.
Definition: bridge.c:5070
#define ao2_ref(o, delta)
Definition: astobj2.h:464
Structure that contains information about a bridge.
Definition: bridge.h:357
#define AST_LIST_TRAVERSE(head, var, field)
Loops over (traverses) the entries in a list.
Definition: linkedlists.h:490
#define ast_bridge_unlock(bridge)
Unlock the bridge.
Definition: bridge.h:493
#define ast_bridge_lock(bridge)
Lock the bridge.
Definition: bridge.h:480
struct ast_bridge_channels_list channels
Definition: bridge.h:371
struct ast_channel * chan
Structure that contains information regarding a channel in a bridge.
const char * ast_channel_name(const struct ast_channel *chan)
Definition: search.h:40
int ast_cli_completion_add(char *value)
Add a result to a request for completion options.
Definition: main/cli.c:2726
short word

◆ complete_bridge_technology()

static char* complete_bridge_technology ( const char *  word)
static

Definition at line 5390 of file bridge.c.

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

Referenced by handle_bridge_technology_suspend().

5391 {
5392  struct ast_bridge_technology *cur;
5393  int wordlen;
5394 
5395  wordlen = strlen(word);
5398  if (!strncasecmp(cur->name, word, wordlen)) {
5399  if (ast_cli_completion_add(ast_strdup(cur->name))) {
5400  break;
5401  }
5402  }
5403  }
5405 
5406  return NULL;
5407 }
#define AST_RWLIST_UNLOCK(head)
Attempts to unlock a read/write based list.
Definition: linkedlists.h:150
#define ast_strdup(str)
A wrapper for strdup()
Definition: astmm.h:243
#define NULL
Definition: resample.c:96
#define AST_RWLIST_RDLOCK(head)
Read locks a list.
Definition: linkedlists.h:77
#define AST_RWLIST_TRAVERSE
Definition: linkedlists.h:493
Structure that is the essence of a bridge technology.
Definition: search.h:40
int ast_cli_completion_add(char *value)
Add a result to a request for completion options.
Definition: main/cli.c:2726
short word

◆ destroy_bridge()

static void destroy_bridge ( void *  obj)
static

Definition at line 658 of file bridge.c.

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

Referenced by bridge_alloc().

659 {
660  struct ast_bridge *bridge = obj;
661 
662  ast_debug(1, "Bridge %s: actually destroying %s bridge, nobody wants it anymore\n",
663  bridge->uniqueid, bridge->v_table->name);
664 
665  if (bridge->construction_completed) {
666  bridge_topics_destroy(bridge);
667  }
668 
669  /* Do any pending actions in the context of destruction. */
670  ast_bridge_lock(bridge);
671  bridge_handle_actions(bridge);
672  ast_bridge_unlock(bridge);
673 
674  /* There should not be any channels left in the bridge. */
676 
677  ast_debug(1, "Bridge %s: calling %s bridge destructor\n",
678  bridge->uniqueid, bridge->v_table->name);
679  bridge->v_table->destroy(bridge);
680 
681  /* Pass off the bridge to the technology to destroy if needed */
682  if (bridge->technology) {
683  ast_debug(1, "Bridge %s: calling %s technology stop\n",
684  bridge->uniqueid, bridge->technology->name);
685  if (bridge->technology->stop) {
686  ast_bridge_lock(bridge);
687  bridge->technology->stop(bridge);
688  ast_bridge_unlock(bridge);
689  }
690  ast_debug(1, "Bridge %s: calling %s technology destructor\n",
691  bridge->uniqueid, bridge->technology->name);
692  if (bridge->technology->destroy) {
693  bridge->technology->destroy(bridge);
694  }
695  ast_module_unref(bridge->technology->mod);
696  bridge->technology = NULL;
697  }
698 
699  AST_VECTOR_FREE(&bridge->media_types);
700 
701  bridge->callid = 0;
702 
703  cleanup_video_mode(bridge);
704 
706  ao2_cleanup(bridge->current_snapshot);
707 }
#define AST_VECTOR_FREE(vec)
Deallocates this vector.
Definition: vector.h:174
const ast_string_field uniqueid
Definition: bridge.h:409
const char * name
Definition: bridge.h:267
ast_callid callid
Definition: bridge.h:369
#define AST_LIST_EMPTY(head)
Checks whether the specified list contains any entries.
Definition: linkedlists.h:449
#define ast_assert(a)
Definition: utils.h:695
#define NULL
Definition: resample.c:96
static void cleanup_video_mode(struct ast_bridge *bridge)
Definition: bridge.c:3793
#define ast_module_unref(mod)
Release a reference to the module.
Definition: module.h:469
void bridge_topics_destroy(struct ast_bridge *bridge)
struct ast_bridge_technology * technology
Definition: bridge.h:363
#define ast_debug(level,...)
Log a DEBUG message.
Definition: logger.h:452
const struct ast_bridge_methods * v_table
Definition: bridge.h:359
struct ast_bridge_snapshot * current_snapshot
Definition: bridge.h:414
Structure that contains information about a bridge.
Definition: bridge.h:357
void(* destroy)(struct ast_bridge *bridge)
Destroy a bridging technology instance for a bridge.
struct ast_module * mod
#define ast_bridge_unlock(bridge)
Unlock the bridge.
Definition: bridge.h:493
#define ast_bridge_lock(bridge)
Lock the bridge.
Definition: bridge.h:480
struct ast_bridge_channels_list channels
Definition: bridge.h:371
#define ao2_cleanup(obj)
Definition: astobj2.h:1958
struct ast_vector_int media_types
Definition: bridge.h:412
ast_bridge_destructor_fn destroy
Definition: bridge.h:269
static void bridge_handle_actions(struct ast_bridge *bridge)
Definition: bridge.c:640
void(* stop)(struct ast_bridge *bridge)
Request a bridge technology instance stop in preparation for being destroyed.
#define ast_string_field_free_memory(x)
free all memory - to be called before destroying the object
Definition: stringfields.h:368
unsigned int construction_completed
Definition: bridge.h:400

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

References buf.

Referenced by set_bridge_peer_vars_multiparty().

1304 {
1305  int need_separator = 0;
1306  unsigned int idx;
1307  const char *src;
1308  char *pos;
1309 
1310  pos = buf;
1311  for (idx = 0; idx < num_names; ++idx) {
1312  if (idx == cur_idx) {
1313  continue;
1314  }
1315 
1316  if (need_separator) {
1317  *pos++ = ',';
1318  }
1319  need_separator = 1;
1320 
1321  /* Copy name into buffer. */
1322  src = names[idx];
1323  while (*src) {
1324  *pos++ = *src++;
1325  }
1326  }
1327  *pos = '\0';
1328 }
char buf[BUFSIZE]
Definition: eagi_proxy.c:66

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

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

Referenced by bridge_base_init(), and smart_bridge_operation().

512 {
513  struct ast_bridge_technology *current;
514  struct ast_bridge_technology *best = NULL;
515 
518  if (current->suspended) {
519  ast_debug(1, "Bridge technology %s is suspended. Skipping.\n",
520  current->name);
521  continue;
522  }
523  if (!(current->capabilities & capabilities)) {
524  ast_debug(1, "Bridge technology %s does not have any capabilities we want.\n",
525  current->name);
526  continue;
527  }
528  if (best && current->preference <= best->preference) {
529  ast_debug(1, "Bridge technology %s has less preference than %s (%u <= %u). Skipping.\n",
530  current->name, best->name, current->preference, best->preference);
531  continue;
532  }
533  if (current->compatible && !current->compatible(bridge)) {
534  ast_debug(1, "Bridge technology %s is not compatible with properties of existing bridge.\n",
535  current->name);
536  continue;
537  }
538  if (!ast_module_running_ref(current->mod)) {
539  ast_debug(1, "Bridge technology %s is not running, skipping.\n", current->name);
540  continue;
541  }
542  if (best) {
543  ast_module_unref(best->mod);
544  }
545  best = current;
546  }
547 
548  if (best) {
549  ast_debug(1, "Chose bridge technology %s\n", best->name);
550  }
551 
553 
554  return best;
555 }
#define AST_RWLIST_UNLOCK(head)
Attempts to unlock a read/write based list.
Definition: linkedlists.h:150
#define NULL
Definition: resample.c:96
#define ast_module_unref(mod)
Release a reference to the module.
Definition: module.h:469
#define AST_RWLIST_RDLOCK(head)
Read locks a list.
Definition: linkedlists.h:77
#define ast_debug(level,...)
Log a DEBUG message.
Definition: logger.h:452
int(* compatible)(struct ast_bridge *bridge)
Check if a bridge is compatible with the bridging technology.
enum ast_bridge_preference preference
#define AST_RWLIST_TRAVERSE
Definition: linkedlists.h:493
struct ast_module * mod
#define ast_module_running_ref(mod)
Hold a reference to the module if it is running.
Definition: module.h:455
Structure that is the essence of a bridge technology.
Definition: search.h:40

◆ get_transferee()

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

Definition at line 4241 of file bridge.c.

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

Referenced by ast_bridge_transfer_attended().

4242 {
4243  struct ao2_iterator channel_iter;
4244  struct ast_channel *transferee;
4245 
4246  for (channel_iter = ao2_iterator_init(channels, 0);
4247  (transferee = ao2_iterator_next(&channel_iter));
4248  ao2_cleanup(transferee)) {
4249  if (transferee != transferer) {
4250  break;
4251  }
4252  }
4253 
4254  ao2_iterator_destroy(&channel_iter);
4255  return transferee;
4256 }
Main Channel structure associated with a channel.
void ao2_iterator_destroy(struct ao2_iterator *iter)
Destroy a container iterator.
#define ao2_iterator_next(iter)
Definition: astobj2.h:1933
When we need to walk through a container, we use an ao2_iterator to keep track of the current positio...
Definition: astobj2.h:1841
#define ao2_cleanup(obj)
Definition: astobj2.h:1958
struct ao2_iterator ao2_iterator_init(struct ao2_container *c, int flags) attribute_warn_unused_result
Create an iterator for a container.

◆ handle_bridge_destroy_specific()

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

Definition at line 5206 of file bridge.c.

References ast_cli_args::argc, ast_cli_args::argv, ast_bridge_destroy(), ast_bridge_find_by_id(), ast_cli(), bridge_manager_request::bridge, CLI_GENERATE, CLI_INIT, CLI_SHOWUSAGE, CLI_SUCCESS, ast_cli_entry::command, complete_bridge_live(), ast_cli_args::fd, NULL, ast_cli_args::pos, ast_cli_entry::usage, and ast_cli_args::word.

5207 {
5208  struct ast_bridge *bridge;
5209 
5210  switch (cmd) {
5211  case CLI_INIT:
5212  e->command = "bridge destroy";
5213  e->usage =
5214  "Usage: bridge destroy <bridge-id>\n"
5215  " Destroy the <bridge-id> bridge\n";
5216  return NULL;
5217  case CLI_GENERATE:
5218  if (a->pos == 2) {
5219  return complete_bridge_live(a->word);
5220  }
5221  return NULL;
5222  }
5223 
5224  if (a->argc != 3) {
5225  return CLI_SHOWUSAGE;
5226  }
5227 
5228  bridge = ast_bridge_find_by_id(a->argv[2]);
5229  if (!bridge) {
5230  ast_cli(a->fd, "Bridge '%s' not found\n", a->argv[2]);
5231  return CLI_SUCCESS;
5232  }
5233 
5234  ast_cli(a->fd, "Destroying bridge '%s'\n", a->argv[2]);
5235  ast_bridge_destroy(bridge, 0);
5236 
5237  return CLI_SUCCESS;
5238 }
const int argc
Definition: cli.h:160
Definition: cli.h:152
#define NULL
Definition: resample.c:96
void ast_cli(int fd, const char *fmt,...)
Definition: clicompat.c:6
static char * complete_bridge_live(const char *word)
Definition: bridge.c:5086
int ast_bridge_destroy(struct ast_bridge *bridge, int cause)
Destroy a bridge.
Definition: bridge.c:970
struct ast_bridge * ast_bridge_find_by_id(const char *bridge_id)
Find bridge by id.
Definition: bridge.c:5070
const int fd
Definition: cli.h:159
const char *const * argv
Definition: cli.h:161
Structure that contains information about a bridge.
Definition: bridge.h:357
#define CLI_SHOWUSAGE
Definition: cli.h:45
char * command
Definition: cli.h:186
const char * word
Definition: cli.h:163
const char * usage
Definition: cli.h:177
#define CLI_SUCCESS
Definition: cli.h:44
const int pos
Definition: cli.h:164

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

References ao2_ref, ast_cli_args::argc, ast_cli_args::argv, 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, bridge_manager_request::bridge, ast_bridge::channels, CLI_GENERATE, CLI_INIT, CLI_SHOWUSAGE, CLI_SUCCESS, ast_cli_entry::command, complete_bridge_live(), complete_bridge_participant(), ast_cli_args::fd, kick_it(), NULL, ast_cli_args::pos, ast_cli_entry::usage, and ast_cli_args::word.

5270 {
5271  static const char * const completions[] = { "all", NULL };
5272  struct ast_bridge *bridge;
5273 
5274  switch (cmd) {
5275  case CLI_INIT:
5276  e->command = "bridge kick";
5277  e->usage =
5278  "Usage: bridge kick <bridge-id> <channel-name | all>\n"
5279  " Kick the <channel-name> channel out of the <bridge-id> bridge\n"
5280  " If all is specified as the channel name then all channels will be\n"
5281  " kicked out of the bridge.\n";
5282  return NULL;
5283  case CLI_GENERATE:
5284  if (a->pos == 2) {
5285  return complete_bridge_live(a->word);
5286  }
5287  if (a->pos == 3) {
5288  ast_cli_complete(a->word, completions, -1);
5289  return complete_bridge_participant(a->argv[2], a->word);
5290  }
5291  return NULL;
5292  }
5293 
5294  if (a->argc != 4) {
5295  return CLI_SHOWUSAGE;
5296  }
5297 
5298  bridge = ast_bridge_find_by_id(a->argv[2]);
5299  if (!bridge) {
5300  ast_cli(a->fd, "Bridge '%s' not found\n", a->argv[2]);
5301  return CLI_SUCCESS;
5302  }
5303 
5304  if (!strcasecmp(a->argv[3], "all")) {
5305  struct ast_bridge_channel *bridge_channel;
5306 
5307  ast_cli(a->fd, "Kicking all channels from bridge '%s'\n", a->argv[2]);
5308 
5309  ast_bridge_lock(bridge);
5310  AST_LIST_TRAVERSE(&bridge->channels, bridge_channel, entry) {
5311  ast_bridge_channel_queue_callback(bridge_channel, 0, kick_it, NULL, 0);
5312  }
5313  ast_bridge_unlock(bridge);
5314  } else {
5315  struct ast_channel *chan;
5316 
5317  chan = ast_channel_get_by_name_prefix(a->argv[3], strlen(a->argv[3]));
5318  if (!chan) {
5319  ast_cli(a->fd, "Channel '%s' not found\n", a->argv[3]);
5320  ao2_ref(bridge, -1);
5321  return CLI_SUCCESS;
5322  }
5323 
5324  ast_cli(a->fd, "Kicking channel '%s' from bridge '%s'\n",
5325  ast_channel_name(chan), a->argv[2]);
5326  ast_bridge_kick(bridge, chan);
5327  ast_channel_unref(chan);
5328  }
5329 
5330  ao2_ref(bridge, -1);
5331  return CLI_SUCCESS;
5332 }
Main Channel structure associated with a channel.
#define ast_channel_unref(c)
Decrease channel reference count.
Definition: channel.h:2981
const int argc
Definition: cli.h:160
static void kick_it(struct ast_bridge_channel *bridge_channel, const void *payload, size_t payload_size)
Definition: bridge.c:2020
Definition: cli.h:152
#define NULL
Definition: resample.c:96
void ast_cli(int fd, const char *fmt,...)
Definition: clicompat.c:6
struct ast_channel * ast_channel_get_by_name_prefix(const char *name, size_t name_len)
Find a channel by a name prefix.
Definition: channel.c:1434
static char * complete_bridge_live(const char *word)
Definition: bridge.c:5086
char * ast_cli_complete(const char *word, const char *const choices[], int pos)
Definition: main/cli.c:1811
struct ast_bridge * ast_bridge_find_by_id(const char *bridge_id)
Find bridge by id.
Definition: bridge.c:5070
const int fd
Definition: cli.h:159
#define ao2_ref(o, delta)
Definition: astobj2.h:464
const char *const * argv
Definition: cli.h:161
Structure that contains information about a bridge.
Definition: bridge.h:357
#define CLI_SHOWUSAGE
Definition: cli.h:45
static char * complete_bridge_participant(const char *bridge_name, const char *word)
Definition: bridge.c:5241
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.
#define AST_LIST_TRAVERSE(head, var, field)
Loops over (traverses) the entries in a list.
Definition: linkedlists.h:490
#define ast_bridge_unlock(bridge)
Unlock the bridge.
Definition: bridge.h:493
char * command
Definition: cli.h:186
const char * word
Definition: cli.h:163
int ast_bridge_kick(struct ast_bridge *bridge, struct ast_channel *chan)
Kick a channel from a bridge.
Definition: bridge.c:2025
const char * usage
Definition: cli.h:177
#define ast_bridge_lock(bridge)
Lock the bridge.
Definition: bridge.h:480
#define CLI_SUCCESS
Definition: cli.h:44
struct ast_bridge_channels_list channels
Definition: bridge.h:371
Structure that contains information regarding a channel in a bridge.
const char * ast_channel_name(const struct ast_channel *chan)
const int pos
Definition: cli.h:164
Definition: search.h:40

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

References 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(), bridge_manager_request::bridge, CLI_GENERATE, CLI_INIT, CLI_SUCCESS, ast_cli_entry::command, ast_bridge_snapshot::creationtime, ast_cli_args::fd, FORMAT_HDR, FORMAT_ROW, NULL, ast_bridge_snapshot::num_channels, S_OR, ast_bridge_snapshot::subclass, ast_bridge_snapshot::technology, ast_bridge_snapshot::uniqueid, and ast_cli_entry::usage.

5095 {
5096 #define FORMAT_HDR "%-36s %5s %-15s %-15s %s\n"
5097 #define FORMAT_ROW "%-36s %5u %-15s %-15s %s\n"
5098 
5099  struct ao2_iterator iter;
5100  struct ast_bridge *bridge;
5101 
5102  switch (cmd) {
5103  case CLI_INIT:
5104  e->command = "bridge show all";
5105  e->usage =
5106  "Usage: bridge show all\n"
5107  " List all bridges\n";
5108  return NULL;
5109  case CLI_GENERATE:
5110  return NULL;
5111  }
5112 
5113  ast_cli(a->fd, FORMAT_HDR, "Bridge-ID", "Chans", "Type", "Technology", "Duration");
5114 
5115  iter = ao2_iterator_init(bridges, 0);
5116  for (; (bridge = ao2_iterator_next(&iter)); ao2_ref(bridge, -1)) {
5117  struct ast_bridge_snapshot *snapshot = ast_bridge_get_snapshot(bridge);
5118  char print_time[32];
5119 
5120  if (snapshot) {
5121  ast_format_duration_hh_mm_ss(ast_tvnow().tv_sec - snapshot->creationtime.tv_sec, print_time, sizeof(print_time));
5122  ast_cli(a->fd, FORMAT_ROW,
5123  snapshot->uniqueid,
5124  snapshot->num_channels,
5125  S_OR(snapshot->subclass, "<unknown>"),
5126  S_OR(snapshot->technology, "<unknown>"),
5127  print_time);
5128  ao2_ref(snapshot, -1);
5129  }
5130  }
5131  ao2_iterator_destroy(&iter);
5132 
5133  return CLI_SUCCESS;
5134 
5135 #undef FORMAT_HDR
5136 #undef FORMAT_ROW
5137 }
#define FORMAT_HDR
struct timeval creationtime
Definition: bridge.h:351
#define FORMAT_ROW
Structure that contains a snapshot of information about a bridge.
Definition: bridge.h:322
Definition: cli.h:152
void ao2_iterator_destroy(struct ao2_iterator *iter)
Destroy a container iterator.
struct timeval ast_tvnow(void)
Returns current timeval. Meant to replace calls to gettimeofday().
Definition: time.h:150
#define NULL
Definition: resample.c:96
void ast_cli(int fd, const char *fmt,...)
Definition: clicompat.c:6
const ast_string_field technology
Definition: bridge.h:336
struct ast_bridge_snapshot * ast_bridge_get_snapshot(struct ast_bridge *bridge)
Returns the current snapshot for the bridge.
const int fd
Definition: cli.h:159
#define ao2_ref(o, delta)
Definition: astobj2.h:464
Structure that contains information about a bridge.
Definition: bridge.h:357
#define ao2_iterator_next(iter)
Definition: astobj2.h:1933
static struct ao2_container * bridges
Definition: bridge.c:123
char * command
Definition: cli.h:186
const ast_string_field uniqueid
Definition: bridge.h:336
unsigned int num_channels
Definition: bridge.h:345
const char * usage
Definition: cli.h:177
#define CLI_SUCCESS
Definition: cli.h:44
When we need to walk through a container, we use an ao2_iterator to keep track of the current positio...
Definition: astobj2.h:1841
#define S_OR(a, b)
returns the equivalent of logic or for strings: first one if not empty, otherwise second one...
Definition: strings.h:79
void ast_format_duration_hh_mm_ss(int duration, char *buf, size_t length)
Formats a duration into HH:MM:SS.
Definition: main/utils.c:2049
const ast_string_field subclass
Definition: bridge.h:336
struct ao2_iterator ao2_iterator_init(struct ao2_container *c, int flags) attribute_warn_unused_result
Create an iterator for a container.

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

References ao2_callback, ao2_ref, ast_cli_args::argc, ast_cli_args::argv, 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_cli_args::fd, ast_bridge_snapshot::name, NULL, ast_bridge_snapshot::num_active, ast_bridge_snapshot::num_channels, OBJ_NODATA, ast_cli_args::pos, S_OR, ast_bridge_snapshot::subclass, ast_bridge_snapshot::technology, ast_bridge_snapshot::uniqueid, ast_cli_entry::usage, ast_bridge_snapshot::video_mode, ast_bridge_snapshot::video_source_id, and ast_cli_args::word.

5158 {
5159  struct ast_bridge_snapshot *snapshot;
5160  char print_time[32];
5161 
5162  switch (cmd) {
5163  case CLI_INIT:
5164  e->command = "bridge show";
5165  e->usage =
5166  "Usage: bridge show <bridge-id>\n"
5167  " Show information about the <bridge-id> bridge\n";
5168  return NULL;
5169  case CLI_GENERATE:
5170  if (a->pos == 2) {
5171  return complete_bridge_live(a->word);
5172  }
5173  return NULL;
5174  }
5175 
5176  if (a->argc != 3) {
5177  return CLI_SHOWUSAGE;
5178  }
5179 
5180  snapshot = ast_bridge_get_snapshot_by_uniqueid(a->argv[2]);
5181  if (!snapshot) {
5182  ast_cli(a->fd, "Bridge '%s' not found\n", a->argv[2]);
5183  return CLI_SUCCESS;
5184  }
5185 
5186  ast_format_duration_hh_mm_ss(ast_tvnow().tv_sec - snapshot->creationtime.tv_sec, print_time, sizeof(print_time));
5187 
5188  ast_cli(a->fd, "Id: %s\n", snapshot->uniqueid);
5189  ast_cli(a->fd, "Type: %s\n", S_OR(snapshot->subclass, "<unknown>"));
5190  ast_cli(a->fd, "Technology: %s\n", S_OR(snapshot->technology, "<unknown>"));
5191  ast_cli(a->fd, "Subclass: %s\n", snapshot->subclass);
5192  ast_cli(a->fd, "Creator: %s\n", snapshot->creator);
5193  ast_cli(a->fd, "Name: %s\n", snapshot->name);
5194  ast_cli(a->fd, "Video-Mode: %s\n", ast_bridge_video_mode_to_string(snapshot->video_mode));
5195  ast_cli(a->fd, "Video-Source-Id: %s\n", snapshot->video_source_id);
5196  ast_cli(a->fd, "Num-Channels: %u\n", snapshot->num_channels);
5197  ast_cli(a->fd, "Num-Active: %u\n", snapshot->num_active);
5198  ast_cli(a->fd, "Duration: %s\n", print_time);
5200  ao2_ref(snapshot, -1);
5201 
5202  return CLI_SUCCESS;
5203 }
struct ao2_container * channels
Definition: bridge.h:339
struct timeval creationtime
Definition: bridge.h:351
const int argc
Definition: cli.h:160
#define ao2_callback(c, flags, cb_fn, arg)
Definition: astobj2.h:1716
Structure that contains a snapshot of information about a bridge.
Definition: bridge.h:322
const ast_string_field video_source_id
Definition: bridge.h:336
Definition: cli.h:152
struct timeval ast_tvnow(void)
Returns current timeval. Meant to replace calls to gettimeofday().
Definition: time.h:150
#define NULL
Definition: resample.c:96
void ast_cli(int fd, const char *fmt,...)
Definition: clicompat.c:6
const ast_string_field creator
Definition: bridge.h:336
static char * complete_bridge_live(const char *word)
Definition: bridge.c:5086
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:4018
const ast_string_field technology
Definition: bridge.h:336
const int fd
Definition: cli.h:159
#define ao2_ref(o, delta)
Definition: astobj2.h:464
const char *const * argv
Definition: cli.h:161
const ast_string_field name
Definition: bridge.h:336
#define CLI_SHOWUSAGE
Definition: cli.h:45
enum ast_bridge_video_mode_type video_mode
Definition: bridge.h:349
char * command
Definition: cli.h:186
const char * word
Definition: cli.h:163
const ast_string_field uniqueid
Definition: bridge.h:336
unsigned int num_channels
Definition: bridge.h:345
const char * usage
Definition: cli.h:177
unsigned int num_active
Definition: bridge.h:347
#define CLI_SUCCESS
Definition: cli.h:44
#define S_OR(a, b)
returns the equivalent of logic or for strings: first one if not empty, otherwise second one...
Definition: strings.h:79
const int pos
Definition: cli.h:164
void ast_format_duration_hh_mm_ss(int duration, char *buf, size_t length)
Formats a duration into HH:MM:SS.
Definition: main/utils.c:2049
const ast_string_field subclass
Definition: bridge.h:336
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:5140
struct ast_bridge_snapshot * ast_bridge_get_snapshot_by_uniqueid(const char *bridge_id)
Returns the current snapshot for the bridge.

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

References 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, ast_cli_args::fd, 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.

5356 {
5357 #define FORMAT_HDR "%-20s %-20s %8s %s\n"
5358 #define FORMAT_ROW "%-20s %-20s %8u %s\n"
5359 
5360  struct ast_bridge_technology *cur;
5361 
5362  switch (cmd) {
5363  case CLI_INIT:
5364  e->command = "bridge technology show";
5365  e->usage =
5366  "Usage: bridge technology show\n"
5367  " List registered bridge technologies\n";
5368  return NULL;
5369  case CLI_GENERATE:
5370  return NULL;
5371  }
5372 
5373  ast_cli(a->fd, FORMAT_HDR, "Name", "Type", "Priority", "Suspended");
5376  const char *type;
5377 
5378  /* Decode type for display */
5379  type = tech_capability2str(cur->capabilities);
5380 
5381  ast_cli(a->fd, FORMAT_ROW, cur->name, type, cur->preference,
5382  AST_CLI_YESNO(cur->suspended));
5383  }
5385  return CLI_SUCCESS;
5386 
5387 #undef FORMAT
5388 }
#define FORMAT_HDR
static const char type[]
Definition: chan_ooh323.c:109
#define FORMAT_ROW
#define AST_RWLIST_UNLOCK(head)
Attempts to unlock a read/write based list.
Definition: linkedlists.h:150
Definition: cli.h:152
#define NULL
Definition: resample.c:96
void ast_cli(int fd, const char *fmt,...)
Definition: clicompat.c:6
#define AST_RWLIST_RDLOCK(head)
Read locks a list.
Definition: linkedlists.h:77
const int fd
Definition: cli.h:159
enum ast_bridge_preference preference
#define AST_RWLIST_TRAVERSE
Definition: linkedlists.h:493
char * command
Definition: cli.h:186
const char * usage
Definition: cli.h:177
#define CLI_SUCCESS
Definition: cli.h:44
Structure that is the essence of a bridge technology.
Definition: search.h:40
#define AST_CLI_YESNO(x)
Return Yes or No depending on the argument.
Definition: cli.h:71
static const char * tech_capability2str(uint32_t capabilities)
Definition: bridge.c:5335

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

References ast_cli_args::argc, ast_cli_args::argv, 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_cli_args::fd, ast_bridge_technology::name, NULL, ast_cli_args::pos, suspend(), ast_cli_entry::usage, and ast_cli_args::word.

5410 {
5411  struct ast_bridge_technology *cur;
5412  int suspend;
5413  int successful;
5414 
5415  switch (cmd) {
5416  case CLI_INIT:
5417  e->command = "bridge technology {suspend|unsuspend}";
5418  e->usage =
5419  "Usage: bridge technology {suspend|unsuspend} <technology-name>\n"
5420  " Suspend or unsuspend a bridge technology.\n";
5421  return NULL;
5422  case CLI_GENERATE:
5423  if (a->pos == 3) {
5424  return complete_bridge_technology(a->word);
5425  }
5426  return NULL;
5427  }
5428 
5429  if (a->argc != 4) {
5430  return CLI_SHOWUSAGE;
5431  }
5432 
5433  suspend = !strcasecmp(a->argv[2], "suspend");
5434  successful = 0;
5437  if (!strcasecmp(cur->name, a->argv[3])) {
5438  successful = 1;
5439  if (suspend) {
5441  } else {
5443  }
5444  break;
5445  }
5446  }
5448 
5449  if (successful) {
5450  if (suspend) {
5451  ast_cli(a->fd, "Suspended bridge technology '%s'\n", a->argv[3]);
5452  } else {
5453  ast_cli(a->fd, "Unsuspended bridge technology '%s'\n", a->argv[3]);
5454  }
5455  } else {
5456  ast_cli(a->fd, "Bridge technology '%s' not found\n", a->argv[3]);
5457  }
5458 
5459  return CLI_SUCCESS;
5460 }
#define AST_RWLIST_WRLOCK(head)
Write locks a list.
Definition: linkedlists.h:51
const int argc
Definition: cli.h:160
#define AST_RWLIST_UNLOCK(head)
Attempts to unlock a read/write based list.
Definition: linkedlists.h:150
Definition: cli.h:152
#define NULL
Definition: resample.c:96
void ast_cli(int fd, const char *fmt,...)
Definition: clicompat.c:6
static char * complete_bridge_technology(const char *word)
Definition: bridge.c:5390
const int fd
Definition: cli.h:159
#define AST_RWLIST_TRAVERSE
Definition: linkedlists.h:493
const char *const * argv
Definition: cli.h:161
#define CLI_SHOWUSAGE
Definition: cli.h:45
void ast_bridge_technology_suspend(struct ast_bridge_technology *technology)
Suspend a bridge technology from consideration.
Definition: bridge.c:3108
char * command
Definition: cli.h:186
static void suspend(struct cc_core_instance *core_instance)
Definition: ccss.c:3193
const char * word
Definition: cli.h:163
const char * usage
Definition: cli.h:177
#define CLI_SUCCESS
Definition: cli.h:44
void ast_bridge_technology_unsuspend(struct ast_bridge_technology *technology)
Unsuspend a bridge technology.
Definition: bridge.c:3113
const int pos
Definition: cli.h:164
Structure that is the essence of a bridge technology.
Definition: search.h:40

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

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(), ast_bridge_technology::name, and name.

Referenced by manager_bridge_tech_suspend(), and manager_bridge_tech_unsuspend().

5475 {
5476  const char *name = astman_get_header(m, "BridgeTechnology");
5477  struct ast_bridge_technology *cur;
5478  int successful = 0;
5479 
5480  if (ast_strlen_zero(name)) {
5481  astman_send_error(s, m, "BridgeTechnology must be provided");
5482  return 0;
5483  }
5484 
5487 
5488  if (!strcasecmp(cur->name, name)) {
5489  successful = 1;
5490  if (suspend) {
5492  } else {
5494  }
5495  break;
5496  }
5497  }
5499  if (!successful) {
5500  astman_send_error(s, m, "BridgeTechnology not found");
5501  return 0;
5502  }
5503 
5504  astman_send_ack(s, m, (suspend ? "Suspended bridge technology" : "Unsuspended bridge technology"));
5505  return 0;
5506 }
#define AST_RWLIST_UNLOCK(head)
Attempts to unlock a read/write based list.
Definition: linkedlists.h:150
void astman_send_ack(struct mansession *s, const struct message *m, char *msg)
Send ack in manager transaction.
Definition: manager.c:3191
const char * astman_get_header(const struct message *m, char *var)
Get header from mananger transaction.
Definition: manager.c:2820
#define ast_strlen_zero(foo)
Definition: strings.h:52
#define AST_RWLIST_RDLOCK(head)
Read locks a list.
Definition: linkedlists.h:77
#define AST_RWLIST_TRAVERSE
Definition: linkedlists.h:493
void ast_bridge_technology_suspend(struct ast_bridge_technology *technology)
Suspend a bridge technology from consideration.
Definition: bridge.c:3108
static const char name[]
Definition: cdr_mysql.c:74
static void suspend(struct cc_core_instance *core_instance)
Definition: ccss.c:3193
void ast_bridge_technology_unsuspend(struct ast_bridge_technology *technology)
Unsuspend a bridge technology.
Definition: bridge.c:3113
Structure that is the essence of a bridge technology.
Definition: search.h:40
void astman_send_error(struct mansession *s, const struct message *m, char *error)
Send error in manager transaction.
Definition: manager.c:3159

◆ hook_remove_match()

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

Definition at line 3508 of file bridge.c.

References ast_test_flag, CMP_MATCH, and ast_bridge_hook::remove_flags.

Referenced by hooks_remove_container().

3509 {
3510  struct ast_bridge_hook *hook = obj;
3512 
3513  if (ast_test_flag(&hook->remove_flags, *remove_flags)) {
3514  return CMP_MATCH;
3515  } else {
3516  return 0;
3517  }
3518 }
#define ast_test_flag(p, flag)
Definition: utils.h:63
ast_bridge_hook_remove_flags
struct ast_flags remove_flags
Structure that is the essence of a feature hook.

◆ hooks_remove_container()

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

Definition at line 3530 of file bridge.c.

References ao2_callback, hook_remove_match(), OBJ_MULTIPLE, OBJ_NODATA, and OBJ_UNLINK.

Referenced by ast_bridge_features_remove().

3531 {
3534 }
#define ao2_callback(c, flags, cb_fn, arg)
Definition: astobj2.h:1716
static int hook_remove_match(void *obj, void *arg, int flags)
Definition: bridge.c:3508
struct ast_flags remove_flags

◆ hooks_remove_heap()

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

Definition at line 3546 of file bridge.c.

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

3547 {
3548  struct ast_bridge_hook *hook;
3549  int changed;
3550 
3551  ast_heap_wrlock(hooks);
3552  do {
3553  int idx;
3554 
3555  changed = 0;
3556  for (idx = ast_heap_size(hooks); idx; --idx) {
3557  hook = ast_heap_peek(hooks, idx);
3558  if (ast_test_flag(&hook->remove_flags, remove_flags)) {
3559  ast_heap_remove(hooks, hook);
3560  ao2_ref(hook, -1);
3561  changed = 1;
3562  }
3563  }
3564  } while (changed);
3565  ast_heap_unlock(hooks);
3566 }
#define ast_test_flag(p, flag)
Definition: utils.h:63
#define ast_heap_unlock(h)
Definition: heap.h:248
#define ao2_ref(o, delta)
Definition: astobj2.h:464
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
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 remove_flags
Structure that is the essence of a feature hook.
#define ast_heap_wrlock(h)
Definition: heap.h:246

◆ interval_hook_time_cmp()

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

Definition at line 3575 of file bridge.c.

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

3576 {
3577  struct ast_bridge_hook_timer *hook_a = a;
3578  struct ast_bridge_hook_timer *hook_b = b;
3579  int cmp;
3580 
3581  cmp = ast_tvcmp(hook_b->timer.trip_time, hook_a->timer.trip_time);
3582  if (cmp) {
3583  return cmp;
3584  }
3585 
3586  cmp = hook_b->timer.seqno - hook_a->timer.seqno;
3587  return cmp;
3588 }
int ast_tvcmp(struct timeval _a, struct timeval _b)
Compres two struct timeval instances returning -1, 0, 1 if the first arg is smaller, equal or greater to the second.
Definition: time.h:128
struct ast_bridge_hook_timer_parms timer
static struct test_val b
static struct test_val a

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

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

Referenced by wrap_hook().

3637 {
3638  struct ast_bridge_hook_timer *hook = obj;
3639 
3640  return hook->generic.callback(bridge_channel, hook->generic.hook_pvt);
3641 }
struct ast_bridge_hook generic
ast_bridge_hook_callback callback

◆ interval_wrapper_pvt_dtor()

static void interval_wrapper_pvt_dtor ( void *  obj)
static

Destructor for the hook wrapper.

Definition at line 3644 of file bridge.c.

References ao2_cleanup.

Referenced by wrap_hook().

3645 {
3646  ao2_cleanup(obj);
3647 }
#define ao2_cleanup(obj)
Definition: astobj2.h:1958

◆ kick_it()

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

Definition at line 2020 of file bridge.c.

References ast_bridge_channel_kick(), and AST_CAUSE_NORMAL_CLEARING.

Referenced by ast_bridge_kick(), and handle_bridge_kick_channel().

2021 {
2023 }
void ast_bridge_channel_kick(struct ast_bridge_channel *bridge_channel, int cause)
Kick the channel out of the bridge.
#define AST_CAUSE_NORMAL_CLEARING
Definition: causes.h:105

◆ manager_bridge_tech_list()

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

Definition at line 5518 of file bridge.c.

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

Referenced by ast_bridging_init().

5519 {
5520  const char *id = astman_get_header(m, "ActionID");
5521  RAII_VAR(struct ast_str *, id_text, ast_str_create(128), ast_free);
5522  struct ast_bridge_technology *cur;
5523  int num_items = 0;
5524 
5525  if (!id_text) {
5526  astman_send_error(s, m, "Internal error");
5527  return -1;
5528  }
5529 
5530  if (!ast_strlen_zero(id)) {
5531  ast_str_set(&id_text, 0, "ActionID: %s\r\n", id);
5532  }
5533 
5534  astman_send_listack(s, m, "Bridge technology listing will follow", "start");
5535 
5538  const char *type;
5539 
5540  type = tech_capability2str(cur->capabilities);
5541 
5542  astman_append(s,
5543  "Event: BridgeTechnologyListItem\r\n"
5544  "BridgeTechnology: %s\r\n"
5545  "BridgeType: %s\r\n"
5546  "BridgePriority: %u\r\n"
5547  "BridgeSuspended: %s\r\n"
5548  "%s"
5549  "\r\n",
5550  cur->name, type, cur->preference, AST_YESNO(cur->suspended),
5551  ast_str_buffer(id_text));
5552  ++num_items;
5553  }
5555 
5556  astman_send_list_complete_start(s, m, "BridgeTechnologyListComplete", num_items);
5558 
5559  return 0;
5560 }
static const char type[]
Definition: chan_ooh323.c:109
void astman_append(struct mansession *s, const char *fmt,...)
Definition: manager.c:3080
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:3237
char * ast_str_buffer(const struct ast_str *buf)
Returns the string buffer within the ast_str buf.
Definition: strings.h:714
#define AST_RWLIST_UNLOCK(head)
Attempts to unlock a read/write based list.
Definition: linkedlists.h:150
const char * astman_get_header(const struct message *m, char *var)
Get header from mananger transaction.
Definition: manager.c:2820
#define ast_strlen_zero(foo)
Definition: strings.h:52
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:1065
#define AST_RWLIST_RDLOCK(head)
Read locks a list.
Definition: linkedlists.h:77
void astman_send_list_complete_end(struct mansession *s)
End the list complete event.
Definition: manager.c:3245
#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:911
enum ast_bridge_preference preference
#define AST_RWLIST_TRAVERSE
Definition: linkedlists.h:493
The descriptor of a dynamic string XXX storage will be optimized later if needed We use the ts field ...
Definition: strings.h:584
#define ast_free(a)
Definition: astmm.h:182
#define AST_YESNO(x)
return Yes or No depending on the argument.
Definition: strings.h:139
Structure that is the essence of a bridge technology.
Definition: search.h:40
void astman_send_error(struct mansession *s, const struct message *m, char *error)
Send error in manager transaction.
Definition: manager.c:3159
static const char * tech_capability2str(uint32_t capabilities)
Definition: bridge.c:5335
#define ast_str_create(init_len)
Create a malloc&#39;ed dynamic length string.
Definition: strings.h:620
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:3201

◆ manager_bridge_tech_suspend()

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

Definition at line 5508 of file bridge.c.

References handle_manager_bridge_tech_suspend().

Referenced by ast_bridging_init().

5509 {
5510  return handle_manager_bridge_tech_suspend(s, m, 1);
5511 }
static int handle_manager_bridge_tech_suspend(struct mansession *s, const struct message *m, int suspend)
Definition: bridge.c:5474

◆ manager_bridge_tech_unsuspend()

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

Definition at line 5513 of file bridge.c.

References handle_manager_bridge_tech_suspend().

Referenced by ast_bridging_init().

5514 {
5515  return handle_manager_bridge_tech_suspend(s, m, 0);
5516 }
static int handle_manager_bridge_tech_suspend(struct mansession *s, const struct message *m, int suspend)
Definition: bridge.c:5474

◆ merge_container_cb()

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

Callback for merging hook ao2_containers.

Definition at line 3629 of file bridge.c.

References ao2_link.

Referenced by ast_bridge_features_merge().

3630 {
3631  ao2_link(data, obj);
3632  return 0;
3633 }
#define ao2_link(container, obj)
Definition: astobj2.h:1549

◆ optimize_lock_chan_stack()

static struct ast_bridge* optimize_lock_chan_stack ( struct ast_channel chan)
static

Definition at line 2627 of file bridge.c.

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_manager_request::bridge, bridge_allows_optimization(), bridge_channel_internal_allows_optimization(), BRIDGE_CHANNEL_STATE_WAIT, BRIDGE_CHANNEL_THREAD_SIMPLE, NULL, and ast_bridge_channel::state.

Referenced by ast_bridge_unreal_optimize_out().

2628 {
2629  struct ast_bridge *bridge;
2630  struct ast_bridge_channel *bridge_channel;
2631 
2632  if (!AST_LIST_EMPTY(ast_channel_readq(chan))) {
2633  return NULL;
2634  }
2636  return NULL;
2637  }
2639  /* Channel has an active monitor, audiohook, or framehook. */
2640  return NULL;
2641  }
2642  bridge_channel = ast_channel_internal_bridge_channel(chan);
2643  if (!bridge_channel || ast_bridge_channel_trylock(bridge_channel)) {
2644  return NULL;
2645  }
2646  bridge = bridge_channel->bridge;
2647  if (bridge_channel->activity != BRIDGE_CHANNEL_THREAD_SIMPLE
2648  || bridge_channel->state != BRIDGE_CHANNEL_STATE_WAIT
2649  || ast_bridge_trylock(bridge)) {
2650  ast_bridge_channel_unlock(bridge_channel);
2651  return NULL;
2652  }
2653  if (!bridge_channel_internal_allows_optimization(bridge_channel) ||
2654  !bridge_allows_optimization(bridge)) {
2655  ast_bridge_unlock(bridge);
2656  ast_bridge_channel_unlock(bridge_channel);
2657  return NULL;
2658  }
2659  return bridge;
2660 }
enum bridge_channel_thread_state activity
The bridge channel thread activity.
#define ast_test_flag(p, flag)
Definition: utils.h:63
enum bridge_channel_state state
#define AST_LIST_EMPTY(head)
Checks whether the specified list contains any entries.
Definition: linkedlists.h:449
#define NULL
Definition: resample.c:96
static int bridge_allows_optimization(struct ast_bridge *bridge)
Definition: bridge.c:2608
struct ast_bridge * bridge
Bridge this channel is participating in.
struct ast_readq_list * ast_channel_readq(struct ast_channel *chan)
int bridge_channel_internal_allows_optimization(struct ast_bridge_channel *bridge_channel)
struct ast_bridge_channel * ast_channel_internal_bridge_channel(const struct ast_channel *chan)
#define ast_bridge_channel_unlock(bridge_channel)
Unlock the bridge_channel.
Structure that contains information about a bridge.
Definition: bridge.h:357
#define ast_bridge_unlock(bridge)
Unlock the bridge.
Definition: bridge.h:493
#define ast_bridge_channel_trylock(bridge_channel)
Try locking the bridge_channel.
Structure that contains information regarding a channel in a bridge.
struct ast_flags * ast_channel_flags(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:2523
#define ast_bridge_trylock(bridge)
Try locking the bridge.
Definition: bridge.h:467

◆ optimize_lock_peer_stack()

static struct ast_bridge* optimize_lock_peer_stack ( struct ast_channel peer)
static

Definition at line 2672 of file bridge.c.

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_manager_request::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().

2673 {
2674  struct ast_bridge *bridge;
2675  struct ast_bridge_channel *bridge_channel;
2676 
2677  if (ast_channel_trylock(peer)) {
2678  return NULL;
2679  }
2680  if (!AST_LIST_EMPTY(ast_channel_readq(peer))) {
2681  ast_channel_unlock(peer);
2682  return NULL;
2683  }
2685  ast_channel_unlock(peer);
2686  return NULL;
2687  }
2689  /* Peer has an active monitor, audiohook, or framehook. */
2690  ast_channel_unlock(peer);
2691  return NULL;
2692  }
2693  bridge_channel = ast_channel_internal_bridge_channel(peer);
2694  if (!bridge_channel || ast_bridge_channel_trylock(bridge_channel)) {
2695  ast_channel_unlock(peer);
2696  return NULL;
2697  }
2698  bridge = bridge_channel->bridge;
2699  if (bridge_channel->activity != BRIDGE_CHANNEL_THREAD_IDLE
2700  || bridge_channel->state != BRIDGE_CHANNEL_STATE_WAIT
2701  || ast_bridge_trylock(bridge)) {
2702  ast_bridge_channel_unlock(bridge_channel);
2703  ast_channel_unlock(peer);
2704  return NULL;
2705  }
2706  if (!bridge_allows_optimization(bridge) ||
2708  ast_bridge_unlock(bridge);
2709  ast_bridge_channel_unlock(bridge_channel);
2710  ast_channel_unlock(peer);
2711  return NULL;
2712  }
2713  return bridge;
2714 }
enum bridge_channel_thread_state activity
The bridge channel thread activity.
#define ast_test_flag(p, flag)
Definition: utils.h:63
enum bridge_channel_state state
#define AST_LIST_EMPTY(head)
Checks whether the specified list contains any entries.
Definition: linkedlists.h:449
#define NULL
Definition: resample.c:96
static int bridge_allows_optimization(struct ast_bridge *bridge)
Definition: bridge.c:2608
struct ast_bridge * bridge
Bridge this channel is participating in.
struct ast_readq_list * ast_channel_readq(struct ast_channel *chan)
int bridge_channel_internal_allows_optimization(struct ast_bridge_channel *bridge_channel)
struct ast_bridge_channel * ast_channel_internal_bridge_channel(const struct ast_channel *chan)
#define ast_bridge_channel_unlock(bridge_channel)
Unlock the bridge_channel.
Structure that contains information about a bridge.
Definition: bridge.h:357
#define ast_channel_unlock(chan)
Definition: channel.h:2946
#define ast_bridge_unlock(bridge)
Unlock the bridge.
Definition: bridge.h:493
#define ast_bridge_channel_trylock(bridge_channel)
Try locking the bridge_channel.
Structure that contains information regarding a channel in a bridge.
#define ast_channel_trylock(chan)
Definition: channel.h:2947
struct ast_flags * ast_channel_flags(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:2523
#define ast_bridge_trylock(bridge)
Try locking the bridge.
Definition: bridge.h:467

◆ set_bridge_peer_vars()

static void set_bridge_peer_vars ( struct ast_bridge bridge)
static

Definition at line 1426 of file bridge.c.

References AST_BRIDGE_CAPABILITY_HOLDING, AST_LIST_FIRST, AST_LIST_LAST, 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().

1427 {
1430  return;
1431  }
1432  if (bridge->num_channels < 2) {
1433  return;
1434  }
1435  if (bridge->num_channels == 2) {
1437  AST_LIST_LAST(&bridge->channels)->chan);
1438  } else {
1440  }
1441 }
#define AST_LIST_FIRST(head)
Returns the first entry contained in a list.
Definition: linkedlists.h:420
static void set_bridge_peer_vars_multiparty(struct ast_bridge *bridge)
Definition: bridge.c:1342
static void set_bridge_peer_vars_2party(struct ast_channel *c0, struct ast_channel *c1)
Definition: bridge.c:1263
struct ast_bridge_technology * technology
Definition: bridge.h:363
static void set_bridge_peer_vars_holding(struct ast_bridge *bridge)
Definition: bridge.c:1404
#define AST_LIST_LAST(head)
Returns the last entry contained in a list.
Definition: linkedlists.h:428
struct ast_bridge_channels_list channels
Definition: bridge.h:371
unsigned int num_channels
Definition: bridge.h:381

◆ set_bridge_peer_vars_2party()

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

Definition at line 1263 of file bridge.c.

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

Referenced by set_bridge_peer_vars().

1264 {
1265  const char *c0_name;
1266  const char *c1_name;
1267  const char *c0_pvtid = NULL;
1268  const char *c1_pvtid = NULL;
1269 #define UPDATE_BRIDGE_VARS_GET(chan, name, pvtid) \
1270  do { \
1271  name = ast_strdupa(ast_channel_name(chan)); \
1272  if (ast_channel_tech(chan)->get_pvt_uniqueid) { \
1273  pvtid = ast_strdupa(ast_channel_tech(chan)->get_pvt_uniqueid(chan)); \
1274  } \
1275  } while (0)
1276 
1277  ast_channel_lock(c1);
1278  UPDATE_BRIDGE_VARS_GET(c1, c1_name, c1_pvtid);
1279  ast_channel_unlock(c1);
1280 
1281  ast_channel_lock(c0);
1282  ast_bridge_vars_set(c0, c1_name, c1_pvtid);
1283  UPDATE_BRIDGE_VARS_GET(c0, c0_name, c0_pvtid);
1284  ast_channel_unlock(c0);
1285 
1286  ast_channel_lock(c1);
1287  ast_bridge_vars_set(c1, c0_name, c0_pvtid);
1288  ast_channel_unlock(c1);
1289 }
#define ast_channel_lock(chan)
Definition: channel.h:2945
#define NULL
Definition: resample.c:96
#define UPDATE_BRIDGE_VARS_GET(chan, name, pvtid)
#define ast_channel_unlock(chan)
Definition: channel.h:2946
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:1242

◆ set_bridge_peer_vars_holding()

static void set_bridge_peer_vars_holding ( struct ast_bridge bridge)
static

Definition at line 1404 of file bridge.c.

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

Referenced by set_bridge_peer_vars().

1405 {
1406  struct ast_bridge_channel *bridge_channel;
1407 
1408  AST_LIST_TRAVERSE(&bridge->channels, bridge_channel, entry) {
1409  ast_channel_lock(bridge_channel->chan);
1410  ast_bridge_vars_set(bridge_channel->chan, NULL, NULL);
1411  ast_channel_unlock(bridge_channel->chan);
1412  }
1413 }
#define ast_channel_lock(chan)
Definition: channel.h:2945
#define NULL
Definition: resample.c:96
#define AST_LIST_TRAVERSE(head, var, field)
Loops over (traverses) the entries in a list.
Definition: linkedlists.h:490
#define ast_channel_unlock(chan)
Definition: channel.h:2946
struct ast_bridge_channels_list channels
Definition: bridge.h:371
struct ast_channel * chan
Structure that contains information regarding a channel in a bridge.
Definition: search.h:40
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:1242

◆ set_bridge_peer_vars_multiparty()

static void set_bridge_peer_vars_multiparty ( struct ast_bridge bridge)
static

Definition at line 1342 of file bridge.c.

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

Referenced by set_bridge_peer_vars().

1343 {
1344 /*
1345  * Set a maximum number of channel names for the BRIDGEPEER
1346  * list. The plus one is for the current channel which is not
1347  * put in the list.
1348  */
1349 #define MAX_BRIDGEPEER_CHANS (10 + 1)
1350 
1351  unsigned int idx;
1352  unsigned int num_names;
1353  unsigned int len;
1354  const char **names;
1355  char *buf;
1356  struct ast_bridge_channel *bridge_channel;
1357 
1358  /* Get first MAX_BRIDGEPEER_CHANS channel names. */
1359  num_names = MIN(bridge->num_channels, MAX_BRIDGEPEER_CHANS);
1360  names = ast_alloca(num_names * sizeof(*names));
1361  idx = 0;
1362  AST_LIST_TRAVERSE(&bridge->channels, bridge_channel, entry) {
1363  if (num_names <= idx) {
1364  break;
1365  }
1366  ast_channel_lock(bridge_channel->chan);
1367  names[idx++] = ast_strdupa(ast_channel_name(bridge_channel->chan));
1368  ast_channel_unlock(bridge_channel->chan);
1369  }
1370 
1371  /* Determine maximum buf size needed. */
1372  len = num_names;
1373  for (idx = 0; idx < num_names; ++idx) {
1374  len += strlen(names[idx]);
1375  }
1376  buf = ast_alloca(len);
1377 
1378  /* Set the bridge channel variables. */
1379  idx = 0;
1380  buf[0] = '\0';
1381  AST_LIST_TRAVERSE(&bridge->channels, bridge_channel, entry) {
1382  if (idx < num_names) {
1383  fill_bridgepeer_buf(buf, idx, names, num_names);
1384  }
1385  ++idx;
1386 
1387  ast_channel_lock(bridge_channel->chan);
1388  ast_bridge_vars_set(bridge_channel->chan, buf, NULL);
1389  ast_channel_unlock(bridge_channel->chan);
1390  }
1391 }
#define ast_channel_lock(chan)
Definition: channel.h:2945
char buf[BUFSIZE]
Definition: eagi_proxy.c:66
#define MAX_BRIDGEPEER_CHANS
#define NULL
Definition: resample.c:96
#define MIN(a, b)
Definition: utils.h:226
static void fill_bridgepeer_buf(char *buf, unsigned int cur_idx, const char *names[], unsigned int num_names)
Definition: bridge.c:1303
#define ast_strdupa(s)
duplicate a string in memory from the stack
Definition: astmm.h:300
#define ast_alloca(size)
call __builtin_alloca to ensure we get gcc builtin semantics
Definition: astmm.h:290
static int len(struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t buflen)
#define AST_LIST_TRAVERSE(head, var, field)
Loops over (traverses) the entries in a list.
Definition: linkedlists.h:490
#define ast_channel_unlock(chan)
Definition: channel.h:2946
struct ast_bridge_channels_list channels
Definition: bridge.h:371
struct ast_channel * chan
Structure that contains information regarding a channel in a bridge.
const char * ast_channel_name(const struct ast_channel *chan)
Definition: search.h:40
unsigned int num_channels
Definition: bridge.h:381
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:1242

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

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, pbx_builtin_getvar_helper(), and S_OR.

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

4436 {
4437  struct ao2_iterator iter;
4438  struct ast_channel *chan;
4439  const char *transferer_name;
4440  const char *transferer_bridgepeer;
4441 
4442  ast_channel_lock(transferer);
4443  transferer_name = ast_strdupa(ast_channel_name(transferer));
4444  transferer_bridgepeer = ast_strdupa(S_OR(pbx_builtin_getvar_helper(transferer, "BRIDGEPEER"), ""));
4445  ast_channel_unlock(transferer);
4446 
4447  for (iter = ao2_iterator_init(channels, 0);
4448  (chan = ao2_iterator_next(&iter));
4449  ao2_cleanup(chan)) {
4450  if (chan == transferer) {
4451  ast_bridge_set_transfer_variables(chan, transferer_bridgepeer, is_attended);
4452  } else {
4453  ast_bridge_set_transfer_variables(chan, transferer_name, is_attended);
4454  }
4455  }
4456 
4457  ao2_iterator_destroy(&iter);
4458 }
#define ast_channel_lock(chan)
Definition: channel.h:2945
Main Channel structure associated with a channel.
void ao2_iterator_destroy(struct ao2_iterator *iter)
Destroy a container iterator.
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 ast_strdupa(s)
duplicate a string in memory from the stack
Definition: astmm.h:300
#define ao2_iterator_next(iter)
Definition: astobj2.h:1933
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:4404
#define ast_channel_unlock(chan)
Definition: channel.h:2946
When we need to walk through a container, we use an ao2_iterator to keep track of the current positio...
Definition: astobj2.h:1841
#define ao2_cleanup(obj)
Definition: astobj2.h:1958
#define S_OR(a, b)
returns the equivalent of logic or for strings: first one if not empty, otherwise second one...
Definition: strings.h:79
const char * ast_channel_name(const struct ast_channel *chan)
struct ao2_iterator ao2_iterator_init(struct ao2_container *c, int flags) attribute_warn_unused_result
Create an iterator for a container.

◆ smart_bridge_operation()

static int smart_bridge_operation ( struct ast_bridge bridge)
static

Definition at line 998 of file bridge.c.

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_technology::name, ast_bridge::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().

999 {
1000  uint32_t new_capabilities;
1001  struct ast_bridge_technology *new_technology;
1002  struct ast_bridge_technology *old_technology = bridge->technology;
1003  struct ast_bridge_channel *bridge_channel;
1004  struct ast_frame *deferred_action;
1005  struct ast_bridge dummy_bridge = {
1006  .technology = bridge->technology,
1007  .tech_pvt = bridge->tech_pvt,
1008  .creator = bridge->creator,
1009  .name = bridge->name,
1010  .uniqueid = bridge->uniqueid,
1011  };
1012 
1013  if (bridge->dissolved) {
1014  ast_debug(1, "Bridge %s is dissolved, not performing smart bridge operation.\n",
1015  bridge->uniqueid);
1016  return 0;
1017  }
1018 
1019  /* Determine new bridge technology capabilities needed. */
1020  if (2 < bridge->num_channels) {
1021  new_capabilities = AST_BRIDGE_CAPABILITY_MULTIMIX;
1022  new_capabilities &= bridge->allowed_capabilities;
1023  } else {
1025  new_capabilities &= bridge->allowed_capabilities;
1026  if (!new_capabilities
1028  /* Allow switching between different multimix bridge technologies. */
1029  new_capabilities = AST_BRIDGE_CAPABILITY_MULTIMIX;
1030  }
1031  }
1032 
1033  /* Find a bridge technology to satisfy the new capabilities. */
1034  new_technology = find_best_technology(new_capabilities, bridge);
1035  if (!new_technology) {
1036  int is_compatible = 0;
1037 
1038  if (old_technology->compatible) {
1039  is_compatible = old_technology->compatible(bridge);
1040  } else if (old_technology->capabilities & AST_BRIDGE_CAPABILITY_MULTIMIX) {
1041  is_compatible = 1;
1042  } else if (bridge->num_channels <= 2
1043  && (old_technology->capabilities & AST_BRIDGE_CAPABILITY_1TO1MIX)) {
1044  is_compatible = 1;
1045  }
1046 
1047  if (is_compatible) {
1048  ast_debug(1, "Bridge %s could not get a new technology, staying with old technology.\n",
1049  bridge->uniqueid);
1050  return 0;
1051  }
1052  ast_log(LOG_WARNING, "Bridge %s has no technology available to support it.\n",
1053  bridge->uniqueid);
1054  return -1;
1055  }
1056  if (new_technology == old_technology) {
1057  ast_debug(1, "Bridge %s is already using the new technology.\n",
1058  bridge->uniqueid);
1059  ast_module_unref(old_technology->mod);
1060  return 0;
1061  }
1062 
1063  if (old_technology->destroy) {
1064  struct tech_deferred_destroy deferred_tech_destroy = {
1065  .tech = dummy_bridge.technology,
1066  .tech_pvt = dummy_bridge.tech_pvt,
1067  };
1068  struct ast_frame action = {
1070  .subclass.integer = BRIDGE_CHANNEL_ACTION_DEFERRED_TECH_DESTROY,
1071  .data.ptr = &deferred_tech_destroy,
1072  .datalen = sizeof(deferred_tech_destroy),
1073  };
1074 
1075  /*
1076  * We need to defer the bridge technology destroy callback
1077  * because we have the bridge locked.
1078  */
1079  deferred_action = ast_frdup(&action);
1080  if (!deferred_action) {
1081  ast_module_unref(new_technology->mod);
1082  return -1;
1083  }
1084  } else {
1085  deferred_action = NULL;
1086  }
1087 
1088  /*
1089  * We are now committed to changing the bridge technology. We
1090  * must not release the bridge lock until we have installed the
1091  * new bridge technology.
1092  */
1093  ast_verb(4, "Bridge %s: switching from %s technology to %s\n",
1094  bridge->uniqueid, old_technology->name, new_technology->name);
1095 
1096  /*
1097  * Since we are soon going to pass this bridge to a new
1098  * technology we need to NULL out the tech_pvt pointer but
1099  * don't worry as it still exists in dummy_bridge, ditto for the
1100  * old technology.
1101  */
1102  bridge->tech_pvt = NULL;
1103  bridge->technology = new_technology;
1104 
1105  /* Setup the new bridge technology. */
1106  ast_debug(1, "Bridge %s: calling %s technology constructor\n",
1107  bridge->uniqueid, new_technology->name);
1108  if (new_technology->create && new_technology->create(bridge)) {
1109  ast_log(LOG_WARNING, "Bridge %s: failed to setup bridge technology %s\n",
1110  bridge->uniqueid, new_technology->name);
1111  bridge->tech_pvt = dummy_bridge.tech_pvt;
1112  bridge->technology = dummy_bridge.technology;
1113  ast_module_unref(new_technology->mod);
1114  return -1;
1115  }
1116 
1117  /* To ensure that things are sane for the old technology move the channels it
1118  * expects to the dummy bridge
1119  */
1120  AST_LIST_TRAVERSE_SAFE_BEGIN(&bridge->channels, bridge_channel, entry) {
1121  if (bridge_channel->just_joined) {
1122  continue;
1123  }
1124  ast_debug(1, "Bridge %s: moving %p(%s) to dummy bridge temporarily\n",
1125  bridge->uniqueid, bridge_channel, ast_channel_name(bridge_channel->chan));
1127  AST_LIST_INSERT_TAIL(&dummy_bridge.channels, bridge_channel, entry);
1128  dummy_bridge.num_channels++;
1130  dummy_bridge.num_lonely++;
1131  }
1132  if (!bridge_channel->suspended) {
1133  dummy_bridge.num_active++;
1134  }
1135  }
1137 
1138  /* Take all the channels out of the old technology */
1139  AST_LIST_TRAVERSE_SAFE_BEGIN(&dummy_bridge.channels, bridge_channel, entry) {
1140  ast_debug(1, "Bridge %s: %p(%s) is leaving %s technology (dummy)\n",
1141  dummy_bridge.uniqueid, bridge_channel, ast_channel_name(bridge_channel->chan),
1142  old_technology->name);
1143  if (old_technology->leave) {
1144  old_technology->leave(&dummy_bridge, bridge_channel);
1145  }
1147  AST_LIST_INSERT_TAIL(&bridge->channels, bridge_channel, entry);
1148  dummy_bridge.num_channels--;
1150  dummy_bridge.num_lonely--;
1151  }
1152  if (!bridge_channel->suspended) {
1153  dummy_bridge.num_active--;
1154  }
1155  }
1157 
1158  ast_debug(1, "Bridge %s: calling %s technology stop\n",
1159  dummy_bridge.uniqueid, old_technology->name);
1160  if (old_technology->stop) {
1161  old_technology->stop(&dummy_bridge);
1162  }
1163 
1164  /* Add any new channels or re-add existing channels to the bridge. */
1165  AST_LIST_TRAVERSE(&bridge->channels, bridge_channel, entry) {
1166  bridge_channel_complete_join(bridge, bridge_channel);
1167  }
1168 
1169  ast_debug(1, "Bridge %s: calling %s technology start\n",
1170  bridge->uniqueid, new_technology->name);
1171  if (new_technology->start && new_technology->start(bridge)) {
1172  ast_log(LOG_WARNING, "Bridge %s: failed to start bridge technology %s\n",
1173  bridge->uniqueid, new_technology->name);
1174  }
1175 
1176  /*
1177  * Now that all the channels have been moved over we need to get
1178  * rid of all the information the old technology may have left
1179  * around.
1180  */
1181  if (old_technology->destroy) {
1182  ast_debug(1, "Bridge %s: deferring %s technology destructor\n",
1183  dummy_bridge.uniqueid, old_technology->name);
1184  bridge_queue_action_nodup(bridge, deferred_action);
1185  } else {
1186  ast_debug(1, "Bridge %s: calling %s technology destructor\n",
1187  dummy_bridge.uniqueid, old_technology->name);
1188  ast_module_unref(old_technology->mod);
1189  }
1190 
1191  return 0;
1192 }
#define ast_frdup(fr)
Copies a frame.
const ast_string_field uniqueid
Definition: bridge.h:409
struct ast_bridge_features * features
unsigned int num_active
Definition: bridge.h:383
#define ast_test_flag(p, flag)
Definition: utils.h:63
#define LOG_WARNING
Definition: logger.h:274
unsigned int dissolved
Definition: bridge.h:398
int(* start)(struct ast_bridge *bridge)
Request a bridge technology instance start operations.
const ast_string_field name
Definition: bridge.h:409
unsigned int suspended
static void bridge_channel_complete_join(struct ast_bridge *bridge, struct ast_bridge_channel *bridge_channel)
Definition: bridge.c:443
static void bridge_queue_action_nodup(struct ast_bridge *bridge, struct ast_frame *action)
Definition: bridge.c:296
#define NULL
Definition: resample.c:96
#define AST_LIST_TRAVERSE_SAFE_END
Closes a safe loop traversal block.
Definition: linkedlists.h:614
#define ast_verb(level,...)
Definition: logger.h:463
#define ast_module_unref(mod)
Release a reference to the module.
Definition: module.h:469
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:511
struct ast_bridge_technology * technology
Definition: bridge.h:363
struct ast_flags feature_flags
#define ast_debug(level,...)
Log a DEBUG message.
Definition: logger.h:452
#define ast_log
Definition: astobj2.c:42
void(* leave)(struct ast_bridge *bridge, struct ast_bridge_channel *bridge_channel)
Remove a channel from a bridging technology instance for a bridge.
int(* compatible)(struct ast_bridge *bridge)
Check if a bridge is compatible with the bridging technology.
#define AST_LIST_REMOVE_CURRENT(field)
Removes the current entry from a list during a traversal.
Definition: linkedlists.h:556
struct ast_bridge_technology * tech
Definition: bridge.c:558
unsigned int just_joined
Structure that contains information about a bridge.
Definition: bridge.h:357
void(* destroy)(struct ast_bridge *bridge)
Destroy a bridging technology instance for a bridge.
#define AST_LIST_INSERT_TAIL(head, elm, field)
Appends a list entry to the tail of a list.
Definition: linkedlists.h:730
unsigned int num_lonely
Definition: bridge.h:385
struct ast_module * mod
#define AST_LIST_TRAVERSE(head, var, field)
Loops over (traverses) the entries in a list.
Definition: linkedlists.h:490
struct ast_bridge_channels_list channels
Definition: bridge.h:371
struct ast_channel * chan
Structure that contains information regarding a channel in a bridge.
const char * ast_channel_name(const struct ast_channel *chan)
Structure that is the essence of a bridge technology.
Data structure associated with a single frame of data.
void * tech_pvt
Definition: bridge.h:365
Definition: search.h:40
#define AST_LIST_TRAVERSE_SAFE_BEGIN(head, var, field)
Loops safely over (traverses) the entries in a list.
Definition: linkedlists.h:528
enum ast_frame_type frametype
int(* create)(struct ast_bridge *bridge)
Create a bridge technology instance for a bridge.
const ast_string_field creator
Definition: bridge.h:409
void(* stop)(struct ast_bridge *bridge)
Request a bridge technology instance stop in preparation for being destroyed.
uint32_t allowed_capabilities
Definition: bridge.h:379
unsigned int num_channels
Definition: bridge.h:381
static void deferred_action(struct ast_bridge_channel *bridge_channel, const void *payload, size_t payload_size)

◆ tech_capability2str()

static const char* tech_capability2str ( uint32_t  capabilities)
static

Bridge technology capabilities to string.

Definition at line 5335 of file bridge.c.

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

5336 {
5337  const char *type;
5338 
5339  if (capabilities & AST_BRIDGE_CAPABILITY_HOLDING) {
5340  type = "Holding";
5341  } else if (capabilities & AST_BRIDGE_CAPABILITY_EARLY) {
5342  type = "Early";
5343  } else if (capabilities & AST_BRIDGE_CAPABILITY_NATIVE) {
5344  type = "Native";
5345  } else if (capabilities & AST_BRIDGE_CAPABILITY_1TO1MIX) {
5346  type = "1to1Mix";
5347  } else if (capabilities & AST_BRIDGE_CAPABILITY_MULTIMIX) {
5348  type = "MultiMix";
5349  } else {
5350  type = "<Unknown>";
5351  }
5352  return type;
5353 }
static const char type[]
Definition: chan_ooh323.c:109

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

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

2921 {
2922  struct merge_direction merge;
2923  struct ast_bridge_channel *kick_me[] = {
2924  chan_bridge_channel,
2925  peer_bridge_channel,
2926  };
2927  unsigned int id;
2928 
2929  switch (bridges_allow_merge_optimization(chan_bridge, peer_bridge, ARRAY_LEN(kick_me), &merge)) {
2930  case MERGE_ALLOWED:
2931  break;
2932  case MERGE_PROHIBITED:
2933  return 0;
2935  ast_debug(4, "Can't optimize %s -- %s out, not enough channels in bridge %s.\n",
2936  ast_channel_name(chan_bridge_channel->chan),
2937  ast_channel_name(peer_bridge_channel->chan),
2938  merge.src->uniqueid);
2939  return 0;
2940  case MERGE_NO_MULTIMIX:
2941  ast_debug(4, "Can't optimize %s -- %s out, multimix is needed and it cannot be acquired.\n",
2942  ast_channel_name(chan_bridge_channel->chan),
2943  ast_channel_name(peer_bridge_channel->chan));
2944  return 0;
2945  }
2946 
2947  ast_verb(4, "Merge optimizing %s -- %s out.\n",
2948  ast_channel_name(chan_bridge_channel->chan),
2949  ast_channel_name(peer_bridge_channel->chan));
2950 
2951  id = ast_atomic_fetchadd_int((int *) &optimization_id, +1);
2952 
2953  if (pvt && !ast_test_flag(pvt, AST_UNREAL_OPTIMIZE_BEGUN) && pvt->callbacks
2954  && pvt->callbacks->optimization_started) {
2955  pvt->callbacks->optimization_started(pvt, NULL,
2957  id);
2959  }
2960  bridge_do_merge(merge.dest, merge.src, kick_me, ARRAY_LEN(kick_me), 1);
2961  if (pvt && pvt->callbacks && pvt->callbacks->optimization_finished) {
2962  pvt->callbacks->optimization_finished(pvt, 1, id);
2963  }
2964 
2965  return -1;
2966 }
#define ARRAY_LEN(a)
Definition: isdn_lib.c:42
#define AST_UNREAL_OPTIMIZE_BEGUN
Definition: core_unreal.h:110
#define ast_test_flag(p, flag)
Definition: utils.h:63
struct ast_unreal_pvt_callbacks * callbacks
Definition: core_unreal.h:92
#define ast_set_flag(p, flag)
Definition: utils.h:70
struct ast_channel * owner
Definition: core_unreal.h:93
struct ast_bridge * ast_channel_internal_bridge(const struct ast_channel *chan)
#define NULL
Definition: resample.c:96
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
#define ast_verb(level,...)
Definition: logger.h:463
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:755
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:2096
#define ast_debug(level,...)
Log a DEBUG message.
Definition: logger.h:452
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
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:2883
struct ast_channel * chan
Structure that contains information regarding a channel in a bridge.
const char * ast_channel_name(const struct ast_channel *chan)
enum queue_result id
Definition: app_queue.c:1507
static unsigned int optimization_id
Definition: bridge.c:127

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

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

Referenced by ast_bridge_transfer_blind().

4381 {
4382  RAII_VAR(struct ast_bridge_channel *, transferer_bridge_channel, NULL, ao2_cleanup);
4383 
4385  return AST_BRIDGE_TRANSFER_FAIL;
4386  }
4387 
4388  ast_channel_lock(transferer);
4389  transferer_bridge_channel = ast_channel_get_bridge_channel(transferer);
4390  ast_channel_unlock(transferer);
4391 
4392  if (!transferer_bridge_channel) {
4393  return AST_BRIDGE_TRANSFER_FAIL;
4394  }
4395 
4396  if (ast_parking_blind_transfer_park(transferer_bridge_channel,
4397  context, exten, new_channel_cb, user_data_wrapper)) {
4398  return AST_BRIDGE_TRANSFER_FAIL;
4399  }
4400 
4402 }
#define ast_channel_lock(chan)
Definition: channel.h:2945
static char exten[AST_MAX_EXTENSION]
Definition: chan_alsa.c:118
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
#define NULL
Definition: resample.c:96
#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:911
int ast_parking_provider_registered(void)
Check whether a parking provider is registered.
Definition: parking.c:241
#define ast_channel_unlock(chan)
Definition: channel.h:2946
struct ast_bridge_channel * ast_channel_get_bridge_channel(struct ast_channel *chan)
Get a reference to the channel&#39;s bridge pointer.
Definition: channel.c:10783
Structure that contains information regarding a channel in a bridge.
#define ao2_cleanup(obj)
Definition: astobj2.h:1958
static char context[AST_MAX_CONTEXT]
Definition: chan_alsa.c:116

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

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

2797 {
2798  struct ast_bridge *dst_bridge;
2799  struct ast_bridge_channel *dst_bridge_channel;
2800  struct ast_bridge_channel *src_bridge_channel;
2801  struct ast_bridge_channel *other;
2802  int res = 1;
2803 
2804  switch (bridges_allow_swap_optimization(chan_bridge, peer_bridge)) {
2805  case SWAP_TO_CHAN_BRIDGE:
2806  dst_bridge = chan_bridge;
2807  dst_bridge_channel = chan_bridge_channel;
2808  src_bridge_channel = peer_bridge_channel;
2809  break;
2810  case SWAP_TO_PEER_BRIDGE:
2811  dst_bridge = peer_bridge;
2812  dst_bridge_channel = peer_bridge_channel;
2813  src_bridge_channel = chan_bridge_channel;
2814  break;
2815  case SWAP_PROHIBITED:
2816  default:
2817  return 0;
2818  }
2819 
2820  other = ast_bridge_channel_peer(src_bridge_channel);
2821  if (other && other->state == BRIDGE_CHANNEL_STATE_WAIT) {
2822  unsigned int id;
2823 
2824  if (ast_channel_trylock(other->chan)) {
2825  return 1;
2826  }
2827 
2828  id = ast_atomic_fetchadd_int((int *) &optimization_id, +1);
2829 
2830  ast_verb(4, "Move-swap optimizing %s <-- %s.\n",
2831  ast_channel_name(dst_bridge_channel->chan),
2832  ast_channel_name(other->chan));
2833 
2834  if (pvt && !ast_test_flag(pvt, AST_UNREAL_OPTIMIZE_BEGUN) && pvt->callbacks
2835  && pvt->callbacks->optimization_started) {
2836  pvt->callbacks->optimization_started(pvt, other->chan,
2837  dst_bridge_channel->chan == pvt->owner ? AST_UNREAL_OWNER : AST_UNREAL_CHAN,
2838  id);
2840  }
2841  other->swap = dst_bridge_channel->chan;
2842  if (!bridge_do_move(dst_bridge, other, 1, 1)) {
2843  ast_bridge_channel_leave_bridge(src_bridge_channel,
2845  res = -1;
2846  }
2847  if (pvt && pvt->callbacks && pvt->callbacks->optimization_finished) {
2848  pvt->callbacks->optimization_finished(pvt, res == 1, id);
2849  }
2850  ast_channel_unlock(other->chan);
2851  }
2852  return res;
2853 }
#define AST_UNREAL_OPTIMIZE_BEGUN
Definition: core_unreal.h:110
#define ast_test_flag(p, flag)
Definition: utils.h:63
struct ast_unreal_pvt_callbacks * callbacks
Definition: core_unreal.h:92
struct ast_bridge_channel * ast_bridge_channel_peer(struct ast_bridge_channel *bridge_channel)
Get the peer bridge channel of a two party bridge.
#define ast_set_flag(p, flag)
Definition: utils.h:70
struct ast_channel * owner
Definition: core_unreal.h:93
enum bridge_channel_state state
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
#define ast_verb(level,...)
Definition: logger.h:463
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:755
int bridge_do_move(struct ast_bridge *dst_bridge, struct ast_bridge_channel *bridge_channel, int attempt_recovery, unsigned int optimized)
Definition: bridge.c:2362
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
#define AST_CAUSE_NORMAL_CLEARING
Definition: causes.h:105
static enum bridge_allow_swap bridges_allow_swap_optimization(struct ast_bridge *chan_bridge, struct ast_bridge *peer_bridge)
Definition: bridge.c:2737
Structure that contains information about a bridge.
Definition: bridge.h:357
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_channel_unlock(chan)
Definition: channel.h:2946
struct ast_channel * swap
struct ast_channel * chan
Structure that contains information regarding a channel in a bridge.
const char * ast_channel_name(const struct ast_channel *chan)
enum queue_result id
Definition: app_queue.c:1507
#define ast_channel_trylock(chan)
Definition: channel.h:2947
static unsigned int optimization_id
Definition: bridge.c:127

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

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

4669 {
4670  struct ast_bridge_channel *kick_me[] = {
4671  to_transferee_bridge_channel,
4672  to_target_bridge_channel,
4673  };
4674  enum ast_transfer_result res;
4675  struct ast_bridge *final_bridge = NULL;
4677 
4678  channels = ast_bridge_peers_nolock(to_transferee_bridge);
4679 
4680  if (!channels) {
4682  goto end;
4683  }
4684 
4685  set_transfer_variables_all(to_transferee, channels, 1);
4686 
4687  switch (ast_bridges_allow_optimization(to_transferee_bridge, to_target_bridge)) {
4689  final_bridge = to_transferee_bridge;
4690  res = bridge_swap_attended_transfer(to_transferee_bridge, to_target_bridge_channel, to_transferee);
4691  goto end;
4693  final_bridge = to_target_bridge;
4694  res = bridge_swap_attended_transfer(to_target_bridge, to_transferee_bridge_channel, to_transfer_target);
4695  goto end;
4697  final_bridge = to_transferee_bridge;
4698  bridge_do_merge(to_transferee_bridge, to_target_bridge, kick_me, ARRAY_LEN(kick_me), 0);
4700  goto end;
4702  final_bridge = to_target_bridge;
4703  bridge_do_merge(to_target_bridge, to_transferee_bridge, kick_me, ARRAY_LEN(kick_me), 0);
4705  goto end;
4707  default:
4708  /* Just because optimization wasn't doable doesn't necessarily mean
4709  * that we can actually perform the transfer. Some reasons for non-optimization
4710  * indicate bridge invalidity, so let's check those before proceeding.
4711  */
4712  if (to_transferee_bridge->inhibit_merge || to_transferee_bridge->dissolved ||
4713  to_target_bridge->inhibit_merge || to_target_bridge->dissolved) {
4715  }
4716 
4717  return attended_transfer_bridge(to_transferee, to_transfer_target,
4718  to_transferee_bridge, to_target_bridge, transfer_msg);
4719  }
4720 
4721 end:
4722  if (res == AST_BRIDGE_TRANSFER_SUCCESS) {
4723  ast_attended_transfer_message_add_merge(transfer_msg, final_bridge);
4724  }
4725 
4726  return res;
4727 }
#define ARRAY_LEN(a)
Definition: isdn_lib.c:42
unsigned int dissolved
Definition: bridge.h:398
unsigned int inhibit_merge
Count of the active temporary requests to inhibit bridge merges. Zero if merges are allowed...
Definition: bridge.h:392
#define NULL
Definition: resample.c:96
char * end
Definition: eagi_proxy.c:73
ast_transfer_result
Definition: bridge.h:1115
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:2096
static void set_transfer_variables_all(struct ast_channel *transferer, struct ao2_container *channels, int is_attended)
Definition: bridge.c:4435
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:4620
#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:911
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.
static struct channel_usage channels
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:4280
Structure that contains information about a bridge.
Definition: bridge.h:357
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:3008
struct ao2_container * ast_bridge_peers_nolock(struct ast_bridge *bridge)
Get a container of all channels in the bridge.
Definition: bridge.c:4085
Structure that contains information regarding a channel in a bridge.
#define ao2_cleanup(obj)
Definition: astobj2.h:1958
Generic container type.

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

References ao2_bump, ast_bridge_interval_hook(), ast_bridge_hook::callback, ast_flags::flags, ast_bridge_hook_timer_parms::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().

3651 {
3652  /* Break out of the current wrapper if it exists to avoid multiple layers */
3653  if (hook->generic.callback == interval_wrapper_cb) {
3654  hook = hook->generic.hook_pvt;
3655  }
3656 
3657  ast_bridge_interval_hook(features, hook->timer.flags, hook->timer.interval,
3659  hook->generic.remove_flags.flags);
3660 }
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:3382
unsigned int flags
Definition: utils.h:200
struct ast_bridge_hook generic
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:3636
#define ao2_bump(obj)
Definition: astobj2.h:491
ast_bridge_hook_callback callback
struct ast_bridge_hook_timer_parms timer
static void interval_wrapper_pvt_dtor(void *obj)
Destructor for the hook wrapper.
Definition: bridge.c:3644
struct ast_flags remove_flags

Variable Documentation

◆ ast_bridge_base_v_table

struct ast_bridge_methods ast_bridge_base_v_table

◆ bridge_channel_impart_ds_info

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

Definition at line 1576 of file bridge.c.

◆ bridge_cli

struct ast_cli_entry bridge_cli[]
static

Definition at line 5462 of file bridge.c.

◆ bridge_manager

struct bridge_manager_controller* bridge_manager
static

Bridge manager controller.

Definition at line 172 of file bridge.c.

◆ bridge_technologies

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

◆ bridges

struct ao2_container* bridges
static

All bridges container.

Definition at line 123 of file bridge.c.

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

◆ builtin_features_dtmf

char builtin_features_dtmf[AST_BRIDGE_BUILTIN_END][MAXIMUM_DTMF_FEATURE_STRING]
static

Default DTMF keys for built in features

Definition at line 144 of file bridge.c.

Referenced by ast_bridge_features_enable(), and ast_bridge_features_register().

◆ builtin_features_handlers

ast_bridge_hook_callback builtin_features_handlers[AST_BRIDGE_BUILTIN_END]
static

Function handlers for the built in features

Definition at line 147 of file bridge.c.

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

◆ builtin_interval_handlers

Function handlers for built in interval features

Definition at line 150 of file bridge.c.

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

◆ optimization_id

unsigned int optimization_id
static

Definition at line 127 of file bridge.c.

Referenced by try_merge_optimize_out(), and try_swap_optimize_out().