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.integer) {
256 ast_bridge_change_state(bridge_channel, AST_BRIDGE_CHANNEL_STATE_FEATURE);
264 /*! \brief Internal function used to determine whether a control frame should be dropped or not */
265 static int bridge_drop_control_frame(int subclass)
268 case AST_CONTROL_ANSWER:
276 void ast_bridge_handle_trip(struct ast_bridge *bridge, struct ast_bridge_channel *bridge_channel, struct ast_channel *chan, int outfd)
278 /* If no bridge channel has been provided and the actual channel has been provided find it */
279 if (chan && !bridge_channel) {
280 bridge_channel = find_bridge_channel(bridge, chan);
283 /* If a bridge channel with actual channel is present read a frame and handle it */
284 if (chan && bridge_channel) {
285 struct ast_frame *frame = (((bridge->features.mute) || (bridge_channel->features && bridge_channel->features->mute)) ? ast_read_noaudio(chan) : ast_read(chan));
287 /* This is pretty simple... see if they hung up */
288 if (!frame || (frame->frametype == AST_FRAME_CONTROL && frame->subclass.integer == AST_CONTROL_HANGUP)) {
289 /* Signal the thread that is handling the bridged channel that it should be ended */
290 ast_bridge_change_state(bridge_channel, AST_BRIDGE_CHANNEL_STATE_END);
291 } else if (frame->frametype == AST_FRAME_CONTROL && bridge_drop_control_frame(frame->subclass.integer)) {
292 ast_debug(1, "Dropping control frame from bridge channel %p\n", bridge_channel);
294 if (frame->frametype == AST_FRAME_DTMF_BEGIN) {
295 frame = bridge_handle_dtmf(bridge, bridge_channel, frame);
297 /* Simply write the frame out to the bridge technology if it still exists */
299 bridge->technology->write(bridge, bridge_channel, frame);
309 /* If a file descriptor actually tripped pass it off to the bridge technology */
310 if (outfd > -1 && bridge->technology->fd) {
311 bridge->technology->fd(bridge, bridge_channel, outfd);
315 /* If all else fails just poke the bridge */
316 if (bridge->technology->poke && bridge_channel) {
317 bridge->technology->poke(bridge, bridge_channel);
324 /*! \brief Generic thread loop, TODO: Rethink this/improve it */
325 static int generic_thread_loop(struct ast_bridge *bridge)
327 while (!bridge->stop && !bridge->refresh && bridge->array_num) {
328 struct ast_channel *winner = NULL;
331 /* Move channels around for priority reasons if we have more than one channel in our array */
332 if (bridge->array_num > 1) {
333 struct ast_channel *first = bridge->array[0];
334 memmove(bridge->array, bridge->array + 1, sizeof(struct ast_channel *) * (bridge->array_num - 1));
335 bridge->array[(bridge->array_num - 1)] = first;
338 /* Wait on the channels */
341 winner = ast_waitfor_n(bridge->array, (int)bridge->array_num, &to);
345 /* Process whatever they did */
346 ast_bridge_handle_trip(bridge, NULL, winner, -1);
352 /*! \brief Bridge thread function */
353 static void *bridge_thread(void *data)
355 struct ast_bridge *bridge = data;
360 ast_debug(1, "Started bridge thread for %p\n", bridge);
362 /* Loop around until we are told to stop */
363 while (!bridge->stop && bridge->array_num && !res) {
364 /* In case the refresh bit was set simply set it back to off */
367 ast_debug(1, "Launching bridge thread function %p for bridge %p\n", (bridge->technology->thread ? bridge->technology->thread : &generic_thread_loop), bridge);
369 /* Execute the appropriate thread function. If the technology does not provide one we use the generic one */
370 res = (bridge->technology->thread ? bridge->technology->thread(bridge) : generic_thread_loop(bridge));
373 ast_debug(1, "Ending bridge thread for %p\n", bridge);
375 /* Indicate the bridge thread is no longer active */
376 bridge->thread = AST_PTHREADT_NULL;
384 /*! \brief Helper function used to find the "best" bridge technology given a specified capabilities */
385 static struct ast_bridge_technology *find_best_technology(format_t capabilities)
387 struct ast_bridge_technology *current = NULL, *best = NULL;
389 AST_RWLIST_RDLOCK(&bridge_technologies);
390 AST_RWLIST_TRAVERSE(&bridge_technologies, current, entry) {
391 char tmp1[256], tmp2[256];
392 ast_debug(1, "Bridge technology %s has capabilities %s and we want %s\n", current->name,
393 ast_getformatname_multiple(tmp1, sizeof(tmp1), current->capabilities),
394 ast_getformatname_multiple(tmp2, sizeof(tmp2), capabilities));
395 if (current->suspended) {
396 ast_debug(1, "Bridge technology %s is suspended. Skipping.\n", current->name);
399 if (!(current->capabilities & capabilities)) {
400 ast_debug(1, "Bridge technology %s does not have the capabilities we need.\n", current->name);
403 if (best && best->preference < current->preference) {
404 ast_debug(1, "Bridge technology %s has preference %d while %s has preference %d. Skipping.\n", current->name, current->preference, best->name, best->preference);
411 /* Increment it's module reference count if present so it does not get unloaded while in use */
413 ast_module_ref(best->mod);
415 ast_debug(1, "Chose bridge technology %s\n", best->name);
418 AST_RWLIST_UNLOCK(&bridge_technologies);
423 static void destroy_bridge(void *obj)
425 struct ast_bridge *bridge = obj;
427 ast_debug(1, "Actually destroying bridge %p, nobody wants it anymore\n", bridge);
429 /* Pass off the bridge to the technology to destroy if needed */
430 if (bridge->technology->destroy) {
431 ast_debug(1, "Giving bridge technology %s the bridge structure %p to destroy\n", bridge->technology->name, bridge);
432 if (bridge->technology->destroy(bridge)) {
433 ast_debug(1, "Bridge technology %s failed to destroy bridge structure %p... trying our best\n", bridge->technology->name, bridge);
437 /* We are no longer using the bridge technology so decrement the module reference count on it */
438 if (bridge->technology->mod) {
439 ast_module_unref(bridge->technology->mod);
442 /* Last but not least clean up the features configuration */
443 ast_bridge_features_cleanup(&bridge->features);
445 /* Drop the array of channels */
446 ast_free(bridge->array);
451 struct ast_bridge *ast_bridge_new(format_t capabilities, int flags)
453 struct ast_bridge *bridge = NULL;
454 struct ast_bridge_technology *bridge_technology = NULL;
456 /* If we need to be a smart bridge see if we can move between 1to1 and multimix bridges */
457 if (flags & AST_BRIDGE_FLAG_SMART) {
458 struct ast_bridge *other_bridge;
460 if (!(other_bridge = ast_bridge_new((capabilities & AST_BRIDGE_CAPABILITY_1TO1MIX) ? AST_BRIDGE_CAPABILITY_MULTIMIX : AST_BRIDGE_CAPABILITY_1TO1MIX, 0))) {
464 ast_bridge_destroy(other_bridge);
467 /* If capabilities were provided use our helper function to find the "best" bridge technology, otherwise we can
468 * just look for the most basic capability needed, single 1to1 mixing. */
469 bridge_technology = (capabilities ? find_best_technology(capabilities) : find_best_technology(AST_BRIDGE_CAPABILITY_1TO1MIX));
471 /* If no bridge technology was found we can't possibly do bridging so fail creation of the bridge */
472 if (!bridge_technology) {
474 ast_debug(1, "Failed to find a bridge technology to satisfy capabilities %s\n",
475 ast_getformatname_multiple(codec_buf, sizeof(codec_buf), capabilities));
479 /* We have everything we need to create this bridge... so allocate the memory, link things together, and fire her up! */
480 if (!(bridge = ao2_alloc(sizeof(*bridge), destroy_bridge))) {
484 bridge->technology = bridge_technology;
485 bridge->thread = AST_PTHREADT_NULL;
487 /* Create an array of pointers for the channels that will be joining us */
488 bridge->array = ast_calloc(BRIDGE_ARRAY_START, sizeof(struct ast_channel*));
489 bridge->array_size = BRIDGE_ARRAY_START;
491 ast_set_flag(&bridge->feature_flags, flags);
493 /* Pass off the bridge to the technology to manipulate if needed */
494 if (bridge->technology->create) {
495 ast_debug(1, "Giving bridge technology %s the bridge structure %p to setup\n", bridge->technology->name, bridge);
496 if (bridge->technology->create(bridge)) {
497 ast_debug(1, "Bridge technology %s failed to setup bridge structure %p\n", bridge->technology->name, bridge);
506 int ast_bridge_check(format_t capabilities)
508 struct ast_bridge_technology *bridge_technology = NULL;
510 if (!(bridge_technology = find_best_technology(capabilities))) {
514 ast_module_unref(bridge_technology->mod);
519 int ast_bridge_destroy(struct ast_bridge *bridge)
521 struct ast_bridge_channel *bridge_channel = NULL;
529 ast_debug(1, "Telling all channels in bridge %p to end and leave the party\n", bridge);
531 /* Drop every bridged channel, the last one will cause the bridge thread (if it exists) to exit */
532 AST_LIST_TRAVERSE(&bridge->channels, bridge_channel, entry) {
533 ast_bridge_change_state(bridge_channel, AST_BRIDGE_CHANNEL_STATE_END);
543 static int bridge_make_compatible(struct ast_bridge *bridge, struct ast_bridge_channel *bridge_channel)
545 format_t formats[2] = {bridge_channel->chan->readformat, bridge_channel->chan->writeformat};
547 /* Are the formats currently in use something ths bridge can handle? */
548 if (!(bridge->technology->formats & bridge_channel->chan->readformat)) {
549 format_t best_format = ast_best_codec(bridge->technology->formats);
551 /* Read format is a no go... */
554 ast_debug(1, "Bridge technology %s wants to read any of formats %s but channel has %s\n", bridge->technology->name,
555 ast_getformatname_multiple(codec_buf, sizeof(codec_buf), bridge->technology->formats),
556 ast_getformatname(formats[0]));
558 /* Switch read format to the best one chosen */
559 if (ast_set_read_format(bridge_channel->chan, best_format)) {
560 ast_log(LOG_WARNING, "Failed to set channel %s to read format %s\n", bridge_channel->chan->name, ast_getformatname(best_format));
563 ast_debug(1, "Bridge %p put channel %s into read format %s\n", bridge, bridge_channel->chan->name, ast_getformatname(best_format));
565 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]));
568 if (!(bridge->technology->formats & formats[1])) {
569 int best_format = ast_best_codec(bridge->technology->formats);
571 /* Write format is a no go... */
574 ast_debug(1, "Bridge technology %s wants to write any of formats %s but channel has %s\n", bridge->technology->name,
575 ast_getformatname_multiple(codec_buf, sizeof(codec_buf), bridge->technology->formats),
576 ast_getformatname(formats[1]));
578 /* Switch write format to the best one chosen */
579 if (ast_set_write_format(bridge_channel->chan, best_format)) {
580 ast_log(LOG_WARNING, "Failed to set channel %s to write format %s\n", bridge_channel->chan->name, ast_getformatname(best_format));
583 ast_debug(1, "Bridge %p put channel %s into write format %s\n", bridge, bridge_channel->chan->name, ast_getformatname(best_format));
585 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]));
591 /*! \brief Perform the smart bridge operation. Basically sees if a new bridge technology should be used instead of the current one. */
592 static int smart_bridge_operation(struct ast_bridge *bridge, struct ast_bridge_channel *bridge_channel, int count)
594 format_t new_capabilities = 0;
595 struct ast_bridge_technology *new_technology = NULL, *old_technology = bridge->technology;
596 struct ast_bridge temp_bridge = {
597 .technology = bridge->technology,
598 .bridge_pvt = bridge->bridge_pvt,
600 struct ast_bridge_channel *bridge_channel2 = NULL;
602 /* Based on current feature determine whether we want to change bridge technologies or not */
603 if (bridge->technology->capabilities & AST_BRIDGE_CAPABILITY_1TO1MIX) {
605 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);
608 new_capabilities = AST_BRIDGE_CAPABILITY_MULTIMIX;
609 } else if (bridge->technology->capabilities & AST_BRIDGE_CAPABILITY_MULTIMIX) {
611 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);
614 new_capabilities = AST_BRIDGE_CAPABILITY_1TO1MIX;
617 if (!new_capabilities) {
618 ast_debug(1, "Bridge '%p' has no new capabilities, not performing smart bridge operation.\n", bridge);
622 /* Attempt to find a new bridge technology to satisfy the capabilities */
623 if (!(new_technology = find_best_technology(new_capabilities))) {
625 ast_debug(1, "Smart bridge operation was unable to find new bridge technology with capabilities %s to satisfy bridge %p\n",
626 ast_getformatname_multiple(codec_buf, sizeof(codec_buf), new_capabilities), bridge);
630 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);
632 /* If a thread is currently executing for the current technology tell it to stop */
633 if (bridge->thread != AST_PTHREADT_NULL) {
634 /* 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. */
635 if (new_technology->capabilities & AST_BRIDGE_CAPABILITY_THREAD) {
636 ast_debug(1, "Telling current bridge thread for bridge %p to refresh\n", bridge);
640 pthread_t bridge_thread = bridge->thread;
641 ast_debug(1, "Telling current bridge thread for bridge %p to stop\n", bridge);
645 pthread_join(bridge_thread, NULL);
650 /* 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 */
651 bridge->bridge_pvt = NULL;
652 bridge->technology = new_technology;
654 /* Pass the bridge to the new bridge technology so it can set it up */
655 if (new_technology->create) {
656 ast_debug(1, "Giving bridge technology %s the bridge structure %p to setup\n", new_technology->name, bridge);
657 if (new_technology->create(bridge)) {
658 ast_debug(1, "Bridge technology %s failed to setup bridge structure %p\n", new_technology->name, bridge);
662 /* Move existing channels over to the new technology, while taking them away from the old one */
663 AST_LIST_TRAVERSE(&bridge->channels, bridge_channel2, entry) {
664 /* Skip over channel that initiated the smart bridge operation */
665 if (bridge_channel == bridge_channel2) {
669 /* First we part them from the old technology */
670 if (old_technology->leave) {
671 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);
672 if (old_technology->leave(&temp_bridge, bridge_channel2)) {
673 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);
677 /* Second we make them compatible again with the bridge */
678 bridge_make_compatible(bridge, bridge_channel2);
680 /* Third we join them to the new technology */
681 if (new_technology->join) {
682 ast_debug(1, "Giving bridge technology %s notification that %p is joining bridge %p\n", new_technology->name, bridge_channel2, bridge);
683 if (new_technology->join(bridge, bridge_channel2)) {
684 ast_debug(1, "Bridge technology %s failed to join %p to bridge %p\n", new_technology->name, bridge_channel2, bridge);
688 /* Fourth we tell them to wake up so they become aware that they above has happened */
689 pthread_kill(bridge_channel2->thread, SIGURG);
690 ast_mutex_lock(&bridge_channel2->lock);
691 ast_cond_signal(&bridge_channel2->cond);
692 ast_mutex_unlock(&bridge_channel2->lock);
695 /* 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 */
696 if (old_technology->destroy) {
697 ast_debug(1, "Giving bridge technology %s the bridge structure %p (really %p) to destroy\n", old_technology->name, &temp_bridge, bridge);
698 if (old_technology->destroy(&temp_bridge)) {
699 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);
703 /* Finally if the old technology has module referencing remove our reference, we are no longer going to use it */
704 if (old_technology->mod) {
705 ast_module_unref(old_technology->mod);
711 /*! \brief Run in a multithreaded model. Each joined channel does writing/reading in their own thread. TODO: Improve */
712 static enum ast_bridge_channel_state bridge_channel_join_multithreaded(struct ast_bridge_channel *bridge_channel)
714 int fds[4] = { -1, }, nfds = 0, i = 0, outfd = -1, ms = -1;
715 struct ast_channel *chan = NULL;
717 /* Add any file descriptors we may want to monitor */
718 if (bridge_channel->bridge->technology->fd) {
719 for (i = 0; i < 4; i ++) {
720 if (bridge_channel->fds[i] >= 0) {
721 fds[nfds++] = bridge_channel->fds[i];
726 ao2_unlock(bridge_channel->bridge);
728 /* Wait for data to either come from the channel or us to be signalled */
729 if (!bridge_channel->suspended) {
730 ast_debug(1, "Going into a multithreaded waitfor for bridge channel %p of bridge %p\n", bridge_channel, bridge_channel->bridge);
731 chan = ast_waitfor_nandfds(&bridge_channel->chan, 1, fds, nfds, NULL, &outfd, &ms);
733 ast_mutex_lock(&bridge_channel->lock);
734 ast_debug(1, "Going into a multithreaded signal wait for bridge channel %p of bridge %p\n", bridge_channel, bridge_channel->bridge);
735 ast_cond_wait(&bridge_channel->cond, &bridge_channel->lock);
736 ast_mutex_unlock(&bridge_channel->lock);
739 ao2_lock(bridge_channel->bridge);
741 if (!bridge_channel->suspended) {
742 ast_bridge_handle_trip(bridge_channel->bridge, bridge_channel, chan, outfd);
745 return bridge_channel->state;
748 /*! \brief Run in a singlethreaded model. Each joined channel yields itself to the main bridge thread. TODO: Improve */
749 static enum ast_bridge_channel_state bridge_channel_join_singlethreaded(struct ast_bridge_channel *bridge_channel)
751 ao2_unlock(bridge_channel->bridge);
752 ast_mutex_lock(&bridge_channel->lock);
753 if (bridge_channel->state == AST_BRIDGE_CHANNEL_STATE_WAIT) {
754 ast_debug(1, "Going into a single threaded signal wait for bridge channel %p of bridge %p\n", bridge_channel, bridge_channel->bridge);
755 ast_cond_wait(&bridge_channel->cond, &bridge_channel->lock);
757 ast_mutex_unlock(&bridge_channel->lock);
758 ao2_lock(bridge_channel->bridge);
760 return bridge_channel->state;
763 /*! \brief Internal function that suspends a channel from a bridge */
764 static void bridge_channel_suspend(struct ast_bridge *bridge, struct ast_bridge_channel *bridge_channel)
766 bridge_channel->suspended = 1;
768 bridge_array_remove(bridge, bridge_channel->chan);
770 if (bridge->technology->suspend) {
771 bridge->technology->suspend(bridge, bridge_channel);
777 /*! \brief Internal function that unsuspends a channel from a bridge */
778 static void bridge_channel_unsuspend(struct ast_bridge *bridge, struct ast_bridge_channel *bridge_channel)
780 bridge_channel->suspended =0;
782 bridge_array_add(bridge, bridge_channel->chan);
784 if (bridge->technology->unsuspend) {
785 bridge->technology->unsuspend(bridge, bridge_channel);
791 /*! \brief Internal function that executes a feature on a bridge channel */
792 static void bridge_channel_feature(struct ast_bridge *bridge, struct ast_bridge_channel *bridge_channel)
794 struct ast_bridge_features *features = (bridge_channel->features ? bridge_channel->features : &bridge->features);
795 struct ast_bridge_features_hook *hook = NULL;
796 char dtmf[MAXIMUM_DTMF_FEATURE_STRING] = "";
797 int look_for_dtmf = 1, dtmf_len = 0;
799 /* 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 */
800 ast_set_flag(bridge_channel->chan, AST_FLAG_END_DTMF_ONLY);
802 /* Wait for DTMF on the channel and put it into a buffer. If the buffer matches any feature hook execute the hook. */
803 while (look_for_dtmf) {
804 int res = ast_waitfordigit(bridge_channel->chan, 3000);
806 /* If the above timed out simply exit */
808 ast_debug(1, "DTMF feature string collection on bridge channel %p timed out\n", bridge_channel);
810 } else if (res < 0) {
811 ast_debug(1, "DTMF feature string collection failed on bridge channel %p for some reason\n", bridge_channel);
815 /* Add the above DTMF into the DTMF string so we can do our matching */
816 dtmf[dtmf_len++] = res;
818 ast_debug(1, "DTMF feature string on bridge channel %p is now '%s'\n", bridge_channel, dtmf);
820 /* Assume that we do not want to look for DTMF any longer */
823 /* See if a DTMF feature hook matches or can match */
824 AST_LIST_TRAVERSE(&features->hooks, hook, entry) {
825 /* If this hook matches just break out now */
826 if (!strcmp(hook->dtmf, dtmf)) {
827 ast_debug(1, "DTMF feature hook %p matched DTMF string '%s' on bridge channel %p\n", hook, dtmf, bridge_channel);
829 } else if (!strncmp(hook->dtmf, dtmf, dtmf_len)) {
830 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);
833 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);
837 /* If we have reached the maximum length of a DTMF feature string bail out */
838 if (dtmf_len == MAXIMUM_DTMF_FEATURE_STRING) {
843 /* Since we are done bringing DTMF in return to using both begin and end frames */
844 ast_clear_flag(bridge_channel->chan, AST_FLAG_END_DTMF_ONLY);
846 /* If a hook was actually matched execute it on this channel, otherwise stream up the DTMF to the other channels */
848 hook->callback(bridge, bridge_channel, hook->hook_pvt);
850 ast_bridge_dtmf_stream(bridge, dtmf, bridge_channel->chan);
851 ast_bridge_change_state(bridge_channel, AST_BRIDGE_CHANNEL_STATE_WAIT);
857 /*! \brief Internal function that plays back DTMF on a bridge channel */
858 static void bridge_channel_dtmf_stream(struct ast_bridge *bridge, struct ast_bridge_channel *bridge_channel)
862 ast_copy_string(dtmf_q, bridge_channel->dtmf_stream_q, sizeof(dtmf_q));
863 bridge_channel->dtmf_stream_q[0] = '\0';
865 ast_debug(1, "Playing DTMF stream '%s' out to bridge channel %p\n", dtmf_q, bridge_channel);
866 ast_dtmf_stream(bridge_channel->chan, NULL, dtmf_q, 250, 0);
868 ast_bridge_change_state(bridge_channel, AST_BRIDGE_CHANNEL_STATE_WAIT);
873 /*! \brief Join a channel to a bridge and handle anything the bridge may want us to do */
874 static enum ast_bridge_channel_state bridge_channel_join(struct ast_bridge_channel *bridge_channel)
876 int formats[2] = { bridge_channel->chan->readformat, bridge_channel->chan->writeformat };
877 enum ast_bridge_channel_state state;
879 /* Record the thread that will be the owner of us */
880 bridge_channel->thread = pthread_self();
882 ast_debug(1, "Joining bridge channel %p to bridge %p\n", bridge_channel, bridge_channel->bridge);
884 ao2_lock(bridge_channel->bridge);
886 state = bridge_channel->state;
888 /* Add channel into the bridge */
889 AST_LIST_INSERT_TAIL(&bridge_channel->bridge->channels, bridge_channel, entry);
890 bridge_channel->bridge->num++;
892 bridge_array_add(bridge_channel->bridge, bridge_channel->chan);
894 if (bridge_channel->swap) {
895 struct ast_bridge_channel *bridge_channel2 = NULL;
897 /* 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 */
898 if ((bridge_channel2 = find_bridge_channel(bridge_channel->bridge, bridge_channel->swap))) {
899 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);
900 ast_bridge_change_state(bridge_channel2, AST_BRIDGE_CHANNEL_STATE_HANGUP);
903 bridge_channel->swap = NULL;
904 } else if (ast_test_flag(&bridge_channel->bridge->feature_flags, AST_BRIDGE_FLAG_SMART)) {
905 /* Perform the smart bridge operation, basically see if we need to move around between technologies */
906 smart_bridge_operation(bridge_channel->bridge, bridge_channel, bridge_channel->bridge->num);
909 /* Make the channel compatible with the bridge */
910 bridge_make_compatible(bridge_channel->bridge, bridge_channel);
912 /* Tell the bridge technology we are joining so they set us up */
913 if (bridge_channel->bridge->technology->join) {
914 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);
915 if (bridge_channel->bridge->technology->join(bridge_channel->bridge, bridge_channel)) {
916 ast_debug(1, "Bridge technology %s failed to join %p to bridge %p\n", bridge_channel->bridge->technology->name, bridge_channel, bridge_channel->bridge);
920 /* Actually execute the respective threading model, and keep our bridge thread alive */
921 while (bridge_channel->state == AST_BRIDGE_CHANNEL_STATE_WAIT) {
922 /* Update bridge pointer on channel */
923 bridge_channel->chan->bridge = bridge_channel->bridge;
924 /* If the technology requires a thread and one is not running, start it up */
925 if (bridge_channel->bridge->thread == AST_PTHREADT_NULL && (bridge_channel->bridge->technology->capabilities & AST_BRIDGE_CAPABILITY_THREAD)) {
926 bridge_channel->bridge->stop = 0;
927 ast_debug(1, "Starting a bridge thread for bridge %p\n", bridge_channel->bridge);
928 ao2_ref(bridge_channel->bridge, +1);
929 if (ast_pthread_create(&bridge_channel->bridge->thread, NULL, bridge_thread, bridge_channel->bridge)) {
930 ast_debug(1, "Failed to create a bridge thread for bridge %p, giving it another go.\n", bridge_channel->bridge);
931 ao2_ref(bridge_channel->bridge, -1);
935 /* Execute the threading model */
936 state = (bridge_channel->bridge->technology->capabilities & AST_BRIDGE_CAPABILITY_MULTITHREADED ? bridge_channel_join_multithreaded(bridge_channel) : bridge_channel_join_singlethreaded(bridge_channel));
937 /* Depending on the above state see what we need to do */
938 if (state == AST_BRIDGE_CHANNEL_STATE_FEATURE) {
939 bridge_channel_suspend(bridge_channel->bridge, bridge_channel);
940 bridge_channel_feature(bridge_channel->bridge, bridge_channel);
941 bridge_channel_unsuspend(bridge_channel->bridge, bridge_channel);
942 } else if (state == AST_BRIDGE_CHANNEL_STATE_DTMF) {
943 bridge_channel_suspend(bridge_channel->bridge, bridge_channel);
944 bridge_channel_dtmf_stream(bridge_channel->bridge, bridge_channel);
945 bridge_channel_unsuspend(bridge_channel->bridge, bridge_channel);
949 bridge_channel->chan->bridge = NULL;
951 /* See if we need to dissolve the bridge itself if they hung up */
952 if (bridge_channel->state == AST_BRIDGE_CHANNEL_STATE_END) {
953 bridge_check_dissolve(bridge_channel->bridge, bridge_channel);
956 /* Tell the bridge technology we are leaving so they tear us down */
957 if (bridge_channel->bridge->technology->leave) {
958 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);
959 if (bridge_channel->bridge->technology->leave(bridge_channel->bridge, bridge_channel)) {
960 ast_debug(1, "Bridge technology %s failed to leave %p from bridge %p\n", bridge_channel->bridge->technology->name, bridge_channel, bridge_channel->bridge);
964 /* Remove channel from the bridge */
965 bridge_channel->bridge->num--;
966 AST_LIST_REMOVE(&bridge_channel->bridge->channels, bridge_channel, entry);
968 bridge_array_remove(bridge_channel->bridge, bridge_channel->chan);
970 /* Perform the smart bridge operation if needed since a channel has left */
971 if (ast_test_flag(&bridge_channel->bridge->feature_flags, AST_BRIDGE_FLAG_SMART)) {
972 smart_bridge_operation(bridge_channel->bridge, NULL, bridge_channel->bridge->num);
975 ao2_unlock(bridge_channel->bridge);
977 /* Restore original formats of the channel as they came in */
978 if (bridge_channel->chan->readformat != formats[0]) {
979 ast_debug(1, "Bridge is returning %p to read format %s(%d)\n", bridge_channel, ast_getformatname(formats[0]), formats[0]);
980 if (ast_set_read_format(bridge_channel->chan, formats[0])) {
981 ast_debug(1, "Bridge failed to return channel %p to read format %s(%d)\n", bridge_channel, ast_getformatname(formats[0]), formats[0]);
984 if (bridge_channel->chan->writeformat != formats[1]) {
985 ast_debug(1, "Bridge is returning %p to write format %s(%d)\n", bridge_channel, ast_getformatname(formats[1]), formats[1]);
986 if (ast_set_write_format(bridge_channel->chan, formats[1])) {
987 ast_debug(1, "Bridge failed to return channel %p to write format %s(%d)\n", bridge_channel, ast_getformatname(formats[1]), formats[1]);
991 return bridge_channel->state;
994 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)
996 struct ast_bridge_channel bridge_channel = {
1000 .features = features,
1002 enum ast_bridge_channel_state state;
1004 /* Initialize various other elements of the bridge channel structure that we can't do above */
1005 ast_mutex_init(&bridge_channel.lock);
1006 ast_cond_init(&bridge_channel.cond, NULL);
1008 ao2_ref(bridge_channel.bridge, +1);
1010 state = bridge_channel_join(&bridge_channel);
1012 ao2_ref(bridge_channel.bridge, -1);
1014 /* Destroy some elements of the bridge channel structure above */
1015 ast_mutex_destroy(&bridge_channel.lock);
1016 ast_cond_destroy(&bridge_channel.cond);
1021 /*! \brief Thread responsible for imparted bridged channels */
1022 static void *bridge_channel_thread(void *data)
1024 struct ast_bridge_channel *bridge_channel = data;
1025 enum ast_bridge_channel_state state;
1027 state = bridge_channel_join(bridge_channel);
1029 ao2_ref(bridge_channel->bridge, -1);
1031 /* 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 */
1032 if (state == AST_BRIDGE_CHANNEL_STATE_END || state == AST_BRIDGE_CHANNEL_STATE_HANGUP) {
1033 ast_hangup(bridge_channel->chan);
1036 /* Destroy elements of the bridge channel structure and the bridge channel structure itself */
1037 ast_mutex_destroy(&bridge_channel->lock);
1038 ast_cond_destroy(&bridge_channel->cond);
1039 ast_free(bridge_channel);
1044 int ast_bridge_impart(struct ast_bridge *bridge, struct ast_channel *chan, struct ast_channel *swap, struct ast_bridge_features *features)
1046 struct ast_bridge_channel *bridge_channel = NULL;
1048 /* Try to allocate a structure for the bridge channel */
1049 if (!(bridge_channel = ast_calloc(1, sizeof(*bridge_channel)))) {
1053 /* Setup various parameters */
1054 bridge_channel->chan = chan;
1055 bridge_channel->swap = swap;
1056 bridge_channel->bridge = bridge;
1057 bridge_channel->features = features;
1059 /* Initialize our mutex lock and condition */
1060 ast_mutex_init(&bridge_channel->lock);
1061 ast_cond_init(&bridge_channel->cond, NULL);
1063 /* Bump up the reference count on the bridge, it'll get decremented later */
1064 ao2_ref(bridge, +1);
1066 /* Actually create the thread that will handle the channel */
1067 if (ast_pthread_create(&bridge_channel->thread, NULL, bridge_channel_thread, bridge_channel)) {
1068 ao2_ref(bridge, -1);
1069 ast_cond_destroy(&bridge_channel->cond);
1070 ast_mutex_destroy(&bridge_channel->lock);
1071 ast_free(bridge_channel);
1078 int ast_bridge_depart(struct ast_bridge *bridge, struct ast_channel *chan)
1080 struct ast_bridge_channel *bridge_channel = NULL;
1085 /* Try to find the channel that we want to depart */
1086 if (!(bridge_channel = find_bridge_channel(bridge, chan))) {
1091 ast_bridge_change_state(bridge_channel, AST_BRIDGE_CHANNEL_STATE_DEPART);
1092 thread = bridge_channel->thread;
1096 pthread_join(thread, NULL);
1101 int ast_bridge_remove(struct ast_bridge *bridge, struct ast_channel *chan)
1103 struct ast_bridge_channel *bridge_channel = NULL;
1107 /* Try to find the channel that we want to remove */
1108 if (!(bridge_channel = find_bridge_channel(bridge, chan))) {
1113 ast_bridge_change_state(bridge_channel, AST_BRIDGE_CHANNEL_STATE_HANGUP);
1120 int ast_bridge_merge(struct ast_bridge *bridge0, struct ast_bridge *bridge1)
1122 struct ast_bridge_channel *bridge_channel = NULL;
1127 /* If the first bridge currently has 2 channels and is not capable of becoming a multimixing bridge we can not merge */
1128 if ((bridge0->num + bridge1->num) > 2 && (!(bridge0->technology->capabilities & AST_BRIDGE_CAPABILITY_MULTIMIX) && !ast_test_flag(&bridge0->feature_flags, AST_BRIDGE_FLAG_SMART))) {
1129 ao2_unlock(bridge1);
1130 ao2_unlock(bridge0);
1131 ast_debug(1, "Can't merge bridge %p into bridge %p, multimix is needed and it could not be acquired.\n", bridge1, bridge0);
1135 ast_debug(1, "Merging channels from bridge %p into bridge %p\n", bridge1, bridge0);
1137 /* Perform smart bridge operation on bridge we are merging into so it can change bridge technology if needed */
1138 if (smart_bridge_operation(bridge0, NULL, bridge0->num + bridge1->num)) {
1139 ao2_unlock(bridge1);
1140 ao2_unlock(bridge0);
1141 ast_debug(1, "Can't merge bridge %p into bridge %p, tried to perform smart bridge operation and failed.\n", bridge1, bridge0);
1145 /* If a thread is currently executing on bridge1 tell it to stop */
1146 if (bridge1->thread) {
1147 ast_debug(1, "Telling bridge thread on bridge %p to stop as it is being merged into %p\n", bridge1, bridge0);
1148 bridge1->thread = AST_PTHREADT_STOP;
1151 /* Move channels from bridge1 over to bridge0 */
1152 while ((bridge_channel = AST_LIST_REMOVE_HEAD(&bridge1->channels, entry))) {
1153 /* Tell the technology handling bridge1 that the bridge channel is leaving */
1154 if (bridge1->technology->leave) {
1155 ast_debug(1, "Giving bridge technology %s notification that %p is leaving bridge %p\n", bridge1->technology->name, bridge_channel, bridge1);
1156 if (bridge1->technology->leave(bridge1, bridge_channel)) {
1157 ast_debug(1, "Bridge technology %s failed to allow %p to leave bridge %p\n", bridge1->technology->name, bridge_channel, bridge1);
1161 /* Drop channel count and reference count on the bridge they are leaving */
1163 ao2_ref(bridge1, -1);
1165 bridge_array_remove(bridge1, bridge_channel->chan);
1167 /* Now add them into the bridge they are joining, increase channel count, and bump up reference count */
1168 bridge_channel->bridge = bridge0;
1169 AST_LIST_INSERT_TAIL(&bridge0->channels, bridge_channel, entry);
1171 ao2_ref(bridge0, +1);
1173 bridge_array_add(bridge0, bridge_channel->chan);
1175 /* Make the channel compatible with the new bridge it is joining or else formats would go amuck */
1176 bridge_make_compatible(bridge0, bridge_channel);
1178 /* Tell the technology handling bridge0 that the bridge channel is joining */
1179 if (bridge0->technology->join) {
1180 ast_debug(1, "Giving bridge technology %s notification that %p is joining bridge %p\n", bridge0->technology->name, bridge_channel, bridge0);
1181 if (bridge0->technology->join(bridge0, bridge_channel)) {
1182 ast_debug(1, "Bridge technology %s failed to join %p to bridge %p\n", bridge0->technology->name, bridge_channel, bridge0);
1186 /* Poke the bridge channel, this will cause it to wake up and execute the proper threading model for the new bridge it is in */
1187 pthread_kill(bridge_channel->thread, SIGURG);
1188 ast_mutex_lock(&bridge_channel->lock);
1189 ast_cond_signal(&bridge_channel->cond);
1190 ast_mutex_unlock(&bridge_channel->lock);
1193 ast_debug(1, "Merged channels from bridge %p into bridge %p\n", bridge1, bridge0);
1195 ao2_unlock(bridge1);
1196 ao2_unlock(bridge0);
1201 int ast_bridge_suspend(struct ast_bridge *bridge, struct ast_channel *chan)
1203 struct ast_bridge_channel *bridge_channel;
1207 if (!(bridge_channel = find_bridge_channel(bridge, chan))) {
1212 bridge_channel_suspend(bridge, bridge_channel);
1219 int ast_bridge_unsuspend(struct ast_bridge *bridge, struct ast_channel *chan)
1221 struct ast_bridge_channel *bridge_channel;
1225 if (!(bridge_channel = find_bridge_channel(bridge, chan))) {
1230 bridge_channel_unsuspend(bridge, bridge_channel);
1237 void ast_bridge_technology_suspend(struct ast_bridge_technology *technology)
1239 technology->suspended = 1;
1243 void ast_bridge_technology_unsuspend(struct ast_bridge_technology *technology)
1245 technology->suspended = 0;
1249 int ast_bridge_features_register(enum ast_bridge_builtin_feature feature, ast_bridge_features_hook_callback callback, const char *dtmf)
1251 if (builtin_features_handlers[feature]) {
1255 if (!ast_strlen_zero(dtmf)) {
1256 ast_copy_string(builtin_features_dtmf[feature], dtmf, sizeof(builtin_features_dtmf[feature]));
1259 builtin_features_handlers[feature] = callback;
1264 int ast_bridge_features_unregister(enum ast_bridge_builtin_feature feature)
1266 if (!builtin_features_handlers[feature]) {
1270 builtin_features_handlers[feature] = NULL;
1275 int ast_bridge_features_hook(struct ast_bridge_features *features, const char *dtmf, ast_bridge_features_hook_callback callback, void *hook_pvt)
1277 struct ast_bridge_features_hook *hook = NULL;
1279 /* Allocate new memory and setup it's various variables */
1280 if (!(hook = ast_calloc(1, sizeof(*hook)))) {
1284 ast_copy_string(hook->dtmf, dtmf, sizeof(hook->dtmf));
1285 hook->callback = callback;
1286 hook->hook_pvt = hook_pvt;
1288 /* Once done we add it onto the list. Now it will be picked up when DTMF is used */
1289 AST_LIST_INSERT_TAIL(&features->hooks, hook, entry);
1291 features->usable = 1;
1296 int ast_bridge_features_enable(struct ast_bridge_features *features, enum ast_bridge_builtin_feature feature, const char *dtmf, void *config)
1298 /* If no alternate DTMF stream was provided use the default one */
1299 if (ast_strlen_zero(dtmf)) {
1300 dtmf = builtin_features_dtmf[feature];
1301 /* If no DTMF is still available (ie: it has been disabled) then error out now */
1302 if (ast_strlen_zero(dtmf)) {
1303 ast_debug(1, "Failed to enable built in feature %d on %p, no DTMF string is available for it.\n", feature, features);
1308 if (!builtin_features_handlers[feature]) {
1312 /* The rest is basically pretty easy. We create another hook using the built in feature's callback and DTMF, easy as pie. */
1313 return ast_bridge_features_hook(features, dtmf, builtin_features_handlers[feature], config);
1316 int ast_bridge_features_set_flag(struct ast_bridge_features *features, enum ast_bridge_feature_flags flag)
1318 ast_set_flag(&features->feature_flags, flag);
1319 features->usable = 1;
1323 int ast_bridge_features_init(struct ast_bridge_features *features)
1325 /* Zero out the structure */
1326 memset(features, 0, sizeof(*features));
1328 /* Initialize the hooks list, just in case */
1329 AST_LIST_HEAD_INIT_NOLOCK(&features->hooks);
1334 int ast_bridge_features_cleanup(struct ast_bridge_features *features)
1336 struct ast_bridge_features_hook *hook = NULL;
1338 /* This is relatively simple, hooks are kept as a list on the features structure so we just pop them off and free them */
1339 while ((hook = AST_LIST_REMOVE_HEAD(&features->hooks, entry))) {
1346 int ast_bridge_dtmf_stream(struct ast_bridge *bridge, const char *dtmf, struct ast_channel *chan)
1348 struct ast_bridge_channel *bridge_channel = NULL;
1352 AST_LIST_TRAVERSE(&bridge->channels, bridge_channel, entry) {
1353 if (bridge_channel->chan == chan) {
1356 ast_copy_string(bridge_channel->dtmf_stream_q, dtmf, sizeof(bridge_channel->dtmf_stream_q));
1357 ast_bridge_change_state(bridge_channel, AST_BRIDGE_CHANNEL_STATE_DTMF);