Sat Apr 26 2014 22:01:29

Asterisk developer's documentation


bridging.c
Go to the documentation of this file.
00001 /*
00002  * Asterisk -- An open source telephony toolkit.
00003  *
00004  * Copyright (C) 2007 - 2009, Digium, Inc.
00005  *
00006  * Joshua Colp <jcolp@digium.com>
00007  *
00008  * See http://www.asterisk.org for more information about
00009  * the Asterisk project. Please do not directly contact
00010  * any of the maintainers of this project for assistance;
00011  * the project provides a web site, mailing lists and IRC
00012  * channels for your use.
00013  *
00014  * This program is free software, distributed under the terms of
00015  * the GNU General Public License Version 2. See the LICENSE file
00016  * at the top of the source tree.
00017  */
00018 
00019 /*! \file
00020  *
00021  * \brief Channel Bridging API
00022  *
00023  * \author Joshua Colp <jcolp@digium.com>
00024  */
00025 
00026 /*** MODULEINFO
00027    <support_level>core</support_level>
00028  ***/
00029 
00030 #include "asterisk.h"
00031 
00032 ASTERISK_FILE_VERSION(__FILE__, "$Revision: 369710 $")
00033 
00034 #include <signal.h>
00035 
00036 #include "asterisk/logger.h"
00037 #include "asterisk/channel.h"
00038 #include "asterisk/options.h"
00039 #include "asterisk/utils.h"
00040 #include "asterisk/lock.h"
00041 #include "asterisk/linkedlists.h"
00042 #include "asterisk/bridging.h"
00043 #include "asterisk/bridging_technology.h"
00044 #include "asterisk/app.h"
00045 #include "asterisk/file.h"
00046 #include "asterisk/module.h"
00047 #include "asterisk/astobj2.h"
00048 #include "asterisk/test.h"
00049 
00050 static AST_RWLIST_HEAD_STATIC(bridge_technologies, ast_bridge_technology);
00051 
00052 /* Initial starting point for the bridge array of channels */
00053 #define BRIDGE_ARRAY_START 128
00054 
00055 /* Grow rate of bridge array of channels */
00056 #define BRIDGE_ARRAY_GROW 32
00057 
00058 static void cleanup_video_mode(struct ast_bridge *bridge);
00059 
00060 /*! Default DTMF keys for built in features */
00061 static char builtin_features_dtmf[AST_BRIDGE_BUILTIN_END][MAXIMUM_DTMF_FEATURE_STRING];
00062 
00063 /*! Function handlers for the built in features */
00064 static void *builtin_features_handlers[AST_BRIDGE_BUILTIN_END];
00065 
00066 int __ast_bridge_technology_register(struct ast_bridge_technology *technology, struct ast_module *module)
00067 {
00068    struct ast_bridge_technology *current = NULL;
00069 
00070    /* Perform a sanity check to make sure the bridge technology conforms to our needed requirements */
00071    if (ast_strlen_zero(technology->name) || !technology->capabilities || !technology->write) {
00072       ast_log(LOG_WARNING, "Bridge technology %s failed registration sanity check.\n", technology->name);
00073       return -1;
00074    }
00075 
00076    AST_RWLIST_WRLOCK(&bridge_technologies);
00077 
00078    /* Look for duplicate bridge technology already using this name, or already registered */
00079    AST_RWLIST_TRAVERSE(&bridge_technologies, current, entry) {
00080       if ((!strcasecmp(current->name, technology->name)) || (current == technology)) {
00081          ast_log(LOG_WARNING, "A bridge technology of %s already claims to exist in our world.\n", technology->name);
00082          AST_RWLIST_UNLOCK(&bridge_technologies);
00083          return -1;
00084       }
00085    }
00086 
00087    /* Copy module pointer so reference counting can keep the module from unloading */
00088    technology->mod = module;
00089 
00090    /* Insert our new bridge technology into the list and print out a pretty message */
00091    AST_RWLIST_INSERT_TAIL(&bridge_technologies, technology, entry);
00092 
00093    AST_RWLIST_UNLOCK(&bridge_technologies);
00094 
00095    ast_verb(2, "Registered bridge technology %s\n", technology->name);
00096 
00097    return 0;
00098 }
00099 
00100 int ast_bridge_technology_unregister(struct ast_bridge_technology *technology)
00101 {
00102    struct ast_bridge_technology *current = NULL;
00103 
00104    AST_RWLIST_WRLOCK(&bridge_technologies);
00105 
00106    /* Ensure the bridge technology is registered before removing it */
00107    AST_RWLIST_TRAVERSE_SAFE_BEGIN(&bridge_technologies, current, entry) {
00108       if (current == technology) {
00109          AST_RWLIST_REMOVE_CURRENT(entry);
00110          ast_verb(2, "Unregistered bridge technology %s\n", technology->name);
00111          break;
00112       }
00113    }
00114    AST_RWLIST_TRAVERSE_SAFE_END;
00115 
00116    AST_RWLIST_UNLOCK(&bridge_technologies);
00117 
00118    return current ? 0 : -1;
00119 }
00120 
00121 void ast_bridge_change_state(struct ast_bridge_channel *bridge_channel, enum ast_bridge_channel_state new_state)
00122 {
00123    /* Change the state on the bridge channel */
00124    bridge_channel->state = new_state;
00125 
00126    /* Only poke the channel's thread if it is not us */
00127    if (!pthread_equal(pthread_self(), bridge_channel->thread)) {
00128       pthread_kill(bridge_channel->thread, SIGURG);
00129       ao2_lock(bridge_channel);
00130       ast_cond_signal(&bridge_channel->cond);
00131       ao2_unlock(bridge_channel);
00132    }
00133 
00134    return;
00135 }
00136 
00137 /*! \brief Helper function to poke the bridge thread */
00138 static void bridge_poke(struct ast_bridge *bridge)
00139 {
00140    /* Poke the thread just in case */
00141    if (bridge->thread != AST_PTHREADT_NULL && bridge->thread != AST_PTHREADT_STOP) {
00142       pthread_kill(bridge->thread, SIGURG);
00143    }
00144 
00145    return;
00146 }
00147 
00148 /*! \brief Helper function to add a channel to the bridge array
00149  *
00150  * \note This function assumes the bridge is locked.
00151  */
00152 static void bridge_array_add(struct ast_bridge *bridge, struct ast_channel *chan)
00153 {
00154    /* We have to make sure the bridge thread is not using the bridge array before messing with it */
00155    while (bridge->waiting) {
00156       bridge_poke(bridge);
00157       sched_yield();
00158    }
00159 
00160    bridge->array[bridge->array_num++] = chan;
00161 
00162    ast_debug(1, "Added channel %s(%p) to bridge array on %p, new count is %d\n", ast_channel_name(chan), chan, bridge, (int)bridge->array_num);
00163 
00164    /* If the next addition of a channel will exceed our array size grow it out */
00165    if (bridge->array_num == bridge->array_size) {
00166       struct ast_channel **tmp;
00167       ast_debug(1, "Growing bridge array on %p from %d to %d\n", bridge, (int)bridge->array_size, (int)bridge->array_size + BRIDGE_ARRAY_GROW);
00168       if (!(tmp = ast_realloc(bridge->array, (bridge->array_size + BRIDGE_ARRAY_GROW) * sizeof(struct ast_channel *)))) {
00169          ast_log(LOG_ERROR, "Failed to allocate more space for another channel on bridge '%p', this is not going to end well\n", bridge);
00170          return;
00171       }
00172       bridge->array = tmp;
00173       bridge->array_size += BRIDGE_ARRAY_GROW;
00174    }
00175 
00176    return;
00177 }
00178 
00179 /*! \brief Helper function to remove a channel from the bridge array
00180  *
00181  * \note This function assumes the bridge is locked.
00182  */
00183 static void bridge_array_remove(struct ast_bridge *bridge, struct ast_channel *chan)
00184 {
00185    int i;
00186 
00187    /* We have to make sure the bridge thread is not using the bridge array before messing with it */
00188    while (bridge->waiting) {
00189       bridge_poke(bridge);
00190       sched_yield();
00191    }
00192 
00193    for (i = 0; i < bridge->array_num; i++) {
00194       if (bridge->array[i] == chan) {
00195          bridge->array[i] = (bridge->array[(bridge->array_num - 1)] != chan ? bridge->array[(bridge->array_num - 1)] : NULL);
00196          bridge->array[(bridge->array_num - 1)] = NULL;
00197          bridge->array_num--;
00198          ast_debug(1, "Removed channel %p from bridge array on %p, new count is %d\n", chan, bridge, (int)bridge->array_num);
00199          break;
00200       }
00201    }
00202 
00203    return;
00204 }
00205 
00206 /*! \brief Helper function to find a bridge channel given a channel */
00207 static struct ast_bridge_channel *find_bridge_channel(struct ast_bridge *bridge, struct ast_channel *chan)
00208 {
00209    struct ast_bridge_channel *bridge_channel = NULL;
00210 
00211    AST_LIST_TRAVERSE(&bridge->channels, bridge_channel, entry) {
00212       if (bridge_channel->chan == chan) {
00213          break;
00214       }
00215    }
00216 
00217    return bridge_channel;
00218 }
00219 
00220 /*! \brief Internal function to see whether a bridge should dissolve, and if so do it */
00221 static void bridge_check_dissolve(struct ast_bridge *bridge, struct ast_bridge_channel *bridge_channel)
00222 {
00223    struct ast_bridge_channel *bridge_channel2 = NULL;
00224 
00225    if (!ast_test_flag(&bridge->feature_flags, AST_BRIDGE_FLAG_DISSOLVE) && (!bridge_channel->features || !bridge_channel->features->usable || !ast_test_flag(&bridge_channel->features->feature_flags, AST_BRIDGE_FLAG_DISSOLVE))) {
00226       return;
00227    }
00228 
00229    ast_debug(1, "Dissolving bridge %p\n", bridge);
00230 
00231    AST_LIST_TRAVERSE(&bridge->channels, bridge_channel2, entry) {
00232       if (bridge_channel2->state != AST_BRIDGE_CHANNEL_STATE_END && bridge_channel2->state != AST_BRIDGE_CHANNEL_STATE_DEPART) {
00233          ast_bridge_change_state(bridge_channel2, AST_BRIDGE_CHANNEL_STATE_HANGUP);
00234       }
00235    }
00236 
00237    return;
00238 }
00239 
00240 /*! \brief Internal function to handle DTMF from a channel */
00241 static struct ast_frame *bridge_handle_dtmf(struct ast_bridge *bridge, struct ast_bridge_channel *bridge_channel, struct ast_frame *frame)
00242 {
00243    struct ast_bridge_features *features = (bridge_channel->features ? bridge_channel->features : &bridge->features);
00244    struct ast_bridge_features_hook *hook = NULL;
00245 
00246    /* If the features structure we grabbed is not usable immediately return the frame */
00247    if (!features->usable) {
00248       return frame;
00249    }
00250 
00251    /* See if this DTMF matches the beginnings of any feature hooks, if so we switch to the feature state to either execute the feature or collect more DTMF */
00252    AST_LIST_TRAVERSE(&features->hooks, hook, entry) {
00253       if (hook->dtmf[0] == frame->subclass.integer) {
00254          ast_frfree(frame);
00255          frame = NULL;
00256          ast_bridge_change_state(bridge_channel, AST_BRIDGE_CHANNEL_STATE_FEATURE);
00257          break;
00258       }
00259    }
00260 
00261    return frame;
00262 }
00263 
00264 /*! \brief Internal function used to determine whether a control frame should be dropped or not */
00265 static int bridge_drop_control_frame(int subclass)
00266 {
00267    switch (subclass) {
00268    case AST_CONTROL_ANSWER:
00269    case -1:
00270       return 1;
00271    default:
00272       return 0;
00273    }
00274 }
00275 
00276 void ast_bridge_notify_talking(struct ast_bridge *bridge, struct ast_bridge_channel *bridge_channel, int started_talking)
00277 {
00278    if (started_talking) {
00279       ast_bridge_change_state(bridge_channel, AST_BRIDGE_CHANNEL_STATE_START_TALKING);
00280    } else {
00281       ast_bridge_change_state(bridge_channel, AST_BRIDGE_CHANNEL_STATE_STOP_TALKING);
00282    }
00283 }
00284 
00285 void ast_bridge_handle_trip(struct ast_bridge *bridge, struct ast_bridge_channel *bridge_channel, struct ast_channel *chan, int outfd)
00286 {
00287    /* If no bridge channel has been provided and the actual channel has been provided find it */
00288    if (chan && !bridge_channel) {
00289       bridge_channel = find_bridge_channel(bridge, chan);
00290    }
00291 
00292    /* If a bridge channel with actual channel is present read a frame and handle it */
00293    if (chan && bridge_channel) {
00294       struct ast_frame *frame = (((bridge->features.mute) || (bridge_channel->features && bridge_channel->features->mute)) ? ast_read_noaudio(chan) : ast_read(chan));
00295 
00296       /* This is pretty simple... see if they hung up */
00297       if (!frame || (frame->frametype == AST_FRAME_CONTROL && frame->subclass.integer == AST_CONTROL_HANGUP)) {
00298          /* Signal the thread that is handling the bridged channel that it should be ended */
00299          ast_bridge_change_state(bridge_channel, AST_BRIDGE_CHANNEL_STATE_END);
00300       } else if (frame->frametype == AST_FRAME_CONTROL && bridge_drop_control_frame(frame->subclass.integer)) {
00301          ast_debug(1, "Dropping control frame from bridge channel %p\n", bridge_channel);
00302       } else if (frame->frametype == AST_FRAME_DTMF_BEGIN || frame->frametype == AST_FRAME_DTMF_END) {
00303          int dtmf_passthrough = bridge_channel->features ?
00304             bridge_channel->features->dtmf_passthrough :
00305             bridge->features.dtmf_passthrough;
00306 
00307          if (frame->frametype == AST_FRAME_DTMF_BEGIN) {
00308             frame = bridge_handle_dtmf(bridge, bridge_channel, frame);
00309          }
00310 
00311          if (frame && dtmf_passthrough) {
00312             bridge->technology->write(bridge, bridge_channel, frame);
00313          }
00314       } else {
00315          /* Simply write the frame out to the bridge technology if it still exists */
00316          bridge->technology->write(bridge, bridge_channel, frame);
00317       }
00318 
00319       if (frame) {
00320          ast_frfree(frame);
00321       }
00322       return;
00323    }
00324 
00325    /* If a file descriptor actually tripped pass it off to the bridge technology */
00326    if (outfd > -1 && bridge->technology->fd) {
00327       bridge->technology->fd(bridge, bridge_channel, outfd);
00328       return;
00329    }
00330 
00331    /* If all else fails just poke the bridge */
00332    if (bridge->technology->poke && bridge_channel) {
00333       bridge->technology->poke(bridge, bridge_channel);
00334       return;
00335    }
00336 
00337    return;
00338 }
00339 
00340 /*! \brief Generic thread loop, TODO: Rethink this/improve it */
00341 static int generic_thread_loop(struct ast_bridge *bridge)
00342 {
00343    while (!bridge->stop && !bridge->refresh && bridge->array_num) {
00344       struct ast_channel *winner = NULL;
00345       int to = -1;
00346 
00347       /* Move channels around for priority reasons if we have more than one channel in our array */
00348       if (bridge->array_num > 1) {
00349          struct ast_channel *first = bridge->array[0];
00350          memmove(bridge->array, bridge->array + 1, sizeof(struct ast_channel *) * (bridge->array_num - 1));
00351          bridge->array[(bridge->array_num - 1)] = first;
00352       }
00353 
00354       /* Wait on the channels */
00355       bridge->waiting = 1;
00356       ao2_unlock(bridge);
00357       winner = ast_waitfor_n(bridge->array, (int)bridge->array_num, &to);
00358       bridge->waiting = 0;
00359       ao2_lock(bridge);
00360 
00361       /* Process whatever they did */
00362       ast_bridge_handle_trip(bridge, NULL, winner, -1);
00363    }
00364 
00365    return 0;
00366 }
00367 
00368 /*! \brief Bridge thread function */
00369 static void *bridge_thread(void *data)
00370 {
00371    struct ast_bridge *bridge = data;
00372    int res = 0;
00373 
00374    ao2_lock(bridge);
00375 
00376    if (bridge->callid) {
00377       ast_callid_threadassoc_add(bridge->callid);
00378    }
00379 
00380    ast_debug(1, "Started bridge thread for %p\n", bridge);
00381 
00382    /* Loop around until we are told to stop */
00383    while (!bridge->stop && bridge->array_num && !res) {
00384       /* In case the refresh bit was set simply set it back to off */
00385       bridge->refresh = 0;
00386 
00387       ast_debug(1, "Launching bridge thread function %p for bridge %p\n", (bridge->technology->thread ? bridge->technology->thread : &generic_thread_loop), bridge);
00388 
00389       /* Execute the appropriate thread function. If the technology does not provide one we use the generic one */
00390       res = (bridge->technology->thread ? bridge->technology->thread(bridge) : generic_thread_loop(bridge));
00391    }
00392 
00393    ast_debug(1, "Ending bridge thread for %p\n", bridge);
00394 
00395    /* Indicate the bridge thread is no longer active */
00396    bridge->thread = AST_PTHREADT_NULL;
00397    ao2_unlock(bridge);
00398 
00399    ao2_ref(bridge, -1);
00400 
00401    return NULL;
00402 }
00403 
00404 /*! \brief Helper function used to find the "best" bridge technology given a specified capabilities */
00405 static struct ast_bridge_technology *find_best_technology(uint32_t capabilities)
00406 {
00407    struct ast_bridge_technology *current = NULL, *best = NULL;
00408 
00409    AST_RWLIST_RDLOCK(&bridge_technologies);
00410    AST_RWLIST_TRAVERSE(&bridge_technologies, current, entry) {
00411       if (current->suspended) {
00412          ast_debug(1, "Bridge technology %s is suspended. Skipping.\n", current->name);
00413          continue;
00414       }
00415       if (!(current->capabilities & capabilities)) {
00416          ast_debug(1, "Bridge technology %s does not have the capabilities we need.\n", current->name);
00417          continue;
00418       }
00419       if (best && best->preference < current->preference) {
00420          ast_debug(1, "Bridge technology %s has preference %d while %s has preference %d. Skipping.\n", current->name, current->preference, best->name, best->preference);
00421          continue;
00422       }
00423       best = current;
00424    }
00425 
00426    if (best) {
00427       /* Increment it's module reference count if present so it does not get unloaded while in use */
00428       if (best->mod) {
00429          ast_module_ref(best->mod);
00430       }
00431       ast_debug(1, "Chose bridge technology %s\n", best->name);
00432    }
00433 
00434    AST_RWLIST_UNLOCK(&bridge_technologies);
00435 
00436    return best;
00437 }
00438 
00439 static void destroy_bridge(void *obj)
00440 {
00441    struct ast_bridge *bridge = obj;
00442 
00443    ast_debug(1, "Actually destroying bridge %p, nobody wants it anymore\n", bridge);
00444 
00445    /* Pass off the bridge to the technology to destroy if needed */
00446    if (bridge->technology->destroy) {
00447       ast_debug(1, "Giving bridge technology %s the bridge structure %p to destroy\n", bridge->technology->name, bridge);
00448       if (bridge->technology->destroy(bridge)) {
00449          ast_debug(1, "Bridge technology %s failed to destroy bridge structure %p... trying our best\n", bridge->technology->name, bridge);
00450       }
00451    }
00452 
00453    /* We are no longer using the bridge technology so decrement the module reference count on it */
00454    if (bridge->technology->mod) {
00455       ast_module_unref(bridge->technology->mod);
00456    }
00457 
00458    /* Last but not least clean up the features configuration */
00459    ast_bridge_features_cleanup(&bridge->features);
00460 
00461    /* Drop the array of channels */
00462    ast_free(bridge->array);
00463 
00464    cleanup_video_mode(bridge);
00465 
00466    return;
00467 }
00468 
00469 struct ast_bridge *ast_bridge_new(uint32_t capabilities, int flags)
00470 {
00471    struct ast_bridge *bridge = NULL;
00472    struct ast_bridge_technology *bridge_technology = NULL;
00473 
00474    /* If we need to be a smart bridge see if we can move between 1to1 and multimix bridges */
00475    if (flags & AST_BRIDGE_FLAG_SMART) {
00476       struct ast_bridge *other_bridge;
00477 
00478       if (!(other_bridge = ast_bridge_new((capabilities & AST_BRIDGE_CAPABILITY_1TO1MIX) ? AST_BRIDGE_CAPABILITY_MULTIMIX : AST_BRIDGE_CAPABILITY_1TO1MIX, 0))) {
00479          return NULL;
00480       }
00481 
00482       ast_bridge_destroy(other_bridge);
00483    }
00484 
00485    /* If capabilities were provided use our helper function to find the "best" bridge technology, otherwise we can
00486     * just look for the most basic capability needed, single 1to1 mixing. */
00487    bridge_technology = (capabilities ? find_best_technology(capabilities) : find_best_technology(AST_BRIDGE_CAPABILITY_1TO1MIX));
00488 
00489    /* If no bridge technology was found we can't possibly do bridging so fail creation of the bridge */
00490    if (!bridge_technology) {
00491       return NULL;
00492    }
00493 
00494    /* We have everything we need to create this bridge... so allocate the memory, link things together, and fire her up! */
00495    if (!(bridge = ao2_alloc(sizeof(*bridge), destroy_bridge))) {
00496       return NULL;
00497    }
00498 
00499    bridge->technology = bridge_technology;
00500    bridge->thread = AST_PTHREADT_NULL;
00501 
00502    /* Create an array of pointers for the channels that will be joining us */
00503    bridge->array = ast_calloc(BRIDGE_ARRAY_START, sizeof(struct ast_channel*));
00504    bridge->array_size = BRIDGE_ARRAY_START;
00505 
00506    ast_set_flag(&bridge->feature_flags, flags);
00507 
00508    /* Pass off the bridge to the technology to manipulate if needed */
00509    if (bridge->technology->create) {
00510       ast_debug(1, "Giving bridge technology %s the bridge structure %p to setup\n", bridge->technology->name, bridge);
00511       if (bridge->technology->create(bridge)) {
00512          ast_debug(1, "Bridge technology %s failed to setup bridge structure %p\n", bridge->technology->name, bridge);
00513          ao2_ref(bridge, -1);
00514          bridge = NULL;
00515       }
00516    }
00517 
00518    return bridge;
00519 }
00520 
00521 int ast_bridge_check(uint32_t capabilities)
00522 {
00523    struct ast_bridge_technology *bridge_technology = NULL;
00524 
00525    if (!(bridge_technology = find_best_technology(capabilities))) {
00526       return 0;
00527    }
00528 
00529    ast_module_unref(bridge_technology->mod);
00530 
00531    return 1;
00532 }
00533 
00534 int ast_bridge_destroy(struct ast_bridge *bridge)
00535 {
00536    struct ast_bridge_channel *bridge_channel = NULL;
00537 
00538    ao2_lock(bridge);
00539 
00540    if (bridge->callid) {
00541       bridge->callid = ast_callid_unref(bridge->callid);
00542    }
00543 
00544    if (bridge->thread != AST_PTHREADT_NULL) {
00545       pthread_t thread = bridge->thread;
00546       bridge->stop = 1;
00547       bridge_poke(bridge);
00548       ao2_unlock(bridge);
00549       pthread_join(thread, NULL);
00550       ao2_lock(bridge);
00551    }
00552 
00553    ast_debug(1, "Telling all channels in bridge %p to end and leave the party\n", bridge);
00554 
00555    /* Drop every bridged channel, the last one will cause the bridge thread (if it exists) to exit */
00556    AST_LIST_TRAVERSE(&bridge->channels, bridge_channel, entry) {
00557       ast_bridge_change_state(bridge_channel, AST_BRIDGE_CHANNEL_STATE_END);
00558    }
00559 
00560    ao2_unlock(bridge);
00561 
00562    ao2_ref(bridge, -1);
00563 
00564    return 0;
00565 }
00566 
00567 static int bridge_make_compatible(struct ast_bridge *bridge, struct ast_bridge_channel *bridge_channel)
00568 {
00569    struct ast_format formats[2];
00570    ast_format_copy(&formats[0], ast_channel_readformat(bridge_channel->chan));
00571    ast_format_copy(&formats[1], ast_channel_writeformat(bridge_channel->chan));
00572 
00573    /* Are the formats currently in use something ths bridge can handle? */
00574    if (!ast_format_cap_iscompatible(bridge->technology->format_capabilities, ast_channel_readformat(bridge_channel->chan))) {
00575       struct ast_format best_format;
00576       ast_best_codec(bridge->technology->format_capabilities, &best_format);
00577 
00578       /* Read format is a no go... */
00579       if (option_debug) {
00580          char codec_buf[512];
00581          ast_debug(1, "Bridge technology %s wants to read any of formats %s but channel has %s\n", bridge->technology->name,
00582             ast_getformatname_multiple(codec_buf, sizeof(codec_buf), bridge->technology->format_capabilities),
00583             ast_getformatname(&formats[0]));
00584       }
00585       /* Switch read format to the best one chosen */
00586       if (ast_set_read_format(bridge_channel->chan, &best_format)) {
00587          ast_log(LOG_WARNING, "Failed to set channel %s to read format %s\n", ast_channel_name(bridge_channel->chan), ast_getformatname(&best_format));
00588          return -1;
00589       }
00590       ast_debug(1, "Bridge %p put channel %s into read format %s\n", bridge, ast_channel_name(bridge_channel->chan), ast_getformatname(&best_format));
00591    } else {
00592       ast_debug(1, "Bridge %p is happy that channel %s already has read format %s\n", bridge, ast_channel_name(bridge_channel->chan), ast_getformatname(&formats[0]));
00593    }
00594 
00595    if (!ast_format_cap_iscompatible(bridge->technology->format_capabilities, &formats[1])) {
00596       struct ast_format best_format;
00597       ast_best_codec(bridge->technology->format_capabilities, &best_format);
00598 
00599       /* Write format is a no go... */
00600       if (option_debug) {
00601          char codec_buf[512];
00602          ast_debug(1, "Bridge technology %s wants to write any of formats %s but channel has %s\n", bridge->technology->name,
00603             ast_getformatname_multiple(codec_buf, sizeof(codec_buf), bridge->technology->format_capabilities),
00604             ast_getformatname(&formats[1]));
00605       }
00606       /* Switch write format to the best one chosen */
00607       if (ast_set_write_format(bridge_channel->chan, &best_format)) {
00608          ast_log(LOG_WARNING, "Failed to set channel %s to write format %s\n", ast_channel_name(bridge_channel->chan), ast_getformatname(&best_format));
00609          return -1;
00610       }
00611       ast_debug(1, "Bridge %p put channel %s into write format %s\n", bridge, ast_channel_name(bridge_channel->chan), ast_getformatname(&best_format));
00612    } else {
00613       ast_debug(1, "Bridge %p is happy that channel %s already has write format %s\n", bridge, ast_channel_name(bridge_channel->chan), ast_getformatname(&formats[1]));
00614    }
00615 
00616    return 0;
00617 }
00618 
00619 /*! \brief Perform the smart bridge operation. Basically sees if a new bridge technology should be used instead of the current one. */
00620 static int smart_bridge_operation(struct ast_bridge *bridge, struct ast_bridge_channel *bridge_channel, int count)
00621 {
00622    uint32_t new_capabilities = 0;
00623    struct ast_bridge_technology *new_technology = NULL, *old_technology = bridge->technology;
00624    struct ast_bridge temp_bridge = {
00625       .technology = bridge->technology,
00626       .bridge_pvt = bridge->bridge_pvt,
00627    };
00628    struct ast_bridge_channel *bridge_channel2 = NULL;
00629 
00630    /* Based on current feature determine whether we want to change bridge technologies or not */
00631    if (bridge->technology->capabilities & AST_BRIDGE_CAPABILITY_1TO1MIX) {
00632       if (count <= 2) {
00633          ast_debug(1, "Bridge %p channel count (%d) is within limits for bridge technology %s, not performing smart bridge operation.\n", bridge, count, bridge->technology->name);
00634          return 0;
00635       }
00636       new_capabilities = AST_BRIDGE_CAPABILITY_MULTIMIX;
00637    } else if (bridge->technology->capabilities & AST_BRIDGE_CAPABILITY_MULTIMIX) {
00638       if (count > 2) {
00639          ast_debug(1, "Bridge %p channel count (%d) is within limits for bridge technology %s, not performing smart bridge operation.\n", bridge, count, bridge->technology->name);
00640          return 0;
00641       }
00642       new_capabilities = AST_BRIDGE_CAPABILITY_1TO1MIX;
00643    }
00644 
00645    if (!new_capabilities) {
00646       ast_debug(1, "Bridge '%p' has no new capabilities, not performing smart bridge operation.\n", bridge);
00647       return 0;
00648    }
00649 
00650    /* Attempt to find a new bridge technology to satisfy the capabilities */
00651    if (!(new_technology = find_best_technology(new_capabilities))) {
00652       return -1;
00653    }
00654 
00655    ast_debug(1, "Performing smart bridge operation on bridge %p, moving from bridge technology %s to %s\n", bridge, old_technology->name, new_technology->name);
00656 
00657    /* If a thread is currently executing for the current technology tell it to stop */
00658    if (bridge->thread != AST_PTHREADT_NULL) {
00659       /* If the new bridge technology also needs a thread simply tell the bridge thread to refresh itself. This has the benefit of not incurring the cost/time of tearing down and bringing up a new thread. */
00660       if (new_technology->capabilities & AST_BRIDGE_CAPABILITY_THREAD) {
00661          ast_debug(1, "Telling current bridge thread for bridge %p to refresh\n", bridge);
00662          bridge->refresh = 1;
00663          bridge_poke(bridge);
00664       } else {
00665          pthread_t bridge_thread = bridge->thread;
00666          ast_debug(1, "Telling current bridge thread for bridge %p to stop\n", bridge);
00667          bridge->stop = 1;
00668          bridge_poke(bridge);
00669          ao2_unlock(bridge);
00670          pthread_join(bridge_thread, NULL);
00671          ao2_lock(bridge);
00672       }
00673    }
00674 
00675    /* Since we are soon going to pass this bridge to a new technology we need to NULL out the bridge_pvt pointer but don't worry as it still exists in temp_bridge, ditto for the old technology */
00676    bridge->bridge_pvt = NULL;
00677    bridge->technology = new_technology;
00678 
00679    /* Pass the bridge to the new bridge technology so it can set it up */
00680    if (new_technology->create) {
00681       ast_debug(1, "Giving bridge technology %s the bridge structure %p to setup\n", new_technology->name, bridge);
00682       if (new_technology->create(bridge)) {
00683          ast_debug(1, "Bridge technology %s failed to setup bridge structure %p\n", new_technology->name, bridge);
00684       }
00685    }
00686 
00687    /* Move existing channels over to the new technology, while taking them away from the old one */
00688    AST_LIST_TRAVERSE(&bridge->channels, bridge_channel2, entry) {
00689       /* Skip over channel that initiated the smart bridge operation */
00690       if (bridge_channel == bridge_channel2) {
00691          continue;
00692       }
00693 
00694       /* First we part them from the old technology */
00695       if (old_technology->leave) {
00696          ast_debug(1, "Giving bridge technology %s notification that %p is leaving bridge %p (really %p)\n", old_technology->name, bridge_channel2, &temp_bridge, bridge);
00697          if (old_technology->leave(&temp_bridge, bridge_channel2)) {
00698             ast_debug(1, "Bridge technology %s failed to allow %p (really %p) to leave bridge %p\n", old_technology->name, bridge_channel2, &temp_bridge, bridge);
00699          }
00700       }
00701 
00702       /* Second we make them compatible again with the bridge */
00703       bridge_make_compatible(bridge, bridge_channel2);
00704 
00705       /* Third we join them to the new technology */
00706       if (new_technology->join) {
00707          ast_debug(1, "Giving bridge technology %s notification that %p is joining bridge %p\n", new_technology->name, bridge_channel2, bridge);
00708          if (new_technology->join(bridge, bridge_channel2)) {
00709             ast_debug(1, "Bridge technology %s failed to join %p to bridge %p\n", new_technology->name, bridge_channel2, bridge);
00710          }
00711       }
00712 
00713       /* Fourth we tell them to wake up so they become aware that they above has happened */
00714       pthread_kill(bridge_channel2->thread, SIGURG);
00715       ao2_lock(bridge_channel2);
00716       ast_cond_signal(&bridge_channel2->cond);
00717       ao2_unlock(bridge_channel2);
00718    }
00719 
00720    /* Now that all the channels have been moved over we need to get rid of all the information the old technology may have left around */
00721    if (old_technology->destroy) {
00722       ast_debug(1, "Giving bridge technology %s the bridge structure %p (really %p) to destroy\n", old_technology->name, &temp_bridge, bridge);
00723       if (old_technology->destroy(&temp_bridge)) {
00724          ast_debug(1, "Bridge technology %s failed to destroy bridge structure %p (really %p)... some memory may have leaked\n", old_technology->name, &temp_bridge, bridge);
00725       }
00726    }
00727 
00728    /* Finally if the old technology has module referencing remove our reference, we are no longer going to use it */
00729    if (old_technology->mod) {
00730       ast_module_unref(old_technology->mod);
00731    }
00732 
00733    return 0;
00734 }
00735 
00736 /*! \brief Run in a multithreaded model. Each joined channel does writing/reading in their own thread. TODO: Improve */
00737 static enum ast_bridge_channel_state bridge_channel_join_multithreaded(struct ast_bridge_channel *bridge_channel)
00738 {
00739    int fds[4] = { -1, }, nfds = 0, i = 0, outfd = -1, ms = -1;
00740    struct ast_channel *chan = NULL;
00741 
00742    /* Add any file descriptors we may want to monitor */
00743    if (bridge_channel->bridge->technology->fd) {
00744       for (i = 0; i < 4; i ++) {
00745          if (bridge_channel->fds[i] >= 0) {
00746             fds[nfds++] = bridge_channel->fds[i];
00747          }
00748       }
00749    }
00750 
00751    ao2_unlock(bridge_channel->bridge);
00752 
00753    ao2_lock(bridge_channel);
00754    /* Wait for data to either come from the channel or us to be signalled */
00755    if (!bridge_channel->suspended) {
00756       ao2_unlock(bridge_channel);
00757       ast_debug(10, "Going into a multithreaded waitfor for bridge channel %p of bridge %p\n", bridge_channel, bridge_channel->bridge);
00758       chan = ast_waitfor_nandfds(&bridge_channel->chan, 1, fds, nfds, NULL, &outfd, &ms);
00759    } else {
00760       ast_debug(10, "Going into a multithreaded signal wait for bridge channel %p of bridge %p\n", bridge_channel, bridge_channel->bridge);
00761       ast_cond_wait(&bridge_channel->cond, ao2_object_get_lockaddr(bridge_channel));
00762       ao2_unlock(bridge_channel);
00763    }
00764 
00765    ao2_lock(bridge_channel->bridge);
00766 
00767    if (!bridge_channel->suspended) {
00768       ast_bridge_handle_trip(bridge_channel->bridge, bridge_channel, chan, outfd);
00769    }
00770 
00771    return bridge_channel->state;
00772 }
00773 
00774 /*! \brief Run in a singlethreaded model. Each joined channel yields itself to the main bridge thread. TODO: Improve */
00775 static enum ast_bridge_channel_state bridge_channel_join_singlethreaded(struct ast_bridge_channel *bridge_channel)
00776 {
00777    ao2_unlock(bridge_channel->bridge);
00778    ao2_lock(bridge_channel);
00779    if (bridge_channel->state == AST_BRIDGE_CHANNEL_STATE_WAIT) {
00780       ast_debug(1, "Going into a single threaded signal wait for bridge channel %p of bridge %p\n", bridge_channel, bridge_channel->bridge);
00781       ast_cond_wait(&bridge_channel->cond, ao2_object_get_lockaddr(bridge_channel));
00782    }
00783    ao2_unlock(bridge_channel);
00784    ao2_lock(bridge_channel->bridge);
00785 
00786    return bridge_channel->state;
00787 }
00788 
00789 /*! \brief Internal function that suspends a channel from a bridge */
00790 static void bridge_channel_suspend(struct ast_bridge *bridge, struct ast_bridge_channel *bridge_channel)
00791 {
00792    ao2_lock(bridge_channel);
00793    bridge_channel->suspended = 1;
00794    bridge_array_remove(bridge, bridge_channel->chan);
00795    ao2_unlock(bridge_channel);
00796 
00797    if (bridge->technology->suspend) {
00798       bridge->technology->suspend(bridge, bridge_channel);
00799    }
00800 
00801    return;
00802 }
00803 
00804 /*! \brief Internal function that unsuspends a channel from a bridge */
00805 static void bridge_channel_unsuspend(struct ast_bridge *bridge, struct ast_bridge_channel *bridge_channel)
00806 {
00807    ao2_lock(bridge_channel);
00808    bridge_channel->suspended = 0;
00809    bridge_array_add(bridge, bridge_channel->chan);
00810    ast_cond_signal(&bridge_channel->cond);
00811    ao2_unlock(bridge_channel);
00812 
00813    if (bridge->technology->unsuspend) {
00814       bridge->technology->unsuspend(bridge, bridge_channel);
00815    }
00816 
00817 
00818 
00819    return;
00820 }
00821 
00822 /*!
00823  * \brief Internal function that executes a feature on a bridge channel
00824  * \note Neither the bridge nor the bridge_channel locks should be held when entering
00825  * this function.
00826  */
00827 static void bridge_channel_feature(struct ast_bridge *bridge, struct ast_bridge_channel *bridge_channel)
00828 {
00829    struct ast_bridge_features *features = (bridge_channel->features ? bridge_channel->features : &bridge->features);
00830    struct ast_bridge_features_hook *hook = NULL;
00831    char dtmf[MAXIMUM_DTMF_FEATURE_STRING] = "";
00832    int look_for_dtmf = 1, dtmf_len = 0;
00833 
00834    /* The channel is now under our control and we don't really want any begin frames to do our DTMF matching so disable 'em at the core level */
00835    ast_set_flag(ast_channel_flags(bridge_channel->chan), AST_FLAG_END_DTMF_ONLY);
00836 
00837    /* Wait for DTMF on the channel and put it into a buffer. If the buffer matches any feature hook execute the hook. */
00838    while (look_for_dtmf) {
00839       int res = ast_waitfordigit(bridge_channel->chan, 3000);
00840 
00841       /* If the above timed out simply exit */
00842       if (!res) {
00843          ast_debug(1, "DTMF feature string collection on bridge channel %p timed out\n", bridge_channel);
00844          break;
00845       } else if (res < 0) {
00846          ast_debug(1, "DTMF feature string collection failed on bridge channel %p for some reason\n", bridge_channel);
00847          break;
00848       }
00849 
00850       /* Add the above DTMF into the DTMF string so we can do our matching */
00851       dtmf[dtmf_len++] = res;
00852 
00853       ast_debug(1, "DTMF feature string on bridge channel %p is now '%s'\n", bridge_channel, dtmf);
00854 
00855       /* Assume that we do not want to look for DTMF any longer */
00856       look_for_dtmf = 0;
00857 
00858       /* See if a DTMF feature hook matches or can match */
00859       AST_LIST_TRAVERSE(&features->hooks, hook, entry) {
00860          /* If this hook matches just break out now */
00861          if (!strcmp(hook->dtmf, dtmf)) {
00862             ast_debug(1, "DTMF feature hook %p matched DTMF string '%s' on bridge channel %p\n", hook, dtmf, bridge_channel);
00863             look_for_dtmf = 0;
00864             break;
00865          } else if (!strncmp(hook->dtmf, dtmf, dtmf_len)) {
00866             ast_debug(1, "DTMF feature hook %p can match DTMF string '%s', it wants '%s', on bridge channel %p\n", hook, dtmf, hook->dtmf, bridge_channel);
00867             look_for_dtmf = 1;
00868          } else {
00869             ast_debug(1, "DTMF feature hook %p does not match DTMF string '%s', it wants '%s', on bridge channel %p\n", hook, dtmf, hook->dtmf, bridge_channel);
00870          }
00871       }
00872 
00873       /* If we have reached the maximum length of a DTMF feature string bail out */
00874       if (dtmf_len == MAXIMUM_DTMF_FEATURE_STRING) {
00875          break;
00876       }
00877    }
00878 
00879    /* Since we are done bringing DTMF in return to using both begin and end frames */
00880    ast_clear_flag(ast_channel_flags(bridge_channel->chan), AST_FLAG_END_DTMF_ONLY);
00881 
00882    /* If a hook was actually matched execute it on this channel, otherwise stream up the DTMF to the other channels */
00883    if (hook) {
00884       hook->callback(bridge, bridge_channel, hook->hook_pvt);
00885       /* If we are handing the channel off to an external hook for ownership,
00886        * we are not guaranteed what kind of state it will come back in.  If
00887        * the channel hungup, we need to detect that here. */
00888       if (bridge_channel->chan && ast_check_hangup_locked(bridge_channel->chan)) {
00889          ast_bridge_change_state(bridge_channel, AST_BRIDGE_CHANNEL_STATE_END);
00890       }
00891    } else {
00892       ast_bridge_dtmf_stream(bridge, dtmf, bridge_channel->chan);
00893    }
00894 
00895    /* if the channel is still in feature state, revert it back to wait state */
00896    if (bridge_channel->state == AST_BRIDGE_CHANNEL_STATE_FEATURE) {
00897       ast_bridge_change_state(bridge_channel, AST_BRIDGE_CHANNEL_STATE_WAIT);
00898    }
00899 
00900    return;
00901 }
00902 
00903 static void bridge_channel_talking(struct ast_bridge *bridge, struct ast_bridge_channel *bridge_channel)
00904 {
00905    struct ast_bridge_features *features = (bridge_channel->features ? bridge_channel->features : &bridge->features);
00906 
00907    if (features && features->talker_cb) {
00908       features->talker_cb(bridge, bridge_channel, features->talker_pvt_data);
00909    }
00910    ast_bridge_change_state(bridge_channel, AST_BRIDGE_CHANNEL_STATE_WAIT);
00911 }
00912 
00913 /*! \brief Internal function that plays back DTMF on a bridge channel */
00914 static void bridge_channel_dtmf_stream(struct ast_bridge *bridge, struct ast_bridge_channel *bridge_channel)
00915 {
00916    char dtmf_q[8] = "";
00917 
00918    ast_copy_string(dtmf_q, bridge_channel->dtmf_stream_q, sizeof(dtmf_q));
00919    bridge_channel->dtmf_stream_q[0] = '\0';
00920 
00921    ast_debug(1, "Playing DTMF stream '%s' out to bridge channel %p\n", dtmf_q, bridge_channel);
00922    ast_dtmf_stream(bridge_channel->chan, NULL, dtmf_q, 250, 0);
00923 
00924    ast_bridge_change_state(bridge_channel, AST_BRIDGE_CHANNEL_STATE_WAIT);
00925 
00926    return;
00927 }
00928 
00929 /*! \brief Join a channel to a bridge and handle anything the bridge may want us to do */
00930 static enum ast_bridge_channel_state bridge_channel_join(struct ast_bridge_channel *bridge_channel)
00931 {
00932    struct ast_format formats[2];
00933    enum ast_bridge_channel_state state;
00934    ast_format_copy(&formats[0], ast_channel_readformat(bridge_channel->chan));
00935    ast_format_copy(&formats[1], ast_channel_writeformat(bridge_channel->chan));
00936 
00937    /* Record the thread that will be the owner of us */
00938    bridge_channel->thread = pthread_self();
00939 
00940    ast_debug(1, "Joining bridge channel %p to bridge %p\n", bridge_channel, bridge_channel->bridge);
00941 
00942    ao2_lock(bridge_channel->bridge);
00943 
00944    if (!bridge_channel->bridge->callid) {
00945       bridge_channel->bridge->callid = ast_read_threadstorage_callid();
00946    }
00947 
00948    state = bridge_channel->state;
00949 
00950    /* Add channel into the bridge */
00951    AST_LIST_INSERT_TAIL(&bridge_channel->bridge->channels, bridge_channel, entry);
00952    bridge_channel->bridge->num++;
00953 
00954    bridge_array_add(bridge_channel->bridge, bridge_channel->chan);
00955 
00956    if (bridge_channel->swap) {
00957       struct ast_bridge_channel *bridge_channel2 = NULL;
00958 
00959       /* If we are performing a swap operation we do not need
00960        * to execute the smart bridge operation as the actual number
00961        * of channels involved will not have changed, we just need to
00962        * tell the other channel to leave */
00963       if ((bridge_channel2 = find_bridge_channel(bridge_channel->bridge, bridge_channel->swap))) {
00964          ast_debug(1, "Swapping bridge channel %p out from bridge %p so bridge channel %p can slip in\n", bridge_channel2, bridge_channel->bridge, bridge_channel);
00965          ast_bridge_change_state(bridge_channel2, AST_BRIDGE_CHANNEL_STATE_HANGUP);
00966       }
00967 
00968       bridge_channel->swap = NULL;
00969    } else if (ast_test_flag(&bridge_channel->bridge->feature_flags, AST_BRIDGE_FLAG_SMART)) {
00970       /* Perform the smart bridge operation, basically see if we need to move around between technologies */
00971       smart_bridge_operation(bridge_channel->bridge, bridge_channel, bridge_channel->bridge->num);
00972    }
00973 
00974    /* Make the channel compatible with the bridge */
00975    bridge_make_compatible(bridge_channel->bridge, bridge_channel);
00976 
00977    /* Tell the bridge technology we are joining so they set us up */
00978    if (bridge_channel->bridge->technology->join) {
00979       ast_debug(1, "Giving bridge technology %s notification that %p is joining bridge %p\n", bridge_channel->bridge->technology->name, bridge_channel, bridge_channel->bridge);
00980       if (bridge_channel->bridge->technology->join(bridge_channel->bridge, bridge_channel)) {
00981          ast_debug(1, "Bridge technology %s failed to join %p to bridge %p\n", bridge_channel->bridge->technology->name, bridge_channel, bridge_channel->bridge);
00982       }
00983    }
00984 
00985    /* Actually execute the respective threading model, and keep our bridge thread alive */
00986    while (bridge_channel->state == AST_BRIDGE_CHANNEL_STATE_WAIT) {
00987       /* Update bridge pointer on channel */
00988       ast_channel_internal_bridge_set(bridge_channel->chan, bridge_channel->bridge);
00989       /* If the technology requires a thread and one is not running, start it up */
00990       if (bridge_channel->bridge->thread == AST_PTHREADT_NULL && (bridge_channel->bridge->technology->capabilities & AST_BRIDGE_CAPABILITY_THREAD)) {
00991          bridge_channel->bridge->stop = 0;
00992          ast_debug(1, "Starting a bridge thread for bridge %p\n", bridge_channel->bridge);
00993          ao2_ref(bridge_channel->bridge, +1);
00994          if (ast_pthread_create(&bridge_channel->bridge->thread, NULL, bridge_thread, bridge_channel->bridge)) {
00995             ast_debug(1, "Failed to create a bridge thread for bridge %p, giving it another go.\n", bridge_channel->bridge);
00996             ao2_ref(bridge_channel->bridge, -1);
00997             continue;
00998          }
00999       }
01000       /* Execute the threading model */
01001       state = (bridge_channel->bridge->technology->capabilities & AST_BRIDGE_CAPABILITY_MULTITHREADED ? bridge_channel_join_multithreaded(bridge_channel) : bridge_channel_join_singlethreaded(bridge_channel));
01002       /* Depending on the above state see what we need to do */
01003       switch (state) {
01004       case AST_BRIDGE_CHANNEL_STATE_FEATURE:
01005          bridge_channel_suspend(bridge_channel->bridge, bridge_channel);
01006          ao2_unlock(bridge_channel->bridge);
01007          bridge_channel_feature(bridge_channel->bridge, bridge_channel);
01008          ao2_lock(bridge_channel->bridge);
01009          bridge_channel_unsuspend(bridge_channel->bridge, bridge_channel);
01010          break;
01011       case AST_BRIDGE_CHANNEL_STATE_DTMF:
01012          bridge_channel_suspend(bridge_channel->bridge, bridge_channel);
01013          bridge_channel_dtmf_stream(bridge_channel->bridge, bridge_channel);
01014          bridge_channel_unsuspend(bridge_channel->bridge, bridge_channel);
01015          break;
01016       case AST_BRIDGE_CHANNEL_STATE_START_TALKING:
01017       case AST_BRIDGE_CHANNEL_STATE_STOP_TALKING:
01018          ao2_unlock(bridge_channel->bridge);
01019          bridge_channel_talking(bridge_channel->bridge, bridge_channel);
01020          ao2_lock(bridge_channel->bridge);
01021          break;
01022       default:
01023          break;
01024       }
01025    }
01026 
01027    ast_channel_internal_bridge_set(bridge_channel->chan, NULL);
01028 
01029    /* See if we need to dissolve the bridge itself if they hung up */
01030    if (bridge_channel->state == AST_BRIDGE_CHANNEL_STATE_END) {
01031       bridge_check_dissolve(bridge_channel->bridge, bridge_channel);
01032    }
01033 
01034    /* Tell the bridge technology we are leaving so they tear us down */
01035    if (bridge_channel->bridge->technology->leave) {
01036       ast_debug(1, "Giving bridge technology %s notification that %p is leaving bridge %p\n", bridge_channel->bridge->technology->name, bridge_channel, bridge_channel->bridge);
01037       if (bridge_channel->bridge->technology->leave(bridge_channel->bridge, bridge_channel)) {
01038          ast_debug(1, "Bridge technology %s failed to leave %p from bridge %p\n", bridge_channel->bridge->technology->name, bridge_channel, bridge_channel->bridge);
01039       }
01040    }
01041 
01042    /* Remove channel from the bridge */
01043    bridge_channel->bridge->num--;
01044    AST_LIST_REMOVE(&bridge_channel->bridge->channels, bridge_channel, entry);
01045 
01046    bridge_array_remove(bridge_channel->bridge, bridge_channel->chan);
01047 
01048    /* Perform the smart bridge operation if needed since a channel has left */
01049    if (ast_test_flag(&bridge_channel->bridge->feature_flags, AST_BRIDGE_FLAG_SMART)) {
01050       smart_bridge_operation(bridge_channel->bridge, NULL, bridge_channel->bridge->num);
01051    }
01052 
01053    ao2_unlock(bridge_channel->bridge);
01054 
01055    /* Restore original formats of the channel as they came in */
01056    if (ast_format_cmp(ast_channel_readformat(bridge_channel->chan), &formats[0]) == AST_FORMAT_CMP_NOT_EQUAL) {
01057       ast_debug(1, "Bridge is returning %p to read format %s(%d)\n", bridge_channel, ast_getformatname(&formats[0]), formats[0].id);
01058       if (ast_set_read_format(bridge_channel->chan, &formats[0])) {
01059          ast_debug(1, "Bridge failed to return channel %p to read format %s(%d)\n", bridge_channel, ast_getformatname(&formats[0]), formats[0].id);
01060       }
01061    }
01062    if (ast_format_cmp(ast_channel_writeformat(bridge_channel->chan), &formats[1]) == AST_FORMAT_CMP_NOT_EQUAL) {
01063       ast_debug(1, "Bridge is returning %p to write format %s(%d)\n", bridge_channel, ast_getformatname(&formats[1]), formats[1].id);
01064       if (ast_set_write_format(bridge_channel->chan, &formats[1])) {
01065          ast_debug(1, "Bridge failed to return channel %p to write format %s(%d)\n", bridge_channel, ast_getformatname(&formats[1]), formats[1].id);
01066       }
01067    }
01068 
01069    return bridge_channel->state;
01070 }
01071 
01072 static void bridge_channel_destroy(void *obj)
01073 {
01074    struct ast_bridge_channel *bridge_channel = obj;
01075 
01076    if (bridge_channel->callid) {
01077       bridge_channel->callid = ast_callid_unref(bridge_channel->callid);
01078    }
01079 
01080    if (bridge_channel->bridge) {
01081       ao2_ref(bridge_channel->bridge, -1);
01082       bridge_channel->bridge = NULL;
01083    }
01084    /* Destroy elements of the bridge channel structure and the bridge channel structure itself */
01085    ast_cond_destroy(&bridge_channel->cond);
01086 }
01087 
01088 static struct ast_bridge_channel *bridge_channel_alloc(struct ast_bridge *bridge)
01089 {
01090    struct ast_bridge_channel *bridge_channel = ao2_alloc(sizeof(struct ast_bridge_channel), bridge_channel_destroy);
01091    if (!(bridge_channel)) {
01092       return NULL;
01093    }
01094    ast_cond_init(&bridge_channel->cond, NULL);
01095    if (bridge) {
01096       bridge_channel->bridge = bridge;
01097       ao2_ref(bridge_channel->bridge, +1);
01098    }
01099    return bridge_channel;
01100 }
01101 
01102 enum ast_bridge_channel_state ast_bridge_join(struct ast_bridge *bridge,
01103    struct ast_channel *chan,
01104    struct ast_channel *swap,
01105    struct ast_bridge_features *features,
01106    struct ast_bridge_tech_optimizations *tech_args)
01107 {
01108    struct ast_bridge_channel *bridge_channel = bridge_channel_alloc(bridge);
01109    enum ast_bridge_channel_state state = AST_BRIDGE_CHANNEL_STATE_HANGUP;
01110 
01111    if (!bridge_channel) {
01112       return state;
01113    }
01114    if (tech_args) {
01115       memcpy(&bridge_channel->tech_args, tech_args, sizeof(bridge_channel->tech_args));
01116    }
01117 
01118    /* Initialize various other elements of the bridge channel structure that we can't do above */
01119    bridge_channel->chan = chan;
01120    bridge_channel->swap = swap;
01121    bridge_channel->features = features;
01122 
01123    state = bridge_channel_join(bridge_channel);
01124 
01125    /* Cleanup all the data in the bridge channel after it leaves the bridge. */
01126    ao2_lock(bridge_channel);
01127    bridge_channel->chan = NULL;
01128    bridge_channel->swap = NULL;
01129    bridge_channel->features = NULL;
01130    ao2_unlock(bridge_channel);
01131 
01132    ao2_ref(bridge_channel, -1);
01133 
01134    return state;
01135 }
01136 
01137 /*! \brief Thread responsible for imparted bridged channels */
01138 static void *bridge_channel_thread(void *data)
01139 {
01140    struct ast_bridge_channel *bridge_channel = data;
01141    enum ast_bridge_channel_state state;
01142 
01143    if (bridge_channel->callid) {
01144       ast_callid_threadassoc_add(bridge_channel->callid);
01145    }
01146 
01147    state = bridge_channel_join(bridge_channel);
01148 
01149    /* If no other thread is going to take the channel then hang it up, or else we would have to service it until something else came along */
01150    if (bridge_channel->allow_impart_hangup && (state == AST_BRIDGE_CHANNEL_STATE_END || state == AST_BRIDGE_CHANNEL_STATE_HANGUP)) {
01151       ast_hangup(bridge_channel->chan);
01152    }
01153 
01154    /* cleanup */
01155    ao2_lock(bridge_channel);
01156    bridge_channel->chan = NULL;
01157    bridge_channel->swap = NULL;
01158    bridge_channel->features = NULL;
01159    ao2_unlock(bridge_channel);
01160 
01161    ao2_ref(bridge_channel, -1);
01162 
01163    return NULL;
01164 }
01165 
01166 int ast_bridge_impart(struct ast_bridge *bridge, struct ast_channel *chan, struct ast_channel *swap, struct ast_bridge_features *features, int allow_hangup)
01167 {
01168    struct ast_bridge_channel *bridge_channel = bridge_channel_alloc(bridge);
01169 
01170    /* Try to allocate a structure for the bridge channel */
01171    if (!(bridge_channel)) {
01172       return -1;
01173    }
01174 
01175    /* Setup various parameters */
01176    bridge_channel->chan = chan;
01177    bridge_channel->swap = swap;
01178    bridge_channel->features = features;
01179    bridge_channel->allow_impart_hangup = allow_hangup;
01180    bridge_channel->callid = ast_read_threadstorage_callid();
01181 
01182    /* Actually create the thread that will handle the channel */
01183    if (ast_pthread_create(&bridge_channel->thread, NULL, bridge_channel_thread, bridge_channel)) {
01184       ao2_ref(bridge_channel, -1);
01185       return -1;
01186    }
01187 
01188    return 0;
01189 }
01190 
01191 int ast_bridge_depart(struct ast_bridge *bridge, struct ast_channel *chan)
01192 {
01193    struct ast_bridge_channel *bridge_channel = NULL;
01194    pthread_t thread;
01195 
01196    ao2_lock(bridge);
01197 
01198    /* Try to find the channel that we want to depart */
01199    if (!(bridge_channel = find_bridge_channel(bridge, chan))) {
01200       ao2_unlock(bridge);
01201       return -1;
01202    }
01203 
01204    ast_bridge_change_state(bridge_channel, AST_BRIDGE_CHANNEL_STATE_DEPART);
01205    thread = bridge_channel->thread;
01206 
01207    ao2_unlock(bridge);
01208 
01209    pthread_join(thread, NULL);
01210 
01211    return 0;
01212 }
01213 
01214 int ast_bridge_remove(struct ast_bridge *bridge, struct ast_channel *chan)
01215 {
01216    struct ast_bridge_channel *bridge_channel = NULL;
01217 
01218    ao2_lock(bridge);
01219 
01220    /* Try to find the channel that we want to remove */
01221    if (!(bridge_channel = find_bridge_channel(bridge, chan))) {
01222       ao2_unlock(bridge);
01223       return -1;
01224    }
01225 
01226    ast_bridge_change_state(bridge_channel, AST_BRIDGE_CHANNEL_STATE_HANGUP);
01227 
01228    ao2_unlock(bridge);
01229 
01230    return 0;
01231 }
01232 
01233 int ast_bridge_merge(struct ast_bridge *bridge0, struct ast_bridge *bridge1)
01234 {
01235    struct ast_bridge_channel *bridge_channel = NULL;
01236 
01237    ao2_lock(bridge0);
01238    ao2_lock(bridge1);
01239 
01240    /* If the first bridge currently has 2 channels and is not capable of becoming a multimixing bridge we can not merge */
01241    if ((bridge0->num + bridge1->num) > 2 && (!(bridge0->technology->capabilities & AST_BRIDGE_CAPABILITY_MULTIMIX) && !ast_test_flag(&bridge0->feature_flags, AST_BRIDGE_FLAG_SMART))) {
01242       ao2_unlock(bridge1);
01243       ao2_unlock(bridge0);
01244       ast_debug(1, "Can't merge bridge %p into bridge %p, multimix is needed and it could not be acquired.\n", bridge1, bridge0);
01245       return -1;
01246    }
01247 
01248    ast_debug(1, "Merging channels from bridge %p into bridge %p\n", bridge1, bridge0);
01249 
01250    /* Perform smart bridge operation on bridge we are merging into so it can change bridge technology if needed */
01251    if (smart_bridge_operation(bridge0, NULL, bridge0->num + bridge1->num)) {
01252       ao2_unlock(bridge1);
01253       ao2_unlock(bridge0);
01254       ast_debug(1, "Can't merge bridge %p into bridge %p, tried to perform smart bridge operation and failed.\n", bridge1, bridge0);
01255       return -1;
01256    }
01257 
01258    /* If a thread is currently executing on bridge1 tell it to stop */
01259    if (bridge1->thread) {
01260       ast_debug(1, "Telling bridge thread on bridge %p to stop as it is being merged into %p\n", bridge1, bridge0);
01261       bridge1->thread = AST_PTHREADT_STOP;
01262    }
01263 
01264    /* Move channels from bridge1 over to bridge0 */
01265    while ((bridge_channel = AST_LIST_REMOVE_HEAD(&bridge1->channels, entry))) {
01266       /* Tell the technology handling bridge1 that the bridge channel is leaving */
01267       if (bridge1->technology->leave) {
01268          ast_debug(1, "Giving bridge technology %s notification that %p is leaving bridge %p\n", bridge1->technology->name, bridge_channel, bridge1);
01269          if (bridge1->technology->leave(bridge1, bridge_channel)) {
01270             ast_debug(1, "Bridge technology %s failed to allow %p to leave bridge %p\n", bridge1->technology->name, bridge_channel, bridge1);
01271          }
01272       }
01273 
01274       /* Drop channel count and reference count on the bridge they are leaving */
01275       bridge1->num--;
01276       ao2_ref(bridge1, -1);
01277 
01278       bridge_array_remove(bridge1, bridge_channel->chan);
01279 
01280       /* Now add them into the bridge they are joining, increase channel count, and bump up reference count */
01281       bridge_channel->bridge = bridge0;
01282       AST_LIST_INSERT_TAIL(&bridge0->channels, bridge_channel, entry);
01283       bridge0->num++;
01284       ao2_ref(bridge0, +1);
01285 
01286       bridge_array_add(bridge0, bridge_channel->chan);
01287 
01288       /* Make the channel compatible with the new bridge it is joining or else formats would go amuck */
01289       bridge_make_compatible(bridge0, bridge_channel);
01290 
01291       /* Tell the technology handling bridge0 that the bridge channel is joining */
01292       if (bridge0->technology->join) {
01293          ast_debug(1, "Giving bridge technology %s notification that %p is joining bridge %p\n", bridge0->technology->name, bridge_channel, bridge0);
01294          if (bridge0->technology->join(bridge0, bridge_channel)) {
01295             ast_debug(1, "Bridge technology %s failed to join %p to bridge %p\n", bridge0->technology->name, bridge_channel, bridge0);
01296          }
01297       }
01298 
01299       /* Poke the bridge channel, this will cause it to wake up and execute the proper threading model for the new bridge it is in */
01300       pthread_kill(bridge_channel->thread, SIGURG);
01301       ao2_lock(bridge_channel);
01302       ast_cond_signal(&bridge_channel->cond);
01303       ao2_unlock(bridge_channel);
01304    }
01305 
01306    ast_debug(1, "Merged channels from bridge %p into bridge %p\n", bridge1, bridge0);
01307 
01308    ao2_unlock(bridge1);
01309    ao2_unlock(bridge0);
01310 
01311    return 0;
01312 }
01313 
01314 int ast_bridge_suspend(struct ast_bridge *bridge, struct ast_channel *chan)
01315 {
01316    struct ast_bridge_channel *bridge_channel;
01317 
01318    ao2_lock(bridge);
01319 
01320    if (!(bridge_channel = find_bridge_channel(bridge, chan))) {
01321       ao2_unlock(bridge);
01322       return -1;
01323    }
01324 
01325    bridge_channel_suspend(bridge, bridge_channel);
01326 
01327    ao2_unlock(bridge);
01328 
01329    return 0;
01330 }
01331 
01332 int ast_bridge_unsuspend(struct ast_bridge *bridge, struct ast_channel *chan)
01333 {
01334    struct ast_bridge_channel *bridge_channel;
01335 
01336    ao2_lock(bridge);
01337 
01338    if (!(bridge_channel = find_bridge_channel(bridge, chan))) {
01339       ao2_unlock(bridge);
01340       return -1;
01341    }
01342 
01343    bridge_channel_unsuspend(bridge, bridge_channel);
01344 
01345    ao2_unlock(bridge);
01346 
01347    return 0;
01348 }
01349 
01350 void ast_bridge_technology_suspend(struct ast_bridge_technology *technology)
01351 {
01352    technology->suspended = 1;
01353    return;
01354 }
01355 
01356 void ast_bridge_technology_unsuspend(struct ast_bridge_technology *technology)
01357 {
01358    technology->suspended = 0;
01359    return;
01360 }
01361 
01362 int ast_bridge_features_register(enum ast_bridge_builtin_feature feature, ast_bridge_features_hook_callback callback, const char *dtmf)
01363 {
01364    if (builtin_features_handlers[feature]) {
01365       return -1;
01366    }
01367 
01368    if (!ast_strlen_zero(dtmf)) {
01369       ast_copy_string(builtin_features_dtmf[feature], dtmf, sizeof(builtin_features_dtmf[feature]));
01370    }
01371 
01372    builtin_features_handlers[feature] = callback;
01373 
01374    return 0;
01375 }
01376 
01377 int ast_bridge_features_unregister(enum ast_bridge_builtin_feature feature)
01378 {
01379    if (!builtin_features_handlers[feature]) {
01380       return -1;
01381    }
01382 
01383    builtin_features_handlers[feature] = NULL;
01384 
01385    return 0;
01386 }
01387 
01388 int ast_bridge_features_hook(struct ast_bridge_features *features,
01389    const char *dtmf,
01390    ast_bridge_features_hook_callback callback,
01391    void *hook_pvt,
01392    ast_bridge_features_hook_pvt_destructor destructor)
01393 {
01394    struct ast_bridge_features_hook *hook = NULL;
01395 
01396    /* Allocate new memory and setup it's various variables */
01397    if (!(hook = ast_calloc(1, sizeof(*hook)))) {
01398       return -1;
01399    }
01400 
01401    ast_copy_string(hook->dtmf, dtmf, sizeof(hook->dtmf));
01402    hook->callback = callback;
01403    hook->destructor = destructor;
01404    hook->hook_pvt = hook_pvt;
01405 
01406    /* Once done we add it onto the list. Now it will be picked up when DTMF is used */
01407    AST_LIST_INSERT_TAIL(&features->hooks, hook, entry);
01408 
01409    features->usable = 1;
01410 
01411    return 0;
01412 }
01413 
01414 int ast_bridge_features_set_talk_detector(struct ast_bridge_features *features,
01415    ast_bridge_talking_indicate_callback talker_cb,
01416    ast_bridge_talking_indicate_destructor talker_destructor,
01417    void *pvt_data)
01418 {
01419    features->talker_cb = talker_cb;
01420    features->talker_destructor_cb = talker_destructor;
01421    features->talker_pvt_data = pvt_data;
01422    return 0;
01423 }
01424 
01425 int ast_bridge_features_enable(struct ast_bridge_features *features, enum ast_bridge_builtin_feature feature, const char *dtmf, void *config)
01426 {
01427    /* If no alternate DTMF stream was provided use the default one */
01428    if (ast_strlen_zero(dtmf)) {
01429       dtmf = builtin_features_dtmf[feature];
01430       /* If no DTMF is still available (ie: it has been disabled) then error out now */
01431       if (ast_strlen_zero(dtmf)) {
01432          ast_debug(1, "Failed to enable built in feature %d on %p, no DTMF string is available for it.\n", feature, features);
01433          return -1;
01434       }
01435    }
01436 
01437    if (!builtin_features_handlers[feature]) {
01438       return -1;
01439    }
01440 
01441    /* The rest is basically pretty easy. We create another hook using the built in feature's callback and DTMF, easy as pie. */
01442    return ast_bridge_features_hook(features, dtmf, builtin_features_handlers[feature], config, NULL);
01443 }
01444 
01445 int ast_bridge_features_set_flag(struct ast_bridge_features *features, enum ast_bridge_feature_flags flag)
01446 {
01447    ast_set_flag(&features->feature_flags, flag);
01448    features->usable = 1;
01449    return 0;
01450 }
01451 
01452 int ast_bridge_features_init(struct ast_bridge_features *features)
01453 {
01454    /* Zero out the structure */
01455    memset(features, 0, sizeof(*features));
01456 
01457    /* Initialize the hooks list, just in case */
01458    AST_LIST_HEAD_INIT_NOLOCK(&features->hooks);
01459 
01460    return 0;
01461 }
01462 
01463 int ast_bridge_features_cleanup(struct ast_bridge_features *features)
01464 {
01465    struct ast_bridge_features_hook *hook = NULL;
01466 
01467    /* This is relatively simple, hooks are kept as a list on the features structure so we just pop them off and free them */
01468    while ((hook = AST_LIST_REMOVE_HEAD(&features->hooks, entry))) {
01469       if (hook->destructor) {
01470          hook->destructor(hook->hook_pvt);
01471       }
01472       ast_free(hook);
01473    }
01474    if (features->talker_destructor_cb && features->talker_pvt_data) {
01475       features->talker_destructor_cb(features->talker_pvt_data);
01476       features->talker_pvt_data = NULL;
01477    }
01478 
01479    return 0;
01480 }
01481 
01482 int ast_bridge_dtmf_stream(struct ast_bridge *bridge, const char *dtmf, struct ast_channel *chan)
01483 {
01484    struct ast_bridge_channel *bridge_channel = NULL;
01485 
01486    ao2_lock(bridge);
01487 
01488    AST_LIST_TRAVERSE(&bridge->channels, bridge_channel, entry) {
01489       if (bridge_channel->chan == chan) {
01490          continue;
01491       }
01492       ast_copy_string(bridge_channel->dtmf_stream_q, dtmf, sizeof(bridge_channel->dtmf_stream_q));
01493       ast_bridge_change_state(bridge_channel, AST_BRIDGE_CHANNEL_STATE_DTMF);
01494    }
01495 
01496    ao2_unlock(bridge);
01497 
01498    return 0;
01499 }
01500 
01501 void ast_bridge_set_mixing_interval(struct ast_bridge *bridge, unsigned int mixing_interval)
01502 {
01503    ao2_lock(bridge);
01504    bridge->internal_mixing_interval = mixing_interval;
01505    ao2_unlock(bridge);
01506 }
01507 
01508 void ast_bridge_set_internal_sample_rate(struct ast_bridge *bridge, unsigned int sample_rate)
01509 {
01510 
01511    ao2_lock(bridge);
01512    bridge->internal_sample_rate = sample_rate;
01513    ao2_unlock(bridge);
01514 }
01515 
01516 static void cleanup_video_mode(struct ast_bridge *bridge)
01517 {
01518    switch (bridge->video_mode.mode) {
01519    case AST_BRIDGE_VIDEO_MODE_NONE:
01520       break;
01521    case AST_BRIDGE_VIDEO_MODE_SINGLE_SRC:
01522       if (bridge->video_mode.mode_data.single_src_data.chan_vsrc) {
01523          ast_channel_unref(bridge->video_mode.mode_data.single_src_data.chan_vsrc);
01524       }
01525       break;
01526    case AST_BRIDGE_VIDEO_MODE_TALKER_SRC:
01527       if (bridge->video_mode.mode_data.talker_src_data.chan_vsrc) {
01528          ast_channel_unref(bridge->video_mode.mode_data.talker_src_data.chan_vsrc);
01529       }
01530       if (bridge->video_mode.mode_data.talker_src_data.chan_old_vsrc) {
01531          ast_channel_unref(bridge->video_mode.mode_data.talker_src_data.chan_old_vsrc);
01532       }
01533    }
01534    memset(&bridge->video_mode, 0, sizeof(bridge->video_mode));
01535 }
01536 
01537 void ast_bridge_set_single_src_video_mode(struct ast_bridge *bridge, struct ast_channel *video_src_chan)
01538 {
01539    ao2_lock(bridge);
01540    cleanup_video_mode(bridge);
01541    bridge->video_mode.mode = AST_BRIDGE_VIDEO_MODE_SINGLE_SRC;
01542    bridge->video_mode.mode_data.single_src_data.chan_vsrc = ast_channel_ref(video_src_chan);
01543    ast_test_suite_event_notify("BRIDGE_VIDEO_MODE", "Message: video mode set to single source\r\nVideo Mode: %d\r\nVideo Channel: %s", bridge->video_mode.mode, ast_channel_name(video_src_chan));
01544    ast_indicate(video_src_chan, AST_CONTROL_VIDUPDATE);
01545    ao2_unlock(bridge);
01546 }
01547 
01548 void ast_bridge_set_talker_src_video_mode(struct ast_bridge *bridge)
01549 {
01550    ao2_lock(bridge);
01551    cleanup_video_mode(bridge);
01552    bridge->video_mode.mode = AST_BRIDGE_VIDEO_MODE_TALKER_SRC;
01553    ast_test_suite_event_notify("BRIDGE_VIDEO_MODE", "Message: video mode set to talker source\r\nVideo Mode: %d", bridge->video_mode.mode);
01554    ao2_unlock(bridge);
01555 }
01556 
01557 void ast_bridge_update_talker_src_video_mode(struct ast_bridge *bridge, struct ast_channel *chan, int talker_energy, int is_keyframe)
01558 {
01559    struct ast_bridge_video_talker_src_data *data;
01560    /* If the channel doesn't support video, we don't care about it */
01561    if (!ast_format_cap_has_type(ast_channel_nativeformats(chan), AST_FORMAT_TYPE_VIDEO)) {
01562       return;
01563    }
01564 
01565    ao2_lock(bridge);
01566    data = &bridge->video_mode.mode_data.talker_src_data;
01567 
01568    if (data->chan_vsrc == chan) {
01569       data->average_talking_energy = talker_energy;
01570    } else if ((data->average_talking_energy < talker_energy) && is_keyframe) {
01571       if (data->chan_old_vsrc) {
01572          ast_channel_unref(data->chan_old_vsrc);
01573       }
01574       if (data->chan_vsrc) {
01575          data->chan_old_vsrc = data->chan_vsrc;
01576          ast_indicate(data->chan_old_vsrc, AST_CONTROL_VIDUPDATE);
01577       }
01578       data->chan_vsrc = ast_channel_ref(chan);
01579       data->average_talking_energy = talker_energy;
01580       ast_test_suite_event_notify("BRIDGE_VIDEO_SRC", "Message: video source updated\r\nVideo Channel: %s", ast_channel_name(data->chan_vsrc));
01581       ast_indicate(data->chan_vsrc, AST_CONTROL_VIDUPDATE);
01582    } else if ((data->average_talking_energy < talker_energy) && !is_keyframe) {
01583       ast_indicate(chan, AST_CONTROL_VIDUPDATE);
01584    } else if (!data->chan_vsrc && is_keyframe) {
01585       data->chan_vsrc = ast_channel_ref(chan);
01586       data->average_talking_energy = talker_energy;
01587       ast_test_suite_event_notify("BRIDGE_VIDEO_SRC", "Message: video source updated\r\nVideo Channel: %s", ast_channel_name(data->chan_vsrc));
01588       ast_indicate(chan, AST_CONTROL_VIDUPDATE);
01589    } else if (!data->chan_old_vsrc && is_keyframe) {
01590       data->chan_old_vsrc = ast_channel_ref(chan);
01591       ast_indicate(chan, AST_CONTROL_VIDUPDATE);
01592    }
01593    ao2_unlock(bridge);
01594 }
01595 
01596 int ast_bridge_number_video_src(struct ast_bridge *bridge)
01597 {
01598    int res = 0;
01599 
01600    ao2_lock(bridge);
01601    switch (bridge->video_mode.mode) {
01602    case AST_BRIDGE_VIDEO_MODE_NONE:
01603       break;
01604    case AST_BRIDGE_VIDEO_MODE_SINGLE_SRC:
01605       if (bridge->video_mode.mode_data.single_src_data.chan_vsrc) {
01606          res = 1;
01607       }
01608       break;
01609    case AST_BRIDGE_VIDEO_MODE_TALKER_SRC:
01610       if (bridge->video_mode.mode_data.talker_src_data.chan_vsrc) {
01611          res++;
01612       }
01613       if (bridge->video_mode.mode_data.talker_src_data.chan_old_vsrc) {
01614          res++;
01615       }
01616    }
01617    ao2_unlock(bridge);
01618    return res;
01619 }
01620 
01621 int ast_bridge_is_video_src(struct ast_bridge *bridge, struct ast_channel *chan)
01622 {
01623    int res = 0;
01624 
01625    ao2_lock(bridge);
01626    switch (bridge->video_mode.mode) {
01627    case AST_BRIDGE_VIDEO_MODE_NONE:
01628       break;
01629    case AST_BRIDGE_VIDEO_MODE_SINGLE_SRC:
01630       if (bridge->video_mode.mode_data.single_src_data.chan_vsrc == chan) {
01631          res = 1;
01632       }
01633       break;
01634    case AST_BRIDGE_VIDEO_MODE_TALKER_SRC:
01635       if (bridge->video_mode.mode_data.talker_src_data.chan_vsrc == chan) {
01636          res = 1;
01637       } else if (bridge->video_mode.mode_data.talker_src_data.chan_old_vsrc == chan) {
01638          res = 2;
01639       }
01640 
01641    }
01642    ao2_unlock(bridge);
01643    return res;
01644 }
01645 
01646 void ast_bridge_remove_video_src(struct ast_bridge *bridge, struct ast_channel *chan)
01647 {
01648    ao2_lock(bridge);
01649    switch (bridge->video_mode.mode) {
01650    case AST_BRIDGE_VIDEO_MODE_NONE:
01651       break;
01652    case AST_BRIDGE_VIDEO_MODE_SINGLE_SRC:
01653       if (bridge->video_mode.mode_data.single_src_data.chan_vsrc == chan) {
01654          if (bridge->video_mode.mode_data.single_src_data.chan_vsrc) {
01655             ast_channel_unref(bridge->video_mode.mode_data.single_src_data.chan_vsrc);
01656          }
01657          bridge->video_mode.mode_data.single_src_data.chan_vsrc = NULL;
01658       }
01659       break;
01660    case AST_BRIDGE_VIDEO_MODE_TALKER_SRC:
01661       if (bridge->video_mode.mode_data.talker_src_data.chan_vsrc == chan) {
01662          if (bridge->video_mode.mode_data.talker_src_data.chan_vsrc) {
01663             ast_channel_unref(bridge->video_mode.mode_data.talker_src_data.chan_vsrc);
01664          }
01665          bridge->video_mode.mode_data.talker_src_data.chan_vsrc = NULL;
01666          bridge->video_mode.mode_data.talker_src_data.average_talking_energy = 0;
01667       }
01668       if (bridge->video_mode.mode_data.talker_src_data.chan_old_vsrc == chan) {
01669          if (bridge->video_mode.mode_data.talker_src_data.chan_old_vsrc) {
01670             ast_channel_unref(bridge->video_mode.mode_data.talker_src_data.chan_old_vsrc);
01671          }
01672          bridge->video_mode.mode_data.talker_src_data.chan_old_vsrc = NULL;
01673       }
01674    }
01675    ao2_unlock(bridge);
01676 }