bridge.h File Reference

Bridging API. More...

#include "asterisk/bridge_features.h"
#include "asterisk/bridge_channel.h"
#include "asterisk/bridge_roles.h"
#include "asterisk/dsp.h"
#include "asterisk/uuid.h"

Include dependency graph for bridge.h:

Go to the source code of this file.

Data Structures

struct  ast_bridge
 Structure that contains information about a bridge. More...
struct  ast_bridge_methods
 Bridge virtual methods table definition. More...
struct  ast_bridge_softmix
struct  ast_bridge_video_mode
 Data structure that defines a video source mode. More...
struct  ast_bridge_video_single_src_data
 This is used for both SINGLE_SRC mode to set what channel should be the current single video feed. More...
struct  ast_bridge_video_talker_src_data
 This is used for both SINGLE_SRC_TALKER mode to set what channel should be the current single video feed. More...
struct  transfer_channel_data
 AO2 object that wraps data for transfer_channel_cb. More...

Defines

#define ast_bridge_lock(bridge)   _ast_bridge_lock(bridge, __FILE__, __PRETTY_FUNCTION__, __LINE__, #bridge)
 Lock the bridge.
#define ast_bridge_lock_both(bridge1, bridge2)
 Lock two bridges.
#define ast_bridge_trylock(bridge)   _ast_bridge_trylock(bridge, __FILE__, __PRETTY_FUNCTION__, __LINE__, #bridge)
 Try locking the bridge.
#define ast_bridge_unlock(bridge)   _ast_bridge_unlock(bridge, __FILE__, __PRETTY_FUNCTION__, __LINE__, #bridge)
 Unlock the bridge.

Typedefs

typedef void(* ast_bridge_destructor_fn )(struct ast_bridge *self)
 Destroy the bridge.
typedef void(* ast_bridge_dissolving_fn )(struct ast_bridge *self)
 The bridge is being dissolved.
typedef int(* ast_bridge_merge_priority_fn )(struct ast_bridge *self)
 Get the merge priority of this bridge.
typedef void(* ast_bridge_notify_masquerade_fn )(struct ast_bridge *self, struct ast_bridge_channel *bridge_channel)
 Notify the bridge that this channel was just masqueraded.
typedef void(* ast_bridge_pull_channel_fn )(struct ast_bridge *self, struct ast_bridge_channel *bridge_channel)
 Pull this channel from the bridge.
typedef int(* ast_bridge_push_channel_fn )(struct ast_bridge *self, struct ast_bridge_channel *bridge_channel, struct ast_bridge_channel *swap)
 Push this channel into the bridge.
typedef void(* transfer_channel_cb )(struct ast_channel *chan, struct transfer_channel_data *user_data, enum ast_transfer_type transfer_type)
 Callback function type called during blind transfers.

Enumerations

enum  ast_bridge_capability {
  AST_BRIDGE_CAPABILITY_HOLDING = (1 << 0), AST_BRIDGE_CAPABILITY_EARLY = (1 << 1), AST_BRIDGE_CAPABILITY_NATIVE = (1 << 2), AST_BRIDGE_CAPABILITY_1TO1MIX = (1 << 3),
  AST_BRIDGE_CAPABILITY_MULTIMIX = (1 << 4)
}
 Capabilities for a bridge technology. More...
enum  ast_bridge_impart_flags { AST_BRIDGE_IMPART_CHAN_MASK = (1 << 0), AST_BRIDGE_IMPART_CHAN_DEPARTABLE = (0 << 0), AST_BRIDGE_IMPART_CHAN_INDEPENDENT = (1 << 0), AST_BRIDGE_IMPART_INHIBIT_JOIN_COLP = (1 << 1) }
enum  ast_bridge_join_flags { AST_BRIDGE_JOIN_PASS_REFERENCE = (1 << 0), AST_BRIDGE_JOIN_INHIBIT_JOIN_COLP = (1 << 1) }
enum  ast_bridge_optimization {
  AST_BRIDGE_OPTIMIZE_SWAP_TO_CHAN_BRIDGE, AST_BRIDGE_OPTIMIZE_SWAP_TO_PEER_BRIDGE, AST_BRIDGE_OPTIMIZE_MERGE_TO_CHAN_BRIDGE, AST_BRIDGE_OPTIMIZE_MERGE_TO_PEER_BRIDGE,
  AST_BRIDGE_OPTIMIZE_PROHIBITED
}
 Tells, if optimization is allowed, how the optimization would be performed. More...
enum  ast_bridge_video_mode_type { AST_BRIDGE_VIDEO_MODE_NONE = 0, AST_BRIDGE_VIDEO_MODE_SINGLE_SRC, AST_BRIDGE_VIDEO_MODE_TALKER_SRC }
 Video source modes. More...
enum  ast_transfer_result { AST_BRIDGE_TRANSFER_SUCCESS, AST_BRIDGE_TRANSFER_NOT_PERMITTED, AST_BRIDGE_TRANSFER_INVALID, AST_BRIDGE_TRANSFER_FAIL }
enum  ast_transfer_type { AST_BRIDGE_TRANSFER_SINGLE_PARTY, AST_BRIDGE_TRANSFER_MULTI_PARTY }

Functions

static void _ast_bridge_lock (struct ast_bridge *bridge, const char *file, const char *function, int line, const char *var)
static int _ast_bridge_trylock (struct ast_bridge *bridge, const char *file, const char *function, int line, const char *var)
static void _ast_bridge_unlock (struct ast_bridge *bridge, const char *file, const char *function, int line, const char *var)
struct ast_bridgeast_bridge_base_new (uint32_t capabilities, unsigned int flags, const char *creator, const char *name, const char *id)
 Create a new base class bridge.
int ast_bridge_depart (struct ast_channel *chan)
 Depart a channel from a bridge.
int ast_bridge_destroy (struct ast_bridge *bridge, int cause)
 Destroy a bridge.
void ast_bridge_features_remove (struct ast_bridge_features *features, enum ast_bridge_hook_remove_flags flags)
 Remove marked bridge channel feature hooks.
struct ast_bridgeast_bridge_find_by_id (const char *bridge_id)
 Find bridge by id.
int ast_bridge_impart (struct ast_bridge *bridge, struct ast_channel *chan, struct ast_channel *swap, struct ast_bridge_features *features, enum ast_bridge_impart_flags flags) attribute_warn_unused_result
 Impart a channel to a bridge (non-blocking).
int ast_bridge_is_video_src (struct ast_bridge *bridge, struct ast_channel *chan)
 Determine if a channel is a video src for the bridge.
int ast_bridge_join (struct ast_bridge *bridge, struct ast_channel *chan, struct ast_channel *swap, struct ast_bridge_features *features, struct ast_bridge_tech_optimizations *tech_args, enum ast_bridge_join_flags flags)
 Join a channel to a bridge (blocking).
int ast_bridge_kick (struct ast_bridge *bridge, struct ast_channel *chan)
 Kick a channel from a bridge.
int ast_bridge_merge (struct ast_bridge *dst_bridge, struct ast_bridge *src_bridge, int merge_best_direction, struct ast_channel **kick_me, unsigned int num_kick)
 Merge two bridges together.
void ast_bridge_merge_inhibit (struct ast_bridge *bridge, int request)
 Adjust the bridge merge inhibit request count.
int ast_bridge_move (struct ast_bridge *dst_bridge, struct ast_bridge *src_bridge, struct ast_channel *chan, struct ast_channel *swap, int attempt_recovery)
 Move a channel from one bridge to another.
void ast_bridge_notify_masquerade (struct ast_channel *chan)
 Notify bridging that this channel was just masqueraded.
int ast_bridge_number_video_src (struct ast_bridge *bridge)
 Returns the number of video sources currently active in the bridge.
struct ast_channelast_bridge_peer (struct ast_bridge *bridge, struct ast_channel *chan)
 Get the channel's bridge peer only if the bridge is two-party.
struct ast_channelast_bridge_peer_nolock (struct ast_bridge *bridge, struct ast_channel *chan)
 Get the channel's bridge peer only if the bridge is two-party.
struct ao2_containerast_bridge_peers (struct ast_bridge *bridge)
 Get a container of all channels in the bridge.
struct ao2_containerast_bridge_peers_nolock (struct ast_bridge *bridge)
 Get a container of all channels in the bridge.
int ast_bridge_queue_action (struct ast_bridge *bridge, struct ast_frame *action)
 Put an action onto the specified bridge.
int ast_bridge_queue_everyone_else (struct ast_bridge *bridge, struct ast_bridge_channel *bridge_channel, struct ast_frame *frame)
 Queue the given frame to everyone else.
int ast_bridge_remove (struct ast_bridge *bridge, struct ast_channel *chan)
 Remove a channel from a bridge.
void ast_bridge_remove_video_src (struct ast_bridge *bridge, struct ast_channel *chan)
 remove a channel as a source of video for the bridge.
void ast_bridge_set_internal_sample_rate (struct ast_bridge *bridge, unsigned int sample_rate)
 Adjust the internal mixing sample rate of a bridge used during multimix mode.
void ast_bridge_set_mixing_interval (struct ast_bridge *bridge, unsigned int mixing_interval)
 Adjust the internal mixing interval of a bridge used during multimix mode.
void ast_bridge_set_single_src_video_mode (struct ast_bridge *bridge, struct ast_channel *video_src_chan)
 Set a bridge to feed a single video source to all participants.
void ast_bridge_set_talker_src_video_mode (struct ast_bridge *bridge)
 Set the bridge to pick the strongest talker supporting video as the single source video feed.
void ast_bridge_set_transfer_variables (struct ast_channel *chan, const char *value, int is_attended)
 Set the relevant transfer variables for a single channel.
int ast_bridge_suspend (struct ast_bridge *bridge, struct ast_channel *chan)
 Suspend a channel temporarily from a bridge.
enum ast_transfer_result ast_bridge_transfer_attended (struct ast_channel *to_transferee, struct ast_channel *to_transfer_target)
 Attended transfer.
enum ast_transfer_result ast_bridge_transfer_blind (int is_external, struct ast_channel *transferer, const char *exten, const char *context, transfer_channel_cb new_channel_cb, void *user_data)
 Blind transfer target to the extension and context provided.
int ast_bridge_unreal_optimize_out (struct ast_channel *chan, struct ast_channel *peer, struct ast_unreal_pvt *pvt)
 Check and optimize out the unreal channels between bridges.
int ast_bridge_unsuspend (struct ast_bridge *bridge, struct ast_channel *chan)
 Unsuspend a channel from a bridge.
void ast_bridge_update_talker_src_video_mode (struct ast_bridge *bridge, struct ast_channel *chan, int talker_energy, int is_keyfame)
 Update information about talker energy for talker src video mode.
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.

Variables

struct ast_bridge_methods ast_bridge_base_v_table
 Bridge base class virtual method table.


Detailed Description

Bridging API.

Author:
Richard Mudgett <rmudgett@digium.com>

Joshua Colp <jcolp@digium.com> Bridging API

See Also:

Definition in file bridge.h.


Define Documentation

#define ast_bridge_lock ( bridge   )     _ast_bridge_lock(bridge, __FILE__, __PRETTY_FUNCTION__, __LINE__, #bridge)

#define ast_bridge_lock_both ( bridge1,
bridge2   ) 

#define ast_bridge_trylock ( bridge   )     _ast_bridge_trylock(bridge, __FILE__, __PRETTY_FUNCTION__, __LINE__, #bridge)

Try locking the bridge.

Parameters:
bridge Bridge to try locking
Return values:
0 on success.
non-zero on error.

Definition at line 361 of file bridge.h.

Referenced by optimize_lock_chan_stack(), and optimize_lock_peer_stack().

#define ast_bridge_unlock ( bridge   )     _ast_bridge_unlock(bridge, __FILE__, __PRETTY_FUNCTION__, __LINE__, #bridge)

Unlock the bridge.

Parameters:
bridge Bridge to unlock
Returns:
Nothing

Definition at line 387 of file bridge.h.

Referenced by agent_alert(), ast_ari_bridges_create(), ast_ari_bridges_create_with_id(), ast_bridge_add_channel(), ast_bridge_basic_set_flags(), ast_bridge_channel_feature_digit(), ast_bridge_channel_lock_bridge(), ast_bridge_channel_merge_inhibit(), ast_bridge_destroy(), ast_bridge_impart(), ast_bridge_is_video_src(), ast_bridge_join(), ast_bridge_kick(), ast_bridge_merge(), ast_bridge_merge_inhibit(), ast_bridge_move(), ast_bridge_notify_masquerade(), ast_bridge_number_video_src(), ast_bridge_peer(), ast_bridge_peers(), ast_bridge_remove(), ast_bridge_remove_video_src(), ast_bridge_set_internal_sample_rate(), ast_bridge_set_mixing_interval(), ast_bridge_set_single_src_video_mode(), ast_bridge_set_talker_src_video_mode(), ast_bridge_suspend(), ast_bridge_transfer_attended(), ast_bridge_transfer_blind(), ast_bridge_unreal_optimize_out(), ast_bridge_unsuspend(), ast_bridge_update_talker_src_video_mode(), AST_TEST_DEFINE(), ast_unreal_channel_push_to_bridge(), basic_hangup_hook(), bridge_action_bridge(), bridge_basic_change_personality(), bridge_channel_internal_join(), bridge_channel_snapshot_pair_init(), bridge_channel_suspend(), bridge_channel_unsuspend(), bridge_channel_wait(), bridge_channel_write_frame(), bridge_manager_service(), bridge_merge(), bridge_move(), bridge_queue_action_nodup(), bridge_register(), complete_bridge_participant(), conf_moh_start(), conf_moh_stop(), create_bridge_snapshot_message(), deferred_action(), destroy_bridge(), feature_automixmonitor(), feature_automonitor(), handle_bridge_kick_channel(), native_rtp_framehook(), optimize_lock_chan_stack(), optimize_lock_peer_stack(), parking_blind_transfer_park(), play_uri(), send_conf_stasis(), softmix_mixing_loop(), and softmix_mixing_thread().


Typedef Documentation

typedef void(* ast_bridge_destructor_fn)(struct ast_bridge *self)

Destroy the bridge.

Parameters:
self Bridge to operate upon.
Returns:
Nothing

Definition at line 142 of file bridge.h.

typedef void(* ast_bridge_dissolving_fn)(struct ast_bridge *self)

The bridge is being dissolved.

Parameters:
self Bridge to operate upon.
The bridge is being dissolved. Remove any external references to the bridge so it can be destroyed.

Note:
On entry, self must NOT be locked.
Returns:
Nothing

Definition at line 157 of file bridge.h.

typedef int(* ast_bridge_merge_priority_fn)(struct ast_bridge *self)

Get the merge priority of this bridge.

Parameters:
self Bridge to operate upon.
Note:
On entry, self is already locked.
Returns:
Merge priority

Definition at line 221 of file bridge.h.

typedef void(* ast_bridge_notify_masquerade_fn)(struct ast_bridge *self, struct ast_bridge_channel *bridge_channel)

Notify the bridge that this channel was just masqueraded.

Parameters:
self Bridge to operate upon.
bridge_channel Bridge channel that was masqueraded.
A masquerade just happened to this channel. The bridge needs to re-evaluate this a channel in the bridge.

Note:
On entry, self is already locked.
Returns:
Nothing

Definition at line 210 of file bridge.h.

typedef void(* ast_bridge_pull_channel_fn)(struct ast_bridge *self, struct ast_bridge_channel *bridge_channel)

Pull this channel from the bridge.

Parameters:
self Bridge to operate upon.
bridge_channel Bridge channel to pull.
Remove any channel hooks controlled by the bridge. Release any resources held by bridge_channel->bridge_pvt and release bridge_channel->bridge_pvt.

Note:
On entry, self is already locked.
Returns:
Nothing

Definition at line 194 of file bridge.h.

typedef int(* ast_bridge_push_channel_fn)(struct ast_bridge *self, struct ast_bridge_channel *bridge_channel, struct ast_bridge_channel *swap)

Push this channel into the bridge.

Parameters:
self Bridge to operate upon.
bridge_channel Bridge channel to push.
swap Bridge channel to swap places with if not NULL.
Setup any channel hooks controlled by the bridge. Allocate bridge_channel->bridge_pvt and initialize any resources put in bridge_channel->bridge_pvt if needed. If there is a swap channel, use it as a guide to setting up the bridge_channel.

Note:
On entry, self is already locked.
Return values:
0 on success.
-1 on failure. The channel did not get pushed.

Definition at line 177 of file bridge.h.

typedef void(* transfer_channel_cb)(struct ast_channel *chan, struct transfer_channel_data *user_data, enum ast_transfer_type transfer_type)

Callback function type called during blind transfers.

A caller of ast_bridge_transfer_blind() may wish to set data on the channel that ends up running dialplan. For instance, it may be useful to set channel variables on the channel.

Parameters:
chan The involved channel
user_data User-provided data needed in the callback
transfer_type The type of transfer being completed

Definition at line 937 of file bridge.h.


Enumeration Type Documentation

Capabilities for a bridge technology.

Enumerator:
AST_BRIDGE_CAPABILITY_HOLDING  Bridge technology can service calls on hold.
AST_BRIDGE_CAPABILITY_EARLY  Bridge waits for channel to answer. Passes early media. (XXX Not supported yet)
AST_BRIDGE_CAPABILITY_NATIVE  Bridge is capable of natively bridging two channels. (Smart bridge only)
AST_BRIDGE_CAPABILITY_1TO1MIX  Bridge is capable of mixing at most two channels. (Smart bridgeable)
AST_BRIDGE_CAPABILITY_MULTIMIX  Bridge is capable of mixing an arbitrary number of channels. (Smart bridgeable)

Definition at line 83 of file bridge.h.

00083                            {
00084    /*! Bridge technology can service calls on hold. */
00085    AST_BRIDGE_CAPABILITY_HOLDING = (1 << 0),
00086    /*! Bridge waits for channel to answer.  Passes early media. (XXX Not supported yet) */
00087    AST_BRIDGE_CAPABILITY_EARLY = (1 << 1),
00088    /*! Bridge is capable of natively bridging two channels. (Smart bridge only) */
00089    AST_BRIDGE_CAPABILITY_NATIVE = (1 << 2),
00090    /*! Bridge is capable of mixing at most two channels. (Smart bridgeable) */
00091    AST_BRIDGE_CAPABILITY_1TO1MIX = (1 << 3),
00092    /*! Bridge is capable of mixing an arbitrary number of channels. (Smart bridgeable) */
00093    AST_BRIDGE_CAPABILITY_MULTIMIX = (1 << 4),
00094 };

Enumerator:
AST_BRIDGE_IMPART_CHAN_MASK  Field describing what the caller can do with the channel after it is imparted.
AST_BRIDGE_IMPART_CHAN_DEPARTABLE  The caller wants to reclaim the channel using ast_bridge_depart().
AST_BRIDGE_IMPART_CHAN_INDEPENDENT  The caller is passing channel control entirely to the bridging system.
AST_BRIDGE_IMPART_INHIBIT_JOIN_COLP  The initial bridge join does not cause a COLP exchange.

Definition at line 492 of file bridge.h.

00492                              {
00493    /*! Field describing what the caller can do with the channel after it is imparted. */
00494    AST_BRIDGE_IMPART_CHAN_MASK = (1 << 0),
00495    /*! The caller wants to reclaim the channel using ast_bridge_depart(). */
00496    AST_BRIDGE_IMPART_CHAN_DEPARTABLE = (0 << 0),
00497    /*! The caller is passing channel control entirely to the bridging system. */
00498    AST_BRIDGE_IMPART_CHAN_INDEPENDENT = (1 << 0),
00499    /*! The initial bridge join does not cause a COLP exchange. */
00500    AST_BRIDGE_IMPART_INHIBIT_JOIN_COLP = (1 << 1),
00501 };

Enumerator:
AST_BRIDGE_JOIN_PASS_REFERENCE  The bridge reference is being passed by the caller.
AST_BRIDGE_JOIN_INHIBIT_JOIN_COLP  The initial bridge join does not cause a COLP exchange.

Definition at line 441 of file bridge.h.

00441                            {
00442    /*! The bridge reference is being passed by the caller. */
00443    AST_BRIDGE_JOIN_PASS_REFERENCE = (1 << 0),
00444    /*! The initial bridge join does not cause a COLP exchange. */
00445    AST_BRIDGE_JOIN_INHIBIT_JOIN_COLP = (1 << 1),
00446 };

Tells, if optimization is allowed, how the optimization would be performed.

Enumerator:
AST_BRIDGE_OPTIMIZE_SWAP_TO_CHAN_BRIDGE  Optimization would swap peer into the chan_bridge
AST_BRIDGE_OPTIMIZE_SWAP_TO_PEER_BRIDGE  Optimization would swap chan into the peer_bridge
AST_BRIDGE_OPTIMIZE_MERGE_TO_CHAN_BRIDGE  Optimization would merge peer_bridge into chan_bridge
AST_BRIDGE_OPTIMIZE_MERGE_TO_PEER_BRIDGE  Optimization would merge chan_bridge into peer_bridge
AST_BRIDGE_OPTIMIZE_PROHIBITED  Optimization is not permitted on one or both bridges

Definition at line 768 of file bridge.h.

00768                              {
00769    /*! Optimization would swap peer into the chan_bridge */
00770    AST_BRIDGE_OPTIMIZE_SWAP_TO_CHAN_BRIDGE,
00771    /*! Optimization would swap chan into the peer_bridge */
00772    AST_BRIDGE_OPTIMIZE_SWAP_TO_PEER_BRIDGE,
00773    /*! Optimization would merge peer_bridge into chan_bridge */
00774    AST_BRIDGE_OPTIMIZE_MERGE_TO_CHAN_BRIDGE,
00775    /*! Optimization would merge chan_bridge into peer_bridge */
00776    AST_BRIDGE_OPTIMIZE_MERGE_TO_PEER_BRIDGE,
00777    /*! Optimization is not permitted on one or both bridges */
00778    AST_BRIDGE_OPTIMIZE_PROHIBITED,
00779 };

Video source modes.

Enumerator:
AST_BRIDGE_VIDEO_MODE_NONE  Video is not allowed in the bridge
AST_BRIDGE_VIDEO_MODE_SINGLE_SRC  A single user is picked as the only distributed of video across the bridge
AST_BRIDGE_VIDEO_MODE_TALKER_SRC  A single user's video feed is distributed to all bridge channels, but that feed is automatically picked based on who is talking the most.

Definition at line 97 of file bridge.h.

00097                                 {
00098    /*! Video is not allowed in the bridge */
00099    AST_BRIDGE_VIDEO_MODE_NONE = 0,
00100    /*! A single user is picked as the only distributed of video across the bridge */
00101    AST_BRIDGE_VIDEO_MODE_SINGLE_SRC,
00102    /*! A single user's video feed is distributed to all bridge channels, but
00103     *  that feed is automatically picked based on who is talking the most. */
00104    AST_BRIDGE_VIDEO_MODE_TALKER_SRC,
00105 };

Enumerator:
AST_BRIDGE_TRANSFER_SUCCESS  The transfer completed successfully
AST_BRIDGE_TRANSFER_NOT_PERMITTED  A bridge involved does not permit transferring
AST_BRIDGE_TRANSFER_INVALID  The current bridge setup makes transferring an invalid operation
AST_BRIDGE_TRANSFER_FAIL  The transfer operation failed for a miscellaneous reason

Definition at line 892 of file bridge.h.

00892                          {
00893    /*! The transfer completed successfully */
00894    AST_BRIDGE_TRANSFER_SUCCESS,
00895    /*! A bridge involved does not permit transferring */
00896    AST_BRIDGE_TRANSFER_NOT_PERMITTED,
00897    /*! The current bridge setup makes transferring an invalid operation */
00898    AST_BRIDGE_TRANSFER_INVALID,
00899    /*! The transfer operation failed for a miscellaneous reason */
00900    AST_BRIDGE_TRANSFER_FAIL,
00901 };

Enumerator:
AST_BRIDGE_TRANSFER_SINGLE_PARTY  Transfer of a single party
AST_BRIDGE_TRANSFER_MULTI_PARTY  Transfer of multiple parties

Definition at line 903 of file bridge.h.

00903                        {
00904    /*! Transfer of a single party */
00905    AST_BRIDGE_TRANSFER_SINGLE_PARTY,
00906    /*! Transfer of multiple parties */
00907    AST_BRIDGE_TRANSFER_MULTI_PARTY,
00908 };


Function Documentation

static void _ast_bridge_lock ( struct ast_bridge bridge,
const char *  file,
const char *  function,
int  line,
const char *  var 
) [inline, static]

Definition at line 375 of file bridge.h.

References __ao2_lock(), and AO2_LOCK_REQ_MUTEX.

00376 {
00377    __ao2_lock(bridge, AO2_LOCK_REQ_MUTEX, file, function, line, var);
00378 }

static int _ast_bridge_trylock ( struct ast_bridge bridge,
const char *  file,
const char *  function,
int  line,
const char *  var 
) [inline, static]

Definition at line 362 of file bridge.h.

References __ao2_trylock(), and AO2_LOCK_REQ_MUTEX.

00363 {
00364    return __ao2_trylock(bridge, AO2_LOCK_REQ_MUTEX, file, function, line, var);
00365 }

static void _ast_bridge_unlock ( struct ast_bridge bridge,
const char *  file,
const char *  function,
int  line,
const char *  var 
) [inline, static]

Definition at line 388 of file bridge.h.

References __ao2_unlock().

00389 {
00390    __ao2_unlock(bridge, file, function, line, var);
00391 }

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

Create a new base class bridge.

Parameters:
capabilities The capabilities that we require to be used on the bridge
flags Flags that will alter the behavior of the bridge
creator Entity that created the bridge (optional)
name Name given to the bridge by its creator (optional, requires named creator)
id Unique ID given to the bridge by its creator (optional)
Return values:
a pointer to a new bridge on success
NULL on 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 932 of file bridge.c.

References bridge_alloc(), bridge_base_init(), and bridge_register().

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

00933 {
00934    void *bridge;
00935 
00936    bridge = bridge_alloc(sizeof(struct ast_bridge), &ast_bridge_base_v_table);
00937    bridge = bridge_base_init(bridge, capabilities, flags, creator, name, id);
00938    bridge = bridge_register(bridge);
00939    return bridge;
00940 }

int ast_bridge_depart ( struct ast_channel chan  ) 

Depart a channel from a bridge.

Parameters:
chan Channel to depart
Note:
chan is locked by this function.
Return values:
0 on success
-1 on 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 1727 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, and ast_bridge_channel::thread.

Referenced by app_control_continue(), app_control_remove_channel_from_bridge(), AST_TEST_DEFINE(), bridge_channel_depart(), conf_announce_channel_depart(), control_add_channel_to_bridge(), and stasis_app_exec().

01728 {
01729    struct ast_bridge_channel *bridge_channel;
01730    int departable;
01731 
01732    ast_channel_lock(chan);
01733    bridge_channel = ast_channel_internal_bridge_channel(chan);
01734    departable = bridge_channel && bridge_channel->depart_wait;
01735    ast_channel_unlock(chan);
01736    if (!departable) {
01737       ast_log(LOG_ERROR, "Channel %s cannot be departed.\n",
01738          ast_channel_name(chan));
01739       /*
01740        * Should never happen.  It likely means that
01741        * ast_bridge_depart() is called by two threads for the same
01742        * channel, the channel was never imparted to be departed, or it
01743        * has already been departed.
01744        */
01745       ast_assert(0);
01746       return -1;
01747    }
01748 
01749    /*
01750     * We are claiming the bridge_channel reference held by
01751     * bridge_channel_depart_thread().
01752     */
01753 
01754    ast_bridge_channel_leave_bridge(bridge_channel,
01755       BRIDGE_CHANNEL_STATE_END_NO_DISSOLVE, AST_CAUSE_NORMAL_CLEARING);
01756 
01757    /* Wait for the depart thread to die */
01758    ast_debug(1, "Waiting for %p(%s) bridge thread to die.\n",
01759       bridge_channel, ast_channel_name(bridge_channel->chan));
01760    pthread_join(bridge_channel->thread, NULL);
01761 
01762    ast_channel_lock(chan);
01763    ast_channel_internal_bridge_channel_set(chan, NULL);
01764    ast_channel_unlock(chan);
01765 
01766    /* We can get rid of the bridge_channel after the depart thread has died. */
01767    ao2_ref(bridge_channel, -1);
01768    return 0;
01769 }

int ast_bridge_destroy ( struct ast_bridge bridge,
int  cause 
)

Destroy a bridge.

Parameters:
bridge Bridge to destroy
cause Cause of bridge being destroyed. (If cause <= 0 then use AST_CAUSE_NORMAL_CLEARING)
Return values:
0 on success
-1 on 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 942 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_exec(), bridge_register(), caller_abort_agent(), destroy_conference_bridge(), fail_enter(), manager_bridge_destroy(), parked_call_app_exec(), parking_lot_destructor(), safe_bridge_destroy(), stasis_app_bridge_create(), stasis_app_bridge_destroy(), unload_module(), wait_bridge_wrapper_alloc(), and wait_bridge_wrapper_destructor().

00943 {
00944    ast_debug(1, "Bridge %s: telling all channels to leave the party\n", bridge->uniqueid);
00945    ast_bridge_lock(bridge);
00946    bridge_dissolve(bridge, cause);
00947    ast_bridge_unlock(bridge);
00948 
00949    ao2_ref(bridge, -1);
00950 
00951    return 0;
00952 }

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:
features Bridge features structure
flags Determinator for whether hook is removed.
Returns:
Nothing

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

03338 {
03339    hooks_remove_container(features->dtmf_hooks, remove_flags);
03340    hooks_remove_container(features->other_hooks, remove_flags);
03341    hooks_remove_heap(features->interval_hooks, remove_flags);
03342 }

struct ast_bridge* ast_bridge_find_by_id ( const char *  bridge_id  )  [read]

Find bridge by id.

Since:
12.0.0
Parameters:
bridge_id Bridge identifier
Returns:
NULL bridge not found

non-NULL reference to bridge

Definition at line 4691 of file bridge.c.

References ao2_find, and OBJ_SEARCH_KEY.

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

04692 {
04693    return ao2_find(bridges, bridge_id, OBJ_SEARCH_KEY);
04694 }

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:
bridge Bridge to impart on
chan Channel to impart (The channel reference is stolen if impart successful.)
swap Channel to swap out if swapping. NULL if not swapping.
features Bridge features structure.
flags defined by enum ast_bridge_impart_flags.
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.

chan is locked by this function.

Return values:
0 on success
-1 on 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().

Definition at line 1637 of file bridge.c.

References ao2_ref, ao2_t_bump, ao2_t_cleanup, 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_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 app_control_dial(), 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_add_channel_to_bridge(), feature_attended_transfer(), handle_invite_replaces(), local_call(), parking_blind_transfer_park(), recalling_exit(), refer_incoming_invite_request(), and retransfer_enter().

01642 {
01643    int res = 0;
01644    struct ast_bridge_channel *bridge_channel;
01645 
01646    /* Imparted channels cannot have a PBX. */
01647    if (ast_channel_pbx(chan)) {
01648       ast_log(AST_LOG_WARNING, "Channel %s has a PBX thread and cannot be imparted into bridge %s\n",
01649          ast_channel_name(chan), bridge->uniqueid);
01650       ast_bridge_features_destroy(features);
01651       return -1;
01652    }
01653 
01654    /* Supply an empty features structure if the caller did not. */
01655    if (!features) {
01656       features = ast_bridge_features_new();
01657       if (!features) {
01658          return -1;
01659       }
01660    }
01661 
01662    /* Try to allocate a structure for the bridge channel */
01663    bridge_channel = bridge_channel_internal_alloc(bridge);
01664    if (!bridge_channel) {
01665       ast_bridge_features_destroy(features);
01666       return -1;
01667    }
01668 
01669    ast_channel_lock(chan);
01670    if (ast_test_flag(ast_channel_flags(chan), AST_FLAG_ZOMBIE)) {
01671       ast_log(AST_LOG_NOTICE, "Channel %s is a zombie and cannot be imparted into bridge %s\n",
01672          ast_channel_name(chan), bridge->uniqueid);
01673       res = -1;
01674    } else {
01675       ast_channel_internal_bridge_channel_set(chan, bridge_channel);
01676    }
01677    ast_channel_unlock(chan);
01678    bridge_channel->chan = chan;
01679    bridge_channel->swap = ao2_t_bump(swap, "Setting up bridge impart");
01680    bridge_channel->features = features;
01681    bridge_channel->inhibit_colp = !!(flags & AST_BRIDGE_IMPART_INHIBIT_JOIN_COLP);
01682    bridge_channel->depart_wait =
01683       (flags & AST_BRIDGE_IMPART_CHAN_MASK) == AST_BRIDGE_IMPART_CHAN_DEPARTABLE;
01684    bridge_channel->callid = ast_read_threadstorage_callid();
01685 
01686    /* allow subclass to peek at swap channel before it can hangup */
01687    if (bridge->v_table->push_peek && !res) {
01688       struct ast_bridge_channel *bcswap = NULL;
01689 
01690       ast_bridge_lock(bridge);
01691       if (bridge_channel->swap) {
01692          bcswap = bridge_find_channel(bridge, bridge_channel->swap);
01693       }
01694       res = bridge->v_table->push_peek(bridge, bridge_channel, bcswap);
01695       ast_bridge_unlock(bridge);
01696    }
01697 
01698    /* Actually create the thread that will handle the channel */
01699    if (!res) {
01700       if ((flags & AST_BRIDGE_IMPART_CHAN_MASK) == AST_BRIDGE_IMPART_CHAN_INDEPENDENT) {
01701          res = ast_pthread_create_detached(&bridge_channel->thread, NULL,
01702             bridge_channel_ind_thread, bridge_channel);
01703       } else {
01704          res = ast_pthread_create(&bridge_channel->thread, NULL,
01705             bridge_channel_depart_thread, bridge_channel);
01706       }
01707    }
01708 
01709    if (res) {
01710       /* cleanup */
01711       ast_channel_lock(chan);
01712       ast_channel_internal_bridge_channel_set(chan, NULL);
01713       ast_channel_unlock(chan);
01714       bridge_channel->chan = NULL;
01715       ao2_t_cleanup(bridge_channel->swap, "Bridge complete: Impart failed");
01716       bridge_channel->swap = NULL;
01717       ast_bridge_features_destroy(bridge_channel->features);
01718       bridge_channel->features = NULL;
01719 
01720       ao2_ref(bridge_channel, -1);
01721       return -1;
01722    }
01723 
01724    return 0;
01725 }

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:
0 Not a current video source of the bridge.
None 0, 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 3655 of file bridge.c.

References ast_bridge_lock, ast_bridge_unlock, AST_BRIDGE_VIDEO_MODE_NONE, AST_BRIDGE_VIDEO_MODE_SINGLE_SRC, AST_BRIDGE_VIDEO_MODE_TALKER_SRC, ast_bridge_video_talker_src_data::chan_old_vsrc, ast_bridge_video_talker_src_data::chan_vsrc, ast_bridge_video_single_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().

03656 {
03657    int res = 0;
03658 
03659    ast_bridge_lock(bridge);
03660    switch (bridge->softmix.video_mode.mode) {
03661    case AST_BRIDGE_VIDEO_MODE_NONE:
03662       break;
03663    case AST_BRIDGE_VIDEO_MODE_SINGLE_SRC:
03664       if (bridge->softmix.video_mode.mode_data.single_src_data.chan_vsrc == chan) {
03665          res = 1;
03666       }
03667       break;
03668    case AST_BRIDGE_VIDEO_MODE_TALKER_SRC:
03669       if (bridge->softmix.video_mode.mode_data.talker_src_data.chan_vsrc == chan) {
03670          res = 1;
03671       } else if (bridge->softmix.video_mode.mode_data.talker_src_data.chan_old_vsrc == chan) {
03672          res = 2;
03673       }
03674 
03675    }
03676    ast_bridge_unlock(bridge);
03677    return res;
03678 }

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:
bridge Bridge to join
chan Channel to join
swap Channel to swap out if swapping (A channel reference is stolen.)
features Bridge features structure
tech_args Optional Bridging tech optimization parameters for this channel.
flags defined 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:
0 if the channel successfully joined the bridge before it exited.
-1 if 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 1495 of file bridge.c.

References ao2_ref, ao2_t_cleanup, 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_softhangup_internal_flag(), ast_channel_unlock, AST_FLAG_ZOMBIE, AST_SOFTHANGUP_ASYNCGOTO, ast_softhangup_nolock(), ast_test_flag, 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, ast_bridge_channel::swap, ast_bridge_channel::tech_args, ast_bridge_channel::thread, and ast_bridge::v_table.

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

01501 {
01502    struct ast_bridge_channel *bridge_channel;
01503    int res = 0;
01504 
01505    bridge_channel = bridge_channel_internal_alloc(bridge);
01506    if (flags & AST_BRIDGE_JOIN_PASS_REFERENCE) {
01507       ao2_ref(bridge, -1);
01508    }
01509    if (!bridge_channel) {
01510       ao2_t_cleanup(swap, "Error exit: bridge_channel alloc failed");
01511       res = -1;
01512       goto join_exit;
01513    }
01514 /* 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. */
01515    ast_assert(features != NULL);
01516    if (!features) {
01517       ao2_ref(bridge_channel, -1);
01518       ao2_t_cleanup(swap, "Error exit: features is NULL");
01519       res = -1;
01520       goto join_exit;
01521    }
01522    if (tech_args) {
01523       bridge_channel->tech_args = *tech_args;
01524    }
01525 
01526    ast_channel_lock(chan);
01527    if (ast_test_flag(ast_channel_flags(chan), AST_FLAG_ZOMBIE)) {
01528       res = -1;
01529    } else {
01530       ast_channel_internal_bridge_channel_set(chan, bridge_channel);
01531    }
01532    ast_channel_unlock(chan);
01533    bridge_channel->thread = pthread_self();
01534    bridge_channel->chan = chan;
01535    bridge_channel->swap = swap;
01536    bridge_channel->features = features;
01537    bridge_channel->inhibit_colp = !!(flags & AST_BRIDGE_JOIN_INHIBIT_JOIN_COLP);
01538 
01539    /* allow subclass to peek at upcoming push operation */
01540    if (bridge->v_table->push_peek && !res) {
01541       struct ast_bridge_channel *bcswap = NULL;
01542 
01543       ast_bridge_lock(bridge);
01544       if (bridge_channel->swap) {
01545          bcswap = bridge_find_channel(bridge, bridge_channel->swap);
01546       }
01547       res = bridge->v_table->push_peek(bridge, bridge_channel, bcswap);
01548       ast_bridge_unlock(bridge);
01549    }
01550 
01551    if (!res) {
01552       res = bridge_channel_internal_join(bridge_channel);
01553    }
01554 
01555    /* Cleanup all the data in the bridge channel after it leaves the bridge. */
01556    ast_channel_lock(chan);
01557    ast_channel_internal_bridge_channel_set(chan, NULL);
01558    ast_channel_unlock(chan);
01559    bridge_channel->chan = NULL;
01560    /* If bridge_channel->swap is not NULL then the join failed. */
01561    ao2_t_cleanup(bridge_channel->swap, "Bridge complete: join failed");
01562    bridge_channel->swap = NULL;
01563    bridge_channel->features = NULL;
01564 
01565    ao2_ref(bridge_channel, -1);
01566 
01567 join_exit:;
01568    ast_bridge_run_after_callback(chan);
01569    if (!(ast_channel_softhangup_internal_flag(chan) & AST_SOFTHANGUP_ASYNCGOTO)
01570       && !ast_bridge_setup_after_goto(chan)) {
01571       /* Claim the after bridge goto is an async goto destination. */
01572       ast_channel_lock(chan);
01573       ast_softhangup_nolock(chan, AST_SOFTHANGUP_ASYNCGOTO);
01574       ast_channel_unlock(chan);
01575    }
01576    return res;
01577 }

int ast_bridge_kick ( struct ast_bridge bridge,
struct ast_channel chan 
)

Kick a channel from a bridge.

Parameters:
bridge Bridge that the channel is to be kicked from
chan Channel to kick
Return values:
0 on success
-1 on failure
Example usage:

 ast_bridge_kick(bridge, chan);

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

01797 {
01798    struct ast_bridge_channel *bridge_channel;
01799    int res;
01800 
01801    ast_bridge_lock(bridge);
01802 
01803    /* Try to find the channel that we want to kick. */
01804    if (!(bridge_channel = bridge_find_channel(bridge, chan))) {
01805       ast_bridge_unlock(bridge);
01806       return -1;
01807    }
01808 
01809    res = ast_bridge_channel_queue_callback(bridge_channel, 0, kick_it, NULL, 0);
01810 
01811    ast_bridge_unlock(bridge);
01812 
01813    return res;
01814 }

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_bridge Destination bridge of merge.
src_bridge Source bridge of merge.
merge_best_direction TRUE if don't care about which bridge merges into the other.
kick_me Array of channels to kick from the bridges.
num_kick Number of channels in the kick_me array.
Note:
Absolutely _NO_ bridge or channel locks should be held before calling this function.
Return values:
0 on success
-1 on 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 2119 of file bridge.c.

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

02120 {
02121    int res;
02122 
02123    /* Sanity check. */
02124    ast_assert(dst_bridge && src_bridge);
02125 
02126    ast_bridge_lock_both(dst_bridge, src_bridge);
02127    res = bridge_merge_locked(dst_bridge, src_bridge, merge_best_direction, kick_me, num_kick);
02128    ast_bridge_unlock(src_bridge);
02129    ast_bridge_unlock(dst_bridge);
02130    return res;
02131 }

void ast_bridge_merge_inhibit ( struct ast_bridge bridge,
int  request 
)

Adjust the bridge merge inhibit request count.

Since:
12.0.0
Parameters:
bridge What to operate on.
request Inhibit request increment. (Positive to add requests. Negative to remove requests.)
Returns:
Nothing

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

02831 {
02832    ast_bridge_lock(bridge);
02833    bridge_merge_inhibit_nolock(bridge, request);
02834    ast_bridge_unlock(bridge);
02835 }

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_bridge Destination bridge of bridge channel move.
src_bridge Source bridge of bridge channel move.
chan Channel to move.
swap Channel to replace in dst_bridge.
attempt_recovery TRUE 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:
0 on success.
-1 on failure.

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

02281 {
02282    int res;
02283 
02284    ast_bridge_lock_both(dst_bridge, src_bridge);
02285    res = bridge_move_locked(dst_bridge, src_bridge, chan, swap, attempt_recovery);
02286    ast_bridge_unlock(src_bridge);
02287    ast_bridge_unlock(dst_bridge);
02288    return res;
02289 }

void ast_bridge_notify_masquerade ( struct ast_channel chan  ) 

Notify bridging that this channel was just masqueraded.

Since:
12.0.0
Parameters:
chan Channel just involved in a masquerade
Returns:
Nothing

Definition at line 1454 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_find_channel(), bridge_reconfigured(), ast_bridge_methods::notify_masquerade, and ast_bridge::v_table.

Referenced by channel_do_masquerade().

01455 {
01456    struct ast_bridge_channel *bridge_channel;
01457    struct ast_bridge *bridge;
01458 
01459    /* Safely get the bridge_channel pointer for the chan. */
01460    ast_channel_lock(chan);
01461    bridge_channel = ast_channel_get_bridge_channel(chan);
01462    ast_channel_unlock(chan);
01463    if (!bridge_channel) {
01464       /* Not in a bridge */
01465       return;
01466    }
01467 
01468    ast_bridge_channel_lock_bridge(bridge_channel);
01469    bridge = bridge_channel->bridge;
01470    if (bridge_channel == bridge_find_channel(bridge, chan)) {
01471 /*
01472  * XXX ASTERISK-22366 this needs more work.  The channels need
01473  * to be made compatible again if the formats change. The
01474  * bridge_channel thread needs to monitor for this case.
01475  */
01476       /* The channel we want to notify is still in a bridge. */
01477       bridge->v_table->notify_masquerade(bridge, bridge_channel);
01478       bridge_reconfigured(bridge, 1);
01479    }
01480    ast_bridge_unlock(bridge);
01481    ao2_ref(bridge_channel, -1);
01482 }

int ast_bridge_number_video_src ( struct ast_bridge bridge  ) 

struct ast_channel* ast_bridge_peer ( struct ast_bridge bridge,
struct ast_channel chan 
) [read]

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

Since:
12.0.0
Parameters:
bridge The bridge
chan Channel desiring the bridge peer channel.
Note:
The returned peer channel is the current peer in the bridge when called.
Return values:
NULL Channel not in a bridge or the bridge is not two-party.
non-NULL Reffed peer channel at time of calling.

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

03815 {
03816    struct ast_channel *peer;
03817 
03818    ast_bridge_lock(bridge);
03819    peer = ast_bridge_peer_nolock(bridge, chan);
03820    ast_bridge_unlock(bridge);
03821 
03822    return peer;
03823 }

struct ast_channel* ast_bridge_peer_nolock ( struct ast_bridge bridge,
struct ast_channel chan 
) [read]

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

Since:
12.0.0
Parameters:
bridge The bridge which is already locked.
chan Channel desiring the bridge peer channel.
Note:
The returned peer channel is the current peer in the bridge when called.
Return values:
NULL Channel not in a bridge or the bridge is not two-party.
non-NULL Reffed peer channel at time of calling.

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

03787 {
03788    struct ast_channel *peer = NULL;
03789    struct ast_bridge_channel *iter;
03790 
03791    /* Asking for the peer channel only makes sense on a two-party bridge. */
03792    if (bridge->num_channels == 2
03793       && bridge->technology->capabilities
03794          & (AST_BRIDGE_CAPABILITY_NATIVE | AST_BRIDGE_CAPABILITY_1TO1MIX)) {
03795       int in_bridge = 0;
03796 
03797       AST_LIST_TRAVERSE(&bridge->channels, iter, entry) {
03798          if (iter->chan != chan) {
03799             peer = iter->chan;
03800          } else {
03801             in_bridge = 1;
03802          }
03803       }
03804       if (in_bridge && peer) {
03805          ast_channel_ref(peer);
03806       } else {
03807          peer = NULL;
03808       }
03809    }
03810 
03811    return peer;
03812 }

struct ao2_container* ast_bridge_peers ( struct ast_bridge bridge  )  [read]

Get a container of all channels in the bridge.

Since:
12.0.0
Parameters:
bridge The bridge
Note:
The returned container is a snapshot of channels in the bridge when called.
Return values:
NULL Failed to create container
non-NULL Container of channels in the bridge

Definition at line 3775 of file bridge.c.

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

03776 {
03777    struct ao2_container *channels;
03778 
03779    ast_bridge_lock(bridge);
03780    channels = ast_bridge_peers_nolock(bridge);
03781    ast_bridge_unlock(bridge);
03782 
03783    return channels;
03784 }

struct ao2_container* ast_bridge_peers_nolock ( struct ast_bridge bridge  )  [read]

Get a container of all channels in the bridge.

Since:
12.0.0
Parameters:
bridge The bridge which is already locked.
Return values:
NULL Failed to create container
non-NULL Container of channels in the bridge

Definition at line 3757 of file bridge.c.

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

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

03758 {
03759    struct ao2_container *channels;
03760    struct ast_bridge_channel *iter;
03761 
03762    channels = ao2_container_alloc_options(AO2_ALLOC_OPT_LOCK_NOLOCK,
03763       13, channel_hash, channel_cmp);
03764    if (!channels) {
03765       return NULL;
03766    }
03767 
03768    AST_LIST_TRAVERSE(&bridge->channels, iter, entry) {
03769       ao2_link(channels, iter->chan);
03770    }
03771 
03772    return channels;
03773 }

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:
bridge What to queue the action on.
action What to do.
Return values:
0 on success.
-1 on error.
Note:
This API call is meant for internal bridging operations.

Definition at line 279 of file bridge.c.

References ast_frdup(), and bridge_queue_action_nodup().

Referenced by bridge_dissolve().

00280 {
00281    struct ast_frame *dup;
00282 
00283    dup = ast_frdup(action);
00284    if (!dup) {
00285       return -1;
00286    }
00287    bridge_queue_action_nodup(bridge, dup);
00288    return 0;
00289 }

int ast_bridge_queue_everyone_else ( struct ast_bridge bridge,
struct ast_bridge_channel bridge_channel,
struct ast_frame frame 
)

Queue the given frame to everyone else.

Since:
12.0.0
Parameters:
bridge What bridge to distribute frame.
bridge_channel Channel to optionally not pass frame to. (NULL to pass to everyone)
frame Frame to pass.
Note:
This is intended to be called by bridge hooks and bridge technologies.
Return values:
0 Frame written to at least one channel.
-1 Frame written to no channels.

Definition at line 935 of file bridge_channel.c.

References ast_bridge_channel_queue_frame(), AST_FRAME_NULL, AST_LIST_TRAVERSE, ast_bridge::channels, and ast_frame::frametype.

Referenced by bridge_hold(), bridge_ringing(), bridge_unhold(), holding_bridge_write(), native_bridge_write(), native_rtp_bridge_write(), simple_bridge_write(), softmix_bridge_write(), and softmix_bridge_write_video().

00936 {
00937    struct ast_bridge_channel *cur;
00938    int not_written = -1;
00939 
00940    if (frame->frametype == AST_FRAME_NULL) {
00941       /* "Accept" the frame and discard it. */
00942       return 0;
00943    }
00944 
00945    AST_LIST_TRAVERSE(&bridge->channels, cur, entry) {
00946       if (cur == bridge_channel) {
00947          continue;
00948       }
00949       if (!ast_bridge_channel_queue_frame(cur, frame)) {
00950          not_written = 0;
00951       }
00952    }
00953    return not_written;
00954 }

int ast_bridge_remove ( struct ast_bridge bridge,
struct ast_channel chan 
)

Remove a channel from a bridge.

Parameters:
bridge Bridge that the channel is to be removed from
chan Channel to remove
Return values:
0 on success
-1 on failure
Example usage:

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

References ast_bridge_channel_leave_bridge(), ast_bridge_lock, ast_bridge_unlock, AST_CAUSE_NORMAL_CLEARING, BRIDGE_CHANNEL_STATE_END_NO_DISSOLVE, and bridge_find_channel().

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

01772 {
01773    struct ast_bridge_channel *bridge_channel;
01774 
01775    ast_bridge_lock(bridge);
01776 
01777    /* Try to find the channel that we want to remove */
01778    if (!(bridge_channel = bridge_find_channel(bridge, chan))) {
01779       ast_bridge_unlock(bridge);
01780       return -1;
01781    }
01782 
01783    ast_bridge_channel_leave_bridge(bridge_channel,
01784       BRIDGE_CHANNEL_STATE_END_NO_DISSOLVE, AST_CAUSE_NORMAL_CLEARING);
01785 
01786    ast_bridge_unlock(bridge);
01787 
01788    return 0;
01789 }

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

References ast_bridge_lock, ast_bridge_unlock, AST_BRIDGE_VIDEO_MODE_NONE, 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_talker_src_data::chan_vsrc, ast_bridge_video_single_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 handle_video_on_exit().

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:
bridge Channel to change the sample rate on.
sample_rate the 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 3540 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().

03541 {
03542    ast_bridge_lock(bridge);
03543    bridge->softmix.internal_sample_rate = sample_rate;
03544    ast_bridge_unlock(bridge);
03545 }

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:
bridge Channel to change the sample rate on.
mixing_interval the 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 3533 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().

03534 {
03535    ast_bridge_lock(bridge);
03536    bridge->softmix.internal_mixing_interval = mixing_interval;
03537    ast_bridge_unlock(bridge);
03538 }

void ast_bridge_set_single_src_video_mode ( struct ast_bridge bridge,
struct ast_channel video_src_chan 
)

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

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

Referenced by handle_video_on_exit(), and join_conference_bridge().

03581 {
03582    ast_bridge_lock(bridge);
03583    cleanup_video_mode(bridge);
03584    bridge->softmix.video_mode.mode = AST_BRIDGE_VIDEO_MODE_TALKER_SRC;
03585    ast_test_suite_event_notify("BRIDGE_VIDEO_MODE", "Message: video mode set to talker source\r\nVideo Mode: %u",
03586       bridge->softmix.video_mode.mode);
03587    ast_bridge_unlock(bridge);
03588 }

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:
chan Channel the variable is being set for
value Value the variable is being set to
is_attended false set BLINDTRANSFER and unset ATTENDEDTRANSFER true set ATTENDEDTRANSFER and unset BLINDTRANSFER

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

04049 {
04050    char *writevar;
04051    char *erasevar;
04052 
04053    if (attended) {
04054       writevar = ATTENDEDTRANSFER;
04055       erasevar = BLINDTRANSFER;
04056    } else {
04057       writevar = BLINDTRANSFER;
04058       erasevar = ATTENDEDTRANSFER;
04059    }
04060 
04061    pbx_builtin_setvar_helper(chan, writevar, value);
04062    pbx_builtin_setvar_helper(chan, erasevar, NULL);
04063 }

int ast_bridge_suspend ( struct ast_bridge bridge,
struct ast_channel chan 
)

Suspend a channel temporarily from a bridge.

Parameters:
bridge Bridge to suspend the channel from
chan Channel to suspend
Return values:
0 on success
-1 on 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 2837 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().

02838 {
02839    struct ast_bridge_channel *bridge_channel;
02840 /* XXX ASTERISK-21271 the case of a disolved bridge while channel is suspended is not handled. */
02841 /* XXX ASTERISK-21271 suspend/unsuspend needs to be rethought. The caller must block until it has successfully suspended the channel for temporary control. */
02842 /* 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. */
02843 
02844    ast_bridge_lock(bridge);
02845 
02846    if (!(bridge_channel = bridge_find_channel(bridge, chan))) {
02847       ast_bridge_unlock(bridge);
02848       return -1;
02849    }
02850 
02851    bridge_channel_internal_suspend_nolock(bridge_channel);
02852 
02853    ast_bridge_unlock(bridge);
02854 
02855    return 0;
02856 }

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_transferee Transferer channel on initial call (presumably bridged to transferee)
to_transfer_target Transferer channel on consultation call (presumably bridged to transfer target)
Returns:
The success or failure of the attended transfer

Definition at line 4373 of file bridge.c.

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

04375 {
04376    RAII_VAR(struct ast_bridge *, to_transferee_bridge, NULL, ao2_cleanup);
04377    RAII_VAR(struct ast_bridge *, to_target_bridge, NULL, ao2_cleanup);
04378    RAII_VAR(struct ast_bridge_channel *, to_transferee_bridge_channel, NULL, ao2_cleanup);
04379    RAII_VAR(struct ast_bridge_channel *, to_target_bridge_channel, NULL, ao2_cleanup);
04380    RAII_VAR(struct ao2_container *, channels, NULL, ao2_cleanup);
04381    RAII_VAR(struct ast_channel *, transferee, NULL, ao2_cleanup);
04382    RAII_VAR(struct ast_attended_transfer_message *, transfer_msg, NULL, ao2_cleanup);
04383    struct ast_bridge *the_bridge = NULL;
04384    struct ast_channel *chan_bridged;
04385    struct ast_channel *chan_unbridged;
04386    int transfer_prohibited;
04387    int do_bridge_transfer;
04388    enum ast_transfer_result res;
04389    const char *app = NULL;
04390 
04391    to_transferee_bridge = acquire_bridge(to_transferee);
04392    to_target_bridge = acquire_bridge(to_transfer_target);
04393 
04394    transfer_msg = ast_attended_transfer_message_create(1, to_transferee, to_transferee_bridge,
04395          to_transfer_target, to_target_bridge, NULL, NULL);
04396    if (!transfer_msg) {
04397       ast_log(LOG_ERROR, "Unable to create Stasis publication for attended transfer from %s\n",
04398             ast_channel_name(to_transferee));
04399       return AST_BRIDGE_TRANSFER_FAIL;
04400    }
04401 
04402    /* They can't both be unbridged, you silly goose! */
04403    if (!to_transferee_bridge && !to_target_bridge) {
04404       res = AST_BRIDGE_TRANSFER_INVALID;
04405       goto end;
04406    }
04407 
04408    ast_channel_lock(to_transferee);
04409    to_transferee_bridge_channel = ast_channel_get_bridge_channel(to_transferee);
04410    ast_channel_unlock(to_transferee);
04411 
04412    ast_channel_lock(to_transfer_target);
04413    to_target_bridge_channel = ast_channel_get_bridge_channel(to_transfer_target);
04414    ast_channel_unlock(to_transfer_target);
04415 
04416    if (to_transferee_bridge_channel) {
04417       /* Take off hold if they are on hold. */
04418       ast_bridge_channel_write_unhold(to_transferee_bridge_channel);
04419    }
04420 
04421    if (to_target_bridge_channel) {
04422       const char *target_complete_sound;
04423 
04424       /* Take off hold if they are on hold. */
04425       ast_bridge_channel_write_unhold(to_target_bridge_channel);
04426 
04427       /* Is there a courtesy sound to play to the target? */
04428       ast_channel_lock(to_transfer_target);
04429       target_complete_sound = pbx_builtin_getvar_helper(to_transfer_target,
04430          "ATTENDED_TRANSFER_COMPLETE_SOUND");
04431       if (!ast_strlen_zero(target_complete_sound)) {
04432          target_complete_sound = ast_strdupa(target_complete_sound);
04433       } else {
04434          target_complete_sound = NULL;
04435       }
04436       ast_channel_unlock(to_transfer_target);
04437       if (!target_complete_sound) {
04438          ast_channel_lock(to_transferee);
04439          target_complete_sound = pbx_builtin_getvar_helper(to_transferee,
04440             "ATTENDED_TRANSFER_COMPLETE_SOUND");
04441          if (!ast_strlen_zero(target_complete_sound)) {
04442             target_complete_sound = ast_strdupa(target_complete_sound);
04443          } else {
04444             target_complete_sound = NULL;
04445          }
04446          ast_channel_unlock(to_transferee);
04447       }
04448       if (target_complete_sound) {
04449          ast_bridge_channel_write_playfile(to_target_bridge_channel, NULL,
04450             target_complete_sound, NULL);
04451       }
04452    }
04453 
04454    /* Let's get the easy one out of the way first */
04455    if (to_transferee_bridge && to_target_bridge) {
04456 
04457       if (!to_transferee_bridge_channel || !to_target_bridge_channel) {
04458          res = AST_BRIDGE_TRANSFER_INVALID;
04459          goto end;
04460       }
04461 
04462       ast_bridge_lock_both(to_transferee_bridge, to_target_bridge);
04463       res = two_bridge_attended_transfer(to_transferee, to_transferee_bridge_channel,
04464             to_transfer_target, to_target_bridge_channel,
04465             to_transferee_bridge, to_target_bridge, transfer_msg);
04466       ast_bridge_unlock(to_transferee_bridge);
04467       ast_bridge_unlock(to_target_bridge);
04468 
04469       ast_softhangup(to_transfer_target, AST_SOFTHANGUP_DEV);
04470       goto end;
04471    }
04472 
04473    the_bridge = to_transferee_bridge ?: to_target_bridge;
04474    chan_bridged = to_transferee_bridge ? to_transferee : to_transfer_target;
04475    chan_unbridged = to_transferee_bridge ? to_transfer_target : to_transferee;
04476 
04477    {
04478       int chan_count;
04479       SCOPED_LOCK(lock, the_bridge, ast_bridge_lock, ast_bridge_unlock);
04480 
04481       channels = ast_bridge_peers_nolock(the_bridge);
04482       if (!channels) {
04483          res = AST_BRIDGE_TRANSFER_FAIL;
04484          goto end;
04485       }
04486       chan_count = ao2_container_count(channels);
04487       if (chan_count <= 1) {
04488          res = AST_BRIDGE_TRANSFER_INVALID;
04489          goto end;
04490       }
04491       transfer_prohibited = ast_test_flag(&the_bridge->feature_flags,
04492             AST_BRIDGE_FLAG_TRANSFER_PROHIBITED);
04493       do_bridge_transfer = ast_test_flag(&the_bridge->feature_flags,
04494             AST_BRIDGE_FLAG_TRANSFER_BRIDGE_ONLY) ||
04495             chan_count > 2;
04496    }
04497 
04498    if (transfer_prohibited) {
04499       res = AST_BRIDGE_TRANSFER_NOT_PERMITTED;
04500       goto end;
04501    }
04502 
04503    set_transfer_variables_all(to_transferee, channels, 1);
04504 
04505    if (do_bridge_transfer) {
04506       ast_bridge_lock(the_bridge);
04507       res = attended_transfer_bridge(chan_bridged, chan_unbridged, the_bridge, NULL, transfer_msg);
04508       ast_bridge_unlock(the_bridge);
04509       goto end;
04510    }
04511 
04512    transferee = get_transferee(channels, chan_bridged);
04513    if (!transferee) {
04514       res = AST_BRIDGE_TRANSFER_FAIL;
04515       goto end;
04516    }
04517 
04518    app = ast_strdupa(ast_channel_appl(chan_unbridged));
04519    if (bridge_channel_internal_queue_attended_transfer(transferee, chan_unbridged)) {
04520       res = AST_BRIDGE_TRANSFER_FAIL;
04521       goto end;
04522    }
04523 
04524    ast_bridge_remove(the_bridge, chan_bridged);
04525 
04526    ast_attended_transfer_message_add_app(transfer_msg, app, NULL);
04527    res = AST_BRIDGE_TRANSFER_SUCCESS;
04528 
04529 end:
04530    transfer_msg->result = res;
04531    ast_bridge_publish_attended_transfer(transfer_msg);
04532    return res;
04533 }

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_external Indicates that transfer was initiated externally
transferer The channel performing the blind transfer
exten The dialplan extension to send the call to
context The dialplan context to send the call to
new_channel_cb A callback to be called on the channel that will be executing dialplan
user_data Argument for new_channel_cb
Returns:
The success or failure result of the blind transfer

Definition at line 4121 of file bridge.c.

References acquire_bridge(), 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_FAIL, AST_BRIDGE_TRANSFER_INVALID, AST_BRIDGE_TRANSFER_NOT_PERMITTED, AST_BRIDGE_TRANSFER_SUCCESS, ast_bridge_unlock, ast_channel_cleanup, ast_channel_get_bridge_channel(), ast_channel_lock, ast_channel_name(), ast_channel_snapshot_get_latest(), ast_channel_uniqueid(), ast_channel_unlock, ast_log, ast_test_flag, blind_transfer_bridge(), bridge_channel_internal_queue_blind_transfer(), channels, 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(), console_transfer(), feature_blind_transfer(), handle_request_refer(), refer_incoming_attended_request(), refer_incoming_blind_request(), skinny_transfer_blind(), and socket_process_helper().

04124 {
04125    RAII_VAR(struct ast_bridge *, bridge, NULL, ao2_cleanup);
04126    RAII_VAR(struct ast_bridge_channel *, bridge_channel, NULL, ao2_cleanup);
04127    RAII_VAR(struct ao2_container *, channels, NULL, ao2_cleanup);
04128    RAII_VAR(struct ast_channel *, transferee, NULL, ast_channel_cleanup);
04129    RAII_VAR(struct transfer_channel_data *, user_data_wrapper, NULL, ao2_cleanup);
04130    RAII_VAR(struct ast_blind_transfer_message *, transfer_message, NULL, ao2_cleanup);
04131    int do_bridge_transfer;
04132    int transfer_prohibited;
04133    enum ast_transfer_result transfer_result;
04134 
04135    transfer_message = ast_blind_transfer_message_create(is_external, transferer, exten, context);
04136    if (!transfer_message) {
04137       /* Out of memory. Not even possible to publish a Stasis message about the
04138        * failure
04139        */
04140       ast_log(LOG_ERROR, "Unable to allocate memory for blind transfer publication from %s\n",
04141             ast_channel_name(transferer));
04142       return AST_BRIDGE_TRANSFER_FAIL;
04143    }
04144 
04145    bridge = acquire_bridge(transferer);
04146    if (!bridge) {
04147       transfer_result = AST_BRIDGE_TRANSFER_INVALID;
04148       goto publish;
04149    }
04150 
04151    ast_bridge_lock(bridge);
04152    transfer_message->bridge = ast_bridge_snapshot_create(bridge);
04153    ast_bridge_unlock(bridge);
04154    if (!transfer_message->bridge) {
04155       transfer_result = AST_BRIDGE_TRANSFER_FAIL;
04156       goto publish;
04157    }
04158 
04159    transferee = ast_bridge_peer(bridge, transferer);
04160    if (transferee) {
04161       transfer_message->transferee = ast_channel_snapshot_get_latest(ast_channel_uniqueid(transferee));
04162       if (!transfer_message->transferee) {
04163          transfer_result = AST_BRIDGE_TRANSFER_FAIL;
04164          goto publish;
04165       }
04166    }
04167 
04168    ast_channel_lock(transferer);
04169    bridge_channel = ast_channel_get_bridge_channel(transferer);
04170    ast_channel_unlock(transferer);
04171    if (!bridge_channel) {
04172       transfer_result = AST_BRIDGE_TRANSFER_INVALID;
04173       goto publish;
04174    }
04175 
04176    user_data_wrapper = ao2_alloc(sizeof(*user_data_wrapper), NULL);
04177    if (!user_data_wrapper) {
04178       transfer_result = AST_BRIDGE_TRANSFER_FAIL;
04179       goto publish;
04180    }
04181 
04182    user_data_wrapper->data = user_data;
04183 
04184    /* Take off hold if they are on hold. */
04185    ast_bridge_channel_write_unhold(bridge_channel);
04186 
04187    transfer_result = try_parking(transferer, context, exten, new_channel_cb, user_data_wrapper);
04188    if (transfer_result == AST_BRIDGE_TRANSFER_SUCCESS) {
04189       goto publish;
04190    }
04191 
04192    /* Since parking didn't take control of the user_data_wrapper, we are just going to raise the completed flag now. */
04193    user_data_wrapper->completed = 1;
04194 
04195    {
04196       SCOPED_LOCK(lock, bridge, ast_bridge_lock, ast_bridge_unlock);
04197 
04198       channels = ast_bridge_peers_nolock(bridge);
04199       if (!channels) {
04200          transfer_result = AST_BRIDGE_TRANSFER_FAIL;
04201          goto publish;
04202       }
04203       if (ao2_container_count(channels) <= 1) {
04204          transfer_result = AST_BRIDGE_TRANSFER_INVALID;
04205          goto publish;
04206       }
04207       transfer_prohibited = ast_test_flag(&bridge->feature_flags,
04208             AST_BRIDGE_FLAG_TRANSFER_PROHIBITED);
04209       do_bridge_transfer = ast_test_flag(&bridge->feature_flags,
04210             AST_BRIDGE_FLAG_TRANSFER_BRIDGE_ONLY) ||
04211             ao2_container_count(channels) > 2;
04212    }
04213 
04214    if (transfer_prohibited) {
04215       transfer_result = AST_BRIDGE_TRANSFER_NOT_PERMITTED;
04216       goto publish;
04217    }
04218 
04219    set_transfer_variables_all(transferer, channels, 0);
04220 
04221    if (do_bridge_transfer) {
04222       transfer_result = blind_transfer_bridge(is_external, transferer, bridge,
04223          exten, context, transferee, new_channel_cb, user_data_wrapper, transfer_message);
04224       goto publish;
04225    }
04226 
04227    /* Reaching this portion means that we're dealing with a two-party bridge */
04228 
04229    if (!transferee) {
04230       transfer_result = AST_BRIDGE_TRANSFER_FAIL;
04231       goto publish;
04232    }
04233 
04234    if (bridge_channel_internal_queue_blind_transfer(transferee, exten, context,
04235             new_channel_cb, user_data_wrapper)) {
04236       transfer_result = AST_BRIDGE_TRANSFER_FAIL;
04237       goto publish;
04238    }
04239 
04240    ast_bridge_remove(bridge, transferer);
04241    transfer_result = AST_BRIDGE_TRANSFER_SUCCESS;
04242 
04243 publish:
04244    transfer_message->result = transfer_result;
04245    ast_bridge_publish_blind_transfer(transfer_message);
04246    return transfer_result;
04247 }

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:
chan Unreal channel writing a frame into the channel driver.
peer Other unreal channel in the pair.
pvt Private 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:
0 if unreal channels were not optimized out.
non-zero if unreal channels were optimized out.

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

02738 {
02739    struct ast_bridge *chan_bridge;
02740    struct ast_bridge *peer_bridge;
02741    struct ast_bridge_channel *chan_bridge_channel;
02742    struct ast_bridge_channel *peer_bridge_channel;
02743    int res = 0;
02744 
02745    chan_bridge = optimize_lock_chan_stack(chan);
02746    if (!chan_bridge) {
02747       return res;
02748    }
02749    chan_bridge_channel = ast_channel_internal_bridge_channel(chan);
02750 
02751    peer_bridge = optimize_lock_peer_stack(peer);
02752    if (peer_bridge) {
02753       peer_bridge_channel = ast_channel_internal_bridge_channel(peer);
02754 
02755       res = try_swap_optimize_out(chan_bridge, chan_bridge_channel,
02756          peer_bridge, peer_bridge_channel, pvt);
02757       if (!res) {
02758          res = try_merge_optimize_out(chan_bridge, chan_bridge_channel,
02759             peer_bridge, peer_bridge_channel, pvt);
02760       } else if (0 < res) {
02761          res = 0;
02762       }
02763 
02764       /* Release peer locks. */
02765       ast_bridge_unlock(peer_bridge);
02766       ast_bridge_channel_unlock(peer_bridge_channel);
02767       ast_channel_unlock(peer);
02768    }
02769 
02770    /* Release chan locks. */
02771    ast_bridge_unlock(chan_bridge);
02772    ast_bridge_channel_unlock(chan_bridge_channel);
02773 
02774    return res;
02775 }

int ast_bridge_unsuspend ( struct ast_bridge bridge,
struct ast_channel chan 
)

Unsuspend a channel from a bridge.

Parameters:
bridge Bridge to unsuspend the channel from
chan Channel to unsuspend
Return values:
0 on success
-1 on 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 2858 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().

02859 {
02860    struct ast_bridge_channel *bridge_channel;
02861 /* XXX ASTERISK-21271 the case of a disolved bridge while channel is suspended is not handled. */
02862 
02863    ast_bridge_lock(bridge);
02864 
02865    if (!(bridge_channel = bridge_find_channel(bridge, chan))) {
02866       ast_bridge_unlock(bridge);
02867       return -1;
02868    }
02869 
02870    bridge_channel_internal_unsuspend_nolock(bridge_channel);
02871 
02872    ast_bridge_unlock(bridge);
02873 
02874    return 0;
02875 }

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

Update information about talker energy for talker src video mode.

Definition at line 3590 of file bridge.c.

References ast_bridge_lock, ast_bridge_unlock, ast_channel_name(), ast_channel_nativeformats(), ast_channel_ref, ast_channel_unref, AST_CONTROL_VIDUPDATE, ast_format_cap_has_type(), ast_indicate(), AST_MEDIA_TYPE_VIDEO, ast_test_suite_event_notify, 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::softmix, ast_bridge_video_mode::talker_src_data, and ast_bridge_softmix::video_mode.

Referenced by softmix_bridge_write_video().

03591 {
03592    struct ast_bridge_video_talker_src_data *data;
03593 
03594    /* If the channel doesn't support video, we don't care about it */
03595    if (!ast_format_cap_has_type(ast_channel_nativeformats(chan), AST_MEDIA_TYPE_VIDEO)) {
03596       return;
03597    }
03598 
03599    ast_bridge_lock(bridge);
03600    data = &bridge->softmix.video_mode.mode_data.talker_src_data;
03601 
03602    if (data->chan_vsrc == chan) {
03603       data->average_talking_energy = talker_energy;
03604    } else if ((data->average_talking_energy < talker_energy) && is_keyframe) {
03605       if (data->chan_old_vsrc) {
03606          ast_channel_unref(data->chan_old_vsrc);
03607       }
03608       if (data->chan_vsrc) {
03609          data->chan_old_vsrc = data->chan_vsrc;
03610          ast_indicate(data->chan_old_vsrc, AST_CONTROL_VIDUPDATE);
03611       }
03612       data->chan_vsrc = ast_channel_ref(chan);
03613       data->average_talking_energy = talker_energy;
03614       ast_test_suite_event_notify("BRIDGE_VIDEO_SRC", "Message: video source updated\r\nVideo Channel: %s", ast_channel_name(data->chan_vsrc));
03615       ast_indicate(data->chan_vsrc, AST_CONTROL_VIDUPDATE);
03616    } else if ((data->average_talking_energy < talker_energy) && !is_keyframe) {
03617       ast_indicate(chan, AST_CONTROL_VIDUPDATE);
03618    } else if (!data->chan_vsrc && is_keyframe) {
03619       data->chan_vsrc = ast_channel_ref(chan);
03620       data->average_talking_energy = talker_energy;
03621       ast_test_suite_event_notify("BRIDGE_VIDEO_SRC", "Message: video source updated\r\nVideo Channel: %s", ast_channel_name(data->chan_vsrc));
03622       ast_indicate(chan, AST_CONTROL_VIDUPDATE);
03623    } else if (!data->chan_old_vsrc && is_keyframe) {
03624       data->chan_old_vsrc = ast_channel_ref(chan);
03625       ast_indicate(chan, AST_CONTROL_VIDUPDATE);
03626    }
03627    ast_bridge_unlock(bridge);
03628 }

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_bridge First bridge being tested
peer_bridge Second 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 2777 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().

02779 {
02780    struct merge_direction merge;
02781 
02782    if (!bridge_allows_optimization(chan_bridge) || !bridge_allows_optimization(peer_bridge)) {
02783       return AST_BRIDGE_OPTIMIZE_PROHIBITED;
02784    }
02785 
02786    switch (bridges_allow_swap_optimization(chan_bridge, peer_bridge)) {
02787    case SWAP_TO_CHAN_BRIDGE:
02788       return AST_BRIDGE_OPTIMIZE_SWAP_TO_CHAN_BRIDGE;
02789    case SWAP_TO_PEER_BRIDGE:
02790       return AST_BRIDGE_OPTIMIZE_SWAP_TO_PEER_BRIDGE;
02791    case SWAP_PROHIBITED:
02792    default:
02793       break;
02794    }
02795 
02796    /* Two channels will be kicked from the bridges, the unreal;1 and unreal;2 channels */
02797    if (bridges_allow_merge_optimization(chan_bridge, peer_bridge, 2, &merge) != MERGE_ALLOWED) {
02798       return AST_BRIDGE_OPTIMIZE_PROHIBITED;
02799    }
02800 
02801    if (merge.dest == chan_bridge) {
02802       return AST_BRIDGE_OPTIMIZE_MERGE_TO_CHAN_BRIDGE;
02803    } else {
02804       return AST_BRIDGE_OPTIMIZE_MERGE_TO_PEER_BRIDGE;
02805    }
02806 }


Variable Documentation


Generated on Thu Apr 16 06:29:07 2015 for Asterisk - The Open Source Telephony Project by  doxygen 1.5.6