bridge_channel_internal.h File Reference

Private Bridging Channel API. More...

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

Go to the source code of this file.

Enumerations

enum  bridge_channel_action_type {
  BRIDGE_CHANNEL_ACTION_DTMF_STREAM, BRIDGE_CHANNEL_ACTION_TALKING_START, BRIDGE_CHANNEL_ACTION_TALKING_STOP, BRIDGE_CHANNEL_ACTION_PLAY_FILE,
  BRIDGE_CHANNEL_ACTION_RUN_APP, BRIDGE_CHANNEL_ACTION_CALLBACK, BRIDGE_CHANNEL_ACTION_PARK, BRIDGE_CHANNEL_ACTION_BLIND_TRANSFER,
  BRIDGE_CHANNEL_ACTION_ATTENDED_TRANSFER, BRIDGE_CHANNEL_ACTION_DEFERRED_TECH_DESTROY = 1000, BRIDGE_CHANNEL_ACTION_DEFERRED_DISSOLVING
}

Functions

struct ast_bridge_channelbridge_channel_internal_alloc (struct ast_bridge *bridge)
int bridge_channel_internal_allows_optimization (struct ast_bridge_channel *bridge_channel)
int bridge_channel_internal_join (struct ast_bridge_channel *bridge_channel)
void bridge_channel_internal_pull (struct ast_bridge_channel *bridge_channel)
int bridge_channel_internal_push (struct ast_bridge_channel *bridge_channel)
int bridge_channel_internal_queue_attended_transfer (struct ast_channel *transferee, struct ast_channel *unbridged_chan)
int bridge_channel_internal_queue_blind_transfer (struct ast_channel *transferee, const char *exten, const char *context, transfer_channel_cb new_channel_cb, void *user_data)
void bridge_channel_internal_suspend_nolock (struct ast_bridge_channel *bridge_channel)
void bridge_channel_internal_unsuspend_nolock (struct ast_bridge_channel *bridge_channel)
void bridge_channel_settle_owed_events (struct ast_bridge *orig_bridge, struct ast_bridge_channel *bridge_channel)


Detailed Description

Private Bridging Channel API.

Author:
Matt Jordan <mjordan@digium.com>
A private API to manipulate channels in a bridge. These can be called on a channel in a bridge by bridge.c. These functions should not be called elsewhere, including by other members of the Bridging API.

See Also:

Definition in file bridge_channel_internal.h.


Enumeration Type Documentation

Enumerator:
BRIDGE_CHANNEL_ACTION_DTMF_STREAM  Bridged channel is to send a DTMF stream out
BRIDGE_CHANNEL_ACTION_TALKING_START  Bridged channel is to indicate talking start
BRIDGE_CHANNEL_ACTION_TALKING_STOP  Bridged channel is to indicate talking stop
BRIDGE_CHANNEL_ACTION_PLAY_FILE  Bridge channel is to play the indicated sound file.
BRIDGE_CHANNEL_ACTION_RUN_APP  Bridge channel is to run the indicated application.
BRIDGE_CHANNEL_ACTION_CALLBACK  Bridge channel is to run the custom callback routine.
BRIDGE_CHANNEL_ACTION_PARK  Bridge channel is to get parked.
BRIDGE_CHANNEL_ACTION_BLIND_TRANSFER  Bridge channel is to execute a blind transfer.
BRIDGE_CHANNEL_ACTION_ATTENDED_TRANSFER  Bridge channel is to execute an attended transfer
BRIDGE_CHANNEL_ACTION_DEFERRED_TECH_DESTROY  Bridge reconfiguration deferred technology destruction.
BRIDGE_CHANNEL_ACTION_DEFERRED_DISSOLVING  Bridge deferred dissolving.

Definition at line 41 of file bridge_channel_internal.h.

00041                                 {
00042    /*! Bridged channel is to send a DTMF stream out */
00043    BRIDGE_CHANNEL_ACTION_DTMF_STREAM,
00044    /*! Bridged channel is to indicate talking start */
00045    BRIDGE_CHANNEL_ACTION_TALKING_START,
00046    /*! Bridged channel is to indicate talking stop */
00047    BRIDGE_CHANNEL_ACTION_TALKING_STOP,
00048    /*! Bridge channel is to play the indicated sound file. */
00049    BRIDGE_CHANNEL_ACTION_PLAY_FILE,
00050    /*! Bridge channel is to run the indicated application. */
00051    BRIDGE_CHANNEL_ACTION_RUN_APP,
00052    /*! Bridge channel is to run the custom callback routine. */
00053    BRIDGE_CHANNEL_ACTION_CALLBACK,
00054    /*! Bridge channel is to get parked. */
00055    BRIDGE_CHANNEL_ACTION_PARK,
00056    /*! Bridge channel is to execute a blind transfer. */
00057    BRIDGE_CHANNEL_ACTION_BLIND_TRANSFER,
00058    /*! Bridge channel is to execute an attended transfer */
00059    BRIDGE_CHANNEL_ACTION_ATTENDED_TRANSFER,
00060 
00061    /*
00062     * Bridge actions put after this comment must never be put onto
00063     * the bridge_channel wr_queue because they have other resources
00064     * that must be freed.
00065     */
00066 
00067    /*! Bridge reconfiguration deferred technology destruction. */
00068    BRIDGE_CHANNEL_ACTION_DEFERRED_TECH_DESTROY = 1000,
00069    /*! Bridge deferred dissolving. */
00070    BRIDGE_CHANNEL_ACTION_DEFERRED_DISSOLVING,
00071 };


Function Documentation

struct ast_bridge_channel* bridge_channel_internal_alloc ( struct ast_bridge bridge  )  [read]

Definition at line 2819 of file bridge_channel.c.

References ast_bridge_channel::alert_pipe, ao2_alloc, ao2_ref, ast_cond_init, ast_bridge_channel::bridge, bridge_channel_destroy(), ast_bridge_channel::cond, NULL, and pipe_init_nonblock().

Referenced by ast_bridge_impart(), and ast_bridge_join().

02820 {
02821    struct ast_bridge_channel *bridge_channel;
02822 
02823    bridge_channel = ao2_alloc(sizeof(struct ast_bridge_channel), bridge_channel_destroy);
02824    if (!bridge_channel) {
02825       return NULL;
02826    }
02827    ast_cond_init(&bridge_channel->cond, NULL);
02828    if (pipe_init_nonblock(bridge_channel->alert_pipe)) {
02829       ao2_ref(bridge_channel, -1);
02830       return NULL;
02831    }
02832    if (bridge) {
02833       bridge_channel->bridge = bridge;
02834       ao2_ref(bridge_channel->bridge, +1);
02835    }
02836 
02837    return bridge_channel;
02838 }

int bridge_channel_internal_allows_optimization ( struct ast_bridge_channel bridge_channel  ) 

Definition at line 2730 of file bridge_channel.c.

References AST_LIST_EMPTY, ast_bridge_channel::in_bridge, and ast_bridge_channel::wr_queue.

Referenced by optimize_lock_chan_stack(), and optimize_lock_peer_stack().

02731 {
02732    return bridge_channel->in_bridge
02733       && AST_LIST_EMPTY(&bridge_channel->wr_queue);
02734 }

int bridge_channel_internal_join ( struct ast_bridge_channel bridge_channel  ) 

Definition at line 2543 of file bridge_channel.c.

References ao2_bump, ao2_t_cleanup, AST_BRIDGE_CAPABILITY_MULTIMIX, ast_bridge_channel_feature_digit(), ast_bridge_channel_kick(), ast_bridge_channel_lock_bridge(), ast_bridge_channel_restore_formats(), ast_bridge_features_merge(), ast_bridge_features_remove(), AST_BRIDGE_HOOK_REMOVE_ON_PULL, AST_BRIDGE_HOOK_TYPE_JOIN, AST_BRIDGE_HOOK_TYPE_LEAVE, ast_bridge_lock, ast_bridge_unlock, ast_channel_end_dtmf(), ast_channel_feature_hooks_get(), ast_channel_flags(), ast_channel_hold_state(), ast_channel_internal_bridge(), ast_channel_internal_bridge_set(), ast_channel_lock, ast_channel_name(), ast_channel_readformat(), ast_channel_sending_dtmf_digit(), ast_channel_sending_dtmf_tv(), ast_channel_unlock, ast_channel_writeformat(), AST_CONTROL_HOLD, AST_CONTROL_SRCCHANGE, AST_CONTROL_UNHOLD, ast_debug, AST_FLAG_BRIDGE_DUAL_REDIRECT_WAIT, AST_FLAG_ZOMBIE, ast_indicate(), ast_jb_enable_for_channel(), ast_read_threadstorage_callid(), ast_test_flag, ast_bridge_channel::bridge, bridge_channel_dissolve_check(), bridge_channel_event_join_leave(), bridge_channel_internal_pull(), bridge_channel_internal_push(), bridge_channel_settle_owed_events(), BRIDGE_CHANNEL_STATE_WAIT, bridge_channel_wait(), bridge_reconfigured(), ast_bridge::callid, ast_bridge_technology::capabilities, ast_bridge::cause, ast_bridge_channel::chan, ast_bridge_channel::features, ast_bridge_channel::inhibit_colp, NULL, ast_bridge_channel::read_format, ast_bridge_channel::state, ast_bridge_channel::swap, ast_bridge::technology, ast_bridge::uniqueid, and ast_bridge_channel::write_format.

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

02544 {
02545    int res = 0;
02546    struct ast_bridge_features *channel_features;
02547    struct ast_channel *swap;
02548 
02549    ast_debug(1, "Bridge %s: %p(%s) is joining\n",
02550       bridge_channel->bridge->uniqueid,
02551       bridge_channel, ast_channel_name(bridge_channel->chan));
02552 
02553    /*
02554     * Directly locking the bridge is safe here because nobody else
02555     * knows about this bridge_channel yet.
02556     */
02557    ast_bridge_lock(bridge_channel->bridge);
02558 
02559    ast_channel_lock(bridge_channel->chan);
02560 
02561    bridge_channel->read_format = ao2_bump(ast_channel_readformat(bridge_channel->chan));
02562    bridge_channel->write_format = ao2_bump(ast_channel_writeformat(bridge_channel->chan));
02563 
02564    /* Make sure we're still good to be put into a bridge */
02565    if (ast_channel_internal_bridge(bridge_channel->chan)
02566       || ast_test_flag(ast_channel_flags(bridge_channel->chan), AST_FLAG_ZOMBIE)) {
02567       ast_channel_unlock(bridge_channel->chan);
02568       ast_bridge_unlock(bridge_channel->bridge);
02569       ast_debug(1, "Bridge %s: %p(%s) failed to join Bridge\n",
02570          bridge_channel->bridge->uniqueid,
02571          bridge_channel,
02572          ast_channel_name(bridge_channel->chan));
02573       return -1;
02574    }
02575    ast_channel_internal_bridge_set(bridge_channel->chan, bridge_channel->bridge);
02576 
02577    /* Attach features requested by the channel */
02578    channel_features = ast_channel_feature_hooks_get(bridge_channel->chan);
02579    if (channel_features) {
02580       ast_bridge_features_merge(bridge_channel->features, channel_features);
02581    }
02582    ast_channel_unlock(bridge_channel->chan);
02583 
02584    /* Add the jitterbuffer if the channel requires it */
02585    ast_jb_enable_for_channel(bridge_channel->chan);
02586 
02587    if (!bridge_channel->bridge->callid) {
02588       bridge_channel->bridge->callid = ast_read_threadstorage_callid();
02589    }
02590 
02591    /* Take the swap channel ref from the bridge_channel struct. */
02592    swap = bridge_channel->swap;
02593 
02594    if (bridge_channel_internal_push(bridge_channel)) {
02595       int cause = bridge_channel->bridge->cause;
02596 
02597       ast_bridge_unlock(bridge_channel->bridge);
02598       ast_bridge_channel_kick(bridge_channel, cause);
02599       ast_bridge_channel_lock_bridge(bridge_channel);
02600       ast_bridge_features_remove(bridge_channel->features,
02601          AST_BRIDGE_HOOK_REMOVE_ON_PULL);
02602       bridge_channel_dissolve_check(bridge_channel);
02603       res = -1;
02604    }
02605    bridge_reconfigured(bridge_channel->bridge, !bridge_channel->inhibit_colp);
02606 
02607    if (bridge_channel->state == BRIDGE_CHANNEL_STATE_WAIT) {
02608       /*
02609        * Indicate a source change since this channel is entering the
02610        * bridge system only if the bridge technology is not MULTIMIX
02611        * capable.  The MULTIMIX technology has already done it.
02612        */
02613       if (!(bridge_channel->bridge->technology->capabilities
02614          & AST_BRIDGE_CAPABILITY_MULTIMIX)) {
02615          ast_indicate(bridge_channel->chan, AST_CONTROL_SRCCHANGE);
02616       }
02617 
02618       ast_bridge_unlock(bridge_channel->bridge);
02619 
02620       /* Must release any swap ref after unlocking the bridge. */
02621       ao2_t_cleanup(swap, "Bridge push with swap successful");
02622       swap = NULL;
02623 
02624       bridge_channel_event_join_leave(bridge_channel, AST_BRIDGE_HOOK_TYPE_JOIN);
02625 
02626       while (bridge_channel->state == BRIDGE_CHANNEL_STATE_WAIT) {
02627          /* Wait for something to do. */
02628          bridge_channel_wait(bridge_channel);
02629       }
02630 
02631       /* Force a timeout on any accumulated DTMF hook digits. */
02632       ast_bridge_channel_feature_digit(bridge_channel, 0);
02633 
02634       bridge_channel_event_join_leave(bridge_channel, AST_BRIDGE_HOOK_TYPE_LEAVE);
02635       ast_bridge_channel_lock_bridge(bridge_channel);
02636    }
02637 
02638    bridge_channel_internal_pull(bridge_channel);
02639    bridge_channel_settle_owed_events(bridge_channel->bridge, bridge_channel);
02640    bridge_reconfigured(bridge_channel->bridge, 1);
02641 
02642    ast_bridge_unlock(bridge_channel->bridge);
02643 
02644    /* Must release any swap ref after unlocking the bridge. */
02645    ao2_t_cleanup(swap, "Bridge push with swap failed or exited immediately");
02646 
02647    /* Complete any active hold before exiting the bridge. */
02648    if (ast_channel_hold_state(bridge_channel->chan) == AST_CONTROL_HOLD) {
02649       ast_debug(1, "Channel %s simulating UNHOLD for bridge end.\n",
02650          ast_channel_name(bridge_channel->chan));
02651       ast_indicate(bridge_channel->chan, AST_CONTROL_UNHOLD);
02652    }
02653 
02654    /* Complete any partial DTMF digit before exiting the bridge. */
02655    if (ast_channel_sending_dtmf_digit(bridge_channel->chan)) {
02656       ast_channel_end_dtmf(bridge_channel->chan,
02657          ast_channel_sending_dtmf_digit(bridge_channel->chan),
02658          ast_channel_sending_dtmf_tv(bridge_channel->chan), "bridge end");
02659    }
02660 
02661    /* Indicate a source change since this channel is leaving the bridge system. */
02662    ast_indicate(bridge_channel->chan, AST_CONTROL_SRCCHANGE);
02663 
02664    /*
02665     * Wait for any dual redirect to complete.
02666     *
02667     * Must be done while "still in the bridge" for ast_async_goto()
02668     * to work right.
02669     */
02670    while (ast_test_flag(ast_channel_flags(bridge_channel->chan), AST_FLAG_BRIDGE_DUAL_REDIRECT_WAIT)) {
02671       sched_yield();
02672    }
02673    ast_channel_lock(bridge_channel->chan);
02674    ast_channel_internal_bridge_set(bridge_channel->chan, NULL);
02675    ast_channel_unlock(bridge_channel->chan);
02676 
02677    ast_bridge_channel_restore_formats(bridge_channel);
02678 
02679    return res;
02680 }

void bridge_channel_internal_pull ( struct ast_bridge_channel bridge_channel  ) 

Definition at line 1952 of file bridge_channel.c.

References ast_bridge_channel_clear_roles(), AST_BRIDGE_CHANNEL_FLAG_LONELY, ast_bridge_publish_leave(), ast_channel_flags(), ast_channel_is_leaving_bridge(), ast_channel_name(), ast_clear_flag, ast_debug, AST_FLAG_OUTGOING, AST_LIST_REMOVE, ast_test_flag, ast_verb, ast_bridge_channel::bridge, bridge_channel_dissolve_check(), BRIDGE_CHANNEL_STATE_WAIT, ast_bridge_channel::chan, ast_bridge::channels, ast_bridge_features::feature_flags, ast_bridge_channel::features, ast_bridge_channel::in_bridge, ast_bridge_channel::just_joined, ast_bridge_technology::leave, ast_bridge_methods::name, ast_bridge_technology::name, ast_bridge::num_active, ast_bridge::num_channels, ast_bridge::num_lonely, ast_bridge_methods::pull, ast_bridge::reconfigured, ast_bridge_channel::state, ast_bridge_channel::suspended, ast_bridge::technology, ast_bridge::uniqueid, and ast_bridge::v_table.

Referenced by bridge_channel_internal_join(), bridge_channel_internal_push(), bridge_do_merge(), and bridge_do_move().

01953 {
01954    struct ast_bridge *bridge = bridge_channel->bridge;
01955 
01956    if (!bridge_channel->in_bridge) {
01957       return;
01958    }
01959    bridge_channel->in_bridge = 0;
01960 
01961    ast_debug(1, "Bridge %s: pulling %p(%s)\n",
01962       bridge->uniqueid, bridge_channel, ast_channel_name(bridge_channel->chan));
01963 
01964    ast_verb(3, "Channel %s left '%s' %s-bridge <%s>\n",
01965       ast_channel_name(bridge_channel->chan),
01966       bridge->technology->name,
01967       bridge->v_table->name,
01968       bridge->uniqueid);
01969 
01970    if (!bridge_channel->just_joined) {
01971       /* Tell the bridge technology we are leaving so they tear us down */
01972       ast_debug(1, "Bridge %s: %p(%s) is leaving %s technology\n",
01973          bridge->uniqueid, bridge_channel, ast_channel_name(bridge_channel->chan),
01974          bridge->technology->name);
01975       if (bridge->technology->leave) {
01976          bridge->technology->leave(bridge, bridge_channel);
01977       }
01978    }
01979 
01980    /* Remove channel from the bridge */
01981    if (!bridge_channel->suspended) {
01982       --bridge->num_active;
01983    }
01984    if (ast_test_flag(&bridge_channel->features->feature_flags, AST_BRIDGE_CHANNEL_FLAG_LONELY)) {
01985       --bridge->num_lonely;
01986    }
01987    --bridge->num_channels;
01988    AST_LIST_REMOVE(&bridge->channels, bridge_channel, entry);
01989 
01990    bridge_channel_dissolve_check(bridge_channel);
01991    bridge->v_table->pull(bridge, bridge_channel);
01992 
01993    ast_bridge_channel_clear_roles(bridge_channel);
01994 
01995    /* If we are not going to be hung up after leaving a bridge, and we were an
01996     * outgoing channel, clear the outgoing flag.
01997     */
01998    if (ast_test_flag(ast_channel_flags(bridge_channel->chan), AST_FLAG_OUTGOING)
01999        && (ast_channel_is_leaving_bridge(bridge_channel->chan)
02000            || bridge_channel->state == BRIDGE_CHANNEL_STATE_WAIT)) {
02001       ast_debug(2, "Channel %s will survive this bridge; clearing outgoing (dialed) flag\n", ast_channel_name(bridge_channel->chan));
02002       ast_clear_flag(ast_channel_flags(bridge_channel->chan), AST_FLAG_OUTGOING);
02003    }
02004 
02005    bridge->reconfigured = 1;
02006    ast_bridge_publish_leave(bridge, bridge_channel->chan);
02007 }

int bridge_channel_internal_push ( struct ast_bridge_channel bridge_channel  ) 

Definition at line 2009 of file bridge_channel.c.

References ast_assert, ast_bridge_channel_establish_roles(), AST_BRIDGE_CHANNEL_FLAG_LONELY, ast_bridge_channel_leave_bridge(), AST_BRIDGE_FLAG_DISSOLVE_EMPTY, ast_bridge_publish_enter(), ast_channel_name(), ast_clear_flag, ast_debug, AST_LIST_INSERT_TAIL, ast_null_frame, ast_queue_frame(), ast_set2_flag, ast_test_flag, ast_verb, ast_bridge_channel::bridge, bridge_channel_internal_pull(), BRIDGE_CHANNEL_STATE_END_NO_DISSOLVE, BRIDGE_CHANNEL_STATE_WAIT, bridge_find_channel(), ast_bridge_channel::chan, ast_bridge::channels, ast_bridge::dissolved, ast_bridge_features::feature_flags, ast_bridge::feature_flags, ast_bridge_channel::features, ast_bridge_channel::in_bridge, ast_bridge_channel::just_joined, ast_bridge_methods::name, ast_bridge_technology::name, NULL, ast_bridge::num_active, ast_bridge::num_channels, ast_bridge::num_lonely, pbx_builtin_setvar_helper(), ast_bridge_methods::push, ast_bridge::reconfigured, ast_bridge_channel::state, ast_bridge_channel::suspended, ast_bridge_channel::swap, ast_bridge::technology, ast_bridge::uniqueid, and ast_bridge::v_table.

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

02010 {
02011    struct ast_bridge *bridge = bridge_channel->bridge;
02012    struct ast_bridge_channel *swap;
02013 
02014    ast_assert(!bridge_channel->in_bridge);
02015 
02016    swap = bridge_find_channel(bridge, bridge_channel->swap);
02017    bridge_channel->swap = NULL;
02018 
02019    if (swap) {
02020       ast_debug(1, "Bridge %s: pushing %p(%s) by swapping with %p(%s)\n",
02021          bridge->uniqueid, bridge_channel, ast_channel_name(bridge_channel->chan),
02022          swap, ast_channel_name(swap->chan));
02023    } else {
02024       ast_debug(1, "Bridge %s: pushing %p(%s)\n",
02025          bridge->uniqueid, bridge_channel, ast_channel_name(bridge_channel->chan));
02026    }
02027 
02028    /* Add channel to the bridge */
02029    if (bridge->dissolved
02030       || bridge_channel->state != BRIDGE_CHANNEL_STATE_WAIT
02031       || (swap && swap->state != BRIDGE_CHANNEL_STATE_WAIT)
02032       || bridge->v_table->push(bridge, bridge_channel, swap)
02033       || ast_bridge_channel_establish_roles(bridge_channel)) {
02034       ast_debug(1, "Bridge %s: pushing %p(%s) into bridge failed\n",
02035          bridge->uniqueid, bridge_channel, ast_channel_name(bridge_channel->chan));
02036       return -1;
02037    }
02038 
02039    if (swap) {
02040       int dissolve = ast_test_flag(&bridge->feature_flags, AST_BRIDGE_FLAG_DISSOLVE_EMPTY);
02041 
02042       /* This flag is cleared so the act of this channel leaving does not cause it to dissolve if need be */
02043       ast_clear_flag(&bridge->feature_flags, AST_BRIDGE_FLAG_DISSOLVE_EMPTY);
02044 
02045       ast_bridge_channel_leave_bridge(swap, BRIDGE_CHANNEL_STATE_END_NO_DISSOLVE, 0);
02046       bridge_channel_internal_pull(swap);
02047 
02048       ast_set2_flag(&bridge->feature_flags, dissolve, AST_BRIDGE_FLAG_DISSOLVE_EMPTY);
02049    }
02050 
02051    bridge_channel->in_bridge = 1;
02052    bridge_channel->just_joined = 1;
02053    AST_LIST_INSERT_TAIL(&bridge->channels, bridge_channel, entry);
02054    ++bridge->num_channels;
02055    if (ast_test_flag(&bridge_channel->features->feature_flags, AST_BRIDGE_CHANNEL_FLAG_LONELY)) {
02056       ++bridge->num_lonely;
02057    }
02058    if (!bridge_channel->suspended) {
02059       ++bridge->num_active;
02060    }
02061 
02062    ast_verb(3, "Channel %s %s%s%s '%s' %s-bridge <%s>\n",
02063       ast_channel_name(bridge_channel->chan),
02064       swap ? "swapped with " : "joined",
02065       swap ? ast_channel_name(swap->chan) : "",
02066       swap ? " into" : "",
02067       bridge->technology->name,
02068       bridge->v_table->name,
02069       bridge->uniqueid);
02070 
02071    ast_bridge_publish_enter(bridge, bridge_channel->chan, swap ? swap->chan : NULL);
02072 
02073    /* Clear any BLINDTRANSFER and ATTENDEDTRANSFER since the transfer has completed. */
02074    pbx_builtin_setvar_helper(bridge_channel->chan, "BLINDTRANSFER", NULL);
02075    pbx_builtin_setvar_helper(bridge_channel->chan, "ATTENDEDTRANSFER", NULL);
02076 
02077    /* Wake up the bridge channel thread to reevaluate any interval timers. */
02078    ast_queue_frame(bridge_channel->chan, &ast_null_frame);
02079 
02080    bridge->reconfigured = 1;
02081    return 0;
02082 }

int bridge_channel_internal_queue_attended_transfer ( struct ast_channel transferee,
struct ast_channel unbridged_chan 
)

Definition at line 2708 of file bridge_channel.c.

References ao2_cleanup, ast_channel_get_bridge_channel(), ast_channel_lock, ast_channel_name(), AST_CHANNEL_NAME, ast_channel_unlock, ast_copy_string(), BRIDGE_CHANNEL_ACTION_ATTENDED_TRANSFER, bridge_channel_queue_action_data(), NULL, and RAII_VAR.

Referenced by ast_bridge_transfer_attended().

02710 {
02711    RAII_VAR(struct ast_bridge_channel *, transferee_bridge_channel, NULL, ao2_cleanup);
02712    char unbridged_chan_name[AST_CHANNEL_NAME];
02713 
02714    ast_channel_lock(transferee);
02715    transferee_bridge_channel = ast_channel_get_bridge_channel(transferee);
02716    ast_channel_unlock(transferee);
02717 
02718    if (!transferee_bridge_channel) {
02719       return -1;
02720    }
02721 
02722    ast_copy_string(unbridged_chan_name, ast_channel_name(unbridged_chan),
02723       sizeof(unbridged_chan_name));
02724 
02725    return bridge_channel_queue_action_data(transferee_bridge_channel,
02726       BRIDGE_CHANNEL_ACTION_ATTENDED_TRANSFER, unbridged_chan_name,
02727       sizeof(unbridged_chan_name));
02728 }

int bridge_channel_internal_queue_blind_transfer ( struct ast_channel transferee,
const char *  exten,
const char *  context,
transfer_channel_cb  new_channel_cb,
void *  user_data 
)

Definition at line 2682 of file bridge_channel.c.

References ao2_cleanup, AST_BRIDGE_TRANSFER_SINGLE_PARTY, ast_channel_get_bridge_channel(), ast_channel_lock, ast_channel_unlock, ast_copy_string(), BRIDGE_CHANNEL_ACTION_BLIND_TRANSFER, bridge_channel_queue_action_data(), blind_transfer_data::context, blind_transfer_data::exten, NULL, and RAII_VAR.

Referenced by ast_bridge_transfer_blind().

02685 {
02686    RAII_VAR(struct ast_bridge_channel *, transferee_bridge_channel, NULL, ao2_cleanup);
02687    struct blind_transfer_data blind_data;
02688 
02689    ast_channel_lock(transferee);
02690    transferee_bridge_channel = ast_channel_get_bridge_channel(transferee);
02691    ast_channel_unlock(transferee);
02692 
02693    if (!transferee_bridge_channel) {
02694       return -1;
02695    }
02696 
02697    if (new_channel_cb) {
02698       new_channel_cb(transferee, user_data, AST_BRIDGE_TRANSFER_SINGLE_PARTY);
02699    }
02700 
02701    ast_copy_string(blind_data.exten, exten, sizeof(blind_data.exten));
02702    ast_copy_string(blind_data.context, context, sizeof(blind_data.context));
02703 
02704    return bridge_channel_queue_action_data(transferee_bridge_channel,
02705       BRIDGE_CHANNEL_ACTION_BLIND_TRANSFER, &blind_data, sizeof(blind_data));
02706 }

void bridge_channel_internal_suspend_nolock ( struct ast_bridge_channel bridge_channel  ) 

Definition at line 705 of file bridge_channel.c.

References ast_bridge_channel::bridge, ast_bridge_channel::in_bridge, ast_bridge::num_active, ast_bridge_technology::suspend, ast_bridge_channel::suspended, and ast_bridge::technology.

Referenced by ast_bridge_channel_feature_digit(), ast_bridge_suspend(), and bridge_channel_suspend().

00706 {
00707    bridge_channel->suspended = 1;
00708    if (bridge_channel->in_bridge) {
00709       --bridge_channel->bridge->num_active;
00710    }
00711 
00712    /* Get technology bridge threads off of the channel. */
00713    if (bridge_channel->bridge->technology->suspend) {
00714       bridge_channel->bridge->technology->suspend(bridge_channel->bridge, bridge_channel);
00715    }
00716 }

void bridge_channel_internal_unsuspend_nolock ( struct ast_bridge_channel bridge_channel  ) 

Definition at line 743 of file bridge_channel.c.

References ast_bridge_channel_lock, ast_bridge_channel_unlock, ast_cond_signal, ast_bridge_channel::bridge, ast_bridge_channel::cond, ast_bridge_channel::in_bridge, ast_bridge::num_active, ast_bridge_channel::suspended, ast_bridge::technology, and ast_bridge_technology::unsuspend.

Referenced by ast_bridge_unsuspend(), and bridge_channel_unsuspend().

00744 {
00745    bridge_channel->suspended = 0;
00746    if (bridge_channel->in_bridge) {
00747       ++bridge_channel->bridge->num_active;
00748    }
00749 
00750    /* Wake technology bridge threads to take care of channel again. */
00751    if (bridge_channel->bridge->technology->unsuspend) {
00752       bridge_channel->bridge->technology->unsuspend(bridge_channel->bridge, bridge_channel);
00753    }
00754 
00755    /* Wake suspended channel. */
00756    ast_bridge_channel_lock(bridge_channel);
00757    ast_cond_signal(&bridge_channel->cond);
00758    ast_bridge_channel_unlock(bridge_channel);
00759 }

void bridge_channel_settle_owed_events ( struct ast_bridge orig_bridge,
struct ast_bridge_channel bridge_channel 
)

Definition at line 674 of file bridge_channel.c.

References ast_channel_name(), AST_FRAME_DTMF_END, ast_log, ast_tvdiff_ms(), ast_tvnow(), ast_bridge_channel::chan, ast_bridge_channel::dtmf_digit, ast_bridge_channel::dtmf_tv, ast_frame::frametype, ast_frame::len, LOG_DTMF, NULL, option_dtmfminduration, ast_bridge_channel::owed, ast_bridge::technology, ast_bridge::uniqueid, and ast_bridge_technology::write.

Referenced by bridge_channel_internal_join(), and bridge_do_move().

00675 {
00676    if (bridge_channel->owed.dtmf_digit) {
00677       struct ast_frame frame = {
00678          .frametype = AST_FRAME_DTMF_END,
00679          .subclass.integer = bridge_channel->owed.dtmf_digit,
00680          .src = "Bridge channel owed DTMF",
00681       };
00682 
00683       frame.len = ast_tvdiff_ms(ast_tvnow(), bridge_channel->owed.dtmf_tv);
00684       if (frame.len < option_dtmfminduration) {
00685          frame.len = option_dtmfminduration;
00686       }
00687       ast_log(LOG_DTMF, "DTMF end '%c' simulated to bridge %s because %s left.  Duration %ld ms.\n",
00688          bridge_channel->owed.dtmf_digit, orig_bridge->uniqueid,
00689          ast_channel_name(bridge_channel->chan), frame.len);
00690       bridge_channel->owed.dtmf_digit = '\0';
00691       orig_bridge->technology->write(orig_bridge, NULL, &frame);
00692    }
00693 }


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