130 #define BRIDGE_ARRAY_START 128 133 #define BRIDGE_ARRAY_GROW 32 136 #define BLINDTRANSFER "BLINDTRANSFER" 139 #define ATTENDEDTRANSFER "ATTENDEDTRANSFER" 193 if (bridge_manager->
stop) {
221 || !technology->
write) {
231 if ((!strcasecmp(current->
name, technology->
name)) || (current == technology)) {
232 ast_log(
LOG_WARNING,
"A bridge technology of %s already claims to exist in our world.\n",
240 technology->
mod = module;
260 ast_verb(2,
"Registered bridge technology %s\n", technology->
name);
273 if (current == technology) {
275 ast_verb(2,
"Unregistered bridge technology %s\n", technology->
name);
283 return current ? 0 : -1;
298 ast_debug(1,
"Bridge %s: queueing action type:%u sub:%d\n",
335 bridge->
cause = cause;
337 ast_debug(1,
"Bridge %s: dissolving bridge with cause %d(%s)\n",
397 unsigned char data[1024];
400 if (!bridge_channel ||
446 ast_debug(1,
"Bridge %s: %p(%s) is joining %s technology\n",
452 ast_debug(1,
"Bridge %s: %p(%s) failed to join %s technology (Kicking it out)\n",
469 bridge_channel->
bridge, bridge_channel);
519 ast_debug(1,
"Bridge technology %s is suspended. Skipping.\n",
524 ast_debug(1,
"Bridge technology %s does not have any capabilities we want.\n",
529 ast_debug(1,
"Bridge technology %s has less preference than %s (%u <= %u). Skipping.\n",
534 ast_debug(1,
"Bridge technology %s is not compatible with properties of existing bridge.\n",
539 ast_debug(1,
"Bridge technology %s is not running, skipping.\n", current->
name);
581 .name = bridge->
name,
585 ast_debug(1,
"Bridge %s: calling %s technology destructor (deferred, dummy)\n",
607 int in_destructor = !
ao2_ref(bridge, 0);
662 ast_debug(1,
"Bridge %s: actually destroying %s bridge, nobody wants it anymore\n",
677 ast_debug(1,
"Bridge %s: calling %s bridge destructor\n",
683 ast_debug(1,
"Bridge %s: calling %s technology stop\n",
690 ast_debug(1,
"Bridge %s: calling %s technology destructor\n",
737 ast_log(
LOG_ERROR,
"Virtual method table for bridge class %s not complete.\n",
738 v_table && v_table->
name ? v_table->
name :
"<unknown>");
780 self->allowed_capabilities = capabilities;
793 if (!self->technology) {
794 ast_log(
LOG_WARNING,
"Bridge %s: Could not create class %s. No technology to support it.\n",
795 self->uniqueid, self->v_table->name);
801 ast_debug(1,
"Bridge %s: calling %s technology constructor\n",
802 self->uniqueid, self->technology->name);
803 if (self->technology->create && self->technology->create(
self)) {
805 self->uniqueid, self->technology->name);
809 ast_debug(1,
"Bridge %s: calling %s technology start\n",
810 self->uniqueid, self->technology->name);
811 if (self->technology->start && self->technology->start(
self)) {
813 self->uniqueid, self->technology->name);
818 if (!(flags & AST_BRIDGE_FLAG_INVISIBLE)) {
910 self->reconfigured = 1;
972 ast_debug(1,
"Bridge %s: telling all channels to leave the party\n", bridge->
uniqueid);
1000 uint32_t new_capabilities;
1009 .name = bridge->
name,
1014 ast_debug(1,
"Bridge %s is dissolved, not performing smart bridge operation.\n",
1026 if (!new_capabilities
1035 if (!new_technology) {
1036 int is_compatible = 0;
1039 is_compatible = old_technology->
compatible(bridge);
1047 if (is_compatible) {
1048 ast_debug(1,
"Bridge %s could not get a new technology, staying with old technology.\n",
1056 if (new_technology == old_technology) {
1057 ast_debug(1,
"Bridge %s is already using the new technology.\n",
1063 if (old_technology->
destroy) {
1071 .data.ptr = &deferred_tech_destroy,
1072 .datalen =
sizeof(deferred_tech_destroy),
1080 if (!deferred_action) {
1085 deferred_action =
NULL;
1093 ast_verb(4,
"Bridge %s: switching from %s technology to %s\n",
1106 ast_debug(1,
"Bridge %s: calling %s technology constructor\n",
1108 if (new_technology->
create && new_technology->
create(bridge)) {
1124 ast_debug(1,
"Bridge %s: moving %p(%s) to dummy bridge temporarily\n",
1140 ast_debug(1,
"Bridge %s: %p(%s) is leaving %s technology (dummy)\n",
1142 old_technology->
name);
1143 if (old_technology->
leave) {
1144 old_technology->
leave(&dummy_bridge, bridge_channel);
1158 ast_debug(1,
"Bridge %s: calling %s technology stop\n",
1160 if (old_technology->
stop) {
1161 old_technology->
stop(&dummy_bridge);
1169 ast_debug(1,
"Bridge %s: calling %s technology start\n",
1171 if (new_technology->
start && new_technology->
start(bridge)) {
1181 if (old_technology->
destroy) {
1182 ast_debug(1,
"Bridge %s: deferring %s technology destructor\n",
1186 ast_debug(1,
"Bridge %s: calling %s technology destructor\n",
1265 const char *c0_name;
1266 const char *c1_name;
1267 const char *c0_pvtid =
NULL;
1268 const char *c1_pvtid =
NULL;
1269 #define UPDATE_BRIDGE_VARS_GET(chan, name, pvtid) \ 1271 name = ast_strdupa(ast_channel_name(chan)); \ 1272 if (ast_channel_tech(chan)->get_pvt_uniqueid) { \ 1273 pvtid = ast_strdupa(ast_channel_tech(chan)->get_pvt_uniqueid(chan)); \ 1305 int need_separator = 0;
1311 for (idx = 0; idx < num_names; ++idx) {
1312 if (idx == cur_idx) {
1316 if (need_separator) {
1349 #define MAX_BRIDGEPEER_CHANS (10 + 1) 1352 unsigned int num_names;
1360 names =
ast_alloca(num_names *
sizeof(*names));
1363 if (num_names <= idx) {
1373 for (idx = 0; idx < num_names; ++idx) {
1374 len += strlen(names[idx]);
1382 if (idx < num_names) {
1474 if (bridge_channel->
chan == chan) {
1479 return bridge_channel;
1491 if (!bridge_channel) {
1497 bridge = bridge_channel->
bridge;
1577 .
type =
"bridge-impart-ds",
1613 datastore->
data = ds_head;
1616 ds_head = datastore->
data;
1650 while (!cond->
done) {
1682 if (!bridge_channel) {
1683 ao2_t_cleanup(swap,
"Error exit: bridge_channel alloc failed");
1706 bridge_channel->
thread = pthread_self();
1717 if (bridge_channel->
swap) {
1762 if (bridge_channel->
callid) {
1773 ao2_t_cleanup(bridge_channel->
swap,
"Bridge complete: Departable impart join failed");
1793 if (bridge_channel->
callid) {
1798 chan = bridge_channel->
chan;
1809 ao2_t_cleanup(bridge_channel->
swap,
"Bridge complete: Independent impart join failed");
1851 if (!bridge_channel) {
1866 bridge_channel->
swap =
ao2_t_bump(swap,
"Setting up bridge impart");
1878 if (bridge_channel->
swap) {
1960 departable = bridge_channel && bridge_channel->
depart_wait;
1984 ast_debug(1,
"Waiting for %p(%s) bridge thread to die.\n",
2001 ast_debug(1,
"Removing channel %s from bridge %s\n",
2062 old_bridge = bridge_channel->
bridge;
2063 bridge_channel->
bridge = new_bridge;
2086 remove_me = move_cb(bridge_channel, hook->
hook_pvt, src, dst);
2088 ast_debug(1,
"Move detection hook %p is being removed from %p(%s)\n",
2097 unsigned int optimized)
2102 ast_debug(1,
"Merging bridge %s into bridge %s\n",
2127 for (idx = 0; idx < num_kick; ++idx) {
2128 if (bridge_channel == kick_me[idx]) {
2163 for (idx = 0; idx < num_kick; ++idx) {
2164 bridge_channel = kick_me[idx];
2178 ast_debug(1,
"Merged bridge %s into bridge %s\n",
2204 int bridge1_priority;
2205 int bridge2_priority;
2215 bridge1_priority = bridge1->v_table->get_merge_priority(bridge1);
2216 bridge2_priority = bridge2->v_table->get_merge_priority(bridge2);
2217 if (bridge2_priority < bridge1_priority) {
2218 merge.
dest = bridge1;
2219 merge.
src = bridge2;
2220 }
else if (bridge1_priority < bridge2_priority) {
2221 merge.
dest = bridge2;
2222 merge.
src = bridge1;
2225 if (bridge2->num_channels <= bridge1->num_channels) {
2226 merge.
dest = bridge1;
2227 merge.
src = bridge2;
2229 merge.
dest = bridge2;
2230 merge.
src = bridge1;
2236 merge.
dest = bridge1;
2237 merge.
src = bridge2;
2241 merge.
dest = bridge2;
2242 merge.
src = bridge1;
2270 ast_assert(dst_bridge && src_bridge && dst_bridge != src_bridge && (!num_kick || kick_me));
2273 ast_debug(1,
"Can't merge bridges %s and %s, at least one bridge is dissolved.\n",
2279 ast_debug(1,
"Can't merge bridges %s and %s, masquerade only.\n",
2284 ast_debug(1,
"Can't merge bridges %s and %s, merging temporarily inhibited.\n",
2289 if (merge_best_direction) {
2292 merge.
dest = dst_bridge;
2293 merge.
src = src_bridge;
2299 ast_debug(1,
"Can't merge bridges %s and %s, merging inhibited.\n",
2309 ast_debug(1,
"Can't merge bridge %s into bridge %s, not enough channels in source bridge.\n",
2317 ast_debug(1,
"Can't merge bridge %s into bridge %s, multimix is needed and it cannot be acquired.\n",
2323 unsigned int num_to_kick = 0;
2326 kick_them =
ast_alloca(num_kick *
sizeof(*kick_them));
2327 for (idx = 0; idx < num_kick; ++idx) {
2329 if (!kick_them[num_to_kick]) {
2332 if (kick_them[num_to_kick]) {
2337 if (num_to_kick != num_kick) {
2338 ast_debug(1,
"Can't merge bridge %s into bridge %s, at least one kicked channel is not in either bridge.\n",
2356 res =
bridge_merge_locked(dst_bridge, src_bridge, merge_best_direction, kick_me, num_kick);
2363 unsigned int optimized)
2369 if (bridge_channel->
swap) {
2370 ast_debug(1,
"Moving %p(%s) into bridge %s swapping with %s\n",
2374 ast_debug(1,
"Moving %p(%s) into bridge %s\n",
2378 orig_bridge = bridge_channel->
bridge;
2379 was_in_bridge = bridge_channel->
in_bridge;
2405 if (attempt_recovery && was_in_bridge) {
2421 }
else if (!optimized) {
2452 ast_debug(1,
"Can't move channel %s from bridge %s into bridge %s, at least one bridge is dissolved.\n",
2458 ast_debug(1,
"Can't move channel %s from bridge %s into bridge %s, masquerade only.\n",
2463 ast_debug(1,
"Can't move channel %s from bridge %s into bridge %s, temporarily inhibited.\n",
2469 if (!bridge_channel) {
2470 ast_debug(1,
"Can't move channel %s from bridge %s into bridge %s, channel not in bridge.\n",
2475 ast_debug(1,
"Can't move channel %s from bridge %s into bridge %s, channel leaving bridge.\n",
2481 ast_debug(1,
"Can't move channel %s from bridge %s into bridge %s, channel immovable.\n",
2490 if (!bridge_channel_swap) {
2491 ast_debug(1,
"Can't move channel %s from bridge %s into bridge %s, swap channel %s not in bridge.\n",
2497 ast_debug(1,
"Can't move channel %s from bridge %s into bridge %s, swap channel %s leaving bridge.\n",
2505 return bridge_do_move(dst_bridge, bridge_channel, attempt_recovery, 0);
2591 struct ast_channel *play_chan = yanked_chan ?: chan;
2598 if (!play_bridge_channel) {
2646 bridge = bridge_channel->
bridge;
2698 bridge = bridge_channel->
bridge;
2756 && chan_priority <= peer_priority) {
2759 && peer_priority <= chan_priority) {
2806 dst_bridge = chan_bridge;
2807 dst_bridge_channel = chan_bridge_channel;
2808 src_bridge_channel = peer_bridge_channel;
2811 dst_bridge = peer_bridge;
2812 dst_bridge_channel = peer_bridge_channel;
2813 src_bridge_channel = chan_bridge_channel;
2830 ast_verb(4,
"Move-swap optimizing %s <-- %s.\n",
2841 other->
swap = dst_bridge_channel->
chan;
2924 chan_bridge_channel,
2925 peer_bridge_channel,
2935 ast_debug(4,
"Can't optimize %s -- %s out, not enough channels in bridge %s.\n",
2941 ast_debug(4,
"Can't optimize %s -- %s out, multimix is needed and it cannot be acquired.\n",
2947 ast_verb(4,
"Merge optimizing %s -- %s out.\n",
2987 peer_bridge, peer_bridge_channel, pvt);
2990 peer_bridge, peer_bridge_channel, pvt);
2991 }
else if (0 < res) {
3032 if (merge.
dest == chan_bridge) {
3163 callback(bridge_channel, hook_pvt);
3257 hook_pvt, destructor, remove_flags);
3334 return bridge_other_hook(features, callback, hook_pvt, destructor, remove_flags,
3344 return bridge_other_hook(features, callback, hook_pvt, destructor, remove_flags,
3354 return bridge_other_hook(features, callback, hook_pvt, destructor, remove_flags,
3384 unsigned int interval,
3393 if (!features ||!interval || !callback) {
3399 hook_pvt, destructor, remove_flags);
3409 ast_debug(1,
"Putting interval hook %p with interval %u in the heap on features %p\n",
3425 return res ? -1 : 0;
3445 ast_debug(1,
"Failed to enable built in feature %u on %p, no DTMF string is available for it.\n",
3456 config, destructor, remove_flags);
3461 memset(limits, 0,
sizeof(*limits));
3483 return callback(features, limits, remove_flags);
3486 ast_log(
LOG_ERROR,
"Attempted to set limits without an AST_BRIDGE_BUILTIN_INTERVAL_LIMITS callback registered.\n");
3610 const char *right_key = obj_right;
3619 cmp = strcasecmp(hook_left->
dtmf.
code, right_key);
3622 cmp = strncasecmp(hook_left->
dtmf.
code, right_key, strlen(right_key));
3690 memset(features, 0,
sizeof(*features));
3821 if (video_src_chan) {
3823 ast_verb(5,
"Video source in bridge '%s' (%s) is now '%s' (%s)\n",
3907 ast_verb(5,
"Video source in bridge '%s' (%s) is now '%s' (%s)\n",
3915 }
else if (!data->
chan_vsrc && is_keyframe) {
3918 ast_verb(5,
"Video source in bridge '%s' (%s) is now '%s' (%s)\n",
4020 switch (video_mode) {
4043 const char *
name = obj;
4067 const char *right_name = arg;
4126 if (iter->
chan != chan) {
4132 if (in_bridge && peer) {
4189 snprintf(chan_name,
sizeof(chan_name),
"%s@%s", exten, context);
4209 if (new_channel_cb) {
4213 if (
ast_call(local, chan_name, 0)) {
4249 if (transferee != transferer) {
4284 #define BRIDGE_LOCK_ONE_OR_BOTH(b1, b2) \ 4287 ast_bridge_lock_both(b1, b2); \ 4289 ast_bridge_lock(b1); \ 4293 static const char *dest =
"_attended@transfer/m";
4332 if (
ast_call(local_chan, dest, 0)) {
4355 if (!locals[0] || !locals[1]) {
4364 if (local_chan != locals[0]) {
4365 SWAP(locals[0], locals[1]);
4392 if (!transferer_bridge_channel) {
4397 context, exten, new_channel_cb, user_data_wrapper)) {
4439 const char *transferer_name;
4440 const char *transferer_bridgepeer;
4450 if (chan == transferer) {
4487 int do_bridge_transfer;
4488 int transfer_prohibited;
4492 if (!transfer_message) {
4496 ast_log(
LOG_ERROR,
"Unable to allocate memory for blind transfer publication from %s\n",
4510 if (!transfer_message->bridge) {
4518 if (!transfer_message->transferee) {
4527 if (!bridge_channel) {
4532 user_data_wrapper =
ao2_alloc(
sizeof(*user_data_wrapper),
NULL);
4533 if (!user_data_wrapper) {
4538 user_data_wrapper->data = user_data;
4543 transfer_result =
try_parking(transferer, context, exten, new_channel_cb, user_data_wrapper);
4549 user_data_wrapper->completed = 1;
4570 if (transfer_prohibited) {
4577 if (do_bridge_transfer) {
4579 exten, context, transferee, new_channel_cb, user_data_wrapper, transfer_message);
4591 new_channel_cb, user_data_wrapper)) {
4600 transfer_message->result = transfer_result;
4602 return transfer_result;
4626 if (bridged_to_source
4630 bridged_to_source->
swap = swap_channel;
4671 to_transferee_bridge_channel,
4672 to_target_bridge_channel,
4689 final_bridge = to_transferee_bridge;
4693 final_bridge = to_target_bridge;
4697 final_bridge = to_transferee_bridge;
4702 final_bridge = to_target_bridge;
4718 to_transferee_bridge, to_target_bridge, transfer_msg);
4742 int transfer_prohibited;
4743 int do_bridge_transfer;
4746 int hangup_target = 0;
4752 to_transfer_target, to_target_bridge,
NULL,
NULL);
4753 if (!transfer_msg) {
4754 ast_log(
LOG_ERROR,
"Unable to create Stasis publication for attended transfer from %s\n",
4760 if (!to_transferee_bridge && !to_target_bridge) {
4773 if (to_transferee_bridge_channel) {
4782 if (to_target_bridge_channel) {
4783 const char *target_complete_sound;
4795 "ATTENDED_TRANSFER_COMPLETE_SOUND");
4797 target_complete_sound =
ast_strdupa(target_complete_sound);
4799 target_complete_sound =
NULL;
4802 if (!target_complete_sound) {
4805 "ATTENDED_TRANSFER_COMPLETE_SOUND");
4807 target_complete_sound =
ast_strdupa(target_complete_sound);
4809 target_complete_sound =
NULL;
4813 if (target_complete_sound) {
4815 target_complete_sound,
NULL);
4820 if (to_transferee_bridge && to_target_bridge) {
4822 if (!to_transferee_bridge_channel || !to_target_bridge_channel) {
4829 to_transfer_target, to_target_bridge_channel,
4830 to_transferee_bridge, to_target_bridge, transfer_msg);
4838 the_bridge = to_transferee_bridge ?: to_target_bridge;
4839 chan_bridged = to_transferee_bridge ? to_transferee : to_transfer_target;
4840 chan_unbridged = to_transferee_bridge ? to_transfer_target : to_transferee;
4858 if (chan_count <= 1) {
4869 if (transfer_prohibited) {
4876 if (do_bridge_transfer) {
4881 hangup_target = chan_bridged == to_transfer_target;
4909 transfer_msg->result = res;
4948 while (!manager->
stop) {
4988 ast_debug(1,
"Waiting for bridge manager thread to die.\n");
5050 const struct ast_bridge *bridge_left = obj_left;
5051 const struct ast_bridge *bridge_right = obj_right;
5052 const char *right_key = obj_right;
5058 right_key = bridge_right->
uniqueid;
5061 cmp = strcmp(bridge_left->
uniqueid, right_key);
5064 cmp = strncmp(bridge_left->
uniqueid, right_key, strlen(right_key));
5096 #define FORMAT_HDR "%-36s %5s %-15s %-15s %s\n" 5097 #define FORMAT_ROW "%-36s %5u %-15s %-15s %s\n"