2 * Asterisk -- An open source telephony toolkit.
4 * Copyright (C) 2007 - 2009, Digium, Inc.
6 * Joshua Colp <jcolp@digium.com>
8 * See http://www.asterisk.org for more information about
9 * the Asterisk project. Please do not directly contact
10 * any of the maintainers of this project for assistance;
11 * the project provides a web site, mailing lists and IRC
12 * channels for your use.
14 * This program is free software, distributed under the terms of
15 * the GNU General Public License Version 2. See the LICENSE file
16 * at the top of the source tree.
21 * \brief Channel Bridging API
23 * \author Joshua Colp <jcolp@digium.com>
28 ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
32 #include "asterisk/logger.h"
33 #include "asterisk/channel.h"
34 #include "asterisk/options.h"
35 #include "asterisk/utils.h"
36 #include "asterisk/lock.h"
37 #include "asterisk/linkedlists.h"
38 #include "asterisk/bridging.h"
39 #include "asterisk/bridging_technology.h"
40 #include "asterisk/app.h"
41 #include "asterisk/file.h"
42 #include "asterisk/module.h"
43 #include "asterisk/astobj2.h"
45 static AST_RWLIST_HEAD_STATIC(bridge_technologies, ast_bridge_technology);
47 /* Initial starting point for the bridge array of channels */
48 #define BRIDGE_ARRAY_START 128
50 /* Grow rate of bridge array of channels */
51 #define BRIDGE_ARRAY_GROW 32
53 /*! Default DTMF keys for built in features */
54 static char builtin_features_dtmf[AST_BRIDGE_BUILTIN_END][MAXIMUM_DTMF_FEATURE_STRING];
56 /*! Function handlers for the built in features */
57 static void *builtin_features_handlers[AST_BRIDGE_BUILTIN_END];
59 int __ast_bridge_technology_register(struct ast_bridge_technology *technology, struct ast_module *module)
61 struct ast_bridge_technology *current = NULL;
63 /* Perform a sanity check to make sure the bridge technology conforms to our needed requirements */
64 if (ast_strlen_zero(technology->name) || !technology->capabilities || !technology->write) {
65 ast_log(LOG_WARNING, "Bridge technology %s failed registration sanity check.\n", technology->name);
69 AST_RWLIST_WRLOCK(&bridge_technologies);
71 /* Look for duplicate bridge technology already using this name, or already registered */
72 AST_RWLIST_TRAVERSE(&bridge_technologies, current, entry) {
73 if ((!strcasecmp(current->name, technology->name)) || (current == technology)) {
74 ast_log(LOG_WARNING, "A bridge technology of %s already claims to exist in our world.\n", technology->name);
75 AST_RWLIST_UNLOCK(&bridge_technologies);
80 /* Copy module pointer so reference counting can keep the module from unloading */
81 technology->mod = module;
83 /* Insert our new bridge technology into the list and print out a pretty message */
84 AST_RWLIST_INSERT_TAIL(&bridge_technologies, technology, entry);
86 AST_RWLIST_UNLOCK(&bridge_technologies);
88 if (option_verbose > 1) {
89 ast_verbose(VERBOSE_PREFIX_2 "Registered bridge technology %s\n", technology->name);
95 int ast_bridge_technology_unregister(struct ast_bridge_technology *technology)
97 struct ast_bridge_technology *current = NULL;
99 AST_RWLIST_WRLOCK(&bridge_technologies);
101 /* Ensure the bridge technology is registered before removing it */
102 AST_RWLIST_TRAVERSE_SAFE_BEGIN(&bridge_technologies, current, entry) {
103 if (current == technology) {
104 AST_RWLIST_REMOVE_CURRENT(entry);
105 if (option_verbose > 1) {
106 ast_verbose(VERBOSE_PREFIX_2 "Unregistered bridge technology %s\n", technology->name);
111 AST_RWLIST_TRAVERSE_SAFE_END;
113 AST_RWLIST_UNLOCK(&bridge_technologies);
115 return current ? 0 : -1;
118 void ast_bridge_change_state(struct ast_bridge_channel *bridge_channel, enum ast_bridge_channel_state new_state)
120 /* Change the state on the bridge channel */
121 bridge_channel->state = new_state;
123 /* Only poke the channel's thread if it is not us */
124 if (!pthread_equal(pthread_self(), bridge_channel->thread)) {
125 pthread_kill(bridge_channel->thread, SIGURG);
126 ast_mutex_lock(&bridge_channel->lock);
127 ast_cond_signal(&bridge_channel->cond);
128 ast_mutex_unlock(&bridge_channel->lock);
134 /*! \brief Helper function to poke the bridge thread */
135 static void bridge_poke(struct ast_bridge *bridge)
137 /* Poke the thread just in case */
138 if (bridge->thread != AST_PTHREADT_NULL && bridge->thread != AST_PTHREADT_STOP) {
139 pthread_kill(bridge->thread, SIGURG);
145 /*! \brief Helper function to add a channel to the bridge array
147 * \note This function assumes the bridge is locked.
149 static void bridge_array_add(struct ast_bridge *bridge, struct ast_channel *chan)
151 /* We have to make sure the bridge thread is not using the bridge array before messing with it */
152 while (bridge->waiting) {
157 bridge->array[bridge->array_num++] = chan;
159 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);
161 /* If the next addition of a channel will exceed our array size grow it out */
162 if (bridge->array_num == bridge->array_size) {
163 struct ast_channel **tmp;
164 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);
165 if (!(tmp = ast_realloc(bridge->array, (bridge->array_size + BRIDGE_ARRAY_GROW) * sizeof(struct ast_channel *)))) {
166 ast_log(LOG_ERROR, "Failed to allocate more space for another channel on bridge '%p', this is not going to end well\n", bridge);
170 bridge->array_size += BRIDGE_ARRAY_GROW;
176 /*! \brief Helper function to remove a channel from the bridge array
178 * \note This function assumes the bridge is locked.
180 static void bridge_array_remove(struct ast_bridge *bridge, struct ast_channel *chan)
184 /* We have to make sure the bridge thread is not using the bridge array before messing with it */
185 while (bridge->waiting) {
190 for (i = 0; i < bridge->array_num; i++) {
191 if (bridge->array[i] == chan) {
192 bridge->array[i] = (bridge->array[(bridge->array_num - 1)] != chan ? bridge->array[(bridge->array_num - 1)] : NULL);
193 bridge->array[(bridge->array_num - 1)] = NULL;
195 ast_debug(1, "Removed channel %p from bridge array on %p, new count is %d\n", chan, bridge, (int)bridge->array_num);
203 /*! \brief Helper function to find a bridge channel given a channel */
204 static struct ast_bridge_channel *find_bridge_channel(struct ast_bridge *bridge, struct ast_channel *chan)
206 struct ast_bridge_channel *bridge_channel = NULL;
208 AST_LIST_TRAVERSE(&bridge->channels, bridge_channel, entry) {
209 if (bridge_channel->chan == chan) {
214 return bridge_channel;
217 /*! \brief Internal function to see whether a bridge should dissolve, and if so do it */
218 static void bridge_check_dissolve(struct ast_bridge *bridge, struct ast_bridge_channel *bridge_channel)
220 struct ast_bridge_channel *bridge_channel2 = NULL;
222 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))) {
226 ast_debug(1, "Dissolving bridge %p\n", bridge);
228 AST_LIST_TRAVERSE(&bridge->channels, bridge_channel2, entry) {
229 if (bridge_channel2->state != AST_BRIDGE_CHANNEL_STATE_END && bridge_channel2->state != AST_BRIDGE_CHANNEL_STATE_DEPART) {
230 ast_bridge_change_state(bridge_channel2, AST_BRIDGE_CHANNEL_STATE_HANGUP);
234 /* Since all the channels are going away let's go ahead and stop our on thread */
240 /*! \brief Internal function to handle DTMF from a channel */
241 static struct ast_frame *bridge_handle_dtmf(struct ast_bridge *bridge, struct ast_bridge_channel *bridge_channel, struct ast_frame *frame)
243 struct ast_bridge_features *features = (bridge_channel->features ? bridge_channel->features : &bridge->features);
244 struct ast_bridge_features_hook *hook = NULL;
246 /* If the features structure we grabbed is not usable immediately return the frame */
247 if (!features->usable) {
251 /* 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 */
252 AST_LIST_TRAVERSE(&features->hooks, hook, entry) {
253 if (hook->dtmf[0] == frame->subclass) {
256 ast_bridge_change_state(bridge_channel, AST_BRIDGE_CHANNEL_STATE_FEATURE);
264 void ast_bridge_handle_trip(struct ast_bridge *bridge, struct ast_bridge_channel *bridge_channel, struct ast_channel *chan, int outfd)
266 /* If no bridge channel has been provided and the actual channel has been provided find it */
267 if (chan && !bridge_channel) {
268 bridge_channel = find_bridge_channel(bridge, chan);
271 /* If a bridge channel with actual channel is present read a frame and handle it */
272 if (chan && bridge_channel) {
273 struct ast_frame *frame = (((bridge->features.mute) || (bridge_channel->features && bridge_channel->features->mute)) ? ast_read_noaudio(chan) : ast_read(chan));
275 /* This is pretty simple... see if they hung up */
276 if (!frame || (frame->frametype == AST_FRAME_CONTROL && frame->subclass == AST_CONTROL_HANGUP)) {
277 /* Signal the thread that is handling the bridged channel that it should be ended */
278 ast_bridge_change_state(bridge_channel, AST_BRIDGE_CHANNEL_STATE_END);
279 } else if (frame->frametype == AST_FRAME_CONTROL && frame->subclass == AST_CONTROL_ANSWER) {
280 ast_debug(1, "Dropping answer frame from bridge channel %p\n", bridge_channel);
282 if (frame->frametype == AST_FRAME_DTMF_BEGIN) {
283 frame = bridge_handle_dtmf(bridge, bridge_channel, frame);
285 /* Simply write the frame out to the bridge technology if it still exists */
287 bridge->technology->write(bridge, bridge_channel, frame);
297 /* If a file descriptor actually tripped pass it off to the bridge technology */
298 if (outfd > -1 && bridge->technology->fd) {
299 bridge->technology->fd(bridge, bridge_channel, outfd);
303 /* If all else fails just poke the bridge */
304 if (bridge->technology->poke && bridge_channel) {
305 bridge->technology->poke(bridge, bridge_channel);
312 /*! \brief Generic thread loop, TODO: Rethink this/improve it */
313 static int generic_thread_loop(struct ast_bridge *bridge)
315 while (!bridge->stop && !bridge->refresh && bridge->array_num) {
316 struct ast_channel *winner = NULL;
319 /* Move channels around for priority reasons if we have more than one channel in our array */
320 if (bridge->array_num > 1) {
321 struct ast_channel *first = bridge->array[0];
322 memmove(bridge->array, bridge->array + 1, sizeof(struct ast_channel *) * (bridge->array_num - 1));
323 bridge->array[(bridge->array_num - 1)] = first;
326 /* Wait on the channels */
329 winner = ast_waitfor_n(bridge->array, (int)bridge->array_num, &to);
333 /* Process whatever they did */
334 ast_bridge_handle_trip(bridge, NULL, winner, -1);
340 /*! \brief Bridge thread function */
341 static void *bridge_thread(void *data)
343 struct ast_bridge *bridge = data;
348 ast_debug(1, "Started bridge thread for %p\n", bridge);
350 /* Loop around until we are told to stop */
351 while (!bridge->stop && bridge->array_num && !res) {
352 /* In case the refresh bit was set simply set it back to off */
355 ast_debug(1, "Launching bridge thread function %p for bridge %p\n", (bridge->technology->thread ? bridge->technology->thread : &generic_thread_loop), bridge);
357 /* Execute the appropriate thread function. If the technology does not provide one we use the generic one */
358 res = (bridge->technology->thread ? bridge->technology->thread(bridge) : generic_thread_loop(bridge));
361 ast_debug(1, "Ending bridge thread for %p\n", bridge);
363 /* Indicate the bridge thread is no longer active */
364 bridge->thread = AST_PTHREADT_NULL;
372 /*! \brief Helper function used to find the "best" bridge technology given a specified capabilities */
373 static struct ast_bridge_technology *find_best_technology(int capabilities)
375 struct ast_bridge_technology *current = NULL, *best = NULL;
377 AST_RWLIST_RDLOCK(&bridge_technologies);
378 AST_RWLIST_TRAVERSE(&bridge_technologies, current, entry) {
379 ast_debug(1, "Bridge technology %s has capabilities %d and we want %d\n", current->name, current->capabilities, capabilities);
380 if (current->suspended) {
381 ast_debug(1, "Bridge technology %s is suspended. Skipping.\n", current->name);
384 if (!(current->capabilities & capabilities)) {
385 ast_debug(1, "Bridge technology %s does not have the capabilities we need.\n", current->name);
388 if (best && best->preference < current->preference) {
389 ast_debug(1, "Bridge technology %s has preference %d while %s has preference %d. Skipping.\n", current->name, current->preference, best->name, best->preference);
396 /* Increment it's module reference count if present so it does not get unloaded while in use */
398 ast_module_ref(best->mod);
400 ast_debug(1, "Chose bridge technology %s\n", best->name);
403 AST_RWLIST_UNLOCK(&bridge_technologies);
408 static void destroy_bridge(void *obj)
410 struct ast_bridge *bridge = obj;
412 ast_debug(1, "Actually destroying bridge %p, nobody wants it anymore\n", bridge);
414 /* Pass off the bridge to the technology to destroy if needed */
415 if (bridge->technology->destroy) {
416 ast_debug(1, "Giving bridge technology %s the bridge structure %p to destroy\n", bridge->technology->name, bridge);
417 if (bridge->technology->destroy(bridge)) {
418 ast_debug(1, "Bridge technology %s failed to destroy bridge structure %p... trying our best\n", bridge->technology->name, bridge);
422 /* We are no longer using the bridge technology so decrement the module reference count on it */
423 if (bridge->technology->mod) {
424 ast_module_unref(bridge->technology->mod);
427 /* Last but not least clean up the features configuration */
428 ast_bridge_features_cleanup(&bridge->features);
430 /* Drop the array of channels */
431 ast_free(bridge->array);
436 struct ast_bridge *ast_bridge_new(int capabilities, int flags)
438 struct ast_bridge *bridge = NULL;
439 struct ast_bridge_technology *bridge_technology = NULL;
441 /* If we need to be a smart bridge see if we can move between 1to1 and multimix bridges */
442 if (flags & AST_BRIDGE_FLAG_SMART) {
443 struct ast_bridge *other_bridge;
445 if (!(other_bridge = ast_bridge_new((capabilities & AST_BRIDGE_CAPABILITY_1TO1MIX) ? AST_BRIDGE_CAPABILITY_MULTIMIX : AST_BRIDGE_CAPABILITY_1TO1MIX, 0))) {
449 ast_bridge_destroy(other_bridge);
452 /* If capabilities were provided use our helper function to find the "best" bridge technology, otherwise we can
453 * just look for the most basic capability needed, single 1to1 mixing. */
454 bridge_technology = (capabilities ? find_best_technology(capabilities) : find_best_technology(AST_BRIDGE_CAPABILITY_1TO1MIX));
456 /* If no bridge technology was found we can't possibly do bridging so fail creation of the bridge */
457 if (!bridge_technology) {
458 ast_debug(1, "Failed to find a bridge technology to satisfy capabilities %d\n", capabilities);
462 /* We have everything we need to create this bridge... so allocate the memory, link things together, and fire her up! */
463 if (!(bridge = ao2_alloc(sizeof(*bridge), destroy_bridge))) {
467 bridge->technology = bridge_technology;
468 bridge->thread = AST_PTHREADT_NULL;
470 /* Create an array of pointers for the channels that will be joining us */
471 bridge->array = ast_calloc(BRIDGE_ARRAY_START, sizeof(struct ast_channel*));
472 bridge->array_size = BRIDGE_ARRAY_START;
474 ast_set_flag(&bridge->feature_flags, flags);
476 /* Pass off the bridge to the technology to manipulate if needed */
477 if (bridge->technology->create) {
478 ast_debug(1, "Giving bridge technology %s the bridge structure %p to setup\n", bridge->technology->name, bridge);
479 if (bridge->technology->create(bridge)) {
480 ast_debug(1, "Bridge technology %s failed to setup bridge structure %p\n", bridge->technology->name, bridge);
489 int ast_bridge_check(int capabilities)
491 struct ast_bridge_technology *bridge_technology = NULL;
493 if (!(bridge_technology = find_best_technology(capabilities))) {
497 ast_module_unref(bridge_technology->mod);
502 int ast_bridge_destroy(struct ast_bridge *bridge)
504 struct ast_bridge_channel *bridge_channel = NULL;
512 ast_debug(1, "Telling all channels in bridge %p to end and leave the party\n", bridge);
514 /* Drop every bridged channel, the last one will cause the bridge thread (if it exists) to exit */
515 AST_LIST_TRAVERSE(&bridge->channels, bridge_channel, entry) {
516 ast_bridge_change_state(bridge_channel, AST_BRIDGE_CHANNEL_STATE_END);
526 static int bridge_make_compatible(struct ast_bridge *bridge, struct ast_bridge_channel *bridge_channel)
528 int formats[2] = {bridge_channel->chan->readformat, bridge_channel->chan->writeformat};
530 /* Are the formats currently in use something ths bridge can handle? */
531 if (!(bridge->technology->formats & bridge_channel->chan->readformat)) {
532 int best_format = ast_best_codec(bridge->technology->formats);
534 /* Read format is a no go... */
537 ast_getformatname_multiple(codec_buf, sizeof(codec_buf), bridge->technology->formats);
538 ast_debug(1, "Bridge technology %s wants to read any of formats %s(%d) but channel has %s(%d)\n", bridge->technology->name, codec_buf, bridge->technology->formats, ast_getformatname(formats[0]), formats[0]);
540 /* Switch read format to the best one chosen */
541 if (ast_set_read_format(bridge_channel->chan, best_format)) {
542 ast_log(LOG_WARNING, "Failed to set channel %s to read format %s(%d)\n", bridge_channel->chan->name, ast_getformatname(best_format), best_format);
545 ast_debug(1, "Bridge %p put channel %s into read format %s(%d)\n", bridge, bridge_channel->chan->name, ast_getformatname(best_format), best_format);
547 ast_debug(1, "Bridge %p is happy that channel %s already has read format %s(%d)\n", bridge, bridge_channel->chan->name, ast_getformatname(formats[0]), formats[0]);
550 if (!(bridge->technology->formats & formats[1])) {
551 int best_format = ast_best_codec(bridge->technology->formats);
553 /* Write format is a no go... */
556 ast_getformatname_multiple(codec_buf, sizeof(codec_buf), bridge->technology->formats);
557 ast_debug(1, "Bridge technology %s wants to write any of formats %s(%d) but channel has %s(%d)\n", bridge->technology->name, codec_buf, bridge->technology->formats, ast_getformatname(formats[1]), formats[1]);
559 /* Switch write format to the best one chosen */
560 if (ast_set_write_format(bridge_channel->chan, best_format)) {
561 ast_log(LOG_WARNING, "Failed to set channel %s to write format %s(%d)\n", bridge_channel->chan->name, ast_getformatname(best_format), best_format);
564 ast_debug(1, "Bridge %p put channel %s into write format %s(%d)\n", bridge, bridge_channel->chan->name, ast_getformatname(best_format), best_format);
566 ast_debug(1, "Bridge %p is happy that channel %s already has write format %s(%d)\n", bridge, bridge_channel->chan->name, ast_getformatname(formats[1]), formats[1]);
572 /*! \brief Perform the smart bridge operation. Basically sees if a new bridge technology should be used instead of the current one. */
573 static int smart_bridge_operation(struct ast_bridge *bridge, struct ast_bridge_channel *bridge_channel, int count)
575 int new_capabilities = 0;
576 struct ast_bridge_technology *new_technology = NULL, *old_technology = bridge->technology;
577 struct ast_bridge temp_bridge = {
578 .technology = bridge->technology,
579 .bridge_pvt = bridge->bridge_pvt,
581 struct ast_bridge_channel *bridge_channel2 = NULL;
583 /* Based on current feature determine whether we want to change bridge technologies or not */
584 if (bridge->technology->capabilities & AST_BRIDGE_CAPABILITY_1TO1MIX) {
586 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);
589 new_capabilities = AST_BRIDGE_CAPABILITY_MULTIMIX;
590 } else if (bridge->technology->capabilities & AST_BRIDGE_CAPABILITY_MULTIMIX) {
592 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);
595 new_capabilities = AST_BRIDGE_CAPABILITY_1TO1MIX;
598 if (!new_capabilities) {
599 ast_debug(1, "Bridge '%p' has no new capabilities, not performing smart bridge operation.\n", bridge);
603 /* Attempt to find a new bridge technology to satisfy the capabilities */
604 if (!(new_technology = find_best_technology(new_capabilities))) {
605 ast_debug(1, "Smart bridge operation was unable to find new bridge technology with capabilities %d to satisfy bridge %p\n", new_capabilities, bridge);
609 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);
611 /* If a thread is currently executing for the current technology tell it to stop */
612 if (bridge->thread != AST_PTHREADT_NULL) {
613 /* 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. */
614 if (new_technology->capabilities & AST_BRIDGE_CAPABILITY_THREAD) {
615 ast_debug(1, "Telling current bridge thread for bridge %p to refresh\n", bridge);
618 ast_debug(1, "Telling current bridge thread for bridge %p to stop\n", bridge);
624 /* 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 */
625 bridge->bridge_pvt = NULL;
626 bridge->technology = new_technology;
628 /* Pass the bridge to the new bridge technology so it can set it up */
629 if (new_technology->create) {
630 ast_debug(1, "Giving bridge technology %s the bridge structure %p to setup\n", new_technology->name, bridge);
631 if (new_technology->create(bridge)) {
632 ast_debug(1, "Bridge technology %s failed to setup bridge structure %p\n", new_technology->name, bridge);
636 /* Move existing channels over to the new technology, while taking them away from the old one */
637 AST_LIST_TRAVERSE(&bridge->channels, bridge_channel2, entry) {
638 /* Skip over channel that initiated the smart bridge operation */
639 if (bridge_channel == bridge_channel2) {
643 /* First we part them from the old technology */
644 if (old_technology->leave) {
645 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);
646 if (old_technology->leave(&temp_bridge, bridge_channel2)) {
647 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);
651 /* Second we make them compatible again with the bridge */
652 bridge_make_compatible(bridge, bridge_channel2);
654 /* Third we join them to the new technology */
655 if (new_technology->join) {
656 ast_debug(1, "Giving bridge technology %s notification that %p is joining bridge %p\n", new_technology->name, bridge_channel2, bridge);
657 if (new_technology->join(bridge, bridge_channel2)) {
658 ast_debug(1, "Bridge technology %s failed to join %p to bridge %p\n", new_technology->name, bridge_channel2, bridge);
662 /* Fourth we tell them to wake up so they become aware that they above has happened */
663 pthread_kill(bridge_channel2->thread, SIGURG);
664 ast_mutex_lock(&bridge_channel2->lock);
665 ast_cond_signal(&bridge_channel2->cond);
666 ast_mutex_unlock(&bridge_channel2->lock);
669 /* 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 */
670 if (old_technology->destroy) {
671 ast_debug(1, "Giving bridge technology %s the bridge structure %p (really %p) to destroy\n", old_technology->name, &temp_bridge, bridge);
672 if (old_technology->destroy(&temp_bridge)) {
673 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);
677 /* Finally if the old technology has module referencing remove our reference, we are no longer going to use it */
678 if (old_technology->mod) {
679 ast_module_unref(old_technology->mod);
685 /*! \brief Run in a multithreaded model. Each joined channel does writing/reading in their own thread. TODO: Improve */
686 static enum ast_bridge_channel_state bridge_channel_join_multithreaded(struct ast_bridge_channel *bridge_channel)
688 int fds[4] = { -1, }, nfds = 0, i = 0, outfd = -1, ms = -1;
689 struct ast_channel *chan = NULL;
691 /* Add any file descriptors we may want to monitor */
692 if (bridge_channel->bridge->technology->fd) {
693 for (i = 0; i < 4; i ++) {
694 if (bridge_channel->fds[i] >= 0) {
695 fds[nfds++] = bridge_channel->fds[i];
700 ao2_unlock(bridge_channel->bridge);
702 /* Wait for data to either come from the channel or us to be signalled */
703 if (!bridge_channel->suspended) {
704 ast_debug(1, "Going into a multithreaded waitfor for bridge channel %p of bridge %p\n", bridge_channel, bridge_channel->bridge);
705 chan = ast_waitfor_nandfds(&bridge_channel->chan, 1, fds, nfds, NULL, &outfd, &ms);
707 ast_mutex_lock(&bridge_channel->lock);
708 ast_debug(1, "Going into a multithreaded signal wait for bridge channel %p of bridge %p\n", bridge_channel, bridge_channel->bridge);
709 ast_cond_wait(&bridge_channel->cond, &bridge_channel->lock);
710 ast_mutex_unlock(&bridge_channel->lock);
713 ao2_lock(bridge_channel->bridge);
715 if (!bridge_channel->suspended) {
716 ast_bridge_handle_trip(bridge_channel->bridge, bridge_channel, chan, outfd);
719 return bridge_channel->state;
722 /*! \brief Run in a singlethreaded model. Each joined channel yields itself to the main bridge thread. TODO: Improve */
723 static enum ast_bridge_channel_state bridge_channel_join_singlethreaded(struct ast_bridge_channel *bridge_channel)
725 ao2_unlock(bridge_channel->bridge);
726 ast_mutex_lock(&bridge_channel->lock);
727 if (bridge_channel->state == AST_BRIDGE_CHANNEL_STATE_WAIT) {
728 ast_debug(1, "Going into a single threaded signal wait for bridge channel %p of bridge %p\n", bridge_channel, bridge_channel->bridge);
729 ast_cond_wait(&bridge_channel->cond, &bridge_channel->lock);
731 ast_mutex_unlock(&bridge_channel->lock);
732 ao2_lock(bridge_channel->bridge);
734 return bridge_channel->state;
737 /*! \brief Internal function that suspends a channel from a bridge */
738 static void bridge_channel_suspend(struct ast_bridge *bridge, struct ast_bridge_channel *bridge_channel)
740 bridge_channel->suspended = 1;
742 bridge_array_remove(bridge, bridge_channel->chan);
744 if (bridge->technology->suspend) {
745 bridge->technology->suspend(bridge, bridge_channel);
751 /*! \brief Internal function that unsuspends a channel from a bridge */
752 static void bridge_channel_unsuspend(struct ast_bridge *bridge, struct ast_bridge_channel *bridge_channel)
754 bridge_channel->suspended =0;
756 bridge_array_add(bridge, bridge_channel->chan);
758 if (bridge->technology->unsuspend) {
759 bridge->technology->unsuspend(bridge, bridge_channel);
765 /*! \brief Internal function that executes a feature on a bridge channel */
766 static void bridge_channel_feature(struct ast_bridge *bridge, struct ast_bridge_channel *bridge_channel)
768 struct ast_bridge_features *features = (bridge_channel->features ? bridge_channel->features : &bridge->features);
769 struct ast_bridge_features_hook *hook = NULL;
770 char dtmf[MAXIMUM_DTMF_FEATURE_STRING] = "";
771 int look_for_dtmf = 1, dtmf_len = 0;
773 /* 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 */
774 ast_set_flag(bridge_channel->chan, AST_FLAG_END_DTMF_ONLY);
776 /* Wait for DTMF on the channel and put it into a buffer. If the buffer matches any feature hook execute the hook. */
777 while (look_for_dtmf) {
778 int res = ast_waitfordigit(bridge_channel->chan, 3000);
780 /* If the above timed out simply exit */
782 ast_debug(1, "DTMF feature string collection on bridge channel %p timed out\n", bridge_channel);
784 } else if (res < 0) {
785 ast_debug(1, "DTMF feature string collection failed on bridge channel %p for some reason\n", bridge_channel);
789 /* Add the above DTMF into the DTMF string so we can do our matching */
790 dtmf[dtmf_len++] = res;
792 ast_debug(1, "DTMF feature string on bridge channel %p is now '%s'\n", bridge_channel, dtmf);
794 /* Assume that we do not want to look for DTMF any longer */
797 /* See if a DTMF feature hook matches or can match */
798 AST_LIST_TRAVERSE(&features->hooks, hook, entry) {
799 /* If this hook matches just break out now */
800 if (!strcmp(hook->dtmf, dtmf)) {
801 ast_debug(1, "DTMF feature hook %p matched DTMF string '%s' on bridge channel %p\n", hook, dtmf, bridge_channel);
803 } else if (!strncmp(hook->dtmf, dtmf, dtmf_len)) {
804 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);
807 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);
811 /* If we have reached the maximum length of a DTMF feature string bail out */
812 if (dtmf_len == MAXIMUM_DTMF_FEATURE_STRING) {
817 /* Since we are done bringing DTMF in return to using both begin and end frames */
818 ast_clear_flag(bridge_channel->chan, AST_FLAG_END_DTMF_ONLY);
820 /* If a hook was actually matched execute it on this channel, otherwise stream up the DTMF to the other channels */
822 hook->callback(bridge, bridge_channel, hook->hook_pvt);
824 ast_bridge_dtmf_stream(bridge, dtmf, bridge_channel->chan);
825 ast_bridge_change_state(bridge_channel, AST_BRIDGE_CHANNEL_STATE_WAIT);
831 /*! \brief Internal function that plays back DTMF on a bridge channel */
832 static void bridge_channel_dtmf_stream(struct ast_bridge *bridge, struct ast_bridge_channel *bridge_channel)
836 ast_copy_string(dtmf_q, bridge_channel->dtmf_stream_q, sizeof(dtmf_q));
837 bridge_channel->dtmf_stream_q[0] = '\0';
839 ast_debug(1, "Playing DTMF stream '%s' out to bridge channel %p\n", dtmf_q, bridge_channel);
840 ast_dtmf_stream(bridge_channel->chan, NULL, dtmf_q, 250, 0);
842 ast_bridge_change_state(bridge_channel, AST_BRIDGE_CHANNEL_STATE_WAIT);
847 /*! \brief Join a channel to a bridge and handle anything the bridge may want us to do */
848 static enum ast_bridge_channel_state bridge_channel_join(struct ast_bridge_channel *bridge_channel)
850 int formats[2] = { bridge_channel->chan->readformat, bridge_channel->chan->writeformat };
851 enum ast_bridge_channel_state state;
853 /* Record the thread that will be the owner of us */
854 bridge_channel->thread = pthread_self();
856 ast_debug(1, "Joining bridge channel %p to bridge %p\n", bridge_channel, bridge_channel->bridge);
858 ao2_lock(bridge_channel->bridge);
860 state = bridge_channel->state;
862 /* Add channel into the bridge */
863 AST_LIST_INSERT_TAIL(&bridge_channel->bridge->channels, bridge_channel, entry);
864 bridge_channel->bridge->num++;
866 bridge_array_add(bridge_channel->bridge, bridge_channel->chan);
868 if (bridge_channel->swap) {
869 struct ast_bridge_channel *bridge_channel2 = NULL;
871 /* 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 */
872 if ((bridge_channel2 = find_bridge_channel(bridge_channel->bridge, bridge_channel->swap))) {
873 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);
874 ast_bridge_change_state(bridge_channel2, AST_BRIDGE_CHANNEL_STATE_HANGUP);
877 bridge_channel->swap = NULL;
878 } else if (ast_test_flag(&bridge_channel->bridge->feature_flags, AST_BRIDGE_FLAG_SMART)) {
879 /* Perform the smart bridge operation, basically see if we need to move around between technologies */
880 smart_bridge_operation(bridge_channel->bridge, bridge_channel, bridge_channel->bridge->num);
883 /* Make the channel compatible with the bridge */
884 bridge_make_compatible(bridge_channel->bridge, bridge_channel);
886 /* Tell the bridge technology we are joining so they set us up */
887 if (bridge_channel->bridge->technology->join) {
888 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);
889 if (bridge_channel->bridge->technology->join(bridge_channel->bridge, bridge_channel)) {
890 ast_debug(1, "Bridge technology %s failed to join %p to bridge %p\n", bridge_channel->bridge->technology->name, bridge_channel, bridge_channel->bridge);
894 /* Actually execute the respective threading model, and keep our bridge thread alive */
895 while (bridge_channel->state == AST_BRIDGE_CHANNEL_STATE_WAIT) {
896 /* Update bridge pointer on channel */
897 bridge_channel->chan->bridge = bridge_channel->bridge;
898 /* If the technology requires a thread and one is not running, start it up */
899 if (bridge_channel->bridge->thread == AST_PTHREADT_NULL && (bridge_channel->bridge->technology->capabilities & AST_BRIDGE_CAPABILITY_THREAD)) {
900 bridge_channel->bridge->stop = 0;
901 ast_debug(1, "Starting a bridge thread for bridge %p\n", bridge_channel->bridge);
902 ao2_ref(bridge_channel->bridge, +1);
903 if (ast_pthread_create(&bridge_channel->bridge->thread, NULL, bridge_thread, bridge_channel->bridge)) {
904 ast_debug(1, "Failed to create a bridge thread for bridge %p, giving it another go.\n", bridge_channel->bridge);
905 ao2_ref(bridge_channel->bridge, -1);
909 /* Execute the threading model */
910 state = (bridge_channel->bridge->technology->capabilities & AST_BRIDGE_CAPABILITY_MULTITHREADED ? bridge_channel_join_multithreaded(bridge_channel) : bridge_channel_join_singlethreaded(bridge_channel));
911 /* Depending on the above state see what we need to do */
912 if (state == AST_BRIDGE_CHANNEL_STATE_FEATURE) {
913 bridge_channel_suspend(bridge_channel->bridge, bridge_channel);
914 bridge_channel_feature(bridge_channel->bridge, bridge_channel);
915 bridge_channel_unsuspend(bridge_channel->bridge, bridge_channel);
916 } else if (state == AST_BRIDGE_CHANNEL_STATE_DTMF) {
917 bridge_channel_suspend(bridge_channel->bridge, bridge_channel);
918 bridge_channel_dtmf_stream(bridge_channel->bridge, bridge_channel);
919 bridge_channel_unsuspend(bridge_channel->bridge, bridge_channel);
923 bridge_channel->chan->bridge = NULL;
925 /* See if we need to dissolve the bridge itself if they hung up */
926 if (bridge_channel->state == AST_BRIDGE_CHANNEL_STATE_END) {
927 bridge_check_dissolve(bridge_channel->bridge, bridge_channel);
930 /* Tell the bridge technology we are leaving so they tear us down */
931 if (bridge_channel->bridge->technology->leave) {
932 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);
933 if (bridge_channel->bridge->technology->leave(bridge_channel->bridge, bridge_channel)) {
934 ast_debug(1, "Bridge technology %s failed to leave %p from bridge %p\n", bridge_channel->bridge->technology->name, bridge_channel, bridge_channel->bridge);
938 /* Remove channel from the bridge */
939 bridge_channel->bridge->num--;
940 AST_LIST_REMOVE(&bridge_channel->bridge->channels, bridge_channel, entry);
942 bridge_array_remove(bridge_channel->bridge, bridge_channel->chan);
944 /* Perform the smart bridge operation if needed since a channel has left */
945 if (ast_test_flag(&bridge_channel->bridge->feature_flags, AST_BRIDGE_FLAG_SMART)) {
946 smart_bridge_operation(bridge_channel->bridge, NULL, bridge_channel->bridge->num);
949 ao2_unlock(bridge_channel->bridge);
951 /* Restore original formats of the channel as they came in */
952 if (bridge_channel->chan->readformat != formats[0]) {
953 ast_debug(1, "Bridge is returning %p to read format %s(%d)\n", bridge_channel, ast_getformatname(formats[0]), formats[0]);
954 if (ast_set_read_format(bridge_channel->chan, formats[0])) {
955 ast_debug(1, "Bridge failed to return channel %p to read format %s(%d)\n", bridge_channel, ast_getformatname(formats[0]), formats[0]);
958 if (bridge_channel->chan->writeformat != formats[1]) {
959 ast_debug(1, "Bridge is returning %p to write format %s(%d)\n", bridge_channel, ast_getformatname(formats[1]), formats[1]);
960 if (ast_set_write_format(bridge_channel->chan, formats[1])) {
961 ast_debug(1, "Bridge failed to return channel %p to write format %s(%d)\n", bridge_channel, ast_getformatname(formats[1]), formats[1]);
965 return bridge_channel->state;
968 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)
970 struct ast_bridge_channel bridge_channel = {
974 .features = features,
976 enum ast_bridge_channel_state state;
978 /* Initialize various other elements of the bridge channel structure that we can't do above */
979 ast_mutex_init(&bridge_channel.lock);
980 ast_cond_init(&bridge_channel.cond, NULL);
982 ao2_ref(bridge_channel.bridge, +1);
984 state = bridge_channel_join(&bridge_channel);
986 ao2_ref(bridge_channel.bridge, -1);
988 /* Destroy some elements of the bridge channel structure above */
989 ast_mutex_destroy(&bridge_channel.lock);
990 ast_cond_destroy(&bridge_channel.cond);
995 /*! \brief Thread responsible for imparted bridged channels */
996 static void *bridge_channel_thread(void *data)
998 struct ast_bridge_channel *bridge_channel = data;
999 enum ast_bridge_channel_state state;
1001 state = bridge_channel_join(bridge_channel);
1003 ao2_ref(bridge_channel->bridge, -1);
1005 /* 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 */
1006 if (state == AST_BRIDGE_CHANNEL_STATE_END || state == AST_BRIDGE_CHANNEL_STATE_HANGUP) {
1007 ast_hangup(bridge_channel->chan);
1010 /* Destroy elements of the bridge channel structure and the bridge channel structure itself */
1011 ast_mutex_destroy(&bridge_channel->lock);
1012 ast_cond_destroy(&bridge_channel->cond);
1013 ast_free(bridge_channel);
1018 int ast_bridge_impart(struct ast_bridge *bridge, struct ast_channel *chan, struct ast_channel *swap, struct ast_bridge_features *features)
1020 struct ast_bridge_channel *bridge_channel = NULL;
1022 /* Try to allocate a structure for the bridge channel */
1023 if (!(bridge_channel = ast_calloc(1, sizeof(*bridge_channel)))) {
1027 /* Setup various parameters */
1028 bridge_channel->chan = chan;
1029 bridge_channel->swap = swap;
1030 bridge_channel->bridge = bridge;
1031 bridge_channel->features = features;
1033 /* Initialize our mutex lock and condition */
1034 ast_mutex_init(&bridge_channel->lock);
1035 ast_cond_init(&bridge_channel->cond, NULL);
1037 /* Bump up the reference count on the bridge, it'll get decremented later */
1038 ao2_ref(bridge, +1);
1040 /* Actually create the thread that will handle the channel */
1041 if (ast_pthread_create(&bridge_channel->thread, NULL, bridge_channel_thread, bridge_channel)) {
1042 ao2_ref(bridge, -1);
1043 ast_cond_destroy(&bridge_channel->cond);
1044 ast_mutex_destroy(&bridge_channel->lock);
1045 ast_free(bridge_channel);
1052 int ast_bridge_depart(struct ast_bridge *bridge, struct ast_channel *chan)
1054 struct ast_bridge_channel *bridge_channel = NULL;
1059 /* Try to find the channel that we want to depart */
1060 if (!(bridge_channel = find_bridge_channel(bridge, chan))) {
1065 ast_bridge_change_state(bridge_channel, AST_BRIDGE_CHANNEL_STATE_DEPART);
1066 thread = bridge_channel->thread;
1070 pthread_join(thread, NULL);
1075 int ast_bridge_remove(struct ast_bridge *bridge, struct ast_channel *chan)
1077 struct ast_bridge_channel *bridge_channel = NULL;
1081 /* Try to find the channel that we want to remove */
1082 if (!(bridge_channel = find_bridge_channel(bridge, chan))) {
1087 ast_bridge_change_state(bridge_channel, AST_BRIDGE_CHANNEL_STATE_HANGUP);
1094 int ast_bridge_merge(struct ast_bridge *bridge0, struct ast_bridge *bridge1)
1096 struct ast_bridge_channel *bridge_channel = NULL;
1101 /* If the first bridge currently has 2 channels and is not capable of becoming a multimixing bridge we can not merge */
1102 if ((bridge0->num + bridge1->num) > 2 && (!(bridge0->technology->capabilities & AST_BRIDGE_CAPABILITY_MULTIMIX) && !ast_test_flag(&bridge0->feature_flags, AST_BRIDGE_FLAG_SMART))) {
1103 ao2_unlock(bridge1);
1104 ao2_unlock(bridge0);
1105 ast_debug(1, "Can't merge bridge %p into bridge %p, multimix is needed and it could not be acquired.\n", bridge1, bridge0);
1109 ast_debug(1, "Merging channels from bridge %p into bridge %p\n", bridge1, bridge0);
1111 /* Perform smart bridge operation on bridge we are merging into so it can change bridge technology if needed */
1112 if (smart_bridge_operation(bridge0, NULL, bridge0->num + bridge1->num)) {
1113 ao2_unlock(bridge1);
1114 ao2_unlock(bridge0);
1115 ast_debug(1, "Can't merge bridge %p into bridge %p, tried to perform smart bridge operation and failed.\n", bridge1, bridge0);
1119 /* If a thread is currently executing on bridge1 tell it to stop */
1120 if (bridge1->thread) {
1121 ast_debug(1, "Telling bridge thread on bridge %p to stop as it is being merged into %p\n", bridge1, bridge0);
1122 bridge1->thread = AST_PTHREADT_STOP;
1125 /* Move channels from bridge1 over to bridge0 */
1126 while ((bridge_channel = AST_LIST_REMOVE_HEAD(&bridge1->channels, entry))) {
1127 /* Tell the technology handling bridge1 that the bridge channel is leaving */
1128 if (bridge1->technology->leave) {
1129 ast_debug(1, "Giving bridge technology %s notification that %p is leaving bridge %p\n", bridge1->technology->name, bridge_channel, bridge1);
1130 if (bridge1->technology->leave(bridge1, bridge_channel)) {
1131 ast_debug(1, "Bridge technology %s failed to allow %p to leave bridge %p\n", bridge1->technology->name, bridge_channel, bridge1);
1135 /* Drop channel count and reference count on the bridge they are leaving */
1137 ao2_ref(bridge1, -1);
1139 bridge_array_remove(bridge1, bridge_channel->chan);
1141 /* Now add them into the bridge they are joining, increase channel count, and bump up reference count */
1142 bridge_channel->bridge = bridge0;
1143 AST_LIST_INSERT_TAIL(&bridge0->channels, bridge_channel, entry);
1145 ao2_ref(bridge0, +1);
1147 bridge_array_add(bridge0, bridge_channel->chan);
1149 /* Make the channel compatible with the new bridge it is joining or else formats would go amuck */
1150 bridge_make_compatible(bridge0, bridge_channel);
1152 /* Tell the technology handling bridge0 that the bridge channel is joining */
1153 if (bridge0->technology->join) {
1154 ast_debug(1, "Giving bridge technology %s notification that %p is joining bridge %p\n", bridge0->technology->name, bridge_channel, bridge0);
1155 if (bridge0->technology->join(bridge0, bridge_channel)) {
1156 ast_debug(1, "Bridge technology %s failed to join %p to bridge %p\n", bridge0->technology->name, bridge_channel, bridge0);
1160 /* Poke the bridge channel, this will cause it to wake up and execute the proper threading model for the new bridge it is in */
1161 pthread_kill(bridge_channel->thread, SIGURG);
1162 ast_mutex_lock(&bridge_channel->lock);
1163 ast_cond_signal(&bridge_channel->cond);
1164 ast_mutex_unlock(&bridge_channel->lock);
1167 ast_debug(1, "Merged channels from bridge %p into bridge %p\n", bridge1, bridge0);
1169 ao2_unlock(bridge1);
1170 ao2_unlock(bridge0);
1175 int ast_bridge_suspend(struct ast_bridge *bridge, struct ast_channel *chan)
1177 struct ast_bridge_channel *bridge_channel;
1181 if (!(bridge_channel = find_bridge_channel(bridge, chan))) {
1186 bridge_channel_suspend(bridge, bridge_channel);
1193 int ast_bridge_unsuspend(struct ast_bridge *bridge, struct ast_channel *chan)
1195 struct ast_bridge_channel *bridge_channel;
1199 if (!(bridge_channel = find_bridge_channel(bridge, chan))) {
1204 bridge_channel_unsuspend(bridge, bridge_channel);
1211 void ast_bridge_technology_suspend(struct ast_bridge_technology *technology)
1213 technology->suspended = 1;
1217 void ast_bridge_technology_unsuspend(struct ast_bridge_technology *technology)
1219 technology->suspended = 0;
1223 int ast_bridge_features_register(enum ast_bridge_builtin_feature feature, ast_bridge_features_hook_callback callback, const char *dtmf)
1225 if (builtin_features_handlers[feature]) {
1229 if (!ast_strlen_zero(dtmf)) {
1230 ast_copy_string(builtin_features_dtmf[feature], dtmf, sizeof(builtin_features_dtmf[feature]));
1233 builtin_features_handlers[feature] = callback;
1238 int ast_bridge_features_unregister(enum ast_bridge_builtin_feature feature)
1240 if (!builtin_features_handlers[feature]) {
1244 builtin_features_handlers[feature] = NULL;
1249 int ast_bridge_features_hook(struct ast_bridge_features *features, const char *dtmf, ast_bridge_features_hook_callback callback, void *hook_pvt)
1251 struct ast_bridge_features_hook *hook = NULL;
1253 /* Allocate new memory and setup it's various variables */
1254 if (!(hook = ast_calloc(1, sizeof(*hook)))) {
1258 ast_copy_string(hook->dtmf, dtmf, sizeof(hook->dtmf));
1259 hook->callback = callback;
1260 hook->hook_pvt = hook_pvt;
1262 /* Once done we add it onto the list. Now it will be picked up when DTMF is used */
1263 AST_LIST_INSERT_TAIL(&features->hooks, hook, entry);
1265 features->usable = 1;
1270 int ast_bridge_features_enable(struct ast_bridge_features *features, enum ast_bridge_builtin_feature feature, const char *dtmf, void *config)
1272 /* If no alternate DTMF stream was provided use the default one */
1273 if (ast_strlen_zero(dtmf)) {
1274 dtmf = builtin_features_dtmf[feature];
1275 /* If no DTMF is still available (ie: it has been disabled) then error out now */
1276 if (ast_strlen_zero(dtmf)) {
1277 ast_debug(1, "Failed to enable built in feature %d on %p, no DTMF string is available for it.\n", feature, features);
1282 if (!builtin_features_handlers[feature]) {
1286 /* The rest is basically pretty easy. We create another hook using the built in feature's callback and DTMF, easy as pie. */
1287 return ast_bridge_features_hook(features, dtmf, builtin_features_handlers[feature], config);
1290 int ast_bridge_features_set_flag(struct ast_bridge_features *features, enum ast_bridge_feature_flags flag)
1292 ast_set_flag(&features->feature_flags, flag);
1293 features->usable = 1;
1297 int ast_bridge_features_init(struct ast_bridge_features *features)
1299 /* Zero out the structure */
1300 memset(features, 0, sizeof(*features));
1302 /* Initialize the hooks list, just in case */
1303 AST_LIST_HEAD_INIT_NOLOCK(&features->hooks);
1308 int ast_bridge_features_cleanup(struct ast_bridge_features *features)
1310 struct ast_bridge_features_hook *hook = NULL;
1312 /* This is relatively simple, hooks are kept as a list on the features structure so we just pop them off and free them */
1313 while ((hook = AST_LIST_REMOVE_HEAD(&features->hooks, entry))) {
1320 int ast_bridge_dtmf_stream(struct ast_bridge *bridge, const char *dtmf, struct ast_channel *chan)
1322 struct ast_bridge_channel *bridge_channel = NULL;
1326 AST_LIST_TRAVERSE(&bridge->channels, bridge_channel, entry) {
1327 if (bridge_channel->chan == chan) {
1330 ast_copy_string(bridge_channel->dtmf_stream_q, dtmf, sizeof(bridge_channel->dtmf_stream_q));
1331 ast_bridge_change_state(bridge_channel, AST_BRIDGE_CHANNEL_STATE_DTMF);