130 #define BRIDGE_ARRAY_START 128
133 #define BRIDGE_ARRAY_GROW 32
136 #define BLINDTRANSFER "BLINDTRANSFER"
139 #define ATTENDEDTRANSFER "ATTENDEDTRANSFER"
219 || !technology->
write) {
230 ast_log(
LOG_WARNING,
"A bridge technology of %s already claims to exist in our world.\n",
238 technology->
mod = module;
258 ast_verb(2,
"Registered bridge technology %s\n", technology->
name);
273 ast_verb(2,
"Unregistered bridge technology %s\n", technology->
name);
294 ast_debug(1,
"Bridge %s: queueing action type:%u sub:%d\n",
331 bridge->
cause = cause;
333 ast_debug(1,
"Bridge %s: dissolving bridge with cause %d(%s)\n",
389 unsigned char data[1024];
392 if (!bridge_channel ||
436 ast_debug(1,
"Bridge %s: %p(%s) is joining %s technology\n",
442 ast_debug(1,
"Bridge %s: %p(%s) failed to join %s technology (Kicking it out)\n",
459 bridge_channel->
bridge, bridge_channel);
507 ast_debug(1,
"Bridge technology %s is suspended. Skipping.\n",
512 ast_debug(1,
"Bridge technology %s does not have any capabilities we want.\n",
517 ast_debug(1,
"Bridge technology %s has less preference than %s (%u <= %u). Skipping.\n",
522 ast_debug(1,
"Bridge technology %s is not compatible with properties of existing bridge.\n",
527 ast_debug(1,
"Bridge technology %s is not running, skipping.\n",
current->name);
567 .name = bridge->
name,
571 ast_debug(1,
"Bridge %s: calling %s technology destructor (deferred, dummy)\n",
591 int in_destructor = !
ao2_ref(bridge, 0);
644 ast_debug(1,
"Bridge %s: actually destroying %s bridge, nobody wants it anymore\n",
659 ast_debug(1,
"Bridge %s: calling %s bridge destructor\n",
665 ast_debug(1,
"Bridge %s: calling %s technology stop\n",
672 ast_debug(1,
"Bridge %s: calling %s technology destructor\n",
719 ast_log(
LOG_ERROR,
"Virtual method table for bridge class %s not complete.\n",
762 self->allowed_capabilities = capabilities;
775 if (!self->technology) {
776 ast_log(
LOG_WARNING,
"Bridge %s: Could not create class %s. No technology to support it.\n",
777 self->uniqueid, self->v_table->name);
783 ast_debug(1,
"Bridge %s: calling %s technology constructor\n",
784 self->uniqueid, self->technology->name);
785 if (self->technology->create && self->technology->create(
self)) {
787 self->uniqueid, self->technology->name);
791 ast_debug(1,
"Bridge %s: calling %s technology start\n",
792 self->uniqueid, self->technology->name);
793 if (self->technology->start && self->technology->start(
self)) {
795 self->uniqueid, self->technology->name);
884 self->reconfigured = 1;
946 ast_debug(1,
"Bridge %s: telling all channels to leave the party\n", bridge->
uniqueid);
974 uint32_t new_capabilities;
983 .name = bridge->
name,
988 ast_debug(1,
"Bridge %s is dissolved, not performing smart bridge operation.\n",
1000 if (!new_capabilities
1009 if (!new_technology) {
1010 int is_compatible = 0;
1013 is_compatible = old_technology->
compatible(bridge);
1021 if (is_compatible) {
1022 ast_debug(1,
"Bridge %s could not get a new technology, staying with old technology.\n",
1030 if (new_technology == old_technology) {
1031 ast_debug(1,
"Bridge %s is already using the new technology.\n",
1037 if (old_technology->
destroy) {
1045 .data.ptr = &deferred_tech_destroy,
1046 .datalen =
sizeof(deferred_tech_destroy),
1067 ast_verb(4,
"Bridge %s: switching from %s technology to %s\n",
1080 ast_debug(1,
"Bridge %s: calling %s technology constructor\n",
1082 if (new_technology->
create && new_technology->
create(bridge)) {
1098 ast_debug(1,
"Bridge %s: moving %p(%s) to dummy bridge temporarily\n",
1114 ast_debug(1,
"Bridge %s: %p(%s) is leaving %s technology (dummy)\n",
1116 old_technology->
name);
1117 if (old_technology->
leave) {
1118 old_technology->
leave(&dummy_bridge, bridge_channel);
1132 ast_debug(1,
"Bridge %s: calling %s technology stop\n",
1134 if (old_technology->
stop) {
1135 old_technology->
stop(&dummy_bridge);
1143 ast_debug(1,
"Bridge %s: calling %s technology start\n",
1145 if (new_technology->
start && new_technology->
start(bridge)) {
1155 if (old_technology->
destroy) {
1156 ast_debug(1,
"Bridge %s: deferring %s technology destructor\n",
1160 ast_debug(1,
"Bridge %s: calling %s technology destructor\n",
1233 const char *c0_name;
1234 const char *c1_name;
1235 const char *c0_pvtid =
NULL;
1236 const char *c1_pvtid =
NULL;
1237 #define UPDATE_BRIDGE_VARS_GET(chan, name, pvtid) \
1239 name = ast_strdupa(ast_channel_name(chan)); \
1240 if (ast_channel_tech(chan)->get_pvt_uniqueid) { \
1241 pvtid = ast_strdupa(ast_channel_tech(chan)->get_pvt_uniqueid(chan)); \
1271 int need_separator = 0;
1277 for (idx = 0; idx < num_names; ++idx) {
1278 if (idx == cur_idx) {
1282 if (need_separator) {
1313 #define MAX_BRIDGEPEER_CHANS (10 + 1)
1316 unsigned int num_names;
1324 names =
ast_alloca(num_names *
sizeof(*names));
1327 if (num_names <= idx) {
1337 for (idx = 0; idx < num_names; ++idx) {
1338 len += strlen(names[idx]);
1346 if (idx < num_names) {
1434 if (bridge_channel->
chan ==
chan) {
1439 return bridge_channel;
1451 if (!bridge_channel) {
1457 bridge = bridge_channel->
bridge;
1533 .
type =
"bridge-impart-ds",
1569 datastore->
data = ds_head;
1572 ds_head = datastore->
data;
1604 while (!
cond->done) {
1636 if (!bridge_channel) {
1660 bridge_channel->
thread = pthread_self();
1671 if (bridge_channel->
swap) {
1716 if (bridge_channel->
callid) {
1727 ao2_t_cleanup(bridge_channel->
swap,
"Bridge complete: Departable impart join failed");
1805 if (!bridge_channel) {
1832 if (bridge_channel->
swap) {
1914 departable = bridge_channel && bridge_channel->
depart_wait;
1938 ast_debug(1,
"Waiting for %p(%s) bridge thread to die.\n",
1955 ast_debug(1,
"Removing channel %s from bridge %s\n",
2014 old_bridge = bridge_channel->
bridge;
2015 bridge_channel->
bridge = new_bridge;
2038 remove_me = move_cb(bridge_channel, hook->
hook_pvt, src, dst);
2040 ast_debug(1,
"Move detection hook %p is being removed from %p(%s)\n",
2049 unsigned int optimized)
2054 ast_debug(1,
"Merging bridge %s into bridge %s\n",
2079 for (idx = 0; idx < num_kick; ++idx) {
2080 if (bridge_channel == kick_me[idx]) {
2115 for (idx = 0; idx < num_kick; ++idx) {
2116 bridge_channel = kick_me[idx];
2130 ast_debug(1,
"Merged bridge %s into bridge %s\n",
2156 int bridge1_priority;
2157 int bridge2_priority;
2167 bridge1_priority = bridge1->v_table->get_merge_priority(bridge1);
2168 bridge2_priority = bridge2->v_table->get_merge_priority(bridge2);
2169 if (bridge2_priority < bridge1_priority) {
2170 merge.
dest = bridge1;
2171 merge.
src = bridge2;
2172 }
else if (bridge1_priority < bridge2_priority) {
2173 merge.
dest = bridge2;
2174 merge.
src = bridge1;
2177 if (bridge2->num_channels <= bridge1->num_channels) {
2178 merge.
dest = bridge1;
2179 merge.
src = bridge2;
2181 merge.
dest = bridge2;
2182 merge.
src = bridge1;
2188 merge.
dest = bridge1;
2189 merge.
src = bridge2;
2193 merge.
dest = bridge2;
2194 merge.
src = bridge1;
2222 ast_assert(dst_bridge && src_bridge && dst_bridge != src_bridge && (!num_kick || kick_me));
2225 ast_debug(1,
"Can't merge bridges %s and %s, at least one bridge is dissolved.\n",
2231 ast_debug(1,
"Can't merge bridges %s and %s, masquerade only.\n",
2236 ast_debug(1,
"Can't merge bridges %s and %s, merging temporarily inhibited.\n",
2241 if (merge_best_direction) {
2244 merge.
dest = dst_bridge;
2245 merge.
src = src_bridge;
2251 ast_debug(1,
"Can't merge bridges %s and %s, merging inhibited.\n",
2261 ast_debug(1,
"Can't merge bridge %s into bridge %s, not enough channels in source bridge.\n",
2269 ast_debug(1,
"Can't merge bridge %s into bridge %s, multimix is needed and it cannot be acquired.\n",
2275 unsigned int num_to_kick = 0;
2278 kick_them =
ast_alloca(num_kick *
sizeof(*kick_them));
2279 for (idx = 0; idx < num_kick; ++idx) {
2281 if (!kick_them[num_to_kick]) {
2284 if (kick_them[num_to_kick]) {
2289 if (num_to_kick != num_kick) {
2290 ast_debug(1,
"Can't merge bridge %s into bridge %s, at least one kicked channel is not in either bridge.\n",
2308 res =
bridge_merge_locked(dst_bridge, src_bridge, merge_best_direction, kick_me, num_kick);
2315 unsigned int optimized)
2321 if (bridge_channel->
swap) {
2322 ast_debug(1,
"Moving %p(%s) into bridge %s swapping with %s\n",
2326 ast_debug(1,
"Moving %p(%s) into bridge %s\n",
2330 orig_bridge = bridge_channel->
bridge;
2331 was_in_bridge = bridge_channel->
in_bridge;
2357 if (attempt_recovery && was_in_bridge) {
2373 }
else if (!optimized) {
2404 ast_debug(1,
"Can't move channel %s from bridge %s into bridge %s, at least one bridge is dissolved.\n",
2410 ast_debug(1,
"Can't move channel %s from bridge %s into bridge %s, masquerade only.\n",
2415 ast_debug(1,
"Can't move channel %s from bridge %s into bridge %s, temporarily inhibited.\n",
2421 if (!bridge_channel) {
2422 ast_debug(1,
"Can't move channel %s from bridge %s into bridge %s, channel not in bridge.\n",
2427 ast_debug(1,
"Can't move channel %s from bridge %s into bridge %s, channel leaving bridge.\n",
2433 ast_debug(1,
"Can't move channel %s from bridge %s into bridge %s, channel immovable.\n",
2442 if (!bridge_channel_swap) {
2443 ast_debug(1,
"Can't move channel %s from bridge %s into bridge %s, swap channel %s not in bridge.\n",
2449 ast_debug(1,
"Can't move channel %s from bridge %s into bridge %s, swap channel %s leaving bridge.\n",
2457 return bridge_do_move(dst_bridge, bridge_channel, attempt_recovery, 0);
2543 struct ast_channel *play_chan = yanked_chan ?: chan;
2550 if (!play_bridge_channel) {
2708 && chan_priority <= peer_priority) {
2711 && peer_priority <= chan_priority) {
2758 dst_bridge = chan_bridge;
2759 dst_bridge_channel = chan_bridge_channel;
2760 src_bridge_channel = peer_bridge_channel;
2763 dst_bridge = peer_bridge;
2764 dst_bridge_channel = peer_bridge_channel;
2765 src_bridge_channel = chan_bridge_channel;
2782 ast_verb(4,
"Move-swap optimizing %s <-- %s.\n",
2793 other->
swap = dst_bridge_channel->
chan;
2876 chan_bridge_channel,
2877 peer_bridge_channel,
2887 ast_debug(4,
"Can't optimize %s -- %s out, not enough channels in bridge %s.\n",
2893 ast_debug(4,
"Can't optimize %s -- %s out, multimix is needed and it cannot be acquired.\n",
2899 ast_verb(4,
"Merge optimizing %s -- %s out.\n",
2939 peer_bridge, peer_bridge_channel, pvt);
2942 peer_bridge, peer_bridge_channel, pvt);
2943 }
else if (0 < res) {
2984 if (merge.
dest == chan_bridge) {
3102 callback(bridge_channel, hook_pvt);
3194 hook_pvt, destructor, remove_flags);
3321 unsigned int interval,
3330 if (!features ||!interval || !callback) {
3336 hook_pvt, destructor, remove_flags);
3346 ast_debug(1,
"Putting interval hook %p with interval %u in the heap on features %p\n",
3362 return res ? -1 : 0;
3382 ast_debug(1,
"Failed to enable built in feature %u on %p, no DTMF string is available for it.\n",
3393 config, destructor, remove_flags);
3420 return callback(features,
limits, remove_flags);
3423 ast_log(
LOG_ERROR,
"Attempted to set limits without an AST_BRIDGE_BUILTIN_INTERVAL_LIMITS callback registered.\n");
3543 const char *right_key = obj_right;
3552 cmp = strcasecmp(hook_left->
dtmf.
code, right_key);
3555 cmp = strncasecmp(hook_left->
dtmf.
code, right_key, strlen(right_key));
3623 memset(features, 0,
sizeof(*features));
3754 if (video_src_chan) {
3756 ast_verb(5,
"Video source in bridge '%s' (%s) is now '%s' (%s)\n",
3840 ast_verb(5,
"Video source in bridge '%s' (%s) is now '%s' (%s)\n",
3848 }
else if (!data->
chan_vsrc && is_keyframe) {
3851 ast_verb(5,
"Video source in bridge '%s' (%s) is now '%s' (%s)\n",
3953 switch (video_mode) {
3976 const char *
name = obj;
4000 const char *right_name = arg;
4122 snprintf(chan_name,
sizeof(chan_name),
"%s@%s",
exten,
context);
4142 if (new_channel_cb) {
4146 if (
ast_call(local, chan_name, 0)) {
4182 if (transferee != transferer) {
4217 #define BRIDGE_LOCK_ONE_OR_BOTH(b1, b2) \
4220 ast_bridge_lock_both(b1, b2); \
4222 ast_bridge_lock(b1); \
4226 static const char *dest =
"_attended@transfer/m";
4265 if (
ast_call(local_chan, dest, 0)) {
4297 if (local_chan !=
locals[0]) {
4325 if (!transferer_bridge_channel) {
4372 const char *transferer_name;
4373 const char *transferer_bridgepeer;
4383 if (chan == transferer) {
4420 int do_bridge_transfer;
4421 int transfer_prohibited;
4425 if (!transfer_message) {
4429 ast_log(
LOG_ERROR,
"Unable to allocate memory for blind transfer publication from %s\n",
4443 if (!transfer_message->
bridge) {
4460 if (!bridge_channel) {
4465 user_data_wrapper =
ao2_alloc(
sizeof(*user_data_wrapper),
NULL);
4466 if (!user_data_wrapper) {
4471 user_data_wrapper->
data = user_data;
4503 if (transfer_prohibited) {
4510 if (do_bridge_transfer) {
4512 exten,
context, transferee, new_channel_cb, user_data_wrapper, transfer_message);
4524 new_channel_cb, user_data_wrapper)) {
4533 transfer_message->
result = transfer_result;
4535 return transfer_result;
4559 if (bridged_to_source
4563 bridged_to_source->
swap = swap_channel;
4604 to_transferee_bridge_channel,
4605 to_target_bridge_channel,
4622 final_bridge = to_transferee_bridge;
4626 final_bridge = to_target_bridge;
4630 final_bridge = to_transferee_bridge;
4635 final_bridge = to_target_bridge;
4651 to_transferee_bridge, to_target_bridge, transfer_msg);
4675 int transfer_prohibited;
4676 int do_bridge_transfer;
4679 int hangup_target = 0;
4685 to_transfer_target, to_target_bridge,
NULL,
NULL);
4686 if (!transfer_msg) {
4687 ast_log(
LOG_ERROR,
"Unable to create Stasis publication for attended transfer from %s\n",
4693 if (!to_transferee_bridge && !to_target_bridge) {
4706 if (to_transferee_bridge_channel) {
4715 if (to_target_bridge_channel) {
4716 const char *target_complete_sound;
4728 "ATTENDED_TRANSFER_COMPLETE_SOUND");
4730 target_complete_sound =
ast_strdupa(target_complete_sound);
4732 target_complete_sound =
NULL;
4735 if (!target_complete_sound) {
4738 "ATTENDED_TRANSFER_COMPLETE_SOUND");
4740 target_complete_sound =
ast_strdupa(target_complete_sound);
4742 target_complete_sound =
NULL;
4746 if (target_complete_sound) {
4748 target_complete_sound,
NULL);
4753 if (to_transferee_bridge && to_target_bridge) {
4755 if (!to_transferee_bridge_channel || !to_target_bridge_channel) {
4762 to_transfer_target, to_target_bridge_channel,
4763 to_transferee_bridge, to_target_bridge, transfer_msg);
4771 the_bridge = to_transferee_bridge ?: to_target_bridge;
4772 chan_bridged = to_transferee_bridge ? to_transferee : to_transfer_target;
4773 chan_unbridged = to_transferee_bridge ? to_transfer_target : to_transferee;
4791 if (chan_count <= 1) {
4802 if (transfer_prohibited) {
4809 if (do_bridge_transfer) {
4814 hangup_target = chan_bridged == to_transfer_target;
4842 transfer_msg->
result = res;