bridge_internal.h File Reference

Private Bridging API. More...

This graph shows which files directly or indirectly include this file:

Go to the source code of this file.

Functions

struct ast_bridgebridge_alloc (size_t size, const struct ast_bridge_methods *v_table)
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.
void bridge_dissolve (struct ast_bridge *bridge, int cause)
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)
struct ast_bridge_channelbridge_find_channel (struct ast_bridge *bridge, struct ast_channel *chan)
void bridge_merge_inhibit_nolock (struct ast_bridge *bridge, int request)
void bridge_reconfigured (struct ast_bridge *bridge, unsigned int colp_update)
struct ast_bridgebridge_register (struct ast_bridge *bridge)
 Register the new bridge with the system.


Detailed Description

Private Bridging API.

Functions in this file are intended to be used by the Bridging API, bridge mixing technologies, and bridge sub-classes. Users of bridges that do not fit those three categories should *not* use the API defined in this file.

Author:
Mark Michelson <mmichelson@digium.com>
See Also:

Definition in file bridge_internal.h.


Function Documentation

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

Definition at line 704 of file bridge.c.

References ao2_alloc, ao2_cleanup, ast_assert, ast_log, ast_string_field_init, ast_bridge_methods::destroy, destroy_bridge(), ast_bridge_methods::dissolving, ast_bridge_methods::get_merge_priority, LOG_ERROR, 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().

00705 {
00706    struct ast_bridge *bridge;
00707 
00708    /* Check v_table that all methods are present. */
00709    if (!v_table
00710       || !v_table->name
00711       || !v_table->destroy
00712       || !v_table->dissolving
00713       || !v_table->push
00714       || !v_table->pull
00715       || !v_table->notify_masquerade
00716       || !v_table->get_merge_priority) {
00717       ast_log(LOG_ERROR, "Virtual method table for bridge class %s not complete.\n",
00718          v_table && v_table->name ? v_table->name : "<unknown>");
00719       ast_assert(0);
00720       return NULL;
00721    }
00722 
00723    bridge = ao2_alloc(size, destroy_bridge);
00724    if (!bridge) {
00725       return NULL;
00726    }
00727 
00728    if (ast_string_field_init(bridge, 80)) {
00729       ao2_cleanup(bridge);
00730       return NULL;
00731    }
00732 
00733    bridge->v_table = v_table;
00734 
00735    return bridge;
00736 }

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 
) [read]

Initialize the base class of the bridge.

Parameters:
self Bridge to operate upon. (Tolerates a NULL pointer)
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:
self on success
NULL on 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 738 of file bridge.c.

References ao2_ref, ast_bridge_topic(), ast_debug, ast_log, ast_set_flag, ast_string_field_set, ast_strlen_zero, 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().

00739 {
00740    char uuid_hold[AST_UUID_STR_LEN];
00741 
00742    if (!self) {
00743       return NULL;
00744    }
00745 
00746    if (!ast_strlen_zero(id)) {
00747       ast_string_field_set(self, uniqueid, id);
00748    } else {
00749       ast_uuid_generate_str(uuid_hold, AST_UUID_STR_LEN);
00750       ast_string_field_set(self, uniqueid, uuid_hold);
00751    }
00752    ast_string_field_set(self, creator, creator);
00753    if (!ast_strlen_zero(creator)) {
00754       ast_string_field_set(self, name, name);
00755    }
00756 
00757    ast_set_flag(&self->feature_flags, flags);
00758    self->allowed_capabilities = capabilities;
00759 
00760    if (bridge_topics_init(self) != 0) {
00761       ast_log(LOG_WARNING, "Bridge %s: Could not initialize topics\n",
00762          self->uniqueid);
00763       ao2_ref(self, -1);
00764       return NULL;
00765    }
00766 
00767    /* Use our helper function to find the "best" bridge technology. */
00768    self->technology = find_best_technology(capabilities, self);
00769    if (!self->technology) {
00770       ast_log(LOG_WARNING, "Bridge %s: Could not create class %s.  No technology to support it.\n",
00771          self->uniqueid, self->v_table->name);
00772       ao2_ref(self, -1);
00773       return NULL;
00774    }
00775 
00776    /* Pass off the bridge to the technology to manipulate if needed */
00777    ast_debug(1, "Bridge %s: calling %s technology constructor\n",
00778       self->uniqueid, self->technology->name);
00779    if (self->technology->create && self->technology->create(self)) {
00780       ast_log(LOG_WARNING, "Bridge %s: failed to setup bridge technology %s\n",
00781          self->uniqueid, self->technology->name);
00782       ao2_ref(self, -1);
00783       return NULL;
00784    }
00785    ast_debug(1, "Bridge %s: calling %s technology start\n",
00786       self->uniqueid, self->technology->name);
00787    if (self->technology->start && self->technology->start(self)) {
00788       ast_log(LOG_WARNING, "Bridge %s: failed to start bridge technology %s\n",
00789          self->uniqueid, self->technology->name);
00790       ao2_ref(self, -1);
00791       return NULL;
00792    }
00793 
00794    if (!ast_bridge_topic(self)) {
00795       ao2_ref(self, -1);
00796       return NULL;
00797    }
00798 
00799    return self;
00800 }

void bridge_dissolve ( struct ast_bridge bridge,
int  cause 
)

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

00292 {
00293    struct ast_bridge_channel *bridge_channel;
00294    struct ast_frame action = {
00295       .frametype = AST_FRAME_BRIDGE_ACTION,
00296       .subclass.integer = BRIDGE_CHANNEL_ACTION_DEFERRED_DISSOLVING,
00297    };
00298 
00299    if (bridge->dissolved) {
00300       return;
00301    }
00302    bridge->dissolved = 1;
00303 
00304    if (cause <= 0) {
00305       cause = AST_CAUSE_NORMAL_CLEARING;
00306    }
00307    bridge->cause = cause;
00308 
00309    ast_debug(1, "Bridge %s: dissolving bridge with cause %d(%s)\n",
00310       bridge->uniqueid, cause, ast_cause2str(cause));
00311 
00312    AST_LIST_TRAVERSE(&bridge->channels, bridge_channel, entry) {
00313       ast_bridge_channel_leave_bridge(bridge_channel,
00314          BRIDGE_CHANNEL_STATE_END_NO_DISSOLVE, cause);
00315    }
00316 
00317    /* Must defer dissolving bridge because it is already locked. */
00318    ast_bridge_queue_action(bridge, &action);
00319 }

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

01869 {
01870    struct ast_bridge_channel *bridge_channel;
01871    unsigned int idx;
01872 
01873    ast_debug(1, "Merging bridge %s into bridge %s\n",
01874       src_bridge->uniqueid, dst_bridge->uniqueid);
01875 
01876    ast_bridge_publish_merge(dst_bridge, src_bridge);
01877 
01878    /*
01879     * Move channels from src_bridge over to dst_bridge.
01880     *
01881     * We must use AST_LIST_TRAVERSE_SAFE_BEGIN() because
01882     * bridge_channel_internal_pull() alters the list we are traversing.
01883     */
01884    AST_LIST_TRAVERSE_SAFE_BEGIN(&src_bridge->channels, bridge_channel, entry) {
01885       if (bridge_channel->state != BRIDGE_CHANNEL_STATE_WAIT) {
01886          /*
01887           * The channel is already leaving let it leave normally because
01888           * pulling it may delete hooks that should run for this channel.
01889           */
01890          continue;
01891       }
01892       if (ast_test_flag(&bridge_channel->features->feature_flags,
01893          AST_BRIDGE_CHANNEL_FLAG_IMMOVABLE)) {
01894          continue;
01895       }
01896 
01897       if (kick_me) {
01898          for (idx = 0; idx < num_kick; ++idx) {
01899             if (bridge_channel == kick_me[idx]) {
01900                ast_bridge_channel_leave_bridge(bridge_channel,
01901                   BRIDGE_CHANNEL_STATE_END_NO_DISSOLVE, AST_CAUSE_NORMAL_CLEARING);
01902                break;
01903             }
01904          }
01905       }
01906       bridge_channel_internal_pull(bridge_channel);
01907       if (bridge_channel->state != BRIDGE_CHANNEL_STATE_WAIT) {
01908          /*
01909           * The channel died as a result of being pulled or it was
01910           * kicked.  Leave it pointing to the original bridge.
01911           */
01912          continue;
01913       }
01914 
01915       bridge_channel_moving(bridge_channel, bridge_channel->bridge, dst_bridge);
01916 
01917       /* Point to new bridge.*/
01918       bridge_channel_change_bridge(bridge_channel, dst_bridge);
01919 
01920       if (bridge_channel_internal_push(bridge_channel)) {
01921          ast_bridge_features_remove(bridge_channel->features,
01922             AST_BRIDGE_HOOK_REMOVE_ON_PULL);
01923          ast_bridge_channel_leave_bridge(bridge_channel,
01924             BRIDGE_CHANNEL_STATE_END_NO_DISSOLVE, bridge_channel->bridge->cause);
01925       }
01926    }
01927    AST_LIST_TRAVERSE_SAFE_END;
01928 
01929    if (kick_me) {
01930       /*
01931        * Now we can kick any channels in the dst_bridge without
01932        * potentially dissolving the bridge.
01933        */
01934       for (idx = 0; idx < num_kick; ++idx) {
01935          bridge_channel = kick_me[idx];
01936          ast_bridge_channel_lock(bridge_channel);
01937          if (bridge_channel->state == BRIDGE_CHANNEL_STATE_WAIT) {
01938             ast_bridge_channel_leave_bridge_nolock(bridge_channel,
01939                BRIDGE_CHANNEL_STATE_END_NO_DISSOLVE, AST_CAUSE_NORMAL_CLEARING);
01940             bridge_channel_internal_pull(bridge_channel);
01941          }
01942          ast_bridge_channel_unlock(bridge_channel);
01943       }
01944    }
01945 
01946    bridge_reconfigured(dst_bridge, !optimized);
01947    bridge_reconfigured(src_bridge, !optimized);
01948 
01949    ast_debug(1, "Merged bridge %s into bridge %s\n",
01950       src_bridge->uniqueid, dst_bridge->uniqueid);
01951 }

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

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

02135 {
02136    struct ast_bridge *orig_bridge;
02137    int was_in_bridge;
02138    int res = 0;
02139 
02140    if (bridge_channel->swap) {
02141       ast_debug(1, "Moving %p(%s) into bridge %s swapping with %s\n",
02142          bridge_channel, ast_channel_name(bridge_channel->chan), dst_bridge->uniqueid,
02143          ast_channel_name(bridge_channel->swap));
02144    } else {
02145       ast_debug(1, "Moving %p(%s) into bridge %s\n",
02146          bridge_channel, ast_channel_name(bridge_channel->chan), dst_bridge->uniqueid);
02147    }
02148 
02149    orig_bridge = bridge_channel->bridge;
02150    was_in_bridge = bridge_channel->in_bridge;
02151 
02152    bridge_channel_internal_pull(bridge_channel);
02153    if (bridge_channel->state != BRIDGE_CHANNEL_STATE_WAIT) {
02154       /*
02155        * The channel died as a result of being pulled.  Leave it
02156        * pointing to the original bridge.
02157        *
02158        * Clear out the swap channel pointer.  A ref is not held
02159        * by bridge_channel->swap at this point.
02160        */
02161       bridge_channel->swap = NULL;
02162       bridge_reconfigured(orig_bridge, 0);
02163       return -1;
02164    }
02165 
02166    /* Point to new bridge.*/
02167    ao2_ref(orig_bridge, +1);/* Keep a ref in case the push fails. */
02168    bridge_channel_change_bridge(bridge_channel, dst_bridge);
02169 
02170    bridge_channel_moving(bridge_channel, orig_bridge, dst_bridge);
02171 
02172    if (bridge_channel_internal_push(bridge_channel)) {
02173       /* Try to put the channel back into the original bridge. */
02174       ast_bridge_features_remove(bridge_channel->features,
02175          AST_BRIDGE_HOOK_REMOVE_ON_PULL);
02176       if (attempt_recovery && was_in_bridge) {
02177          /* Point back to original bridge. */
02178          bridge_channel_change_bridge(bridge_channel, orig_bridge);
02179 
02180          if (bridge_channel_internal_push(bridge_channel)) {
02181             ast_bridge_features_remove(bridge_channel->features,
02182                AST_BRIDGE_HOOK_REMOVE_ON_PULL);
02183             ast_bridge_channel_leave_bridge(bridge_channel,
02184                BRIDGE_CHANNEL_STATE_END_NO_DISSOLVE, bridge_channel->bridge->cause);
02185             bridge_channel_settle_owed_events(orig_bridge, bridge_channel);
02186          }
02187       } else {
02188          ast_bridge_channel_leave_bridge(bridge_channel,
02189             BRIDGE_CHANNEL_STATE_END_NO_DISSOLVE, bridge_channel->bridge->cause);
02190          bridge_channel_settle_owed_events(orig_bridge, bridge_channel);
02191       }
02192       res = -1;
02193    } else {
02194       bridge_channel_settle_owed_events(orig_bridge, bridge_channel);
02195    }
02196 
02197    bridge_reconfigured(dst_bridge, !optimized);
02198    bridge_reconfigured(orig_bridge, !optimized);
02199    ao2_ref(orig_bridge, -1);
02200    return res;
02201 }

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

Definition at line 1441 of file bridge.c.

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

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

01442 {
01443    struct ast_bridge_channel *bridge_channel;
01444 
01445    AST_LIST_TRAVERSE(&bridge->channels, bridge_channel, entry) {
01446       if (bridge_channel->chan == chan) {
01447          break;
01448       }
01449    }
01450 
01451    return bridge_channel;
01452 }

void bridge_merge_inhibit_nolock ( struct ast_bridge bridge,
int  request 
)

Definition at line 2821 of file bridge.c.

References ast_assert, and ast_bridge::inhibit_merge.

Referenced by ast_bridge_channel_merge_inhibit(), and ast_bridge_merge_inhibit().

02822 {
02823    int new_request;
02824 
02825    new_request = bridge->inhibit_merge + request;
02826    ast_assert(0 <= new_request);
02827    bridge->inhibit_merge = new_request;
02828 }

void bridge_reconfigured ( struct ast_bridge bridge,
unsigned int  colp_update 
)

Definition at line 1415 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_internal_join(), bridge_channel_wait(), bridge_do_merge(), and bridge_do_move().

01416 {
01417    if (!bridge->reconfigured) {
01418       return;
01419    }
01420    bridge->reconfigured = 0;
01421    if (ast_test_flag(&bridge->feature_flags, AST_BRIDGE_FLAG_SMART)
01422       && smart_bridge_operation(bridge)) {
01423       /* Smart bridge failed. */
01424       bridge_dissolve(bridge, 0);
01425       return;
01426    }
01427    bridge_complete_join(bridge);
01428 
01429    if (bridge->dissolved) {
01430       return;
01431    }
01432    check_bridge_play_sounds(bridge);
01433    set_bridge_peer_vars(bridge);
01434    ast_bridge_publish_state(bridge);
01435 
01436    if (colp_update) {
01437       bridge_reconfigured_connected_line_update(bridge);
01438    }
01439 }

struct ast_bridge* bridge_register ( struct ast_bridge bridge  )  [read]

Register the new bridge with the system.

Since:
12.0.0
Parameters:
bridge What 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:
bridge on success.
NULL on error.

Definition at line 689 of file bridge.c.

References ao2_link, ast_bridge_destroy(), ast_bridge_lock, ast_bridge_publish_state(), ast_bridge_unlock, 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().

00690 {
00691    if (bridge) {
00692       bridge->construction_completed = 1;
00693       ast_bridge_lock(bridge);
00694       ast_bridge_publish_state(bridge);
00695       ast_bridge_unlock(bridge);
00696       if (!ao2_link(bridges, bridge)) {
00697          ast_bridge_destroy(bridge, 0);
00698          bridge = NULL;
00699       }
00700    }
00701    return bridge;
00702 }


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