Mon Jun 27 16:50:49 2011

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 #include "asterisk.h"
00027 
00028 ASTERISK_FILE_VERSION(__FILE__, "$Revision: 266877 $")
00029 
00030 #include <signal.h>
00031 
00032 #include "asterisk/logger.h"
00033 #include "asterisk/channel.h"
00034 #include "asterisk/options.h"
00035 #include "asterisk/utils.h"
00036 #include "asterisk/lock.h"
00037 #include "asterisk/linkedlists.h"
00038 #include "asterisk/bridging.h"
00039 #include "asterisk/bridging_technology.h"
00040 #include "asterisk/app.h"
00041 #include "asterisk/file.h"
00042 #include "asterisk/module.h"
00043 #include "asterisk/astobj2.h"
00044 
00045 static AST_RWLIST_HEAD_STATIC(bridge_technologies, ast_bridge_technology);
00046 
00047 /* Initial starting point for the bridge array of channels */
00048 #define BRIDGE_ARRAY_START 128
00049 
00050 /* Grow rate of bridge array of channels */
00051 #define BRIDGE_ARRAY_GROW 32
00052 
00053 /*! Default DTMF keys for built in features */
00054 static char builtin_features_dtmf[AST_BRIDGE_BUILTIN_END][MAXIMUM_DTMF_FEATURE_STRING];
00055 
00056 /*! Function handlers for the built in features */
00057 static void *builtin_features_handlers[AST_BRIDGE_BUILTIN_END];
00058 
00059 int __ast_bridge_technology_register(struct ast_bridge_technology *technology, struct ast_module *module)
00060 {
00061    struct ast_bridge_technology *current = NULL;
00062 
00063    /* Perform a sanity check to make sure the bridge technology conforms to our needed requirements */
00064    if (ast_strlen_zero(technology->name) || !technology->capabilities || !technology->write) {
00065       ast_log(LOG_WARNING, "Bridge technology %s failed registration sanity check.\n", technology->name);
00066       return -1;
00067    }
00068 
00069    AST_RWLIST_WRLOCK(&bridge_technologies);
00070 
00071    /* Look for duplicate bridge technology already using this name, or already registered */
00072    AST_RWLIST_TRAVERSE(&bridge_technologies, current, entry) {
00073       if ((!strcasecmp(current->name, technology->name)) || (current == technology)) {
00074          ast_log(LOG_WARNING, "A bridge technology of %s already claims to exist in our world.\n", technology->name);
00075          AST_RWLIST_UNLOCK(&bridge_technologies);
00076          return -1;
00077       }
00078    }
00079 
00080    /* Copy module pointer so reference counting can keep the module from unloading */
00081    technology->mod = module;
00082 
00083    /* Insert our new bridge technology into the list and print out a pretty message */
00084    AST_RWLIST_INSERT_TAIL(&bridge_technologies, technology, entry);
00085 
00086    AST_RWLIST_UNLOCK(&bridge_technologies);
00087 
00088    if (option_verbose > 1) {
00089       ast_verbose(VERBOSE_PREFIX_2 "Registered bridge technology %s\n", technology->name);
00090    }
00091 
00092    return 0;
00093 }
00094 
00095 int ast_bridge_technology_unregister(struct ast_bridge_technology *technology)
00096 {
00097    struct ast_bridge_technology *current = NULL;
00098 
00099    AST_RWLIST_WRLOCK(&bridge_technologies);
00100 
00101    /* Ensure the bridge technology is registered before removing it */
00102    AST_RWLIST_TRAVERSE_SAFE_BEGIN(&bridge_technologies, current, entry) {
00103       if (current == technology) {
00104          AST_RWLIST_REMOVE_CURRENT(entry);
00105          if (option_verbose > 1) {
00106             ast_verbose(VERBOSE_PREFIX_2 "Unregistered bridge technology %s\n", technology->name);
00107          }
00108          break;
00109       }
00110    }
00111    AST_RWLIST_TRAVERSE_SAFE_END;
00112 
00113    AST_RWLIST_UNLOCK(&bridge_technologies);
00114 
00115    return current ? 0 : -1;
00116 }
00117 
00118 void ast_bridge_change_state(struct ast_bridge_channel *bridge_channel, enum ast_bridge_channel_state new_state)
00119 {
00120    /* Change the state on the bridge channel */
00121    bridge_channel->state = new_state;
00122 
00123    /* Only poke the channel's thread if it is not us */
00124    if (!pthread_equal(pthread_self(), bridge_channel->thread)) {
00125       pthread_kill(bridge_channel->thread, SIGURG);
00126       ast_mutex_lock(&bridge_channel->lock);
00127       ast_cond_signal(&bridge_channel->cond);
00128       ast_mutex_unlock(&bridge_channel->lock);
00129    }
00130 
00131    return;
00132 }
00133 
00134 /*! \brief Helper function to poke the bridge thread */
00135 static void bridge_poke(struct ast_bridge *bridge)
00136 {
00137    /* Poke the thread just in case */
00138    if (bridge->thread != AST_PTHREADT_NULL && bridge->thread != AST_PTHREADT_STOP) {
00139       pthread_kill(bridge->thread, SIGURG);
00140    }
00141 
00142    return;
00143 }
00144 
00145 /*! \brief Helper function to add a channel to the bridge array
00146  *
00147  * \note This function assumes the bridge is locked.
00148  */
00149 static void bridge_array_add(struct ast_bridge *bridge, struct ast_channel *chan)
00150 {
00151    /* We have to make sure the bridge thread is not using the bridge array before messing with it */
00152    while (bridge->waiting) {
00153       bridge_poke(bridge);
00154       sched_yield();
00155    }
00156 
00157    bridge->array[bridge->array_num++] = chan;
00158 
00159    ast_debug(1, "Added channel %s(%p) to bridge array on %p, new count is %d\n", chan->name, chan, bridge, (int)bridge->array_num);
00160 
00161    /* If the next addition of a channel will exceed our array size grow it out */
00162    if (bridge->array_num == bridge->array_size) {
00163       struct ast_channel **tmp;
00164       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);
00165       if (!(tmp = ast_realloc(bridge->array, (bridge->array_size + BRIDGE_ARRAY_GROW) * sizeof(struct ast_channel *)))) {
00166          ast_log(LOG_ERROR, "Failed to allocate more space for another channel on bridge '%p', this is not going to end well\n", bridge);
00167          return;
00168       }
00169       bridge->array = tmp;
00170       bridge->array_size += BRIDGE_ARRAY_GROW;
00171    }
00172 
00173    return;
00174 }
00175 
00176 /*! \brief Helper function to remove a channel from the bridge array
00177  *
00178  * \note This function assumes the bridge is locked.
00179  */
00180 static void bridge_array_remove(struct ast_bridge *bridge, struct ast_channel *chan)
00181 {
00182    int i;
00183 
00184    /* We have to make sure the bridge thread is not using the bridge array before messing with it */
00185    while (bridge->waiting) {
00186       bridge_poke(bridge);
00187       sched_yield();
00188    }
00189 
00190    for (i = 0; i < bridge->array_num; i++) {
00191       if (bridge->array[i] == chan) {
00192          bridge->array[i] = (bridge->array[(bridge->array_num - 1)] != chan ? bridge->array[(bridge->array_num - 1)] : NULL);
00193          bridge->array[(bridge->array_num - 1)] = NULL;
00194          bridge->array_num--;
00195          ast_debug(1, "Removed channel %p from bridge array on %p, new count is %d\n", chan, bridge, (int)bridge->array_num);
00196          break;
00197       }
00198    }
00199 
00200    return;
00201 }
00202 
00203 /*! \brief Helper function to find a bridge channel given a channel */
00204 static struct ast_bridge_channel *find_bridge_channel(struct ast_bridge *bridge, struct ast_channel *chan)
00205 {
00206    struct ast_bridge_channel *bridge_channel = NULL;
00207 
00208    AST_LIST_TRAVERSE(&bridge->channels, bridge_channel, entry) {
00209       if (bridge_channel->chan == chan) {
00210          break;
00211       }
00212    }
00213 
00214    return bridge_channel;
00215 }
00216 
00217 /*! \brief Internal function to see whether a bridge should dissolve, and if so do it */
00218 static void bridge_check_dissolve(struct ast_bridge *bridge, struct ast_bridge_channel *bridge_channel)
00219 {
00220    struct ast_bridge_channel *bridge_channel2 = NULL;
00221 
00222    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))) {
00223       return;
00224    }
00225 
00226    ast_debug(1, "Dissolving bridge %p\n", bridge);
00227 
00228    AST_LIST_TRAVERSE(&bridge->channels, bridge_channel2, entry) {
00229       if (bridge_channel2->state != AST_BRIDGE_CHANNEL_STATE_END && bridge_channel2->state != AST_BRIDGE_CHANNEL_STATE_DEPART) {
00230          ast_bridge_change_state(bridge_channel2, AST_BRIDGE_CHANNEL_STATE_HANGUP);
00231       }
00232    }
00233 
00234    /* Since all the channels are going away let's go ahead and stop our on thread */
00235    bridge->stop = 1;
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_handle_trip(struct ast_bridge *bridge, struct ast_bridge_channel *bridge_channel, struct ast_channel *chan, int outfd)
00277 {
00278    /* If no bridge channel has been provided and the actual channel has been provided find it */
00279    if (chan && !bridge_channel) {
00280       bridge_channel = find_bridge_channel(bridge, chan);
00281    }
00282 
00283    /* If a bridge channel with actual channel is present read a frame and handle it */
00284    if (chan && bridge_channel) {
00285       struct ast_frame *frame = (((bridge->features.mute) || (bridge_channel->features && bridge_channel->features->mute)) ? ast_read_noaudio(chan) : ast_read(chan));
00286 
00287       /* This is pretty simple... see if they hung up */
00288       if (!frame || (frame->frametype == AST_FRAME_CONTROL && frame->subclass.integer == AST_CONTROL_HANGUP)) {
00289          /* Signal the thread that is handling the bridged channel that it should be ended */
00290          ast_bridge_change_state(bridge_channel, AST_BRIDGE_CHANNEL_STATE_END);
00291       } else if (frame->frametype == AST_FRAME_CONTROL && bridge_drop_control_frame(frame->subclass.integer)) {
00292          ast_debug(1, "Dropping control frame from bridge channel %p\n", bridge_channel);
00293       } else {
00294          if (frame->frametype == AST_FRAME_DTMF_BEGIN) {
00295             frame = bridge_handle_dtmf(bridge, bridge_channel, frame);
00296          }
00297          /* Simply write the frame out to the bridge technology if it still exists */
00298          if (frame) {
00299             bridge->technology->write(bridge, bridge_channel, frame);
00300          }
00301       }
00302 
00303       if (frame) {
00304          ast_frfree(frame);
00305       }
00306       return;
00307    }
00308 
00309    /* If a file descriptor actually tripped pass it off to the bridge technology */
00310    if (outfd > -1 && bridge->technology->fd) {
00311       bridge->technology->fd(bridge, bridge_channel, outfd);
00312       return;
00313    }
00314 
00315    /* If all else fails just poke the bridge */
00316    if (bridge->technology->poke && bridge_channel) {
00317       bridge->technology->poke(bridge, bridge_channel);
00318       return;
00319    }
00320 
00321    return;
00322 }
00323 
00324 /*! \brief Generic thread loop, TODO: Rethink this/improve it */
00325 static int generic_thread_loop(struct ast_bridge *bridge)
00326 {
00327    while (!bridge->stop && !bridge->refresh && bridge->array_num) {
00328       struct ast_channel *winner = NULL;
00329       int to = -1;
00330 
00331       /* Move channels around for priority reasons if we have more than one channel in our array */
00332       if (bridge->array_num > 1) {
00333          struct ast_channel *first = bridge->array[0];
00334          memmove(bridge->array, bridge->array + 1, sizeof(struct ast_channel *) * (bridge->array_num - 1));
00335          bridge->array[(bridge->array_num - 1)] = first;
00336       }
00337 
00338       /* Wait on the channels */
00339       bridge->waiting = 1;
00340       ao2_unlock(bridge);
00341       winner = ast_waitfor_n(bridge->array, (int)bridge->array_num, &to);
00342       bridge->waiting = 0;
00343       ao2_lock(bridge);
00344 
00345       /* Process whatever they did */
00346       ast_bridge_handle_trip(bridge, NULL, winner, -1);
00347    }
00348 
00349    return 0;
00350 }
00351 
00352 /*! \brief Bridge thread function */
00353 static void *bridge_thread(void *data)
00354 {
00355    struct ast_bridge *bridge = data;
00356    int res = 0;
00357 
00358    ao2_lock(bridge);
00359 
00360    ast_debug(1, "Started bridge thread for %p\n", bridge);
00361 
00362    /* Loop around until we are told to stop */
00363    while (!bridge->stop && bridge->array_num && !res) {
00364       /* In case the refresh bit was set simply set it back to off */
00365       bridge->refresh = 0;
00366 
00367       ast_debug(1, "Launching bridge thread function %p for bridge %p\n", (bridge->technology->thread ? bridge->technology->thread : &generic_thread_loop), bridge);
00368 
00369       /* Execute the appropriate thread function. If the technology does not provide one we use the generic one */
00370       res = (bridge->technology->thread ? bridge->technology->thread(bridge) : generic_thread_loop(bridge));
00371    }
00372 
00373    ast_debug(1, "Ending bridge thread for %p\n", bridge);
00374 
00375    /* Indicate the bridge thread is no longer active */
00376    bridge->thread = AST_PTHREADT_NULL;
00377    ao2_unlock(bridge);
00378 
00379    ao2_ref(bridge, -1);
00380 
00381    return NULL;
00382 }
00383 
00384 /*! \brief Helper function used to find the "best" bridge technology given a specified capabilities */
00385 static struct ast_bridge_technology *find_best_technology(format_t capabilities)
00386 {
00387    struct ast_bridge_technology *current = NULL, *best = NULL;
00388 
00389    AST_RWLIST_RDLOCK(&bridge_technologies);
00390    AST_RWLIST_TRAVERSE(&bridge_technologies, current, entry) {
00391       char tmp1[256], tmp2[256];
00392       ast_debug(1, "Bridge technology %s has capabilities %s and we want %s\n", current->name,
00393          ast_getformatname_multiple(tmp1, sizeof(tmp1), current->capabilities),
00394          ast_getformatname_multiple(tmp2, sizeof(tmp2), capabilities));
00395       if (current->suspended) {
00396          ast_debug(1, "Bridge technology %s is suspended. Skipping.\n", current->name);
00397          continue;
00398       }
00399       if (!(current->capabilities & capabilities)) {
00400          ast_debug(1, "Bridge technology %s does not have the capabilities we need.\n", current->name);
00401          continue;
00402       }
00403       if (best && best->preference < current->preference) {
00404          ast_debug(1, "Bridge technology %s has preference %d while %s has preference %d. Skipping.\n", current->name, current->preference, best->name, best->preference);
00405          continue;
00406       }
00407       best = current;
00408    }
00409 
00410    if (best) {
00411       /* Increment it's module reference count if present so it does not get unloaded while in use */
00412       if (best->mod) {
00413          ast_module_ref(best->mod);
00414       }
00415       ast_debug(1, "Chose bridge technology %s\n", best->name);
00416    }
00417 
00418    AST_RWLIST_UNLOCK(&bridge_technologies);
00419 
00420    return best;
00421 }
00422 
00423 static void destroy_bridge(void *obj)
00424 {
00425    struct ast_bridge *bridge = obj;
00426 
00427    ast_debug(1, "Actually destroying bridge %p, nobody wants it anymore\n", bridge);
00428 
00429    /* Pass off the bridge to the technology to destroy if needed */
00430    if (bridge->technology->destroy) {
00431       ast_debug(1, "Giving bridge technology %s the bridge structure %p to destroy\n", bridge->technology->name, bridge);
00432       if (bridge->technology->destroy(bridge)) {
00433          ast_debug(1, "Bridge technology %s failed to destroy bridge structure %p... trying our best\n", bridge->technology->name, bridge);
00434       }
00435    }
00436 
00437    /* We are no longer using the bridge technology so decrement the module reference count on it */
00438    if (bridge->technology->mod) {
00439       ast_module_unref(bridge->technology->mod);
00440    }
00441 
00442    /* Last but not least clean up the features configuration */
00443    ast_bridge_features_cleanup(&bridge->features);
00444 
00445    /* Drop the array of channels */
00446    ast_free(bridge->array);
00447 
00448    return;
00449 }
00450 
00451 struct ast_bridge *ast_bridge_new(format_t capabilities, int flags)
00452 {
00453    struct ast_bridge *bridge = NULL;
00454    struct ast_bridge_technology *bridge_technology = NULL;
00455 
00456    /* If we need to be a smart bridge see if we can move between 1to1 and multimix bridges */
00457    if (flags & AST_BRIDGE_FLAG_SMART) {
00458       struct ast_bridge *other_bridge;
00459 
00460       if (!(other_bridge = ast_bridge_new((capabilities & AST_BRIDGE_CAPABILITY_1TO1MIX) ? AST_BRIDGE_CAPABILITY_MULTIMIX : AST_BRIDGE_CAPABILITY_1TO1MIX, 0))) {
00461          return NULL;
00462       }
00463 
00464       ast_bridge_destroy(other_bridge);
00465    }
00466 
00467    /* If capabilities were provided use our helper function to find the "best" bridge technology, otherwise we can
00468     * just look for the most basic capability needed, single 1to1 mixing. */
00469    bridge_technology = (capabilities ? find_best_technology(capabilities) : find_best_technology(AST_BRIDGE_CAPABILITY_1TO1MIX));
00470 
00471    /* If no bridge technology was found we can't possibly do bridging so fail creation of the bridge */
00472    if (!bridge_technology) {
00473       char codec_buf[256];
00474       ast_debug(1, "Failed to find a bridge technology to satisfy capabilities %s\n",
00475          ast_getformatname_multiple(codec_buf, sizeof(codec_buf), capabilities));
00476       return NULL;
00477    }
00478 
00479    /* We have everything we need to create this bridge... so allocate the memory, link things together, and fire her up! */
00480    if (!(bridge = ao2_alloc(sizeof(*bridge), destroy_bridge))) {
00481       return NULL;
00482    }
00483 
00484    bridge->technology = bridge_technology;
00485    bridge->thread = AST_PTHREADT_NULL;
00486 
00487    /* Create an array of pointers for the channels that will be joining us */
00488    bridge->array = ast_calloc(BRIDGE_ARRAY_START, sizeof(struct ast_channel*));
00489    bridge->array_size = BRIDGE_ARRAY_START;
00490 
00491    ast_set_flag(&bridge->feature_flags, flags);
00492 
00493    /* Pass off the bridge to the technology to manipulate if needed */
00494    if (bridge->technology->create) {
00495       ast_debug(1, "Giving bridge technology %s the bridge structure %p to setup\n", bridge->technology->name, bridge);
00496       if (bridge->technology->create(bridge)) {
00497          ast_debug(1, "Bridge technology %s failed to setup bridge structure %p\n", bridge->technology->name, bridge);
00498          ao2_ref(bridge, -1);
00499          bridge = NULL;
00500       }
00501    }
00502 
00503    return bridge;
00504 }
00505 
00506 int ast_bridge_check(format_t capabilities)
00507 {
00508    struct ast_bridge_technology *bridge_technology = NULL;
00509 
00510    if (!(bridge_technology = find_best_technology(capabilities))) {
00511       return 0;
00512    }
00513 
00514    ast_module_unref(bridge_technology->mod);
00515 
00516    return 1;
00517 }
00518 
00519 int ast_bridge_destroy(struct ast_bridge *bridge)
00520 {
00521    struct ast_bridge_channel *bridge_channel = NULL;
00522 
00523    ao2_lock(bridge);
00524 
00525    bridge->stop = 1;
00526 
00527    bridge_poke(bridge);
00528 
00529    ast_debug(1, "Telling all channels in bridge %p to end and leave the party\n", bridge);
00530 
00531    /* Drop every bridged channel, the last one will cause the bridge thread (if it exists) to exit */
00532    AST_LIST_TRAVERSE(&bridge->channels, bridge_channel, entry) {
00533       ast_bridge_change_state(bridge_channel, AST_BRIDGE_CHANNEL_STATE_END);
00534    }
00535 
00536    ao2_unlock(bridge);
00537 
00538    ao2_ref(bridge, -1);
00539 
00540    return 0;
00541 }
00542 
00543 static int bridge_make_compatible(struct ast_bridge *bridge, struct ast_bridge_channel *bridge_channel)
00544 {
00545    format_t formats[2] = {bridge_channel->chan->readformat, bridge_channel->chan->writeformat};
00546 
00547    /* Are the formats currently in use something ths bridge can handle? */
00548    if (!(bridge->technology->formats & bridge_channel->chan->readformat)) {
00549       format_t best_format = ast_best_codec(bridge->technology->formats);
00550 
00551       /* Read format is a no go... */
00552       if (option_debug) {
00553          char codec_buf[512];
00554          ast_debug(1, "Bridge technology %s wants to read any of formats %s but channel has %s\n", bridge->technology->name,
00555             ast_getformatname_multiple(codec_buf, sizeof(codec_buf), bridge->technology->formats),
00556             ast_getformatname(formats[0]));
00557       }
00558       /* Switch read format to the best one chosen */
00559       if (ast_set_read_format(bridge_channel->chan, best_format)) {
00560          ast_log(LOG_WARNING, "Failed to set channel %s to read format %s\n", bridge_channel->chan->name, ast_getformatname(best_format));
00561          return -1;
00562       }
00563       ast_debug(1, "Bridge %p put channel %s into read format %s\n", bridge, bridge_channel->chan->name, ast_getformatname(best_format));
00564    } else {
00565       ast_debug(1, "Bridge %p is happy that channel %s already has read format %s\n", bridge, bridge_channel->chan->name, ast_getformatname(formats[0]));
00566    }
00567 
00568    if (!(bridge->technology->formats & formats[1])) {
00569       int best_format = ast_best_codec(bridge->technology->formats);
00570 
00571       /* Write format is a no go... */
00572       if (option_debug) {
00573          char codec_buf[512];
00574          ast_debug(1, "Bridge technology %s wants to write any of formats %s but channel has %s\n", bridge->technology->name,
00575             ast_getformatname_multiple(codec_buf, sizeof(codec_buf), bridge->technology->formats),
00576             ast_getformatname(formats[1]));
00577       }
00578       /* Switch write format to the best one chosen */
00579       if (ast_set_write_format(bridge_channel->chan, best_format)) {
00580          ast_log(LOG_WARNING, "Failed to set channel %s to write format %s\n", bridge_channel->chan->name, ast_getformatname(best_format));
00581          return -1;
00582       }
00583       ast_debug(1, "Bridge %p put channel %s into write format %s\n", bridge, bridge_channel->chan->name, ast_getformatname(best_format));
00584    } else {
00585       ast_debug(1, "Bridge %p is happy that channel %s already has write format %s\n", bridge, bridge_channel->chan->name, ast_getformatname(formats[1]));
00586    }
00587 
00588    return 0;
00589 }
00590 
00591 /*! \brief Perform the smart bridge operation. Basically sees if a new bridge technology should be used instead of the current one. */
00592 static int smart_bridge_operation(struct ast_bridge *bridge, struct ast_bridge_channel *bridge_channel, int count)
00593 {
00594    format_t new_capabilities = 0;
00595    struct ast_bridge_technology *new_technology = NULL, *old_technology = bridge->technology;
00596    struct ast_bridge temp_bridge = {
00597       .technology = bridge->technology,
00598       .bridge_pvt = bridge->bridge_pvt,
00599    };
00600    struct ast_bridge_channel *bridge_channel2 = NULL;
00601 
00602    /* Based on current feature determine whether we want to change bridge technologies or not */
00603    if (bridge->technology->capabilities & AST_BRIDGE_CAPABILITY_1TO1MIX) {
00604       if (count <= 2) {
00605          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);
00606          return 0;
00607       }
00608       new_capabilities = AST_BRIDGE_CAPABILITY_MULTIMIX;
00609    } else if (bridge->technology->capabilities & AST_BRIDGE_CAPABILITY_MULTIMIX) {
00610       if (count > 2) {
00611          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);
00612          return 0;
00613       }
00614       new_capabilities = AST_BRIDGE_CAPABILITY_1TO1MIX;
00615    }
00616 
00617    if (!new_capabilities) {
00618       ast_debug(1, "Bridge '%p' has no new capabilities, not performing smart bridge operation.\n", bridge);
00619       return 0;
00620    }
00621 
00622    /* Attempt to find a new bridge technology to satisfy the capabilities */
00623    if (!(new_technology = find_best_technology(new_capabilities))) {
00624       char codec_buf[256];
00625       ast_debug(1, "Smart bridge operation was unable to find new bridge technology with capabilities %s to satisfy bridge %p\n",
00626          ast_getformatname_multiple(codec_buf, sizeof(codec_buf), new_capabilities), bridge);
00627       return -1;
00628    }
00629 
00630    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);
00631 
00632    /* If a thread is currently executing for the current technology tell it to stop */
00633    if (bridge->thread != AST_PTHREADT_NULL) {
00634       /* 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. */
00635       if (new_technology->capabilities & AST_BRIDGE_CAPABILITY_THREAD) {
00636          ast_debug(1, "Telling current bridge thread for bridge %p to refresh\n", bridge);
00637          bridge->refresh = 1;
00638          bridge_poke(bridge);
00639       } else {
00640          pthread_t bridge_thread = bridge->thread;
00641          ast_debug(1, "Telling current bridge thread for bridge %p to stop\n", bridge);
00642          bridge->stop = 1;
00643          bridge_poke(bridge);
00644          ao2_unlock(bridge);
00645          pthread_join(bridge_thread, NULL);
00646          ao2_lock(bridge);
00647       }
00648    }
00649 
00650    /* 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 */
00651    bridge->bridge_pvt = NULL;
00652    bridge->technology = new_technology;
00653 
00654    /* Pass the bridge to the new bridge technology so it can set it up */
00655    if (new_technology->create) {
00656       ast_debug(1, "Giving bridge technology %s the bridge structure %p to setup\n", new_technology->name, bridge);
00657       if (new_technology->create(bridge)) {
00658          ast_debug(1, "Bridge technology %s failed to setup bridge structure %p\n", new_technology->name, bridge);
00659       }
00660    }
00661 
00662    /* Move existing channels over to the new technology, while taking them away from the old one */
00663    AST_LIST_TRAVERSE(&bridge->channels, bridge_channel2, entry) {
00664       /* Skip over channel that initiated the smart bridge operation */
00665       if (bridge_channel == bridge_channel2) {
00666          continue;
00667       }
00668 
00669       /* First we part them from the old technology */
00670       if (old_technology->leave) {
00671          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);
00672          if (old_technology->leave(&temp_bridge, bridge_channel2)) {
00673             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);
00674          }
00675       }
00676 
00677       /* Second we make them compatible again with the bridge */
00678       bridge_make_compatible(bridge, bridge_channel2);
00679 
00680       /* Third we join them to the new technology */
00681       if (new_technology->join) {
00682          ast_debug(1, "Giving bridge technology %s notification that %p is joining bridge %p\n", new_technology->name, bridge_channel2, bridge);
00683          if (new_technology->join(bridge, bridge_channel2)) {
00684             ast_debug(1, "Bridge technology %s failed to join %p to bridge %p\n", new_technology->name, bridge_channel2, bridge);
00685          }
00686       }
00687 
00688       /* Fourth we tell them to wake up so they become aware that they above has happened */
00689       pthread_kill(bridge_channel2->thread, SIGURG);
00690       ast_mutex_lock(&bridge_channel2->lock);
00691       ast_cond_signal(&bridge_channel2->cond);
00692       ast_mutex_unlock(&bridge_channel2->lock);
00693    }
00694 
00695    /* 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 */
00696    if (old_technology->destroy) {
00697       ast_debug(1, "Giving bridge technology %s the bridge structure %p (really %p) to destroy\n", old_technology->name, &temp_bridge, bridge);
00698       if (old_technology->destroy(&temp_bridge)) {
00699          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);
00700       }
00701    }
00702 
00703    /* Finally if the old technology has module referencing remove our reference, we are no longer going to use it */
00704    if (old_technology->mod) {
00705       ast_module_unref(old_technology->mod);
00706    }
00707 
00708    return 0;
00709 }
00710 
00711 /*! \brief Run in a multithreaded model. Each joined channel does writing/reading in their own thread. TODO: Improve */
00712 static enum ast_bridge_channel_state bridge_channel_join_multithreaded(struct ast_bridge_channel *bridge_channel)
00713 {
00714    int fds[4] = { -1, }, nfds = 0, i = 0, outfd = -1, ms = -1;
00715    struct ast_channel *chan = NULL;
00716 
00717    /* Add any file descriptors we may want to monitor */
00718    if (bridge_channel->bridge->technology->fd) {
00719       for (i = 0; i < 4; i ++) {
00720          if (bridge_channel->fds[i] >= 0) {
00721             fds[nfds++] = bridge_channel->fds[i];
00722          }
00723       }
00724    }
00725 
00726    ao2_unlock(bridge_channel->bridge);
00727 
00728    /* Wait for data to either come from the channel or us to be signalled */
00729    if (!bridge_channel->suspended) {
00730       ast_debug(1, "Going into a multithreaded waitfor for bridge channel %p of bridge %p\n", bridge_channel, bridge_channel->bridge);
00731       chan = ast_waitfor_nandfds(&bridge_channel->chan, 1, fds, nfds, NULL, &outfd, &ms);
00732    } else {
00733       ast_mutex_lock(&bridge_channel->lock);
00734       ast_debug(1, "Going into a multithreaded signal wait for bridge channel %p of bridge %p\n", bridge_channel, bridge_channel->bridge);
00735       ast_cond_wait(&bridge_channel->cond, &bridge_channel->lock);
00736       ast_mutex_unlock(&bridge_channel->lock);
00737    }
00738 
00739    ao2_lock(bridge_channel->bridge);
00740 
00741    if (!bridge_channel->suspended) {
00742       ast_bridge_handle_trip(bridge_channel->bridge, bridge_channel, chan, outfd);
00743    }
00744 
00745    return bridge_channel->state;
00746 }
00747 
00748 /*! \brief Run in a singlethreaded model. Each joined channel yields itself to the main bridge thread. TODO: Improve */
00749 static enum ast_bridge_channel_state bridge_channel_join_singlethreaded(struct ast_bridge_channel *bridge_channel)
00750 {
00751    ao2_unlock(bridge_channel->bridge);
00752    ast_mutex_lock(&bridge_channel->lock);
00753    if (bridge_channel->state == AST_BRIDGE_CHANNEL_STATE_WAIT) {
00754       ast_debug(1, "Going into a single threaded signal wait for bridge channel %p of bridge %p\n", bridge_channel, bridge_channel->bridge);
00755       ast_cond_wait(&bridge_channel->cond, &bridge_channel->lock);
00756    }
00757    ast_mutex_unlock(&bridge_channel->lock);
00758    ao2_lock(bridge_channel->bridge);
00759 
00760    return bridge_channel->state;
00761 }
00762 
00763 /*! \brief Internal function that suspends a channel from a bridge */
00764 static void bridge_channel_suspend(struct ast_bridge *bridge, struct ast_bridge_channel *bridge_channel)
00765 {
00766    bridge_channel->suspended = 1;
00767 
00768    bridge_array_remove(bridge, bridge_channel->chan);
00769 
00770    if (bridge->technology->suspend) {
00771       bridge->technology->suspend(bridge, bridge_channel);
00772    }
00773 
00774    return;
00775 }
00776 
00777 /*! \brief Internal function that unsuspends a channel from a bridge */
00778 static void bridge_channel_unsuspend(struct ast_bridge *bridge, struct ast_bridge_channel *bridge_channel)
00779 {
00780    bridge_channel->suspended =0;
00781 
00782    bridge_array_add(bridge, bridge_channel->chan);
00783 
00784    if (bridge->technology->unsuspend) {
00785       bridge->technology->unsuspend(bridge, bridge_channel);
00786    }
00787 
00788    return;
00789 }
00790 
00791 /*! \brief Internal function that executes a feature on a bridge channel */
00792 static void bridge_channel_feature(struct ast_bridge *bridge, struct ast_bridge_channel *bridge_channel)
00793 {
00794    struct ast_bridge_features *features = (bridge_channel->features ? bridge_channel->features : &bridge->features);
00795    struct ast_bridge_features_hook *hook = NULL;
00796    char dtmf[MAXIMUM_DTMF_FEATURE_STRING] = "";
00797    int look_for_dtmf = 1, dtmf_len = 0;
00798 
00799    /* 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 */
00800    ast_set_flag(bridge_channel->chan, AST_FLAG_END_DTMF_ONLY);
00801 
00802    /* Wait for DTMF on the channel and put it into a buffer. If the buffer matches any feature hook execute the hook. */
00803    while (look_for_dtmf) {
00804       int res = ast_waitfordigit(bridge_channel->chan, 3000);
00805 
00806       /* If the above timed out simply exit */
00807       if (!res) {
00808          ast_debug(1, "DTMF feature string collection on bridge channel %p timed out\n", bridge_channel);
00809          break;
00810       } else if (res < 0) {
00811          ast_debug(1, "DTMF feature string collection failed on bridge channel %p for some reason\n", bridge_channel);
00812          break;
00813       }
00814 
00815       /* Add the above DTMF into the DTMF string so we can do our matching */
00816       dtmf[dtmf_len++] = res;
00817 
00818       ast_debug(1, "DTMF feature string on bridge channel %p is now '%s'\n", bridge_channel, dtmf);
00819 
00820       /* Assume that we do not want to look for DTMF any longer */
00821       look_for_dtmf = 0;
00822 
00823       /* See if a DTMF feature hook matches or can match */
00824       AST_LIST_TRAVERSE(&features->hooks, hook, entry) {
00825          /* If this hook matches just break out now */
00826          if (!strcmp(hook->dtmf, dtmf)) {
00827             ast_debug(1, "DTMF feature hook %p matched DTMF string '%s' on bridge channel %p\n", hook, dtmf, bridge_channel);
00828             break;
00829          } else if (!strncmp(hook->dtmf, dtmf, dtmf_len)) {
00830             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);
00831             look_for_dtmf = 1;
00832          } else {
00833             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);
00834          }
00835       }
00836 
00837       /* If we have reached the maximum length of a DTMF feature string bail out */
00838       if (dtmf_len == MAXIMUM_DTMF_FEATURE_STRING) {
00839          break;
00840       }
00841    }
00842 
00843    /* Since we are done bringing DTMF in return to using both begin and end frames */
00844    ast_clear_flag(bridge_channel->chan, AST_FLAG_END_DTMF_ONLY);
00845 
00846    /* If a hook was actually matched execute it on this channel, otherwise stream up the DTMF to the other channels */
00847    if (hook) {
00848       hook->callback(bridge, bridge_channel, hook->hook_pvt);
00849    } else {
00850       ast_bridge_dtmf_stream(bridge, dtmf, bridge_channel->chan);
00851       ast_bridge_change_state(bridge_channel, AST_BRIDGE_CHANNEL_STATE_WAIT);
00852    }
00853 
00854    return;
00855 }
00856 
00857 /*! \brief Internal function that plays back DTMF on a bridge channel */
00858 static void bridge_channel_dtmf_stream(struct ast_bridge *bridge, struct ast_bridge_channel *bridge_channel)
00859 {
00860    char dtmf_q[8] = "";
00861 
00862    ast_copy_string(dtmf_q, bridge_channel->dtmf_stream_q, sizeof(dtmf_q));
00863    bridge_channel->dtmf_stream_q[0] = '\0';
00864 
00865    ast_debug(1, "Playing DTMF stream '%s' out to bridge channel %p\n", dtmf_q, bridge_channel);
00866    ast_dtmf_stream(bridge_channel->chan, NULL, dtmf_q, 250, 0);
00867 
00868    ast_bridge_change_state(bridge_channel, AST_BRIDGE_CHANNEL_STATE_WAIT);
00869 
00870    return;
00871 }
00872 
00873 /*! \brief Join a channel to a bridge and handle anything the bridge may want us to do */
00874 static enum ast_bridge_channel_state bridge_channel_join(struct ast_bridge_channel *bridge_channel)
00875 {
00876    int formats[2] = { bridge_channel->chan->readformat, bridge_channel->chan->writeformat };
00877    enum ast_bridge_channel_state state;
00878 
00879    /* Record the thread that will be the owner of us */
00880    bridge_channel->thread = pthread_self();
00881 
00882    ast_debug(1, "Joining bridge channel %p to bridge %p\n", bridge_channel, bridge_channel->bridge);
00883 
00884    ao2_lock(bridge_channel->bridge);
00885 
00886    state = bridge_channel->state;
00887 
00888    /* Add channel into the bridge */
00889    AST_LIST_INSERT_TAIL(&bridge_channel->bridge->channels, bridge_channel, entry);
00890    bridge_channel->bridge->num++;
00891 
00892    bridge_array_add(bridge_channel->bridge, bridge_channel->chan);
00893 
00894    if (bridge_channel->swap) {
00895       struct ast_bridge_channel *bridge_channel2 = NULL;
00896 
00897       /* If we are performing a swap operation we do not need to execute the smart bridge operation as the actual number of channels involved will not have changed, we just need to tell the other channel to leave */
00898       if ((bridge_channel2 = find_bridge_channel(bridge_channel->bridge, bridge_channel->swap))) {
00899          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);
00900          ast_bridge_change_state(bridge_channel2, AST_BRIDGE_CHANNEL_STATE_HANGUP);
00901       }
00902 
00903       bridge_channel->swap = NULL;
00904    } else if (ast_test_flag(&bridge_channel->bridge->feature_flags, AST_BRIDGE_FLAG_SMART)) {
00905       /* Perform the smart bridge operation, basically see if we need to move around between technologies */
00906       smart_bridge_operation(bridge_channel->bridge, bridge_channel, bridge_channel->bridge->num);
00907    }
00908 
00909    /* Make the channel compatible with the bridge */
00910    bridge_make_compatible(bridge_channel->bridge, bridge_channel);
00911 
00912    /* Tell the bridge technology we are joining so they set us up */
00913    if (bridge_channel->bridge->technology->join) {
00914       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);
00915       if (bridge_channel->bridge->technology->join(bridge_channel->bridge, bridge_channel)) {
00916          ast_debug(1, "Bridge technology %s failed to join %p to bridge %p\n", bridge_channel->bridge->technology->name, bridge_channel, bridge_channel->bridge);
00917       }
00918    }
00919 
00920    /* Actually execute the respective threading model, and keep our bridge thread alive */
00921    while (bridge_channel->state == AST_BRIDGE_CHANNEL_STATE_WAIT) {
00922       /* Update bridge pointer on channel */
00923       bridge_channel->chan->bridge = bridge_channel->bridge;
00924       /* If the technology requires a thread and one is not running, start it up */
00925       if (bridge_channel->bridge->thread == AST_PTHREADT_NULL && (bridge_channel->bridge->technology->capabilities & AST_BRIDGE_CAPABILITY_THREAD)) {
00926          bridge_channel->bridge->stop = 0;
00927          ast_debug(1, "Starting a bridge thread for bridge %p\n", bridge_channel->bridge);
00928          ao2_ref(bridge_channel->bridge, +1);
00929          if (ast_pthread_create(&bridge_channel->bridge->thread, NULL, bridge_thread, bridge_channel->bridge)) {
00930             ast_debug(1, "Failed to create a bridge thread for bridge %p, giving it another go.\n", bridge_channel->bridge);
00931             ao2_ref(bridge_channel->bridge, -1);
00932             continue;
00933          }
00934       }
00935       /* Execute the threading model */
00936       state = (bridge_channel->bridge->technology->capabilities & AST_BRIDGE_CAPABILITY_MULTITHREADED ? bridge_channel_join_multithreaded(bridge_channel) : bridge_channel_join_singlethreaded(bridge_channel));
00937       /* Depending on the above state see what we need to do */
00938       if (state == AST_BRIDGE_CHANNEL_STATE_FEATURE) {
00939          bridge_channel_suspend(bridge_channel->bridge, bridge_channel);
00940          bridge_channel_feature(bridge_channel->bridge, bridge_channel);
00941          bridge_channel_unsuspend(bridge_channel->bridge, bridge_channel);
00942       } else if (state == AST_BRIDGE_CHANNEL_STATE_DTMF) {
00943          bridge_channel_suspend(bridge_channel->bridge, bridge_channel);
00944          bridge_channel_dtmf_stream(bridge_channel->bridge, bridge_channel);
00945          bridge_channel_unsuspend(bridge_channel->bridge, bridge_channel);
00946       }
00947    }
00948 
00949    bridge_channel->chan->bridge = NULL;
00950 
00951    /* See if we need to dissolve the bridge itself if they hung up */
00952    if (bridge_channel->state == AST_BRIDGE_CHANNEL_STATE_END) {
00953       bridge_check_dissolve(bridge_channel->bridge, bridge_channel);
00954    }
00955 
00956    /* Tell the bridge technology we are leaving so they tear us down */
00957    if (bridge_channel->bridge->technology->leave) {
00958       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);
00959       if (bridge_channel->bridge->technology->leave(bridge_channel->bridge, bridge_channel)) {
00960          ast_debug(1, "Bridge technology %s failed to leave %p from bridge %p\n", bridge_channel->bridge->technology->name, bridge_channel, bridge_channel->bridge);
00961       }
00962    }
00963 
00964    /* Remove channel from the bridge */
00965    bridge_channel->bridge->num--;
00966    AST_LIST_REMOVE(&bridge_channel->bridge->channels, bridge_channel, entry);
00967 
00968    bridge_array_remove(bridge_channel->bridge, bridge_channel->chan);
00969 
00970    /* Perform the smart bridge operation if needed since a channel has left */
00971    if (ast_test_flag(&bridge_channel->bridge->feature_flags, AST_BRIDGE_FLAG_SMART)) {
00972       smart_bridge_operation(bridge_channel->bridge, NULL, bridge_channel->bridge->num);
00973    }
00974 
00975    ao2_unlock(bridge_channel->bridge);
00976 
00977    /* Restore original formats of the channel as they came in */
00978    if (bridge_channel->chan->readformat != formats[0]) {
00979       ast_debug(1, "Bridge is returning %p to read format %s(%d)\n", bridge_channel, ast_getformatname(formats[0]), formats[0]);
00980       if (ast_set_read_format(bridge_channel->chan, formats[0])) {
00981          ast_debug(1, "Bridge failed to return channel %p to read format %s(%d)\n", bridge_channel, ast_getformatname(formats[0]), formats[0]);
00982       }
00983    }
00984    if (bridge_channel->chan->writeformat != formats[1]) {
00985       ast_debug(1, "Bridge is returning %p to write format %s(%d)\n", bridge_channel, ast_getformatname(formats[1]), formats[1]);
00986       if (ast_set_write_format(bridge_channel->chan, formats[1])) {
00987          ast_debug(1, "Bridge failed to return channel %p to write format %s(%d)\n", bridge_channel, ast_getformatname(formats[1]), formats[1]);
00988       }
00989    }
00990 
00991    return bridge_channel->state;
00992 }
00993 
00994 enum ast_bridge_channel_state ast_bridge_join(struct ast_bridge *bridge, struct ast_channel *chan, struct ast_channel *swap, struct ast_bridge_features *features)
00995 {
00996    struct ast_bridge_channel bridge_channel = {
00997       .chan = chan,
00998       .swap = swap,
00999       .bridge = bridge,
01000       .features = features,
01001    };
01002    enum ast_bridge_channel_state state;
01003 
01004    /* Initialize various other elements of the bridge channel structure that we can't do above */
01005    ast_mutex_init(&bridge_channel.lock);
01006    ast_cond_init(&bridge_channel.cond, NULL);
01007 
01008    ao2_ref(bridge_channel.bridge, +1);
01009 
01010    state = bridge_channel_join(&bridge_channel);
01011 
01012    ao2_ref(bridge_channel.bridge, -1);
01013 
01014    /* Destroy some elements of the bridge channel structure above */
01015    ast_mutex_destroy(&bridge_channel.lock);
01016    ast_cond_destroy(&bridge_channel.cond);
01017 
01018    return state;
01019 }
01020 
01021 /*! \brief Thread responsible for imparted bridged channels */
01022 static void *bridge_channel_thread(void *data)
01023 {
01024    struct ast_bridge_channel *bridge_channel = data;
01025    enum ast_bridge_channel_state state;
01026 
01027    state = bridge_channel_join(bridge_channel);
01028 
01029    ao2_ref(bridge_channel->bridge, -1);
01030 
01031    /* 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 */
01032    if (state == AST_BRIDGE_CHANNEL_STATE_END || state == AST_BRIDGE_CHANNEL_STATE_HANGUP) {
01033       ast_hangup(bridge_channel->chan);
01034    }
01035 
01036    /* Destroy elements of the bridge channel structure and the bridge channel structure itself */
01037    ast_mutex_destroy(&bridge_channel->lock);
01038    ast_cond_destroy(&bridge_channel->cond);
01039    ast_free(bridge_channel);
01040 
01041    return NULL;
01042 }
01043 
01044 int ast_bridge_impart(struct ast_bridge *bridge, struct ast_channel *chan, struct ast_channel *swap, struct ast_bridge_features *features)
01045 {
01046    struct ast_bridge_channel *bridge_channel = NULL;
01047 
01048    /* Try to allocate a structure for the bridge channel */
01049    if (!(bridge_channel = ast_calloc(1, sizeof(*bridge_channel)))) {
01050       return -1;
01051    }
01052 
01053    /* Setup various parameters */
01054    bridge_channel->chan = chan;
01055    bridge_channel->swap = swap;
01056    bridge_channel->bridge = bridge;
01057    bridge_channel->features = features;
01058 
01059    /* Initialize our mutex lock and condition */
01060    ast_mutex_init(&bridge_channel->lock);
01061    ast_cond_init(&bridge_channel->cond, NULL);
01062 
01063    /* Bump up the reference count on the bridge, it'll get decremented later */
01064    ao2_ref(bridge, +1);
01065 
01066    /* Actually create the thread that will handle the channel */
01067    if (ast_pthread_create(&bridge_channel->thread, NULL, bridge_channel_thread, bridge_channel)) {
01068       ao2_ref(bridge, -1);
01069       ast_cond_destroy(&bridge_channel->cond);
01070       ast_mutex_destroy(&bridge_channel->lock);
01071       ast_free(bridge_channel);
01072       return -1;
01073    }
01074 
01075    return 0;
01076 }
01077 
01078 int ast_bridge_depart(struct ast_bridge *bridge, struct ast_channel *chan)
01079 {
01080    struct ast_bridge_channel *bridge_channel = NULL;
01081    pthread_t thread;
01082 
01083    ao2_lock(bridge);
01084 
01085    /* Try to find the channel that we want to depart */
01086    if (!(bridge_channel = find_bridge_channel(bridge, chan))) {
01087       ao2_unlock(bridge);
01088       return -1;
01089    }
01090 
01091    ast_bridge_change_state(bridge_channel, AST_BRIDGE_CHANNEL_STATE_DEPART);
01092    thread = bridge_channel->thread;
01093 
01094    ao2_unlock(bridge);
01095 
01096    pthread_join(thread, NULL);
01097 
01098    return 0;
01099 }
01100 
01101 int ast_bridge_remove(struct ast_bridge *bridge, struct ast_channel *chan)
01102 {
01103    struct ast_bridge_channel *bridge_channel = NULL;
01104 
01105    ao2_lock(bridge);
01106 
01107    /* Try to find the channel that we want to remove */
01108    if (!(bridge_channel = find_bridge_channel(bridge, chan))) {
01109       ao2_unlock(bridge);
01110       return -1;
01111    }
01112 
01113    ast_bridge_change_state(bridge_channel, AST_BRIDGE_CHANNEL_STATE_HANGUP);
01114 
01115    ao2_unlock(bridge);
01116 
01117    return 0;
01118 }
01119 
01120 int ast_bridge_merge(struct ast_bridge *bridge0, struct ast_bridge *bridge1)
01121 {
01122    struct ast_bridge_channel *bridge_channel = NULL;
01123 
01124    ao2_lock(bridge0);
01125    ao2_lock(bridge1);
01126 
01127    /* If the first bridge currently has 2 channels and is not capable of becoming a multimixing bridge we can not merge */
01128    if ((bridge0->num + bridge1->num) > 2 && (!(bridge0->technology->capabilities & AST_BRIDGE_CAPABILITY_MULTIMIX) && !ast_test_flag(&bridge0->feature_flags, AST_BRIDGE_FLAG_SMART))) {
01129       ao2_unlock(bridge1);
01130       ao2_unlock(bridge0);
01131       ast_debug(1, "Can't merge bridge %p into bridge %p, multimix is needed and it could not be acquired.\n", bridge1, bridge0);
01132       return -1;
01133    }
01134 
01135    ast_debug(1, "Merging channels from bridge %p into bridge %p\n", bridge1, bridge0);
01136 
01137    /* Perform smart bridge operation on bridge we are merging into so it can change bridge technology if needed */
01138    if (smart_bridge_operation(bridge0, NULL, bridge0->num + bridge1->num)) {
01139       ao2_unlock(bridge1);
01140       ao2_unlock(bridge0);
01141       ast_debug(1, "Can't merge bridge %p into bridge %p, tried to perform smart bridge operation and failed.\n", bridge1, bridge0);
01142       return -1;
01143    }
01144 
01145    /* If a thread is currently executing on bridge1 tell it to stop */
01146    if (bridge1->thread) {
01147       ast_debug(1, "Telling bridge thread on bridge %p to stop as it is being merged into %p\n", bridge1, bridge0);
01148       bridge1->thread = AST_PTHREADT_STOP;
01149    }
01150 
01151    /* Move channels from bridge1 over to bridge0 */
01152    while ((bridge_channel = AST_LIST_REMOVE_HEAD(&bridge1->channels, entry))) {
01153       /* Tell the technology handling bridge1 that the bridge channel is leaving */
01154       if (bridge1->technology->leave) {
01155          ast_debug(1, "Giving bridge technology %s notification that %p is leaving bridge %p\n", bridge1->technology->name, bridge_channel, bridge1);
01156          if (bridge1->technology->leave(bridge1, bridge_channel)) {
01157             ast_debug(1, "Bridge technology %s failed to allow %p to leave bridge %p\n", bridge1->technology->name, bridge_channel, bridge1);
01158          }
01159       }
01160 
01161       /* Drop channel count and reference count on the bridge they are leaving */
01162       bridge1->num--;
01163       ao2_ref(bridge1, -1);
01164 
01165       bridge_array_remove(bridge1, bridge_channel->chan);
01166 
01167       /* Now add them into the bridge they are joining, increase channel count, and bump up reference count */
01168       bridge_channel->bridge = bridge0;
01169       AST_LIST_INSERT_TAIL(&bridge0->channels, bridge_channel, entry);
01170       bridge0->num++;
01171       ao2_ref(bridge0, +1);
01172 
01173       bridge_array_add(bridge0, bridge_channel->chan);
01174 
01175       /* Make the channel compatible with the new bridge it is joining or else formats would go amuck */
01176       bridge_make_compatible(bridge0, bridge_channel);
01177 
01178       /* Tell the technology handling bridge0 that the bridge channel is joining */
01179       if (bridge0->technology->join) {
01180          ast_debug(1, "Giving bridge technology %s notification that %p is joining bridge %p\n", bridge0->technology->name, bridge_channel, bridge0);
01181          if (bridge0->technology->join(bridge0, bridge_channel)) {
01182             ast_debug(1, "Bridge technology %s failed to join %p to bridge %p\n", bridge0->technology->name, bridge_channel, bridge0);
01183          }
01184       }
01185 
01186       /* Poke the bridge channel, this will cause it to wake up and execute the proper threading model for the new bridge it is in */
01187       pthread_kill(bridge_channel->thread, SIGURG);
01188       ast_mutex_lock(&bridge_channel->lock);
01189       ast_cond_signal(&bridge_channel->cond);
01190       ast_mutex_unlock(&bridge_channel->lock);
01191    }
01192 
01193    ast_debug(1, "Merged channels from bridge %p into bridge %p\n", bridge1, bridge0);
01194 
01195    ao2_unlock(bridge1);
01196    ao2_unlock(bridge0);
01197 
01198    return 0;
01199 }
01200 
01201 int ast_bridge_suspend(struct ast_bridge *bridge, struct ast_channel *chan)
01202 {
01203    struct ast_bridge_channel *bridge_channel;
01204 
01205    ao2_lock(bridge);
01206 
01207    if (!(bridge_channel = find_bridge_channel(bridge, chan))) {
01208       ao2_unlock(bridge);
01209       return -1;
01210    }
01211 
01212    bridge_channel_suspend(bridge, bridge_channel);
01213 
01214    ao2_unlock(bridge);
01215 
01216    return 0;
01217 }
01218 
01219 int ast_bridge_unsuspend(struct ast_bridge *bridge, struct ast_channel *chan)
01220 {
01221    struct ast_bridge_channel *bridge_channel;
01222 
01223    ao2_lock(bridge);
01224 
01225    if (!(bridge_channel = find_bridge_channel(bridge, chan))) {
01226       ao2_unlock(bridge);
01227       return -1;
01228    }
01229 
01230    bridge_channel_unsuspend(bridge, bridge_channel);
01231 
01232    ao2_unlock(bridge);
01233 
01234    return 0;
01235 }
01236 
01237 void ast_bridge_technology_suspend(struct ast_bridge_technology *technology)
01238 {
01239    technology->suspended = 1;
01240    return;
01241 }
01242 
01243 void ast_bridge_technology_unsuspend(struct ast_bridge_technology *technology)
01244 {
01245    technology->suspended = 0;
01246    return;
01247 }
01248 
01249 int ast_bridge_features_register(enum ast_bridge_builtin_feature feature, ast_bridge_features_hook_callback callback, const char *dtmf)
01250 {
01251    if (builtin_features_handlers[feature]) {
01252       return -1;
01253    }
01254 
01255    if (!ast_strlen_zero(dtmf)) {
01256       ast_copy_string(builtin_features_dtmf[feature], dtmf, sizeof(builtin_features_dtmf[feature]));
01257    }
01258 
01259    builtin_features_handlers[feature] = callback;
01260 
01261    return 0;
01262 }
01263 
01264 int ast_bridge_features_unregister(enum ast_bridge_builtin_feature feature)
01265 {
01266    if (!builtin_features_handlers[feature]) {
01267       return -1;
01268    }
01269 
01270    builtin_features_handlers[feature] = NULL;
01271 
01272    return 0;
01273 }
01274 
01275 int ast_bridge_features_hook(struct ast_bridge_features *features, const char *dtmf, ast_bridge_features_hook_callback callback, void *hook_pvt)
01276 {
01277    struct ast_bridge_features_hook *hook = NULL;
01278 
01279    /* Allocate new memory and setup it's various variables */
01280    if (!(hook = ast_calloc(1, sizeof(*hook)))) {
01281       return -1;
01282    }
01283 
01284    ast_copy_string(hook->dtmf, dtmf, sizeof(hook->dtmf));
01285    hook->callback = callback;
01286    hook->hook_pvt = hook_pvt;
01287 
01288    /* Once done we add it onto the list. Now it will be picked up when DTMF is used */
01289    AST_LIST_INSERT_TAIL(&features->hooks, hook, entry);
01290 
01291    features->usable = 1;
01292 
01293    return 0;
01294 }
01295 
01296 int ast_bridge_features_enable(struct ast_bridge_features *features, enum ast_bridge_builtin_feature feature, const char *dtmf, void *config)
01297 {
01298    /* If no alternate DTMF stream was provided use the default one */
01299    if (ast_strlen_zero(dtmf)) {
01300       dtmf = builtin_features_dtmf[feature];
01301       /* If no DTMF is still available (ie: it has been disabled) then error out now */
01302       if (ast_strlen_zero(dtmf)) {
01303          ast_debug(1, "Failed to enable built in feature %d on %p, no DTMF string is available for it.\n", feature, features);
01304          return -1;
01305       }
01306    }
01307 
01308    if (!builtin_features_handlers[feature]) {
01309       return -1;
01310    }
01311 
01312    /* The rest is basically pretty easy. We create another hook using the built in feature's callback and DTMF, easy as pie. */
01313    return ast_bridge_features_hook(features, dtmf, builtin_features_handlers[feature], config);
01314 }
01315 
01316 int ast_bridge_features_set_flag(struct ast_bridge_features *features, enum ast_bridge_feature_flags flag)
01317 {
01318    ast_set_flag(&features->feature_flags, flag);
01319    features->usable = 1;
01320    return 0;
01321 }
01322 
01323 int ast_bridge_features_init(struct ast_bridge_features *features)
01324 {
01325    /* Zero out the structure */
01326    memset(features, 0, sizeof(*features));
01327 
01328    /* Initialize the hooks list, just in case */
01329    AST_LIST_HEAD_INIT_NOLOCK(&features->hooks);
01330 
01331    return 0;
01332 }
01333 
01334 int ast_bridge_features_cleanup(struct ast_bridge_features *features)
01335 {
01336    struct ast_bridge_features_hook *hook = NULL;
01337 
01338    /* This is relatively simple, hooks are kept as a list on the features structure so we just pop them off and free them */
01339    while ((hook = AST_LIST_REMOVE_HEAD(&features->hooks, entry))) {
01340       ast_free(hook);
01341    }
01342 
01343    return 0;
01344 }
01345 
01346 int ast_bridge_dtmf_stream(struct ast_bridge *bridge, const char *dtmf, struct ast_channel *chan)
01347 {
01348    struct ast_bridge_channel *bridge_channel = NULL;
01349 
01350    ao2_lock(bridge);
01351 
01352    AST_LIST_TRAVERSE(&bridge->channels, bridge_channel, entry) {
01353       if (bridge_channel->chan == chan) {
01354          continue;
01355       }
01356       ast_copy_string(bridge_channel->dtmf_stream_q, dtmf, sizeof(bridge_channel->dtmf_stream_q));
01357       ast_bridge_change_state(bridge_channel, AST_BRIDGE_CHANNEL_STATE_DTMF);
01358    }
01359 
01360    ao2_unlock(bridge);
01361 
01362    return 0;
01363 }

Generated on Mon Jun 27 16:50:49 2011 for Asterisk - The Open Source Telephony Project by  doxygen 1.4.7