Asterisk - The Open Source Telephony Project GIT-master-754dea3
All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Macros Modules Pages
bridge.c
Go to the documentation of this file.
1/*
2 * Asterisk -- An open source telephony toolkit.
3 *
4 * Copyright (C) 2007 - 2009, Digium, Inc.
5 *
6 * Joshua Colp <jcolp@digium.com>
7 *
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.
13 *
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.
17 */
18
19/*! \file
20 *
21 * \brief Bridging API
22 *
23 * \author Joshua Colp <jcolp@digium.com>
24 */
25
26/*** MODULEINFO
27 <support_level>core</support_level>
28 ***/
29
30/*** DOCUMENTATION
31 <manager name="BridgeTechnologyList" language="en_US">
32 <since>
33 <version>12.0.0</version>
34 </since>
35 <synopsis>
36 List available bridging technologies and their statuses.
37 </synopsis>
38 <syntax>
39 <xi:include xpointer="xpointer(/docs/manager[@name='Login']/syntax/parameter[@name='ActionID'])" />
40 </syntax>
41 <description>
42 <para>Returns detailed information about the available bridging technologies.</para>
43 </description>
44 <see-also>
45 <ref type="manager">BridgeTechnologySuspend</ref>
46 <ref type="manager">BridgeTechnologyUnsuspend</ref>
47 </see-also>
48 </manager>
49 <manager name="BridgeTechnologySuspend" language="en_US">
50 <since>
51 <version>12.0.0</version>
52 </since>
53 <synopsis>
54 Suspend a bridging technology.
55 </synopsis>
56 <syntax>
57 <xi:include xpointer="xpointer(/docs/manager[@name='Login']/syntax/parameter[@name='ActionID'])" />
58 <parameter name="BridgeTechnology" required="true">
59 <para>The name of the bridging technology to suspend.</para>
60 </parameter>
61 </syntax>
62 <description>
63 <para>Marks a bridging technology as suspended, which prevents subsequently created bridges from using it.</para>
64 </description>
65 <see-also>
66 <ref type="manager">BridgeTechnologySuspend</ref>
67 <ref type="manager">BridgeTechnologyUnsuspend</ref>
68 </see-also>
69 </manager>
70 <manager name="BridgeTechnologyUnsuspend" language="en_US">
71 <since>
72 <version>12.0.0</version>
73 </since>
74 <synopsis>
75 Unsuspend a bridging technology.
76 </synopsis>
77 <syntax>
78 <xi:include xpointer="xpointer(/docs/manager[@name='Login']/syntax/parameter[@name='ActionID'])" />
79 <parameter name="BridgeTechnology" required="true">
80 <para>The name of the bridging technology to unsuspend.</para>
81 </parameter>
82 </syntax>
83 <description>
84 <para>Clears a previously suspended bridging technology, which allows subsequently created bridges to use it.</para>
85 </description>
86 <see-also>
87 <ref type="manager">BridgeTechnologyList</ref>
88 <ref type="manager">BridgeTechnologySuspend</ref>
89 </see-also>
90 </manager>
91***/
92
93#include "asterisk.h"
94
95#include "asterisk/logger.h"
96#include "asterisk/channel.h"
97#include "asterisk/options.h"
98#include "asterisk/utils.h"
99#include "asterisk/lock.h"
100#include "asterisk/linkedlists.h"
101#include "asterisk/bridge.h"
112#include "asterisk/app.h"
113#include "asterisk/file.h"
114#include "asterisk/module.h"
115#include "asterisk/astobj2.h"
116#include "asterisk/pbx.h"
117#include "asterisk/test.h"
118#include "asterisk/_private.h"
119#include "asterisk/heap.h"
120#include "asterisk/say.h"
121#include "asterisk/timing.h"
123#include "asterisk/musiconhold.h"
124#include "asterisk/features.h"
125#include "asterisk/cli.h"
126#include "asterisk/parking.h"
127#include "asterisk/core_local.h"
128#include "asterisk/core_unreal.h"
129#include "asterisk/causes.h"
130
131/*! All bridges container. */
132static struct ao2_container *bridges;
133
135
137
138static unsigned int optimization_id;
139
140/* Initial starting point for the bridge array of channels */
141#define BRIDGE_ARRAY_START 128
142
143/* Grow rate of bridge array of channels */
144#define BRIDGE_ARRAY_GROW 32
145
146/* Variable name - stores peer information about the most recent blind transfer */
147#define BLINDTRANSFER "BLINDTRANSFER"
148
149/* Variable name - stores peer information about the most recent attended transfer */
150#define ATTENDEDTRANSFER "ATTENDEDTRANSFER"
151
152static void cleanup_video_mode(struct ast_bridge *bridge);
153
154/*! Default DTMF keys for built in features */
156
157/*! Function handlers for the built in features */
159
160/*! Function handlers for built in interval features */
162
163/*! Bridge manager service request */
165 /*! List of bridge service requests. */
167 /*! Refed bridge requesting service. */
169};
170
172 /*! Condition, used to wake up the bridge manager thread. */
174 /*! Queue of bridge service requests. */
176 /*! Manager thread */
177 pthread_t thread;
178 /*! TRUE if the manager needs to stop. */
179 unsigned int stop:1;
180};
181
182/*! Bridge manager controller. */
184
186{
187 return ao2_bump(bridges);
188}
189
190/*!
191 * \internal
192 * \brief Request service for a bridge from the bridge manager.
193 * \since 12.0.0
194 *
195 * \param bridge Requesting service.
196 */
197static void bridge_manager_service_req(struct ast_bridge *bridge)
198{
200
202 if (bridge_manager->stop) {
204 return;
205 }
206
207 /* Create the service request. */
208 request = ast_calloc(1, sizeof(*request));
209 if (!request) {
210 /* Well. This isn't good. */
212 return;
213 }
214 ao2_ref(bridge, +1);
215 request->bridge = bridge;
216
217 /* Put request into the queue and wake the bridge manager. */
221}
222
224{
226
227 /* Perform a sanity check to make sure the bridge technology conforms to our needed requirements */
228 if (ast_strlen_zero(technology->name)
229 || !technology->capabilities
230 || !technology->write) {
231 ast_log(LOG_WARNING, "Bridge technology %s failed registration sanity check.\n",
232 technology->name);
233 return -1;
234 }
235
237
238 /* Look for duplicate bridge technology already using this name, or already registered */
240 if ((!strcasecmp(current->name, technology->name)) || (current == technology)) {
241 ast_log(LOG_WARNING, "A bridge technology of %s already claims to exist in our world.\n",
242 technology->name);
244 return -1;
245 }
246 }
247
248 /* Copy module pointer so reference counting can keep the module from unloading */
249 technology->mod = module;
250
251 /* Find the correct position to insert the technology. */
253 /* Put the highest preference tech's first in the list. */
254 if (technology->preference >= current->preference) {
255 AST_RWLIST_INSERT_BEFORE_CURRENT(technology, entry);
256
257 break;
258 }
259 }
261
262 if (!current) {
263 /* Insert our new bridge technology to the end of the list. */
264 AST_RWLIST_INSERT_TAIL(&bridge_technologies, technology, entry);
265 }
266
268
269 ast_verb(5, "Registered bridge technology %s\n", technology->name);
270
271 return 0;
272}
273
275{
277
279
280 /* Ensure the bridge technology is registered before removing it */
282 if (current == technology) {
284 ast_verb(5, "Unregistered bridge technology %s\n", technology->name);
285 break;
286 }
287 }
289
291
292 return current ? 0 : -1;
293}
294
295/*!
296 * \internal
297 * \brief Put an action onto the specified bridge. Don't dup the action frame.
298 * \since 12.0.0
299 *
300 * \param bridge What to queue the action on.
301 * \param action What to do.
302 */
303static void bridge_queue_action_nodup(struct ast_bridge *bridge, struct ast_frame *action)
304{
305 ast_debug(1, "Bridge %s: queueing action type:%u sub:%d\n",
306 bridge->uniqueid, action->frametype, action->subclass.integer);
307
308 ast_bridge_lock(bridge);
310 ast_bridge_unlock(bridge);
312}
313
314int ast_bridge_queue_action(struct ast_bridge *bridge, struct ast_frame *action)
315{
316 struct ast_frame *dup;
317
318 dup = ast_frdup(action);
319 if (!dup) {
320 return -1;
321 }
322 bridge_queue_action_nodup(bridge, dup);
323 return 0;
324}
325
326void bridge_dissolve(struct ast_bridge *bridge, int cause)
327{
328 struct ast_bridge_channel *bridge_channel;
329 struct ast_frame action = {
332 };
333
334 if (bridge->dissolved) {
335 ast_debug(1, "Bridge " BRIDGE_PRINTF_SPEC ": already dissolved\n",
336 BRIDGE_PRINTF_VARS(bridge));
337 return;
338 }
339 bridge->dissolved = 1;
340
341 if (cause <= 0) {
343 }
344 bridge->cause = cause;
345
346 ast_debug(1, "Bridge " BRIDGE_PRINTF_SPEC ": dissolving with cause %d(%s)\n",
347 BRIDGE_PRINTF_VARS(bridge), cause, ast_cause2str(cause));
348
349 AST_LIST_TRAVERSE(&bridge->channels, bridge_channel, entry) {
350 ast_debug(1, "Bridge " BRIDGE_PRINTF_SPEC ": kicking channel %s\n",
351 BRIDGE_PRINTF_VARS(bridge),
352 ast_channel_name(bridge_channel->chan));
353 ast_bridge_channel_leave_bridge(bridge_channel,
355 }
356
357 /* Must defer dissolving bridge because it is already locked. */
358 ast_bridge_queue_action(bridge, &action);
359 ast_debug(1, "Bridge " BRIDGE_PRINTF_SPEC ": DEFERRED_DISSOLVING queued. current refcound: %d\n",
360 BRIDGE_PRINTF_VARS(bridge), ao2_ref(bridge, 0));
361
362}
363
364/*!
365 * \internal
366 * \brief Check if a bridge should dissolve because of a stolen channel and do it.
367 * \since 12.0.0
368 *
369 * \param bridge Bridge to check.
370 * \param bridge_channel Stolen channel causing the check. It is not in the bridge to check and may be in another bridge.
371 *
372 * \note On entry, bridge and bridge_channel->bridge are already locked.
373 */
374static void bridge_dissolve_check_stolen(struct ast_bridge *bridge, struct ast_bridge_channel *bridge_channel)
375{
376 if (bridge->dissolved) {
377 return;
378 }
379
380 if (bridge_channel->features->usable
381 && ast_test_flag(&bridge_channel->features->feature_flags,
383 /* The stolen channel controlled the bridge it was stolen from. */
384 bridge_dissolve(bridge, 0);
385 return;
386 }
387 if (bridge->num_channels < 2
389 /*
390 * The stolen channel has not left enough channels to keep the
391 * bridge alive. Assume the stolen channel hung up.
392 */
393 bridge_dissolve(bridge, 0);
394 return;
395 }
396}
397
398/*!
399 * \internal
400 * \brief Update connected line information after a bridge has been reconfigured.
401 *
402 * \param bridge The bridge itself.
403 */
405{
407 struct ast_bridge_channel *bridge_channel = AST_LIST_FIRST(&bridge->channels), *peer;
408 unsigned char data[1024];
409 size_t datalen;
410
411 if (!bridge_channel ||
413 !(peer = ast_bridge_channel_peer(bridge_channel)) ||
416 ast_check_hangup_locked(bridge_channel->chan) ||
417 ast_check_hangup_locked(peer->chan)) {
418 return;
419 }
420
422
423 ast_channel_lock(bridge_channel->chan);
425 ast_channel_unlock(bridge_channel->chan);
426
427 if ((datalen = ast_connected_line_build_data(data, sizeof(data), &connected, NULL)) != (size_t) -1) {
429 }
430
431 ast_channel_lock(peer->chan);
433 ast_channel_unlock(peer->chan);
434
435 if ((datalen = ast_connected_line_build_data(data, sizeof(data), &connected, NULL)) != (size_t) -1) {
437 }
438
440}
441
442/*!
443 * \internal
444 * \brief Complete joining a channel to the bridge.
445 * \since 12.0.0
446 *
447 * \param bridge What to operate upon.
448 * \param bridge_channel What is joining the bridge technology.
449 *
450 * \note On entry, bridge is already locked.
451 */
452static void bridge_channel_complete_join(struct ast_bridge *bridge, struct ast_bridge_channel *bridge_channel)
453{
454 /* Tell the bridge technology we are joining so they set us up */
455 ast_debug(1, "Bridge %s: %p(%s) is joining %s technology\n",
456 bridge->uniqueid, bridge_channel, ast_channel_name(bridge_channel->chan),
459 && bridge->technology->join(bridge, bridge_channel)) {
460 /* We cannot leave the channel partially in the bridge so we must kick it out */
461 ast_debug(1, "Bridge %s: %p(%s) failed to join %s technology (Kicking it out)\n",
462 bridge->uniqueid, bridge_channel, ast_channel_name(bridge_channel->chan),
464 bridge_channel->just_joined = 1;
466 return;
467 }
468
469 bridge_channel->just_joined = 0;
470
471 /*
472 * When a channel joins the bridge its streams need to be mapped to the bridge's
473 * media types vector. This way all streams map to the same media type index for
474 * a given channel.
475 */
476 if (bridge_channel->bridge->technology->stream_topology_changed) {
477 bridge_channel->bridge->technology->stream_topology_changed(
478 bridge_channel->bridge, bridge_channel);
479 } else {
480 ast_bridge_channel_stream_map(bridge_channel);
481 }
482}
483
484/*!
485 * \internal
486 * \brief Complete joining new channels to the bridge.
487 * \since 12.0.0
488 *
489 * \param bridge Check for new channels on this bridge.
490 *
491 * \note On entry, bridge is already locked.
492 */
494{
495 struct ast_bridge_channel *bridge_channel;
496
497 if (bridge->dissolved) {
498 /*
499 * No sense in completing the join on channels for a dissolved
500 * bridge. They are just going to be removed soon anyway.
501 * However, we do have reason to abort here because the bridge
502 * technology may not be able to handle the number of channels
503 * still in the bridge.
504 */
505 return;
506 }
507
508 AST_LIST_TRAVERSE(&bridge->channels, bridge_channel, entry) {
510 if (!bridge_channel->just_joined) {
511 continue;
512 }
513 bridge_channel_complete_join(bridge, bridge_channel);
514 }
515}
516
517/*! \brief Helper function used to find the "best" bridge technology given specified capabilities */
519{
521 struct ast_bridge_technology *best = NULL;
522
525 if (current->suspended) {
526 ast_debug(2, "Bridge technology %s is suspended. Skipping.\n",
527 current->name);
528 continue;
529 }
530 if (!(current->capabilities & capabilities)) {
531 ast_debug(2, "Bridge technology %s does not have any capabilities we want.\n",
532 current->name);
533 continue;
534 }
535 if (best && current->preference <= best->preference) {
536 ast_debug(2, "Bridge technology %s has less preference than %s (%u <= %u). Skipping.\n",
537 current->name, best->name, current->preference, best->preference);
538 continue;
539 }
540 if (current->compatible && !current->compatible(bridge)) {
541 ast_debug(2, "Bridge technology %s is not compatible with properties of existing bridge.\n",
542 current->name);
543 continue;
544 }
545 if (!ast_module_running_ref(current->mod)) {
546 ast_debug(2, "Bridge technology %s is not running, skipping.\n", current->name);
547 continue;
548 }
549 if (best) {
550 ast_module_unref(best->mod);
551 }
552 best = current;
553 }
554
555 if (best) {
556 ast_debug(1, "Chose bridge technology %s\n", best->name);
557 }
558
560
561 return best;
562}
563
566 void *tech_pvt;
567};
568
569/*!
570 * \internal
571 * \brief Deferred destruction of bridge tech private structure.
572 * \since 12.0.0
573 *
574 * \param bridge What to execute the action on.
575 * \param action Deferred bridge tech destruction.
576 *
577 * \note On entry, bridge must not be locked.
578 */
579static void bridge_tech_deferred_destroy(struct ast_bridge *bridge, struct ast_frame *action)
580{
581 struct tech_deferred_destroy *deferred = action->data.ptr;
582 struct ast_bridge dummy_bridge = {
583 .technology = deferred->tech,
584 .tech_pvt = deferred->tech_pvt,
585 .creator = bridge->creator,
586 .name = bridge->name,
587 .uniqueid = bridge->uniqueid,
588 };
589
590 ast_debug(1, "Bridge %s: calling %s technology destructor (deferred, dummy)\n",
591 dummy_bridge.uniqueid, dummy_bridge.technology->name);
592 dummy_bridge.technology->destroy(&dummy_bridge);
593 ast_module_unref(dummy_bridge.technology->mod);
594}
595
596/*!
597 * \internal
598 * \brief Handle bridge action frame.
599 * \since 12.0.0
600 *
601 * \param bridge What to execute the action on.
602 * \param action What to do.
603 *
604 * \note On entry, bridge is already locked.
605 * \note Can be called by the bridge destructor
606 */
607static void bridge_action_bridge(struct ast_bridge *bridge, struct ast_frame *action)
608{
609#if 0 /* In case we need to know when the destructor is calling us. */
610 int in_destructor = !ao2_ref(bridge, 0);
611#endif
612
613 switch (action->subclass.integer) {
615 ast_bridge_unlock(bridge);
616 bridge_tech_deferred_destroy(bridge, action);
617 ast_bridge_lock(bridge);
618 break;
620 ast_bridge_unlock(bridge);
621 bridge->v_table->dissolving(bridge);
622 ast_bridge_lock(bridge);
623 break;
624 default:
625 /* Unexpected deferred action type. Should never happen. */
626 ast_assert(0);
627 break;
628 }
629}
630
631/*!
632 * \internal
633 * \brief Do any pending bridge actions.
634 * \since 12.0.0
635 *
636 * \param bridge What to do actions on.
637 *
638 * \note On entry, bridge is already locked.
639 * \note Can be called by the bridge destructor.
640 */
641static void bridge_handle_actions(struct ast_bridge *bridge)
642{
643 struct ast_frame *action;
644
645 while ((action = AST_LIST_REMOVE_HEAD(&bridge->action_queue, frame_list))) {
646 switch (action->frametype) {
648 bridge_action_bridge(bridge, action);
649 break;
650 default:
651 /* Unexpected deferred frame type. Should never happen. */
652 ast_assert(0);
653 break;
654 }
655 ast_frfree(action);
656 }
657}
658
659static void destroy_bridge(void *obj)
660{
661 struct ast_bridge *bridge = obj;
662
663 ast_debug(1, "Bridge " BRIDGE_PRINTF_SPEC ": actually destroying %s bridge, nobody wants it anymore\n",
664 BRIDGE_PRINTF_VARS(bridge), bridge->v_table->name);
665
666 if (bridge->construction_completed) {
667 bridge_topics_destroy(bridge);
668 }
669
670 /* Do any pending actions in the context of destruction. */
671 ast_bridge_lock(bridge);
672 bridge_handle_actions(bridge);
673 ast_bridge_unlock(bridge);
674
675 /* There should not be any channels left in the bridge. */
677
678 ast_debug(1, "Bridge %s: calling %s bridge destructor\n",
679 bridge->uniqueid, bridge->v_table->name);
680 bridge->v_table->destroy(bridge);
681
682 /* Pass off the bridge to the technology to destroy if needed */
683 if (bridge->technology) {
684 ast_debug(1, "Bridge %s: calling %s technology stop\n",
685 bridge->uniqueid, bridge->technology->name);
686 if (bridge->technology->stop) {
687 ast_bridge_lock(bridge);
688 bridge->technology->stop(bridge);
689 ast_bridge_unlock(bridge);
690 }
691 ast_debug(1, "Bridge %s: calling %s technology destructor\n",
692 bridge->uniqueid, bridge->technology->name);
693 if (bridge->technology->destroy) {
694 bridge->technology->destroy(bridge);
695 }
697 bridge->technology = NULL;
698 }
699
701
702 bridge->callid = 0;
703
704 cleanup_video_mode(bridge);
705
706 ast_debug(1, "Bridge " BRIDGE_PRINTF_SPEC ": destroyed\n",
707 BRIDGE_PRINTF_VARS(bridge));
710 bridge->current_snapshot = NULL;
711}
712
713struct ast_bridge *bridge_register(struct ast_bridge *bridge)
714{
715 if (bridge) {
717 /*
718 * Although bridge_base_init() should have already checked for
719 * an existing bridge with the same uniqueid, bridge_base_init()
720 * and bridge_register() are two separate public APIs so we need
721 * to check again here.
722 */
723 struct ast_bridge *existing = ast_bridge_find_by_id(bridge->uniqueid);
724 if (existing) {
725 ast_log(LOG_WARNING, "Bridge " BRIDGE_PRINTF_SPEC ": already registered\n",
726 BRIDGE_PRINTF_VARS(bridge));
727 ao2_ref(existing, -1);
728 ast_bridge_destroy(bridge, 0);
729 return NULL;
730 }
731 ast_debug(1, "Bridge " BRIDGE_PRINTF_SPEC ": registering\n",
732 BRIDGE_PRINTF_VARS(bridge));
733 bridge->construction_completed = 1;
734 ast_bridge_lock(bridge);
736 ast_bridge_unlock(bridge);
737 if (!ao2_link(bridges, bridge)) {
738 ast_log(LOG_WARNING, "Bridge " BRIDGE_PRINTF_SPEC ": failed to link\n",
739 BRIDGE_PRINTF_VARS(bridge));
740 ast_bridge_destroy(bridge, 0);
741 bridge = NULL;
742 }
743 }
744 return bridge;
745}
746
747struct ast_bridge *bridge_alloc(size_t size, const struct ast_bridge_methods *v_table)
748{
749 struct ast_bridge *bridge;
750
751 /* Check v_table that all methods are present. */
752 if (!v_table
753 || !v_table->name
754 || !v_table->destroy
756 || !v_table->push
757 || !v_table->pull
760 ast_log(LOG_ERROR, "Virtual method table for bridge class %s not complete.\n",
761 v_table && v_table->name ? v_table->name : "<unknown>");
762 ast_assert(0);
763 return NULL;
764 }
765
766 bridge = ao2_alloc(size, destroy_bridge);
767 if (!bridge) {
768 return NULL;
769 }
770
771 if (ast_string_field_init(bridge, 80)) {
772 ao2_cleanup(bridge);
773 return NULL;
774 }
775
776 bridge->v_table = v_table;
777
779
780 return bridge;
781}
782
783struct ast_bridge *bridge_base_init(struct ast_bridge *self, uint32_t capabilities, unsigned int flags, const char *creator, const char *name, const char *id)
784{
785 char uuid_hold[AST_UUID_STR_LEN];
786
787 if (!self) {
788 return NULL;
789 }
790
791 {
792 /*
793 * We need to ensure that another bridge with the same uniqueid
794 * doesn't get created before the previous bridge's destructor
795 * has run and deleted the existing topic.
796 */
798 if (!ast_strlen_zero(id)) {
799 if (ast_bridge_topic_exists(id)) {
800 ast_log(LOG_WARNING, "Bridge " BRIDGE_PRINTF_SPEC ": already registered\n",
801 BRIDGE_PRINTF_VARS(self));
802 ast_bridge_destroy(self, 0);
803 return NULL;
804 }
806 } else {
808 ast_string_field_set(self, uniqueid, uuid_hold);
809 }
810 if (!(flags & AST_BRIDGE_FLAG_INVISIBLE)) {
811 if (bridge_topics_init(self) != 0) {
812 ast_log(LOG_WARNING, "Bridge " BRIDGE_PRINTF_SPEC ": Could not initialize topics\n",
813 BRIDGE_PRINTF_VARS(self));
814 ao2_ref(self, -1);
815 return NULL;
816 }
817 }
818 }
819
821 if (!ast_strlen_zero(creator)) {
823 }
824 ast_debug(1, "Bridge " BRIDGE_PRINTF_SPEC ": base_init\n",
825 BRIDGE_PRINTF_VARS(self));
826
827 ast_set_flag(&self->feature_flags, flags);
828 self->allowed_capabilities = capabilities;
829
830 /* Use our helper function to find the "best" bridge technology. */
831 self->technology = find_best_technology(capabilities, self);
832 if (!self->technology) {
833 ast_log(LOG_WARNING, "Bridge %s: Could not create class %s. No technology to support it.\n",
834 self->uniqueid, self->v_table->name);
835 ao2_ref(self, -1);
836 return NULL;
837 }
838
839 /* Pass off the bridge to the technology to manipulate if needed */
840 ast_debug(1, "Bridge %s: calling %s technology constructor\n",
841 self->uniqueid, self->technology->name);
842 if (self->technology->create && self->technology->create(self)) {
843 ast_log(LOG_WARNING, "Bridge %s: failed to setup bridge technology %s\n",
844 self->uniqueid, self->technology->name);
845 ao2_ref(self, -1);
846 return NULL;
847 }
848 ast_debug(1, "Bridge %s: calling %s technology start\n",
849 self->uniqueid, self->technology->name);
850 if (self->technology->start && self->technology->start(self)) {
851 ast_log(LOG_WARNING, "Bridge %s: failed to start bridge technology %s\n",
852 self->uniqueid, self->technology->name);
853 ao2_ref(self, -1);
854 return NULL;
855 }
856
857 if (!(flags & AST_BRIDGE_FLAG_INVISIBLE)) {
858 if (!ast_bridge_topic(self)) {
859 ao2_ref(self, -1);
860 return NULL;
861 }
862 }
863
864 self->creationtime = ast_tvnow();
865 ast_debug(1, "Bridge " BRIDGE_PRINTF_SPEC ": base_init complete\n",
866 BRIDGE_PRINTF_VARS(self));
867
868 return self;
869}
870
871/*!
872 * \internal
873 * \brief ast_bridge base class destructor.
874 * \since 12.0.0
875 *
876 * \param self Bridge to operate upon.
877 *
878 * \note Stub because of nothing to do.
879 */
880static void bridge_base_destroy(struct ast_bridge *self)
881{
882 ast_debug(1, "Bridge " BRIDGE_PRINTF_SPEC ": destroying bridge (noop)\n",
883 BRIDGE_PRINTF_VARS(self));
884}
885
886/*!
887 * \internal
888 * \brief The bridge is being dissolved.
889 * \since 12.0.0
890 *
891 * \param self Bridge to operate upon.
892 */
893static void bridge_base_dissolving(struct ast_bridge *self)
894{
895 ast_debug(1, "Bridge " BRIDGE_PRINTF_SPEC ": unlinking bridge. Refcount: %d\n",
896 BRIDGE_PRINTF_VARS(self), ao2_ref(self, 0));
897 ao2_unlink(bridges, self);
898 ast_debug(1, "Bridge " BRIDGE_PRINTF_SPEC ": unlinked bridge. Refcount: %d\n",
899 BRIDGE_PRINTF_VARS(self), ao2_ref(self, 0));
900}
901
902/*!
903 * \internal
904 * \brief ast_bridge base push method.
905 * \since 12.0.0
906 *
907 * \param self Bridge to operate upon.
908 * \param bridge_channel Bridge channel to push.
909 * \param swap Bridge channel to swap places with if not NULL.
910 *
911 * \note On entry, self is already locked.
912 * \note Stub because of nothing to do.
913 *
914 * \retval 0 on success
915 * \retval -1 on failure
916 */
917static int bridge_base_push(struct ast_bridge *self, struct ast_bridge_channel *bridge_channel, struct ast_bridge_channel *swap)
918{
919 return 0;
920}
921
922/*!
923 * \internal
924 * \brief ast_bridge base pull method.
925 * \since 12.0.0
926 *
927 * \param self Bridge to operate upon.
928 * \param bridge_channel Bridge channel to pull.
929 *
930 * \note On entry, self is already locked.
931 */
932static void bridge_base_pull(struct ast_bridge *self, struct ast_bridge_channel *bridge_channel)
933{
935}
936
937/*!
938 * \internal
939 * \brief ast_bridge base notify_masquerade method.
940 * \since 12.0.0
941 *
942 * \param self Bridge to operate upon.
943 * \param bridge_channel Bridge channel that was masqueraded.
944 *
945 * \note On entry, self is already locked.
946 */
947static void bridge_base_notify_masquerade(struct ast_bridge *self, struct ast_bridge_channel *bridge_channel)
948{
949 self->reconfigured = 1;
950}
951
952/*!
953 * \internal
954 * \brief Get the merge priority of this bridge.
955 * \since 12.0.0
956 *
957 * \param self Bridge to operate upon.
958 *
959 * \note On entry, self is already locked.
960 *
961 * \return Merge priority
962 */
964{
965 return 0;
966}
967
968/*!
969 * \internal
970 * \brief ast_bridge base push_peek method.
971 * \since 13.2.0
972 *
973 * \param self Bridge to operate upon.
974 * \param bridge_channel Bridge channel to push.
975 * \param swap Bridge channel to swap places with if not NULL.
976 *
977 * \note On entry, self is already locked.
978 * \note Stub because of nothing to do.
979 *
980 * \retval 0 on success
981 * \retval -1 on failure
982 */
983static int bridge_base_push_peek(struct ast_bridge *self, struct ast_bridge_channel *bridge_channel, struct ast_bridge_channel *swap)
984{
985 return 0;
986}
987
989 .name = "base",
990 .destroy = bridge_base_destroy,
991 .dissolving = bridge_base_dissolving,
992 .push = bridge_base_push,
993 .pull = bridge_base_pull,
994 .notify_masquerade = bridge_base_notify_masquerade,
995 .get_merge_priority = bridge_base_get_merge_priority,
996 .push_peek = bridge_base_push_peek,
997};
998
999struct ast_bridge *ast_bridge_base_new(uint32_t capabilities, unsigned int flags, const char *creator, const char *name, const char *id)
1000{
1001 void *bridge;
1002
1003 bridge = bridge_alloc(sizeof(struct ast_bridge), &ast_bridge_base_v_table);
1004 bridge = bridge_base_init(bridge, capabilities, flags, creator, name, id);
1005 bridge = bridge_register(bridge);
1006 return bridge;
1007}
1008
1009int ast_bridge_destroy(struct ast_bridge *bridge, int cause)
1010{
1011 ast_debug(1, "Bridge " BRIDGE_PRINTF_SPEC ": destroying. current refcount: %d\n",
1012 BRIDGE_PRINTF_VARS(bridge), ao2_ref(bridge, 0));
1013 ast_bridge_lock(bridge);
1014 bridge_dissolve(bridge, cause);
1015 ast_bridge_unlock(bridge);
1016
1017 ast_debug(1, "Bridge " BRIDGE_PRINTF_SPEC ": unreffing. current refcount: %d\n",
1018 BRIDGE_PRINTF_VARS(bridge), ao2_ref(bridge, 0));
1019
1020 ao2_ref(bridge, -1);
1021
1022 return 0;
1023}
1024
1025/*!
1026 * \internal
1027 * \brief Perform the smart bridge operation.
1028 * \since 12.0.0
1029 *
1030 * \param bridge Work on this bridge.
1031 *
1032 * \details
1033 * Basically see if a new bridge technology should be used instead
1034 * of the current one.
1035 *
1036 * \note On entry, bridge is already locked.
1037 *
1038 * \retval 0 on success.
1039 * \retval -1 on error.
1040 */
1041static int smart_bridge_operation(struct ast_bridge *bridge)
1042{
1043 uint32_t new_capabilities;
1044 struct ast_bridge_technology *new_technology;
1045 struct ast_bridge_technology *old_technology = bridge->technology;
1046 struct ast_bridge_channel *bridge_channel;
1047 struct ast_frame *deferred_action;
1048 struct ast_bridge dummy_bridge = {
1049 .technology = bridge->technology,
1050 .tech_pvt = bridge->tech_pvt,
1051 .creator = bridge->creator,
1052 .name = bridge->name,
1053 .uniqueid = bridge->uniqueid,
1054 };
1055
1056 if (bridge->dissolved) {
1057 ast_debug(1, "Bridge %s is dissolved, not performing smart bridge operation.\n",
1058 bridge->uniqueid);
1059 return 0;
1060 }
1061
1062 /* Determine new bridge technology capabilities needed. */
1063 if (2 < bridge->num_channels) {
1064 new_capabilities = AST_BRIDGE_CAPABILITY_MULTIMIX;
1065 new_capabilities &= bridge->allowed_capabilities;
1066 } else {
1068 new_capabilities &= bridge->allowed_capabilities;
1069 if (!new_capabilities
1071 /* Allow switching between different multimix bridge technologies. */
1072 new_capabilities = AST_BRIDGE_CAPABILITY_MULTIMIX;
1073 }
1074 }
1075
1076 /* Find a bridge technology to satisfy the new capabilities. */
1077 new_technology = find_best_technology(new_capabilities, bridge);
1078 if (!new_technology) {
1079 int is_compatible = 0;
1080
1081 if (old_technology->compatible) {
1082 is_compatible = old_technology->compatible(bridge);
1083 } else if (old_technology->capabilities & AST_BRIDGE_CAPABILITY_MULTIMIX) {
1084 is_compatible = 1;
1085 } else if (bridge->num_channels <= 2
1086 && (old_technology->capabilities & AST_BRIDGE_CAPABILITY_1TO1MIX)) {
1087 is_compatible = 1;
1088 }
1089
1090 if (is_compatible) {
1091 ast_debug(1, "Bridge %s could not get a new technology, staying with old technology.\n",
1092 bridge->uniqueid);
1093 return 0;
1094 }
1095 ast_log(LOG_WARNING, "Bridge %s has no technology available to support it.\n",
1096 bridge->uniqueid);
1097 return -1;
1098 }
1099 if (new_technology == old_technology) {
1100 ast_debug(1, "Bridge %s is already using the new technology.\n",
1101 bridge->uniqueid);
1102 ast_module_unref(old_technology->mod);
1103 return 0;
1104 }
1105
1106 if (old_technology->destroy) {
1107 struct tech_deferred_destroy deferred_tech_destroy = {
1108 .tech = dummy_bridge.technology,
1109 .tech_pvt = dummy_bridge.tech_pvt,
1110 };
1111 struct ast_frame action = {
1114 .data.ptr = &deferred_tech_destroy,
1115 .datalen = sizeof(deferred_tech_destroy),
1116 };
1117
1118 /*
1119 * We need to defer the bridge technology destroy callback
1120 * because we have the bridge locked.
1121 */
1122 deferred_action = ast_frdup(&action);
1123 if (!deferred_action) {
1124 ast_module_unref(new_technology->mod);
1125 return -1;
1126 }
1127 } else {
1129 }
1130
1131 /*
1132 * We are now committed to changing the bridge technology. We
1133 * must not release the bridge lock until we have installed the
1134 * new bridge technology.
1135 */
1136 ast_verb(4, "Bridge %s: switching from %s technology to %s\n",
1137 bridge->uniqueid, old_technology->name, new_technology->name);
1138
1139 /*
1140 * Since we are soon going to pass this bridge to a new
1141 * technology we need to NULL out the tech_pvt pointer but
1142 * don't worry as it still exists in dummy_bridge, ditto for the
1143 * old technology.
1144 */
1145 bridge->tech_pvt = NULL;
1146 bridge->technology = new_technology;
1147
1148 /* Setup the new bridge technology. */
1149 ast_debug(1, "Bridge %s: calling %s technology constructor\n",
1150 bridge->uniqueid, new_technology->name);
1151 if (new_technology->create && new_technology->create(bridge)) {
1152 ast_log(LOG_WARNING, "Bridge %s: failed to setup bridge technology %s\n",
1153 bridge->uniqueid, new_technology->name);
1154 bridge->tech_pvt = dummy_bridge.tech_pvt;
1155 bridge->technology = dummy_bridge.technology;
1156 ast_module_unref(new_technology->mod);
1157 return -1;
1158 }
1159
1160 /* To ensure that things are sane for the old technology move the channels it
1161 * expects to the dummy bridge
1162 */
1163 AST_LIST_TRAVERSE_SAFE_BEGIN(&bridge->channels, bridge_channel, entry) {
1164 if (bridge_channel->just_joined) {
1165 continue;
1166 }
1167 ast_debug(1, "Bridge %s: moving %p(%s) to dummy bridge temporarily\n",
1168 bridge->uniqueid, bridge_channel, ast_channel_name(bridge_channel->chan));
1170 AST_LIST_INSERT_TAIL(&dummy_bridge.channels, bridge_channel, entry);
1171 dummy_bridge.num_channels++;
1173 dummy_bridge.num_lonely++;
1174 }
1175 if (!bridge_channel->suspended) {
1176 dummy_bridge.num_active++;
1177 }
1178 }
1180
1181 /* Take all the channels out of the old technology */
1182 AST_LIST_TRAVERSE_SAFE_BEGIN(&dummy_bridge.channels, bridge_channel, entry) {
1183 ast_debug(1, "Bridge %s: %p(%s) is leaving %s technology (dummy)\n",
1184 dummy_bridge.uniqueid, bridge_channel, ast_channel_name(bridge_channel->chan),
1185 old_technology->name);
1186 if (old_technology->leave) {
1187 old_technology->leave(&dummy_bridge, bridge_channel);
1188 }
1190 AST_LIST_INSERT_TAIL(&bridge->channels, bridge_channel, entry);
1191 dummy_bridge.num_channels--;
1193 dummy_bridge.num_lonely--;
1194 }
1195 if (!bridge_channel->suspended) {
1196 dummy_bridge.num_active--;
1197 }
1198 }
1200
1201 ast_debug(1, "Bridge %s: calling %s technology stop\n",
1202 dummy_bridge.uniqueid, old_technology->name);
1203 if (old_technology->stop) {
1204 old_technology->stop(&dummy_bridge);
1205 }
1206
1207 /* Add any new channels or re-add existing channels to the bridge. */
1208 AST_LIST_TRAVERSE(&bridge->channels, bridge_channel, entry) {
1209 bridge_channel_complete_join(bridge, bridge_channel);
1210 }
1211
1212 ast_debug(1, "Bridge %s: calling %s technology start\n",
1213 bridge->uniqueid, new_technology->name);
1214 if (new_technology->start && new_technology->start(bridge)) {
1215 ast_log(LOG_WARNING, "Bridge %s: failed to start bridge technology %s\n",
1216 bridge->uniqueid, new_technology->name);
1217 }
1218
1219 /*
1220 * Now that all the channels have been moved over we need to get
1221 * rid of all the information the old technology may have left
1222 * around.
1223 */
1224 if (old_technology->destroy) {
1225 ast_debug(1, "Bridge %s: deferring %s technology destructor\n",
1226 dummy_bridge.uniqueid, old_technology->name);
1228 } else {
1229 ast_debug(1, "Bridge %s: calling %s technology destructor\n",
1230 dummy_bridge.uniqueid, old_technology->name);
1231 ast_module_unref(old_technology->mod);
1232 }
1233
1234 return 0;
1235}
1236
1237/*!
1238 * \internal
1239 * \brief Bridge channel to check if a BRIDGE_PLAY_SOUND needs to be played.
1240 * \since 12.0.0
1241 *
1242 * \param bridge_channel What to check.
1243 */
1244static void check_bridge_play_sound(struct ast_bridge_channel *bridge_channel)
1245{
1246 const char *play_file;
1247
1248 ast_channel_lock(bridge_channel->chan);
1249 play_file = pbx_builtin_getvar_helper(bridge_channel->chan, "BRIDGE_PLAY_SOUND");
1250 if (!ast_strlen_zero(play_file)) {
1252 pbx_builtin_setvar_helper(bridge_channel->chan, "BRIDGE_PLAY_SOUND", NULL);
1253 } else {
1254 play_file = NULL;
1255 }
1256 ast_channel_unlock(bridge_channel->chan);
1257
1258 if (play_file) {
1260 }
1261}
1262
1263/*!
1264 * \internal
1265 * \brief Check for any BRIDGE_PLAY_SOUND channel variables in the bridge.
1266 * \since 12.0.0
1267 *
1268 * \param bridge What to operate on.
1269 *
1270 * \note On entry, the bridge is already locked.
1271 */
1272static void check_bridge_play_sounds(struct ast_bridge *bridge)
1273{
1274 struct ast_bridge_channel *bridge_channel;
1275
1276 AST_LIST_TRAVERSE(&bridge->channels, bridge_channel, entry) {
1277 check_bridge_play_sound(bridge_channel);
1278 }
1279}
1280
1281void ast_bridge_vars_set(struct ast_channel *chan, const char *name, const char *pvtid)
1282{
1284 pbx_builtin_setvar_helper(chan, "BRIDGEPEER", name);
1285 pbx_builtin_setvar_helper(chan, "BRIDGEPVTCALLID", pvtid);
1287}
1288
1289/*!
1290 * \internal
1291 * \brief Set BRIDGEPEER and BRIDGEPVTCALLID channel variables in a 2 party bridge.
1292 * \since 12.0.0
1293 *
1294 * \param c0 Party of the first part.
1295 * \param c1 Party of the second part.
1296 *
1297 * \note On entry, the bridge is already locked.
1298 * \note The bridge is expected to have exactly two parties.
1299 */
1300static void set_bridge_peer_vars_2party(struct ast_channel *c0, struct ast_channel *c1)
1301{
1302 const char *c0_name;
1303 const char *c1_name;
1304 const char *c0_pvtid = NULL;
1305 const char *c1_pvtid = NULL;
1306#define UPDATE_BRIDGE_VARS_GET(chan, name, pvtid) \
1307 do { \
1308 name = ast_strdupa(ast_channel_name(chan)); \
1309 if (ast_channel_tech(chan)->get_pvt_uniqueid) { \
1310 pvtid = ast_strdupa(ast_channel_tech(chan)->get_pvt_uniqueid(chan)); \
1311 } \
1312 } while (0)
1313
1314 ast_channel_lock(c1);
1315 UPDATE_BRIDGE_VARS_GET(c1, c1_name, c1_pvtid);
1317
1318 ast_channel_lock(c0);
1319 ast_bridge_vars_set(c0, c1_name, c1_pvtid);
1320 UPDATE_BRIDGE_VARS_GET(c0, c0_name, c0_pvtid);
1322
1323 ast_channel_lock(c1);
1324 ast_bridge_vars_set(c1, c0_name, c0_pvtid);
1326}
1327
1328/*!
1329 * \internal
1330 * \brief Fill the BRIDGEPEER value buffer with a comma separated list of channel names.
1331 * \since 12.0.0
1332 *
1333 * \param buf Buffer to fill. The caller must guarantee the buffer is large enough.
1334 * \param cur_idx Which index into names[] to skip.
1335 * \param names Channel names to put in the buffer.
1336 * \param num_names Number of names in the array.
1337 */
1338static void fill_bridgepeer_buf(char *buf, unsigned int cur_idx, const char *names[], unsigned int num_names)
1339{
1340 int need_separator = 0;
1341 unsigned int idx;
1342 const char *src;
1343 char *pos;
1344
1345 pos = buf;
1346 for (idx = 0; idx < num_names; ++idx) {
1347 if (idx == cur_idx) {
1348 continue;
1349 }
1350
1351 if (need_separator) {
1352 *pos++ = ',';
1353 }
1354 need_separator = 1;
1355
1356 /* Copy name into buffer. */
1357 src = names[idx];
1358 while (*src) {
1359 *pos++ = *src++;
1360 }
1361 }
1362 *pos = '\0';
1363}
1364
1365/*!
1366 * \internal
1367 * \brief Set BRIDGEPEER and BRIDGEPVTCALLID channel variables in a multi-party bridge.
1368 * \since 12.0.0
1369 *
1370 * \param bridge What to operate on.
1371 *
1372 * \note On entry, the bridge is already locked.
1373 * \note The bridge is expected to have more than two parties.
1374 */
1376{
1377/*
1378 * Set a maximum number of channel names for the BRIDGEPEER
1379 * list. The plus one is for the current channel which is not
1380 * put in the list.
1381 */
1382#define MAX_BRIDGEPEER_CHANS (10 + 1)
1383
1384 unsigned int idx;
1385 unsigned int num_names;
1386 unsigned int len;
1387 const char **names;
1388 char *buf;
1389 struct ast_bridge_channel *bridge_channel;
1390
1391 /* Get first MAX_BRIDGEPEER_CHANS channel names. */
1393 names = ast_alloca(num_names * sizeof(*names));
1394 idx = 0;
1395 AST_LIST_TRAVERSE(&bridge->channels, bridge_channel, entry) {
1396 if (num_names <= idx) {
1397 break;
1398 }
1399 ast_channel_lock(bridge_channel->chan);
1400 names[idx++] = ast_strdupa(ast_channel_name(bridge_channel->chan));
1401 ast_channel_unlock(bridge_channel->chan);
1402 }
1403
1404 /* Determine maximum buf size needed. */
1405 len = num_names;
1406 for (idx = 0; idx < num_names; ++idx) {
1407 len += strlen(names[idx]);
1408 }
1409 buf = ast_alloca(len);
1410
1411 /* Set the bridge channel variables. */
1412 idx = 0;
1413 buf[0] = '\0';
1414 AST_LIST_TRAVERSE(&bridge->channels, bridge_channel, entry) {
1415 if (idx < num_names) {
1416 fill_bridgepeer_buf(buf, idx, names, num_names);
1417 }
1418 ++idx;
1419
1420 ast_channel_lock(bridge_channel->chan);
1421 ast_bridge_vars_set(bridge_channel->chan, buf, NULL);
1422 ast_channel_unlock(bridge_channel->chan);
1423 }
1424}
1425
1426/*!
1427 * \internal
1428 * \brief Set BRIDGEPEER and BRIDGEPVTCALLID channel variables in a holding bridge.
1429 * \since 12.0.0
1430 *
1431 * \param bridge What to operate on.
1432 *
1433 * \note On entry, the bridge is already locked.
1434 */
1436{
1437 struct ast_bridge_channel *bridge_channel;
1438
1439 AST_LIST_TRAVERSE(&bridge->channels, bridge_channel, entry) {
1440 ast_channel_lock(bridge_channel->chan);
1441 ast_bridge_vars_set(bridge_channel->chan, NULL, NULL);
1442 ast_channel_unlock(bridge_channel->chan);
1443 }
1444}
1445
1446/*!
1447 * \internal
1448 * \brief Set BRIDGEPEER and BRIDGEPVTCALLID channel variables in the bridge.
1449 * \since 12.0.0
1450 *
1451 * \param bridge What to operate on.
1452 *
1453 * \note On entry, the bridge is already locked.
1454 */
1456{
1459 return;
1460 }
1461 if (bridge->num_channels < 2) {
1462 return;
1463 }
1464 if (bridge->num_channels == 2) {
1466 AST_LIST_LAST(&bridge->channels)->chan);
1467 } else {
1469 }
1470}
1471
1472void bridge_reconfigured(struct ast_bridge *bridge, unsigned int colp_update)
1473{
1474 if (!bridge->reconfigured) {
1475 return;
1476 }
1477 bridge->reconfigured = 0;
1480 /* Smart bridge failed. */
1482 return;
1483 }
1485
1486 if (bridge->dissolved) {
1487 return;
1488 }
1492
1493 if (colp_update) {
1495 }
1496}
1497
1499{
1500 struct ast_bridge_channel *bridge_channel;
1501
1502 AST_LIST_TRAVERSE(&bridge->channels, bridge_channel, entry) {
1503 if (bridge_channel->chan == chan) {
1504 break;
1505 }
1506 }
1507
1508 return bridge_channel;
1509}
1510
1512{
1513 struct ast_bridge_channel *bridge_channel;
1514 struct ast_bridge *bridge;
1515
1516 /* Safely get the bridge_channel pointer for the chan. */
1517 ast_channel_lock(chan);
1518 bridge_channel = ast_channel_get_bridge_channel(chan);
1519 ast_channel_unlock(chan);
1520 if (!bridge_channel) {
1521 /* Not in a bridge */
1522 return;
1523 }
1524
1525 ast_bridge_channel_lock_bridge(bridge_channel);
1526 bridge = bridge_channel->bridge;
1527 if (bridge_channel == bridge_find_channel(bridge, chan)) {
1528/*
1529 * XXX ASTERISK-22366 this needs more work. The channels need
1530 * to be made compatible again if the formats change. The
1531 * bridge_channel thread needs to monitor for this case.
1532 */
1533 /* The channel we want to notify is still in a bridge. */
1534 bridge->v_table->notify_masquerade(bridge, bridge_channel);
1535 bridge_reconfigured(bridge, 1);
1536 }
1537 ast_bridge_unlock(bridge);
1538 ao2_ref(bridge_channel, -1);
1539}
1540
1541/*!
1542 * \brief Internal bridge impart wait condition and associated conditional.
1543 */
1546 /*! Lock for the data structure */
1548 /*! Wait condition */
1550 /*! Wait until done */
1551 int done;
1552};
1553
1555
1556/*!
1557 * \internal
1558 * \brief Signal imparting threads to wake up.
1559 * \since 13.9.0
1560 *
1561 * \param ds_head List of imparting threads to wake up.
1562 */
1564{
1565 if (ds_head) {
1567
1568 while ((cond = AST_LIST_REMOVE_HEAD(ds_head, node))) {
1569 ast_mutex_lock(&cond->lock);
1570 cond->done = 1;
1571 ast_cond_signal(&cond->cond);
1572 ast_mutex_unlock(&cond->lock);
1573 }
1574 }
1575}
1576
1577static void bridge_channel_impart_ds_head_dtor(void *doomed)
1578{
1580 ast_free(doomed);
1581}
1582
1583/*!
1584 * \internal
1585 * \brief Fixup the bridge impart datastore.
1586 * \since 13.9.0
1587 *
1588 * \param data Bridge impart datastore data to fixup from old_chan.
1589 * \param old_chan The datastore is moving from this channel.
1590 * \param new_chan The datastore is moving to this channel.
1591 */
1592static void bridge_channel_impart_ds_head_fixup(void *data, struct ast_channel *old_chan, struct ast_channel *new_chan)
1593{
1594 /*
1595 * Signal any waiting impart threads. The masquerade is going to kill
1596 * old_chan and we don't need to be waiting on new_chan.
1597 */
1599}
1600
1602 .type = "bridge-impart-ds",
1605};
1606
1607/*!
1608 * \internal
1609 * \brief Add impart wait datastore conditional to channel.
1610 * \since 13.9.0
1611 *
1612 * \param chan Channel to add the impart wait conditional.
1613 * \param cond Imparting conditional to add.
1614 *
1615 * \retval 0 on success.
1616 * \retval -1 on error.
1617 */
1619{
1620 struct ast_datastore *datastore;
1621 struct bridge_channel_impart_ds_head *ds_head;
1622
1623 ast_channel_lock(chan);
1624
1626 if (!datastore) {
1628 if (!datastore) {
1629 ast_channel_unlock(chan);
1630 return -1;
1631 }
1632 ds_head = ast_calloc(1, sizeof(*ds_head));
1633 if (!ds_head) {
1634 ast_channel_unlock(chan);
1635 ast_datastore_free(datastore);
1636 return -1;
1637 }
1638 datastore->data = ds_head;
1639 ast_channel_datastore_add(chan, datastore);
1640 } else {
1641 ds_head = datastore->data;
1642 ast_assert(ds_head != NULL);
1643 }
1644
1645 AST_LIST_INSERT_TAIL(ds_head, cond, node);
1646
1647 ast_channel_unlock(chan);
1648 return 0;
1649}
1650
1652{
1653 struct ast_datastore *datastore;
1654
1655 ast_channel_lock(chan);
1657 if (datastore) {
1659 }
1660 ast_channel_unlock(chan);
1661}
1662
1663/*!
1664 * \internal
1665 * \brief Block imparting channel thread until signaled.
1666 * \since 13.9.0
1667 *
1668 * \param cond Imparting conditional to wait for.
1669 */
1671{
1672 ast_mutex_lock(&cond->lock);
1673 while (!cond->done) {
1674 ast_cond_wait(&cond->cond, &cond->lock);
1675 }
1676 ast_mutex_unlock(&cond->lock);
1677}
1678
1679/*
1680 * XXX ASTERISK-21271 make ast_bridge_join() require features to be allocated just like ast_bridge_impart() and not expect the struct back.
1681 *
1682 * This change is really going to break ConfBridge. All other
1683 * users are easily changed. However, it is needed so the
1684 * bridging code can manipulate features on all channels
1685 * consistently no matter how they joined.
1686 *
1687 * Need to update the features parameter doxygen when this
1688 * change is made to be like ast_bridge_impart().
1689 */
1690int ast_bridge_join(struct ast_bridge *bridge,
1691 struct ast_channel *chan,
1692 struct ast_channel *swap,
1693 struct ast_bridge_features *features,
1694 struct ast_bridge_tech_optimizations *tech_args,
1695 enum ast_bridge_join_flags flags)
1696{
1697 struct ast_bridge_channel *bridge_channel;
1698 int res = 0;
1699 SCOPE_TRACE(1, "%s Bridge: %s\n", ast_channel_name(chan), bridge->uniqueid);
1700
1701 bridge_channel = bridge_channel_internal_alloc(bridge);
1702 if (flags & AST_BRIDGE_JOIN_PASS_REFERENCE) {
1703 ao2_ref(bridge, -1);
1704 }
1705 if (!bridge_channel) {
1706 ao2_t_cleanup(swap, "Error exit: bridge_channel alloc failed");
1707 res = -1;
1708 goto join_exit;
1709 }
1710/* XXX ASTERISK-21271 features cannot be NULL when passed in. When it is changed to allocated we can do like ast_bridge_impart() and allocate one. */
1712 if (!features) {
1713 ao2_ref(bridge_channel, -1);
1714 ao2_t_cleanup(swap, "Error exit: features is NULL");
1715 res = -1;
1716 goto join_exit;
1717 }
1718 if (tech_args) {
1719 bridge_channel->tech_args = *tech_args;
1720 }
1721
1724 res = -1;
1725 } else {
1727 }
1729 bridge_channel->thread = pthread_self();
1730 bridge_channel->chan = chan;
1731 bridge_channel->swap = swap;
1732 bridge_channel->features = features;
1733 bridge_channel->inhibit_colp = !!(flags & AST_BRIDGE_JOIN_INHIBIT_JOIN_COLP);
1734
1735 /* allow subclass to peek at upcoming push operation */
1736 if (bridge->v_table->push_peek && !res) {
1737 struct ast_bridge_channel *bcswap = NULL;
1738
1740 if (bridge_channel->swap) {
1741 bcswap = bridge_find_channel(bridge, bridge_channel->swap);
1742 }
1743 res = bridge->v_table->push_peek(bridge, bridge_channel, bcswap);
1745 }
1746
1747 if (!res) {
1748 res = bridge_channel_internal_join(bridge_channel);
1749 }
1750
1751 /* Cleanup all the data in the bridge channel after it leaves the bridge. */
1755 /* Due to a race condition, we lock the bridge channel here for ast_bridge_channel_get_chan */
1756 ao2_lock(bridge_channel);
1757 bridge_channel->chan = NULL;
1758 ao2_unlock(bridge_channel);
1759 /* If bridge_channel->swap is not NULL then the join failed. */
1760 ao2_t_cleanup(bridge_channel->swap, "Bridge complete: join failed");
1761 bridge_channel->swap = NULL;
1762 bridge_channel->features = NULL;
1763
1764 ao2_ref(bridge_channel, -1);
1765
1766join_exit:
1771 /* Claim the after bridge goto is an async goto destination. */
1775 }
1776 return res;
1777}
1778
1779/*! \brief Thread responsible for imparted bridged channels to be departed */
1780static void *bridge_channel_depart_thread(void *data)
1781{
1782 struct ast_bridge_channel *bridge_channel = data;
1783 int res = 0;
1784
1785 if (bridge_channel->callid) {
1786 ast_callid_threadassoc_add(bridge_channel->callid);
1787 }
1788
1789 res = bridge_channel_internal_join(bridge_channel);
1790
1791 /*
1792 * cleanup
1793 *
1794 * If bridge_channel->swap is not NULL then the join failed.
1795 */
1796 ao2_t_cleanup(bridge_channel->swap, "Bridge complete: Departable impart join failed");
1797 bridge_channel->swap = NULL;
1798 ast_bridge_features_destroy(bridge_channel->features);
1799 bridge_channel->features = NULL;
1800
1803 /* If join failed there will be impart threads waiting. */
1804 bridge_channel_impart_signal(bridge_channel->chan);
1805 ast_bridge_discard_after_goto(bridge_channel->chan);
1806
1807 return NULL;
1808}
1809
1810/*! \brief Thread responsible for independent imparted bridged channels */
1811static void *bridge_channel_ind_thread(void *data)
1812{
1813 struct ast_bridge_channel *bridge_channel = data;
1814 struct ast_channel *chan;
1815
1816 if (bridge_channel->callid) {
1818 }
1819
1821 chan = bridge_channel->chan;
1822
1823 /* cleanup */
1824 ast_channel_lock(chan);
1826 ast_channel_unlock(chan);
1827 /* Lock here for ast_bridge_channel_get_chan */
1831 /* If bridge_channel->swap is not NULL then the join failed. */
1832 ao2_t_cleanup(bridge_channel->swap, "Bridge complete: Independent impart join failed");
1836
1838
1840 /* If join failed there will be impart threads waiting. */
1843 return NULL;
1844}
1845
1847 struct ast_channel *chan,
1848 struct ast_channel *swap,
1849 struct ast_bridge_features *features,
1852{
1853 int res = 0;
1854 struct ast_bridge_channel *bridge_channel;
1855
1856 /* Imparted channels cannot have a PBX. */
1857 if (ast_channel_pbx(chan)) {
1858 ast_log(AST_LOG_WARNING, "Channel %s has a PBX thread and cannot be imparted into bridge %s\n",
1861 return -1;
1862 }
1863
1864 /* Supply an empty features structure if the caller did not. */
1865 if (!features) {
1867 if (!features) {
1868 return -1;
1869 }
1870 }
1871
1872 /* Try to allocate a structure for the bridge channel */
1873 bridge_channel = bridge_channel_internal_alloc(bridge);
1874 if (!bridge_channel) {
1876 return -1;
1877 }
1878
1881 ast_log(AST_LOG_NOTICE, "Channel %s is a zombie and cannot be imparted into bridge %s\n",
1883 res = -1;
1884 } else {
1886 }
1888 bridge_channel->chan = chan;
1889 bridge_channel->swap = ao2_t_bump(swap, "Setting up bridge impart");
1890 bridge_channel->features = features;
1891 bridge_channel->inhibit_colp = !!(flags & AST_BRIDGE_IMPART_INHIBIT_JOIN_COLP);
1892 bridge_channel->depart_wait =
1894 bridge_channel->callid = ast_read_threadstorage_callid();
1895
1896 /* allow subclass to peek at swap channel before it can hangup */
1897 if (bridge->v_table->push_peek && !res) {
1898 struct ast_bridge_channel *bcswap = NULL;
1899
1901 if (bridge_channel->swap) {
1902 bcswap = bridge_find_channel(bridge, bridge_channel->swap);
1903 }
1904 res = bridge->v_table->push_peek(bridge, bridge_channel, bcswap);
1906 }
1907
1908 /* Actually create the thread that will handle the channel */
1909 if (!res) {
1911 }
1912 if (!res) {
1914 res = ast_pthread_create_detached(&bridge_channel->thread, NULL,
1915 bridge_channel_ind_thread, bridge_channel);
1916 } else {
1917 res = ast_pthread_create(&bridge_channel->thread, NULL,
1918 bridge_channel_depart_thread, bridge_channel);
1919 }
1920
1921 if (!res) {
1923 }
1924 }
1925
1926 if (res) {
1927 /* cleanup */
1931 /* Lock here for ast_bridge_channel_get_chan */
1932 ao2_lock(bridge_channel);
1933 bridge_channel->chan = NULL;
1934 ao2_unlock(bridge_channel);
1935 ao2_t_cleanup(bridge_channel->swap, "Bridge complete: Impart failed");
1936 bridge_channel->swap = NULL;
1937 ast_bridge_features_destroy(bridge_channel->features);
1938 bridge_channel->features = NULL;
1939
1940 ao2_ref(bridge_channel, -1);
1941 return -1;
1942 }
1943
1944 return 0;
1945}
1946
1948 struct ast_channel *chan,
1949 struct ast_channel *swap,
1951 enum ast_bridge_impart_flags flags)
1952{
1954 .done = 0,
1955 };
1956 int res;
1957 SCOPE_TRACE(1, "%s Bridge: %s\n", ast_channel_name(chan), bridge->uniqueid);
1958
1959 ast_mutex_init(&cond.lock);
1960 ast_cond_init(&cond.cond, NULL);
1961
1962 res = bridge_impart_internal(bridge, chan, swap, features, flags, &cond);
1963 if (res) {
1964 /* Impart failed. Signal any other waiting impart threads */
1967 }
1968
1969 ast_cond_destroy(&cond.cond);
1970 ast_mutex_destroy(&cond.lock);
1971
1972 return res;
1973}
1974
1976{
1977 struct ast_bridge_channel *bridge_channel;
1978 int departable;
1979 SCOPE_TRACE(1, "%s\n", ast_channel_name(chan));
1980
1982 bridge_channel = ast_channel_internal_bridge_channel(chan);
1983 departable = bridge_channel && bridge_channel->depart_wait;
1985 if (!departable) {
1986 ast_log(LOG_ERROR, "Channel %s cannot be departed.\n",
1988 /*
1989 * Should never happen. It likely means that
1990 * ast_bridge_depart() is called by two threads for the same
1991 * channel, the channel was never imparted to be departed, or it
1992 * has already been departed.
1993 */
1994 ast_assert(0);
1995 return -1;
1996 }
1997
1998 /*
1999 * We are claiming the bridge_channel reference held by
2000 * bridge_channel_depart_thread().
2001 */
2002
2003 ast_bridge_channel_leave_bridge(bridge_channel,
2005
2006 /* Wait for the depart thread to die */
2007 ast_debug(1, "Waiting for %p(%s) bridge thread to die.\n",
2008 bridge_channel, ast_channel_name(bridge_channel->chan));
2009 pthread_join(bridge_channel->thread, NULL);
2010
2014
2015 /* We can get rid of the bridge_channel after the depart thread has died. */
2016 ao2_ref(bridge_channel, -1);
2017 return 0;
2018}
2019
2021{
2022 struct ast_bridge_channel *bridge_channel;
2023
2024 ast_debug(1, "Removing channel %s from bridge %s\n",
2026
2028
2029 /* Try to find the channel that we want to remove */
2030 if (!(bridge_channel = bridge_find_channel(bridge, chan))) {
2032 return -1;
2033 }
2034
2035 ast_bridge_channel_leave_bridge(bridge_channel,
2037
2039
2040 return 0;
2041}
2042
2043static void kick_it(struct ast_bridge_channel *bridge_channel, const void *payload, size_t payload_size)
2044{
2046}
2047
2049{
2050 struct ast_bridge_channel *bridge_channel;
2051 int res;
2052
2054
2055 /* Try to find the channel that we want to kick. */
2056 if (!(bridge_channel = bridge_find_channel(bridge, chan))) {
2058 return -1;
2059 }
2060
2061 res = ast_bridge_channel_queue_callback(bridge_channel, 0, kick_it, NULL, 0);
2062
2064
2065 return res;
2066}
2067
2068/*!
2069 * \internal
2070 * \brief Point the bridge_channel to a new bridge.
2071 * \since 12.0.0
2072 *
2073 * \param bridge_channel What is to point to a new bridge.
2074 * \param new_bridge Where the bridge channel should point.
2075 */
2076static void bridge_channel_change_bridge(struct ast_bridge_channel *bridge_channel, struct ast_bridge *new_bridge)
2077{
2078 struct ast_bridge *old_bridge;
2079
2080 ao2_ref(new_bridge, +1);
2081 ast_bridge_channel_lock(bridge_channel);
2082 ast_channel_lock(bridge_channel->chan);
2083 old_bridge = bridge_channel->bridge;
2084 bridge_channel->bridge = new_bridge;
2085 ast_channel_internal_bridge_set(bridge_channel->chan, new_bridge);
2086 ast_channel_unlock(bridge_channel->chan);
2087 ast_bridge_channel_unlock(bridge_channel);
2088 ao2_ref(old_bridge, -1);
2089}
2090
2091static void bridge_channel_moving(struct ast_bridge_channel *bridge_channel, struct ast_bridge *src, struct ast_bridge *dst)
2092{
2093 struct ast_bridge_features *features = bridge_channel->features;
2094 struct ast_bridge_hook *hook;
2095 struct ao2_iterator iter;
2096
2097 /* Run any moving hooks. */
2098 iter = ao2_iterator_init(features->other_hooks, 0);
2099 for (; (hook = ao2_iterator_next(&iter)); ao2_ref(hook, -1)) {
2100 int remove_me;
2102
2103 if (hook->type != AST_BRIDGE_HOOK_TYPE_MOVE) {
2104 continue;
2105 }
2107 remove_me = move_cb(bridge_channel, hook->hook_pvt, src, dst);
2108 if (remove_me) {
2109 ast_debug(1, "Move detection hook %p is being removed from %p(%s)\n",
2110 hook, bridge_channel, ast_channel_name(bridge_channel->chan));
2111 ao2_unlink(features->other_hooks, hook);
2112 }
2113 }
2114 ao2_iterator_destroy(&iter);
2115}
2116
2117void bridge_do_merge(struct ast_bridge *dst_bridge, struct ast_bridge *src_bridge, struct ast_bridge_channel **kick_me, unsigned int num_kick,
2118 unsigned int optimized)
2119{
2120 struct ast_bridge_channel *bridge_channel;
2121 unsigned int idx;
2122
2123 ast_debug(1, "Merging bridge %s into bridge %s\n",
2124 src_bridge->uniqueid, dst_bridge->uniqueid);
2125
2126 ast_bridge_publish_merge(dst_bridge, src_bridge);
2127
2128 /*
2129 * Move channels from src_bridge over to dst_bridge.
2130 *
2131 * We must use AST_LIST_TRAVERSE_SAFE_BEGIN() because
2132 * bridge_channel_internal_pull() alters the list we are traversing.
2133 */
2134 AST_LIST_TRAVERSE_SAFE_BEGIN(&src_bridge->channels, bridge_channel, entry) {
2135 if (bridge_channel->state != BRIDGE_CHANNEL_STATE_WAIT) {
2136 /*
2137 * The channel is already leaving let it leave normally because
2138 * pulling it may delete hooks that should run for this channel.
2139 */
2140 continue;
2141 }
2142 if (ast_test_flag(&bridge_channel->features->feature_flags,
2144 continue;
2145 }
2146
2147 if (kick_me) {
2148 for (idx = 0; idx < num_kick; ++idx) {
2149 if (bridge_channel == kick_me[idx]) {
2150 ast_bridge_channel_leave_bridge(bridge_channel,
2152 break;
2153 }
2154 }
2155 }
2156 bridge_channel_internal_pull(bridge_channel);
2157 if (bridge_channel->state != BRIDGE_CHANNEL_STATE_WAIT) {
2158 /*
2159 * The channel died as a result of being pulled or it was
2160 * kicked. Leave it pointing to the original bridge.
2161 */
2162 continue;
2163 }
2164
2165 bridge_channel_moving(bridge_channel, bridge_channel->bridge, dst_bridge);
2166
2167 /* Point to new bridge.*/
2168 bridge_channel_change_bridge(bridge_channel, dst_bridge);
2169
2170 if (bridge_channel_internal_push(bridge_channel)) {
2171 ast_bridge_features_remove(bridge_channel->features,
2173 ast_bridge_channel_leave_bridge(bridge_channel,
2175 }
2176 }
2178
2179 if (kick_me) {
2180 /*
2181 * Now we can kick any channels in the dst_bridge without
2182 * potentially dissolving the bridge.
2183 */
2184 for (idx = 0; idx < num_kick; ++idx) {
2185 bridge_channel = kick_me[idx];
2186 ast_bridge_channel_lock(bridge_channel);
2187 if (bridge_channel->state == BRIDGE_CHANNEL_STATE_WAIT) {
2190 bridge_channel_internal_pull(bridge_channel);
2191 }
2192 ast_bridge_channel_unlock(bridge_channel);
2193 }
2194 }
2195
2196 bridge_reconfigured(dst_bridge, !optimized);
2197 bridge_reconfigured(src_bridge, !optimized);
2198
2199 ast_debug(1, "Merged bridge %s into bridge %s\n",
2200 src_bridge->uniqueid, dst_bridge->uniqueid);
2201}
2202
2204 /*! Destination merge bridge. */
2206 /*! Source merge bridge. */
2208};
2209
2210/*!
2211 * \internal
2212 * \brief Determine which bridge should merge into the other.
2213 * \since 12.0.0
2214 *
2215 * \param bridge1 A bridge for merging
2216 * \param bridge2 A bridge for merging
2217 *
2218 * \note The two bridges are assumed already locked.
2219 *
2220 * \return Which bridge merges into which or NULL bridges if cannot merge.
2221 */
2222static struct merge_direction bridge_merge_determine_direction(struct ast_bridge *bridge1, struct ast_bridge *bridge2)
2223{
2224 struct merge_direction merge = { NULL, NULL };
2225 int bridge1_priority;
2226 int bridge2_priority;
2227
2228 if (!ast_test_flag(&bridge1->feature_flags,
2230 && !ast_test_flag(&bridge2->feature_flags,
2232 /*
2233 * Can merge either way. Merge to the higher priority merge
2234 * bridge. Otherwise merge to the larger bridge.
2235 */
2236 bridge1_priority = bridge1->v_table->get_merge_priority(bridge1);
2237 bridge2_priority = bridge2->v_table->get_merge_priority(bridge2);
2238 if (bridge2_priority < bridge1_priority) {
2239 merge.dest = bridge1;
2240 merge.src = bridge2;
2241 } else if (bridge1_priority < bridge2_priority) {
2242 merge.dest = bridge2;
2243 merge.src = bridge1;
2244 } else {
2245 /* Merge to the larger bridge. */
2246 if (bridge2->num_channels <= bridge1->num_channels) {
2247 merge.dest = bridge1;
2248 merge.src = bridge2;
2249 } else {
2250 merge.dest = bridge2;
2251 merge.src = bridge1;
2252 }
2253 }
2254 } else if (!ast_test_flag(&bridge1->feature_flags, AST_BRIDGE_FLAG_MERGE_INHIBIT_TO)
2255 && !ast_test_flag(&bridge2->feature_flags, AST_BRIDGE_FLAG_MERGE_INHIBIT_FROM)) {
2256 /* Can merge only one way. */
2257 merge.dest = bridge1;
2258 merge.src = bridge2;
2259 } else if (!ast_test_flag(&bridge2->feature_flags, AST_BRIDGE_FLAG_MERGE_INHIBIT_TO)
2260 && !ast_test_flag(&bridge1->feature_flags, AST_BRIDGE_FLAG_MERGE_INHIBIT_FROM)) {
2261 /* Can merge only one way. */
2262 merge.dest = bridge2;
2263 merge.src = bridge1;
2264 }
2265
2266 return merge;
2267}
2268
2269/*!
2270 * \internal
2271 * \brief Merge two bridges together
2272 * \since 12.0.0
2273 *
2274 * \param dst_bridge Destination bridge of merge.
2275 * \param src_bridge Source bridge of merge.
2276 * \param merge_best_direction TRUE if don't care about which bridge merges into the other.
2277 * \param kick_me Array of channels to kick from the bridges.
2278 * \param num_kick Number of channels in the kick_me array.
2279 *
2280 * \note The dst_bridge and src_bridge are assumed already locked.
2281 *
2282 * \retval 0 on success
2283 * \retval -1 on failure
2284 */
2285static int bridge_merge_locked(struct ast_bridge *dst_bridge, struct ast_bridge *src_bridge, int merge_best_direction, struct ast_channel **kick_me, unsigned int num_kick)
2286{
2287 struct merge_direction merge;
2288 struct ast_bridge_channel **kick_them = NULL;
2289
2290 /* Sanity check. */
2291 ast_assert(dst_bridge && src_bridge && dst_bridge != src_bridge && (!num_kick || kick_me));
2292
2293 if (dst_bridge->dissolved || src_bridge->dissolved) {
2294 ast_debug(1, "Can't merge bridges %s and %s, at least one bridge is dissolved.\n",
2295 src_bridge->uniqueid, dst_bridge->uniqueid);
2296 return -1;
2297 }
2300 ast_debug(1, "Can't merge bridges %s and %s, masquerade only.\n",
2301 src_bridge->uniqueid, dst_bridge->uniqueid);
2302 return -1;
2303 }
2304 if (dst_bridge->inhibit_merge || src_bridge->inhibit_merge) {
2305 ast_debug(1, "Can't merge bridges %s and %s, merging temporarily inhibited.\n",
2306 src_bridge->uniqueid, dst_bridge->uniqueid);
2307 return -1;
2308 }
2309
2310 if (merge_best_direction) {
2311 merge = bridge_merge_determine_direction(dst_bridge, src_bridge);
2312 } else {
2313 merge.dest = dst_bridge;
2314 merge.src = src_bridge;
2315 }
2316
2317 if (!merge.dest
2320 ast_debug(1, "Can't merge bridges %s and %s, merging inhibited.\n",
2321 src_bridge->uniqueid, dst_bridge->uniqueid);
2322 return -1;
2323 }
2324 if (merge.src->num_channels < 2) {
2325 /*
2326 * For a two party bridge, a channel may be temporarily removed
2327 * from the source bridge or the initial bridge members have not
2328 * joined yet.
2329 */
2330 ast_debug(1, "Can't merge bridge %s into bridge %s, not enough channels in source bridge.\n",
2331 merge.src->uniqueid, merge.dest->uniqueid);
2332 return -1;
2333 }
2334 if (2 + num_kick < merge.dest->num_channels + merge.src->num_channels
2338 ast_debug(1, "Can't merge bridge %s into bridge %s, multimix is needed and it cannot be acquired.\n",
2339 merge.src->uniqueid, merge.dest->uniqueid);
2340 return -1;
2341 }
2342
2343 if (num_kick) {
2344 unsigned int num_to_kick = 0;
2345 unsigned int idx;
2346
2347 kick_them = ast_alloca(num_kick * sizeof(*kick_them));
2348 for (idx = 0; idx < num_kick; ++idx) {
2349 kick_them[num_to_kick] = bridge_find_channel(merge.src, kick_me[idx]);
2350 if (!kick_them[num_to_kick]) {
2351 kick_them[num_to_kick] = bridge_find_channel(merge.dest, kick_me[idx]);
2352 }
2353 if (kick_them[num_to_kick]) {
2354 ++num_to_kick;
2355 }
2356 }
2357
2358 if (num_to_kick != num_kick) {
2359 ast_debug(1, "Can't merge bridge %s into bridge %s, at least one kicked channel is not in either bridge.\n",
2360 merge.src->uniqueid, merge.dest->uniqueid);
2361 return -1;
2362 }
2363 }
2364
2365 bridge_do_merge(merge.dest, merge.src, kick_them, num_kick, 0);
2366 return 0;
2367}
2368
2369int ast_bridge_merge(struct ast_bridge *dst_bridge, struct ast_bridge *src_bridge, int merge_best_direction, struct ast_channel **kick_me, unsigned int num_kick)
2370{
2371 int res;
2372
2373 /* Sanity check. */
2374 ast_assert(dst_bridge && src_bridge);
2375
2376 ast_bridge_lock_both(dst_bridge, src_bridge);
2377 res = bridge_merge_locked(dst_bridge, src_bridge, merge_best_direction, kick_me, num_kick);
2378 ast_bridge_unlock(src_bridge);
2379 ast_bridge_unlock(dst_bridge);
2380 return res;
2381}
2382
2383int bridge_do_move(struct ast_bridge *dst_bridge, struct ast_bridge_channel *bridge_channel, int attempt_recovery,
2384 unsigned int optimized)
2385{
2386 struct ast_bridge *orig_bridge;
2387 int was_in_bridge;
2388 int res = 0;
2389
2390 if (bridge_channel->swap) {
2391 ast_debug(1, "Moving %p(%s) into bridge %s swapping with %s\n",
2392 bridge_channel, ast_channel_name(bridge_channel->chan), dst_bridge->uniqueid,
2393 ast_channel_name(bridge_channel->swap));
2394 } else {
2395 ast_debug(1, "Moving %p(%s) into bridge %s\n",
2396 bridge_channel, ast_channel_name(bridge_channel->chan), dst_bridge->uniqueid);
2397 }
2398
2399 orig_bridge = bridge_channel->bridge;
2400 was_in_bridge = bridge_channel->in_bridge;
2401
2402 bridge_channel_internal_pull(bridge_channel);
2403 if (bridge_channel->state != BRIDGE_CHANNEL_STATE_WAIT) {
2404 /*
2405 * The channel died as a result of being pulled. Leave it
2406 * pointing to the original bridge.
2407 *
2408 * Clear out the swap channel pointer. A ref is not held
2409 * by bridge_channel->swap at this point.
2410 */
2411 bridge_channel->swap = NULL;
2412 bridge_reconfigured(orig_bridge, 0);
2413 return -1;
2414 }
2415
2416 /* Point to new bridge.*/
2417 ao2_ref(orig_bridge, +1);/* Keep a ref in case the push fails. */
2418 bridge_channel_change_bridge(bridge_channel, dst_bridge);
2419
2420 bridge_channel_moving(bridge_channel, orig_bridge, dst_bridge);
2421
2422 if (bridge_channel_internal_push_full(bridge_channel, optimized)) {
2423 /* Try to put the channel back into the original bridge. */
2424 ast_bridge_features_remove(bridge_channel->features,
2426 if (attempt_recovery && was_in_bridge) {
2427 /* Point back to original bridge. */
2428 bridge_channel_change_bridge(bridge_channel, orig_bridge);
2429
2430 if (bridge_channel_internal_push(bridge_channel)) {
2431 ast_bridge_features_remove(bridge_channel->features,
2433 ast_bridge_channel_leave_bridge(bridge_channel,
2435 }
2436 } else {
2437 ast_bridge_channel_leave_bridge(bridge_channel,
2439 bridge_channel_settle_owed_events(orig_bridge, bridge_channel);
2440 }
2441 res = -1;
2442 } else if (!optimized) {
2443 bridge_channel_settle_owed_events(orig_bridge, bridge_channel);
2444 }
2445
2446 bridge_reconfigured(dst_bridge, !optimized);
2447 bridge_reconfigured(orig_bridge, !optimized);
2448 ao2_ref(orig_bridge, -1);
2449 return res;
2450}
2451
2452/*!
2453 * \internal
2454 * \brief Move a channel from one bridge to another.
2455 * \since 12.0.0
2456 *
2457 * \param dst_bridge Destination bridge of bridge channel move.
2458 * \param src_bridge Source bridge of bridge channel move.
2459 * \param chan Channel to move.
2460 * \param swap Channel to replace in dst_bridge.
2461 * \param attempt_recovery TRUE if failure attempts to push channel back into original bridge.
2462 *
2463 * \note The dst_bridge and src_bridge are assumed already locked.
2464 *
2465 * \retval 0 on success.
2466 * \retval -1 on failure.
2467 */
2468static int bridge_move_locked(struct ast_bridge *dst_bridge, struct ast_bridge *src_bridge, struct ast_channel *chan, struct ast_channel *swap, int attempt_recovery)
2469{
2470 struct ast_bridge_channel *bridge_channel;
2471
2472 if (dst_bridge->dissolved || src_bridge->dissolved) {
2473 ast_debug(1, "Can't move channel %s from bridge %s into bridge %s, at least one bridge is dissolved.\n",
2474 ast_channel_name(chan), src_bridge->uniqueid, dst_bridge->uniqueid);
2475 return -1;
2476 }
2479 ast_debug(1, "Can't move channel %s from bridge %s into bridge %s, masquerade only.\n",
2480 ast_channel_name(chan), src_bridge->uniqueid, dst_bridge->uniqueid);
2481 return -1;
2482 }
2483 if (dst_bridge->inhibit_merge || src_bridge->inhibit_merge) {
2484 ast_debug(1, "Can't move channel %s from bridge %s into bridge %s, temporarily inhibited.\n",
2485 ast_channel_name(chan), src_bridge->uniqueid, dst_bridge->uniqueid);
2486 return -1;
2487 }
2488
2489 bridge_channel = bridge_find_channel(src_bridge, chan);
2490 if (!bridge_channel) {
2491 ast_debug(1, "Can't move channel %s from bridge %s into bridge %s, channel not in bridge.\n",
2492 ast_channel_name(chan), src_bridge->uniqueid, dst_bridge->uniqueid);
2493 return -1;
2494 }
2495 if (bridge_channel->state != BRIDGE_CHANNEL_STATE_WAIT) {
2496 ast_debug(1, "Can't move channel %s from bridge %s into bridge %s, channel leaving bridge.\n",
2497 ast_channel_name(chan), src_bridge->uniqueid, dst_bridge->uniqueid);
2498 return -1;
2499 }
2500 if (ast_test_flag(&bridge_channel->features->feature_flags,
2502 ast_debug(1, "Can't move channel %s from bridge %s into bridge %s, channel immovable.\n",
2503 ast_channel_name(chan), src_bridge->uniqueid, dst_bridge->uniqueid);
2504 return -1;
2505 }
2506
2507 if (swap) {
2508 struct ast_bridge_channel *bridge_channel_swap;
2509
2510 bridge_channel_swap = bridge_find_channel(dst_bridge, swap);
2511 if (!bridge_channel_swap) {
2512 ast_debug(1, "Can't move channel %s from bridge %s into bridge %s, swap channel %s not in bridge.\n",
2513 ast_channel_name(chan), src_bridge->uniqueid, dst_bridge->uniqueid,
2515 return -1;
2516 }
2517 if (bridge_channel_swap->state != BRIDGE_CHANNEL_STATE_WAIT) {
2518 ast_debug(1, "Can't move channel %s from bridge %s into bridge %s, swap channel %s leaving bridge.\n",
2519 ast_channel_name(chan), src_bridge->uniqueid, dst_bridge->uniqueid,
2521 return -1;
2522 }
2523 }
2524
2525 bridge_channel->swap = swap;
2526 return bridge_do_move(dst_bridge, bridge_channel, attempt_recovery, 0);
2527}
2528
2529int ast_bridge_move(struct ast_bridge *dst_bridge, struct ast_bridge *src_bridge, struct ast_channel *chan, struct ast_channel *swap, int attempt_recovery)
2530{
2531 int res;
2532
2533 ast_bridge_lock_both(dst_bridge, src_bridge);
2534 res = bridge_move_locked(dst_bridge, src_bridge, chan, swap, attempt_recovery);
2535 ast_bridge_unlock(src_bridge);
2536 ast_bridge_unlock(dst_bridge);
2537 return res;
2538}
2539
2541 struct ast_bridge_features *features, int play_tone, const char *xfersound)
2542{
2543 RAII_VAR(struct ast_bridge *, chan_bridge, NULL, ao2_cleanup);
2544 RAII_VAR(struct ast_channel *, yanked_chan, NULL, ao2_cleanup);
2545
2547
2549 chan_bridge = ast_channel_get_bridge(chan);
2551
2552 if (chan_bridge) {
2553 struct ast_bridge_channel *bridge_channel;
2554
2555 /* The channel is in a bridge so it is not getting any new features. */
2557
2558 ast_bridge_lock_both(bridge, chan_bridge);
2559 bridge_channel = bridge_find_channel(chan_bridge, chan);
2560
2561 if (bridge_move_locked(bridge, chan_bridge, chan, NULL, 1)) {
2562 ast_bridge_unlock(chan_bridge);
2564 return -1;
2565 }
2566
2567 /*
2568 * bridge_move_locked() will implicitly ensure that
2569 * bridge_channel is not NULL.
2570 */
2571 ast_assert(bridge_channel != NULL);
2572
2573 /*
2574 * Additional checks if the channel we just stole dissolves the
2575 * original bridge.
2576 */
2577 bridge_dissolve_check_stolen(chan_bridge, bridge_channel);
2578 ast_bridge_unlock(chan_bridge);
2580 } else {
2581 /* Slightly less easy case. We need to yank channel A from
2582 * where he currently is and impart him into our bridge.
2583 */
2584 yanked_chan = ast_channel_yank(chan);
2585 if (!yanked_chan) {
2586 ast_log(LOG_WARNING, "Could not gain control of channel %s\n", ast_channel_name(chan));
2588 return -1;
2589 }
2590 if (ast_channel_state(yanked_chan) != AST_STATE_UP) {
2591 ast_answer(yanked_chan);
2592 }
2593 ast_channel_ref(yanked_chan);
2594 if (ast_bridge_impart(bridge, yanked_chan, NULL, features,
2596 /* It is possible for us to yank a channel and have some other
2597 * thread start a PBX on the channel after we yanked it. In particular,
2598 * this can theoretically happen on the ;2 of a Local channel if we
2599 * yank it prior to the ;1 being answered. Make sure that it isn't
2600 * executing a PBX before hanging it up.
2601 */
2602 if (ast_channel_pbx(yanked_chan)) {
2603 ast_channel_unref(yanked_chan);
2604 } else {
2605 ast_hangup(yanked_chan);
2606 }
2607 return -1;
2608 }
2609 }
2610
2611 if (play_tone && !ast_strlen_zero(xfersound)) {
2612 struct ast_channel *play_chan = yanked_chan ?: chan;
2613 RAII_VAR(struct ast_bridge_channel *, play_bridge_channel, NULL, ao2_cleanup);
2614
2615 ast_channel_lock(play_chan);
2616 play_bridge_channel = ast_channel_get_bridge_channel(play_chan);
2617 ast_channel_unlock(play_chan);
2618
2619 if (!play_bridge_channel) {
2620 ast_log(LOG_WARNING, "Unable to play tone for channel %s. No longer in a bridge.\n",
2621 ast_channel_name(play_chan));
2622 } else {
2623 ast_bridge_channel_queue_playfile(play_bridge_channel, NULL, xfersound, NULL);
2624 }
2625 }
2626 return 0;
2627}
2628
2630{
2631 return !(bridge->inhibit_merge
2632 || bridge->dissolved
2634}
2635
2636/*!
2637 * \internal
2638 * \brief Lock the unreal channel stack for chan and prequalify it.
2639 * \since 12.0.0
2640 *
2641 * \param chan Unreal channel writing a frame into the channel driver.
2642 *
2643 * \note It is assumed that chan is already locked.
2644 *
2645 * \return bridge on success with bridge and bridge_channel locked.
2646 * \retval NULL if cannot do optimization now.
2647 */
2649{
2650 struct ast_bridge *bridge;
2651 struct ast_bridge_channel *bridge_channel;
2652
2654 return NULL;
2655 }
2657 return NULL;
2658 }
2660 /* Channel has an active monitor, audiohook, or framehook. */
2661 return NULL;
2662 }
2663 bridge_channel = ast_channel_internal_bridge_channel(chan);
2664 if (!bridge_channel || ast_bridge_channel_trylock(bridge_channel)) {
2665 return NULL;
2666 }
2667 bridge = bridge_channel->bridge;
2668 if (bridge_channel->activity != BRIDGE_CHANNEL_THREAD_SIMPLE
2669 || bridge_channel->state != BRIDGE_CHANNEL_STATE_WAIT
2671 ast_bridge_channel_unlock(bridge_channel);
2672 return NULL;
2673 }
2674 if (!bridge_channel_internal_allows_optimization(bridge_channel) ||
2677 ast_bridge_channel_unlock(bridge_channel);
2678 return NULL;
2679 }
2680 return bridge;
2681}
2682
2683/*!
2684 * \internal
2685 * \brief Lock the unreal channel stack for peer and prequalify it.
2686 * \since 12.0.0
2687 *
2688 * \param peer Other unreal channel in the pair.
2689 *
2690 * \return bridge on success with bridge, bridge_channel, and peer locked.
2691 * \retval NULL if cannot do optimization now.
2692 */
2694{
2695 struct ast_bridge *bridge;
2696 struct ast_bridge_channel *bridge_channel;
2697
2698 if (ast_channel_trylock(peer)) {
2699 return NULL;
2700 }
2701 if (!AST_LIST_EMPTY(ast_channel_readq(peer))) {
2702 ast_channel_unlock(peer);
2703 return NULL;
2704 }
2706 ast_channel_unlock(peer);
2707 return NULL;
2708 }
2710 /* Peer has an active monitor, audiohook, or framehook. */
2711 ast_channel_unlock(peer);
2712 return NULL;
2713 }
2714 bridge_channel = ast_channel_internal_bridge_channel(peer);
2715 if (!bridge_channel || ast_bridge_channel_trylock(bridge_channel)) {
2716 ast_channel_unlock(peer);
2717 return NULL;
2718 }
2719 bridge = bridge_channel->bridge;
2720 if (bridge_channel->activity != BRIDGE_CHANNEL_THREAD_IDLE
2721 || bridge_channel->state != BRIDGE_CHANNEL_STATE_WAIT
2723 ast_bridge_channel_unlock(bridge_channel);
2724 ast_channel_unlock(peer);
2725 return NULL;
2726 }
2730 ast_bridge_channel_unlock(bridge_channel);
2731 ast_channel_unlock(peer);
2732 return NULL;
2733 }
2734 return bridge;
2735}
2736
2737/*!
2738 * \internal
2739 * \brief Indicates allowability of a swap optimization
2740 */
2742 /*! Bridges cannot allow for a swap optimization to occur */
2744 /*! Bridge swap optimization can occur into the chan_bridge */
2746 /*! Bridge swap optimization can occur into the peer_bridge */
2748};
2749
2750/*!
2751 * \internal
2752 * \brief Determine if two bridges allow for swap optimization to occur
2753 *
2754 * \param chan_bridge First bridge being tested
2755 * \param peer_bridge Second bridge being tested
2756 * \return Allowability of swap optimization
2757 */
2759 struct ast_bridge *peer_bridge)
2760{
2761 int chan_priority;
2762 int peer_priority;
2763
2764 if (!ast_test_flag(&chan_bridge->feature_flags,
2767 && !ast_test_flag(&peer_bridge->feature_flags,
2770 /*
2771 * Can swap either way. Swap to the higher priority merge
2772 * bridge.
2773 */
2774 chan_priority = chan_bridge->v_table->get_merge_priority(chan_bridge);
2775 peer_priority = peer_bridge->v_table->get_merge_priority(peer_bridge);
2776 if (chan_bridge->num_channels == 2
2777 && chan_priority <= peer_priority) {
2778 return SWAP_TO_PEER_BRIDGE;
2779 } else if (peer_bridge->num_channels == 2
2780 && peer_priority <= chan_priority) {
2781 return SWAP_TO_CHAN_BRIDGE;
2782 }
2783 } else if (chan_bridge->num_channels == 2
2786 /* Can swap optimize only one way. */
2787 return SWAP_TO_PEER_BRIDGE;
2788 } else if (peer_bridge->num_channels == 2
2791 /* Can swap optimize only one way. */
2792 return SWAP_TO_CHAN_BRIDGE;
2793 }
2794
2795 return SWAP_PROHIBITED;
2796}
2797
2798/*!
2799 * \internal
2800 * \brief Check and attempt to swap optimize out the unreal channels.
2801 * \since 12.0.0
2802 *
2803 * \param chan_bridge
2804 * \param chan_bridge_channel
2805 * \param peer_bridge
2806 * \param peer_bridge_channel
2807 * \param pvt Unreal data containing callbacks to call if the optimization actually
2808 * happens
2809 *
2810 * \retval 1 if unreal channels failed to optimize out.
2811 * \retval 0 if unreal channels were not optimized out.
2812 * \retval -1 if unreal channels were optimized out.
2813 */
2814static int try_swap_optimize_out(struct ast_bridge *chan_bridge,
2815 struct ast_bridge_channel *chan_bridge_channel, struct ast_bridge *peer_bridge,
2816 struct ast_bridge_channel *peer_bridge_channel,
2817 struct ast_unreal_pvt *pvt)
2818{
2819 struct ast_bridge *dst_bridge;
2820 struct ast_bridge_channel *dst_bridge_channel;
2821 struct ast_bridge_channel *src_bridge_channel;
2822 struct ast_bridge_channel *other;
2823 int res = 1;
2824
2825 switch (bridges_allow_swap_optimization(chan_bridge, peer_bridge)) {
2827 dst_bridge = chan_bridge;
2828 dst_bridge_channel = chan_bridge_channel;
2829 src_bridge_channel = peer_bridge_channel;
2830 break;
2832 dst_bridge = peer_bridge;
2833 dst_bridge_channel = peer_bridge_channel;
2834 src_bridge_channel = chan_bridge_channel;
2835 break;
2836 case SWAP_PROHIBITED:
2837 default:
2838 return 0;
2839 }
2840
2841 other = ast_bridge_channel_peer(src_bridge_channel);
2842 if (other && other->state == BRIDGE_CHANNEL_STATE_WAIT) {
2843 unsigned int id;
2844
2845 if (ast_channel_trylock(other->chan)) {
2846 return 1;
2847 }
2848
2849 id = ast_atomic_fetchadd_int((int *) &optimization_id, +1);
2850
2851 ast_verb(4, "Move-swap optimizing %s <-- %s.\n",
2852 ast_channel_name(dst_bridge_channel->chan),
2853 ast_channel_name(other->chan));
2854
2855 if (pvt && !ast_test_flag(pvt, AST_UNREAL_OPTIMIZE_BEGUN) && pvt->callbacks
2857 pvt->callbacks->optimization_started(pvt, other->chan,
2858 dst_bridge_channel->chan == pvt->owner ? AST_UNREAL_OWNER : AST_UNREAL_CHAN,
2859 id);
2861 }
2862 other->swap = dst_bridge_channel->chan;
2863 if (!bridge_do_move(dst_bridge, other, 1, 1)) {
2864 ast_bridge_channel_leave_bridge(src_bridge_channel,
2866 res = -1;
2867 }
2868 if (pvt && pvt->callbacks && pvt->callbacks->optimization_finished) {
2869 pvt->callbacks->optimization_finished(pvt, res == 1, id);
2870 }
2871 ast_channel_unlock(other->chan);
2872 }
2873 return res;
2874}
2875
2876/*!
2877 * \internal
2878 * \brief Indicates allowability of a merge optimization
2879 */
2881 /*! Bridge properties prohibit merge optimization */
2883 /*! Merge optimization cannot occur because the source bridge has too few channels */
2885 /*! Merge optimization cannot occur because multimix capability could not be requested */
2887 /*! Merge optimization allowed between bridges */
2889};
2890
2891/*!
2892 * \internal
2893 * \brief Determines allowability of a merge optimization
2894 *
2895 * \note The merge output parameter is undefined if MERGE_PROHIBITED is returned. For success
2896 * and other failure returns, a merge direction was determined, and the parameter is safe to
2897 * access.
2898 *
2899 * \param chan_bridge First bridge being tested
2900 * \param peer_bridge Second bridge being tested
2901 * \param num_kick_channels The number of channels to remove from the bridges during merging
2902 * \param[out] merge Indicates the recommended direction for the bridge merge
2903 */
2905 struct ast_bridge *peer_bridge, int num_kick_channels, struct merge_direction *merge)
2906{
2907 *merge = bridge_merge_determine_direction(chan_bridge, peer_bridge);
2908 if (!merge->dest) {
2909 return MERGE_PROHIBITED;
2910 }
2911 if (merge->src->num_channels < 2) {
2913 } else if ((2 + num_kick_channels) < merge->dest->num_channels + merge->src->num_channels
2917 return MERGE_NO_MULTIMIX;
2918 }
2919
2920 return MERGE_ALLOWED;
2921}
2922
2923/*!
2924 * \internal
2925 * \brief Check and attempt to merge optimize out the unreal channels.
2926 * \since 12.0.0
2927 *
2928 * \param chan_bridge
2929 * \param chan_bridge_channel
2930 * \param peer_bridge
2931 * \param peer_bridge_channel
2932 * \param pvt Unreal data containing callbacks to call if the optimization actually
2933 * happens
2934 *
2935 * \retval 0 if unreal channels were not optimized out.
2936 * \retval -1 if unreal channels were optimized out.
2937 */
2938static int try_merge_optimize_out(struct ast_bridge *chan_bridge,
2939 struct ast_bridge_channel *chan_bridge_channel, struct ast_bridge *peer_bridge,
2940 struct ast_bridge_channel *peer_bridge_channel,
2941 struct ast_unreal_pvt *pvt)
2942{
2943 struct merge_direction merge;
2944 struct ast_bridge_channel *kick_me[] = {
2945 chan_bridge_channel,
2946 peer_bridge_channel,
2947 };
2948 unsigned int id;
2949
2950 switch (bridges_allow_merge_optimization(chan_bridge, peer_bridge, ARRAY_LEN(kick_me), &merge)) {
2951 case MERGE_ALLOWED:
2952 break;
2953 case MERGE_PROHIBITED:
2954 return 0;
2956 ast_debug(4, "Can't optimize %s -- %s out, not enough channels in bridge %s.\n",
2957 ast_channel_name(chan_bridge_channel->chan),
2958 ast_channel_name(peer_bridge_channel->chan),
2959 merge.src->uniqueid);
2960 return 0;
2961 case MERGE_NO_MULTIMIX:
2962 ast_debug(4, "Can't optimize %s -- %s out, multimix is needed and it cannot be acquired.\n",
2963 ast_channel_name(chan_bridge_channel->chan),
2964 ast_channel_name(peer_bridge_channel->chan));
2965 return 0;
2966 }
2967
2968 ast_verb(4, "Merge optimizing %s -- %s out.\n",
2969 ast_channel_name(chan_bridge_channel->chan),
2970 ast_channel_name(peer_bridge_channel->chan));
2971
2972 id = ast_atomic_fetchadd_int((int *) &optimization_id, +1);
2973
2974 if (pvt && !ast_test_flag(pvt, AST_UNREAL_OPTIMIZE_BEGUN) && pvt->callbacks
2978 id);
2980 }
2981 bridge_do_merge(merge.dest, merge.src, kick_me, ARRAY_LEN(kick_me), 1);
2982 if (pvt && pvt->callbacks && pvt->callbacks->optimization_finished) {
2983 pvt->callbacks->optimization_finished(pvt, 1, id);
2984 }
2985
2986 return -1;
2987}
2988
2990{
2991 struct ast_bridge *chan_bridge;
2992 struct ast_bridge *peer_bridge;
2993 struct ast_bridge_channel *chan_bridge_channel;
2994 struct ast_bridge_channel *peer_bridge_channel;
2995 int res = 0;
2996
2997 chan_bridge = optimize_lock_chan_stack(chan);
2998 if (!chan_bridge) {
2999 return res;
3000 }
3001 chan_bridge_channel = ast_channel_internal_bridge_channel(chan);
3002
3003 peer_bridge = optimize_lock_peer_stack(peer);
3004 if (peer_bridge) {
3005 peer_bridge_channel = ast_channel_internal_bridge_channel(peer);
3006
3007 res = try_swap_optimize_out(chan_bridge, chan_bridge_channel,
3008 peer_bridge, peer_bridge_channel, pvt);
3009 if (!res) {
3010 res = try_merge_optimize_out(chan_bridge, chan_bridge_channel,
3011 peer_bridge, peer_bridge_channel, pvt);
3012 } else if (0 < res) {
3013 res = 0;
3014 }
3015
3016 /* Release peer locks. */
3017 ast_bridge_unlock(peer_bridge);
3018 ast_bridge_channel_unlock(peer_bridge_channel);
3019 ast_channel_unlock(peer);
3020 }
3021
3022 /* Release chan locks. */
3023 ast_bridge_unlock(chan_bridge);
3024 ast_bridge_channel_unlock(chan_bridge_channel);
3025
3026 return res;
3027}
3028
3030 struct ast_bridge *peer_bridge)
3031{
3032 struct merge_direction merge;
3033
3034 if (!bridge_allows_optimization(chan_bridge) || !bridge_allows_optimization(peer_bridge)) {
3036 }
3037
3038 switch (bridges_allow_swap_optimization(chan_bridge, peer_bridge)) {
3043 case SWAP_PROHIBITED:
3044 default:
3045 break;
3046 }
3047
3048 /* Two channels will be kicked from the bridges, the unreal;1 and unreal;2 channels */
3049 if (bridges_allow_merge_optimization(chan_bridge, peer_bridge, 2, &merge) != MERGE_ALLOWED) {
3051 }
3052
3053 if (merge.dest == chan_bridge) {
3055 } else {
3057 }
3058}
3059
3061{
3062 int new_request;
3063
3064 new_request = bridge->inhibit_merge + request;
3065 ast_assert(0 <= new_request);
3066 bridge->inhibit_merge = new_request;
3067}
3068
3070{
3071 ast_bridge_lock(bridge);
3073 ast_bridge_unlock(bridge);
3074}
3075
3076int ast_bridge_suspend(struct ast_bridge *bridge, struct ast_channel *chan)
3077{
3078 struct ast_bridge_channel *bridge_channel;
3079/* XXX ASTERISK-21271 the case of a dissolved bridge while channel is suspended is not handled. */
3080/* XXX ASTERISK-21271 suspend/unsuspend needs to be rethought. The caller must block until it has successfully suspended the channel for temporary control. */
3081/* XXX ASTERISK-21271 external suspend/unsuspend needs to be eliminated. The channel may be playing a file at the time and stealing it then is not good. */
3082
3084
3085 if (!(bridge_channel = bridge_find_channel(bridge, chan))) {
3087 return -1;
3088 }
3089
3091
3093
3094 return 0;
3095}
3096
3098{
3099 struct ast_bridge_channel *bridge_channel;
3100/* XXX ASTERISK-21271 the case of a dissolved bridge while channel is suspended is not handled. */
3101
3103
3104 if (!(bridge_channel = bridge_find_channel(bridge, chan))) {
3106 return -1;
3107 }
3108
3110
3112
3113 return 0;
3114}
3115
3117{
3118 technology->suspended = 1;
3119}
3120
3122{
3123 /*
3124 * XXX We may want the act of unsuspending a bridge technology
3125 * to prod all existing bridges to see if they should start
3126 * using it.
3127 */
3128 technology->suspended = 0;
3129}
3130
3132{
3133 if (ARRAY_LEN(builtin_features_handlers) <= feature
3134 || builtin_features_handlers[feature]) {
3135 return -1;
3136 }
3137
3138 if (!ast_strlen_zero(dtmf)) {
3139 ast_copy_string(builtin_features_dtmf[feature], dtmf, sizeof(builtin_features_dtmf[feature]));
3140 }
3141
3142 builtin_features_handlers[feature] = callback;
3143
3144 return 0;
3145}
3146
3148{
3149 if (ARRAY_LEN(builtin_features_handlers) <= feature
3150 || !builtin_features_handlers[feature]) {
3151 return -1;
3152 }
3153
3155
3156 return 0;
3157}
3158
3159int ast_bridge_features_do(enum ast_bridge_builtin_feature feature, struct ast_bridge_channel *bridge_channel, void *hook_pvt)
3160{
3161 ast_bridge_hook_callback callback;
3162
3163 if (ARRAY_LEN(builtin_features_handlers) <= feature) {
3164 return -1;
3165 }
3166
3167 callback = builtin_features_handlers[feature];
3168 if (!callback) {
3169 return -1;
3170 }
3171 callback(bridge_channel, hook_pvt);
3172
3173 return 0;
3174}
3175
3177{
3178 if (ARRAY_LEN(builtin_interval_handlers) <= interval
3179 || builtin_interval_handlers[interval]) {
3180 return -1;
3181 }
3182
3183 builtin_interval_handlers[interval] = callback;
3184
3185 return 0;
3186}
3187
3189{
3190 if (ARRAY_LEN(builtin_interval_handlers) <= interval
3191 || !builtin_interval_handlers[interval]) {
3192 return -1;
3193 }
3194
3195 builtin_interval_handlers[interval] = NULL;
3196
3197 return 0;
3198
3199}
3200
3201/*!
3202 * \internal
3203 * \brief Bridge hook destructor.
3204 * \since 12.0.0
3205 *
3206 * \param vhook Object to destroy.
3207 */
3208static void bridge_hook_destroy(void *vhook)
3209{
3210 struct ast_bridge_hook *hook = vhook;
3211
3212 if (hook->destructor) {
3213 hook->destructor(hook->hook_pvt);
3214 }
3215}
3216
3217/*!
3218 * \internal
3219 * \brief Allocate and setup a generic bridge hook.
3220 * \since 12.0.0
3221 *
3222 * \param size How big an object to allocate.
3223 * \param callback Function to execute upon activation
3224 * \param hook_pvt Unique data
3225 * \param destructor Optional destructor callback for hook_pvt data
3226 * \param remove_flags Dictates what situations the hook should be removed.
3227 *
3228 * \return hook on success.
3229 * \retval NULL on error.
3230 */
3231static struct ast_bridge_hook *bridge_hook_generic(size_t size,
3233 void *hook_pvt,
3236{
3237 struct ast_bridge_hook *hook;
3238
3239 /* Allocate new hook and setup it's basic variables */
3241 if (hook) {
3242 hook->callback = callback;
3243 hook->destructor = destructor;
3244 hook->hook_pvt = hook_pvt;
3246 }
3247
3248 return hook;
3249}
3250
3252 const char *dtmf,
3254 void *hook_pvt,
3257{
3258 struct ast_bridge_hook_dtmf *hook;
3259 int res;
3260
3261 /* Allocate new hook and setup it's various variables */
3262 hook = (struct ast_bridge_hook_dtmf *) bridge_hook_generic(sizeof(*hook), callback,
3263 hook_pvt, destructor, remove_flags);
3264 if (!hook) {
3265 return -1;
3266 }
3268 ast_copy_string(hook->dtmf.code, dtmf, sizeof(hook->dtmf.code));
3269
3270 /* Once done we put it in the container. */
3271 res = ao2_link(features->dtmf_hooks, hook) ? 0 : -1;
3272 if (res) {
3273 /*
3274 * Could not link the hook into the container.
3275 *
3276 * Remove the hook_pvt destructor call from the hook since we
3277 * are returning failure to install the hook.
3278 */
3279 hook->generic.destructor = NULL;
3280 }
3281 ao2_ref(hook, -1);
3282
3283 return res;
3284}
3285
3286/*!
3287 * \internal
3288 * \brief Attach an other hook to a bridge features structure
3289 *
3290 * \param features Bridge features structure
3291 * \param callback Function to execute upon activation
3292 * \param hook_pvt Unique data
3293 * \param destructor Optional destructor callback for hook_pvt data
3294 * \param remove_flags Dictates what situations the hook should be removed.
3295 * \param type What type of hook is being attached.
3296 *
3297 * \retval 0 on success
3298 * \retval -1 on failure (The caller must cleanup any hook_pvt resources.)
3299 */
3300static int bridge_other_hook(struct ast_bridge_features *features,
3301 ast_bridge_hook_callback callback,
3302 void *hook_pvt,
3304 enum ast_bridge_hook_remove_flags remove_flags,
3306{
3307 struct ast_bridge_hook *hook;
3308 int res;
3309
3310 /* Allocate new hook and setup it's various variables */
3311 hook = bridge_hook_generic(sizeof(*hook), callback, hook_pvt, destructor,
3312 remove_flags);
3313 if (!hook) {
3314 return -1;
3315 }
3316 hook->type = type;
3317
3318 /* Once done we put it in the container. */
3319 res = ao2_link(features->other_hooks, hook) ? 0 : -1;
3320 if (res) {
3321 /*
3322 * Could not link the hook into the container.
3323 *
3324 * Remove the hook_pvt destructor call from the hook since we
3325 * are returning failure to install the hook.
3326 */
3327 hook->destructor = NULL;
3328 }
3329 ao2_ref(hook, -1);
3330
3331 return res;
3332}
3333
3336 void *hook_pvt,
3339{
3342}
3343
3346 void *hook_pvt,
3349{
3352}
3353
3356 void *hook_pvt,
3359{
3362}
3363
3366 void *hook_pvt,
3369{
3371
3374}
3375
3378 void *hook_pvt,
3381{
3383
3386}
3387
3390 unsigned int interval,
3392 void *hook_pvt,
3395{
3396 struct ast_bridge_hook_timer *hook;
3397 int res;
3398
3399 if (!features ||!interval || !callback) {
3400 return -1;
3401 }
3402
3403 /* Allocate new hook and setup it's various variables */
3404 hook = (struct ast_bridge_hook_timer *) bridge_hook_generic(sizeof(*hook), callback,
3405 hook_pvt, destructor, remove_flags);
3406 if (!hook) {
3407 return -1;
3408 }
3410 hook->timer.interval = interval;
3411 hook->timer.trip_time = ast_tvadd(ast_tvnow(), ast_samp2tv(interval, 1000));
3412 hook->timer.seqno = ast_atomic_fetchadd_int((int *) &features->interval_sequence, +1);
3413 hook->timer.flags = flags;
3414
3415 ast_debug(1, "Putting interval hook %p with interval %u in the heap on features %p\n",
3416 hook, hook->timer.interval, features);
3418 res = ast_heap_push(features->interval_hooks, hook);
3420 if (res) {
3421 /*
3422 * Could not push the hook into the heap
3423 *
3424 * Remove the hook_pvt destructor call from the hook since we
3425 * are returning failure to install the hook.
3426 */
3427 hook->generic.destructor = NULL;
3428 ao2_ref(hook, -1);
3429 }
3430
3431 return res ? -1 : 0;
3432}
3433
3435 enum ast_bridge_builtin_feature feature,
3436 const char *dtmf,
3437 void *config,
3439 enum ast_bridge_hook_remove_flags remove_flags)
3440{
3441 if (ARRAY_LEN(builtin_features_handlers) <= feature
3442 || !builtin_features_handlers[feature]) {
3443 return -1;
3444 }
3445
3446 /* If no alternate DTMF stream was provided use the default one */
3447 if (ast_strlen_zero(dtmf)) {
3448 dtmf = builtin_features_dtmf[feature];
3449 /* If no DTMF is still available (ie: it has been disabled) then error out now */
3450 if (ast_strlen_zero(dtmf)) {
3451 ast_debug(1, "Failed to enable built in feature %u on %p, no DTMF string is available for it.\n",
3452 feature, features);
3453 return -1;
3454 }
3455 }
3456
3457 /*
3458 * The rest is basically pretty easy. We create another hook
3459 * using the built in feature's DTMF callback. Easy as pie.
3460 */
3461 return ast_bridge_dtmf_hook(features, dtmf, builtin_features_handlers[feature],
3462 config, destructor, remove_flags);
3463}
3464
3466{
3467 memset(limits, 0, sizeof(*limits));
3468
3469 if (ast_string_field_init(limits, 256)) {
3470 return -1;
3471 }
3472
3473 return 0;
3474}
3475
3477{
3479}
3480
3483 enum ast_bridge_hook_remove_flags remove_flags)
3484{
3487
3489 return callback(features, limits, remove_flags);
3490 }
3491
3492 ast_log(LOG_ERROR, "Attempted to set limits without an AST_BRIDGE_BUILTIN_INTERVAL_LIMITS callback registered.\n");
3493 return -1;
3494}
3495
3496void ast_bridge_features_set_flag(struct ast_bridge_features *features, unsigned int flag)
3497{
3498 ast_set_flag(&features->feature_flags, flag);
3499 features->usable = 1;
3500}
3501
3502/*!
3503 * \internal
3504 * \brief ao2 object match hooks with appropriate remove_flags.
3505 * \since 12.0.0
3506 *
3507 * \param obj Feature hook object.
3508 * \param arg Removal flags
3509 * \param flags Not used
3510 *
3511 * \retval CMP_MATCH if hook's remove_flags match the removal flags set.
3512 * \retval 0 if not match.
3513 */
3514static int hook_remove_match(void *obj, void *arg, int flags)
3515{
3516 struct ast_bridge_hook *hook = obj;
3518
3519 if (ast_test_flag(&hook->remove_flags, *remove_flags)) {
3520 return CMP_MATCH;
3521 } else {
3522 return 0;
3523 }
3524}
3525
3526/*!
3527 * \internal
3528 * \brief Remove all hooks with appropriate remove_flags in the container.
3529 * \since 12.0.0
3530 *
3531 * \param hooks Hooks container to work on.
3532 * \param remove_flags Determinator for whether hook is removed
3533 */
3535{
3538}
3539
3540/*!
3541 * \internal
3542 * \brief Remove all hooks in the heap with appropriate remove_flags set.
3543 * \since 12.0.0
3544 *
3545 * \param hooks Hooks heap to work on.
3546 * \param remove_flags Determinator for whether hook is removed
3547 */
3549{
3550 struct ast_bridge_hook *hook;
3551 int changed;
3552
3553 ast_heap_wrlock(hooks);
3554 do {
3555 int idx;
3556
3557 changed = 0;
3558 for (idx = ast_heap_size(hooks); idx; --idx) {
3559 hook = ast_heap_peek(hooks, idx);
3561 ast_heap_remove(hooks, hook);
3562 ao2_ref(hook, -1);
3563 changed = 1;
3564 }
3565 }
3566 } while (changed);
3567 ast_heap_unlock(hooks);
3568}
3569
3571{
3575}
3576
3577static int interval_hook_time_cmp(void *a, void *b)
3578{
3579 struct ast_bridge_hook_timer *hook_a = a;
3580 struct ast_bridge_hook_timer *hook_b = b;
3581 int cmp;
3582
3583 cmp = ast_tvcmp(hook_b->timer.trip_time, hook_a->timer.trip_time);
3584 if (cmp) {
3585 return cmp;
3586 }
3587
3588 cmp = hook_b->timer.seqno - hook_a->timer.seqno;
3589 return cmp;
3590}
3591
3592/*!
3593 * \internal
3594 * \brief DTMF hook container sort comparison function.
3595 * \since 12.0.0
3596 *
3597 * \param obj_left pointer to the (user-defined part) of an object.
3598 * \param obj_right pointer to the (user-defined part) of an object.
3599 * \param flags flags from ao2_callback()
3600 * OBJ_POINTER - if set, 'obj_right', is an object.
3601 * OBJ_KEY - if set, 'obj_right', is a search key item that is not an object.
3602 * OBJ_PARTIAL_KEY - if set, 'obj_right', is a partial search key item that is not an object.
3603 *
3604 * \retval <0 if obj_left < obj_right
3605 * \retval =0 if obj_left == obj_right
3606 * \retval >0 if obj_left > obj_right
3607 */
3608static int bridge_dtmf_hook_sort(const void *obj_left, const void *obj_right, int flags)
3609{
3610 const struct ast_bridge_hook_dtmf *hook_left = obj_left;
3611 const struct ast_bridge_hook_dtmf *hook_right = obj_right;
3612 const char *right_key = obj_right;
3613 int cmp;
3614
3615 switch (flags & (OBJ_POINTER | OBJ_KEY | OBJ_PARTIAL_KEY)) {
3616 default:
3617 case OBJ_POINTER:
3618 right_key = hook_right->dtmf.code;
3619 /* Fall through */
3620 case OBJ_KEY:
3621 cmp = strcasecmp(hook_left->dtmf.code, right_key);
3622 break;
3623 case OBJ_PARTIAL_KEY:
3624 cmp = strncasecmp(hook_left->dtmf.code, right_key, strlen(right_key));
3625 break;
3626 }
3627 return cmp;
3628}
3629
3630/*! \brief Callback for merging hook ao2_containers */
3631static int merge_container_cb(void *obj, void *data, int flags)
3632{
3633 ao2_link(data, obj);
3634 return 0;
3635}
3636
3637/*! \brief Wrapper for interval hooks that calls into the wrapped hook */
3638static int interval_wrapper_cb(struct ast_bridge_channel *bridge_channel, void *obj)
3639{
3640 struct ast_bridge_hook_timer *hook = obj;
3641
3642 return hook->generic.callback(bridge_channel, hook->generic.hook_pvt);
3643}
3644
3645/*! \brief Destructor for the hook wrapper */
3646static void interval_wrapper_pvt_dtor(void *obj)
3647{
3648 ao2_cleanup(obj);
3649}
3650
3651/*! \brief Wrap the provided interval hook and add it to features */
3652static void wrap_hook(struct ast_bridge_features *features, struct ast_bridge_hook_timer *hook)
3653{
3654 /* Break out of the current wrapper if it exists to avoid multiple layers */
3655 if (hook->generic.callback == interval_wrapper_cb) {
3656 hook = hook->generic.hook_pvt;
3657 }
3658
3659 ast_bridge_interval_hook(features, hook->timer.flags, hook->timer.interval,
3661 hook->generic.remove_flags.flags);
3662}
3663
3665{
3666 struct ast_bridge_hook_timer *hook;
3667 int idx;
3668
3669 /* Merge hook containers */
3672
3673 /* Merge hook heaps */
3675 for (idx = 1; (hook = ast_heap_peek(from->interval_hooks, idx)); idx++) {
3676 wrap_hook(into, hook);
3677 }
3679
3680 /* Merge feature flags */
3681 into->feature_flags.flags |= from->feature_flags.flags;
3682 into->usable |= from->usable;
3683
3684 into->mute |= from->mute;
3685 into->dtmf_passthrough |= from->dtmf_passthrough;
3686}
3687
3688/* XXX ASTERISK-21271 make ast_bridge_features_init() static when make ast_bridge_join() requires features to be allocated. */
3690{
3691 /* Zero out the structure */
3692 memset(features, 0, sizeof(*features));
3693
3694 /* Initialize the DTMF hooks container */
3697 if (!features->dtmf_hooks) {
3698 return -1;
3699 }
3700
3701 /* Initialize the miscellaneous other hooks container */
3703 NULL);
3704 if (!features->other_hooks) {
3705 return -1;
3706 }
3707
3708 /* Initialize the interval hooks heap */
3710 offsetof(struct ast_bridge_hook_timer, timer.heap_index));
3711 if (!features->interval_hooks) {
3712 return -1;
3713 }
3714
3715 features->dtmf_passthrough = 1;
3716 features->text_messaging = 1;
3717
3718 return 0;
3719}
3720
3721/* XXX ASTERISK-21271 make ast_bridge_features_cleanup() static when make ast_bridge_join() requires features to be allocated. */
3723{
3724 struct ast_bridge_hook_timer *hook;
3725
3726 /* Destroy the interval hooks heap. */
3727 if (features->interval_hooks) {
3728 while ((hook = ast_heap_pop(features->interval_hooks))) {
3729 ao2_ref(hook, -1);
3730 }
3731 features->interval_hooks = ast_heap_destroy(features->interval_hooks);
3732 }
3733
3734 /* Destroy the miscellaneous other hooks container. */
3735 ao2_cleanup(features->other_hooks);
3736 features->other_hooks = NULL;
3737
3738 /* Destroy the DTMF hooks container. */
3739 ao2_cleanup(features->dtmf_hooks);
3740 features->dtmf_hooks = NULL;
3741}
3742
3744{
3745 if (!features) {
3746 return;
3747 }
3749 ast_free(features);
3750}
3751
3753{
3754 struct ast_bridge_features *features;
3755
3756 features = ast_malloc(sizeof(*features));
3757 if (features) {
3758 if (ast_bridge_features_init(features)) {
3760 features = NULL;
3761 }
3762 }
3763
3764 return features;
3765}
3766
3767void ast_bridge_set_mixing_interval(struct ast_bridge *bridge, unsigned int mixing_interval)
3768{
3769 ast_bridge_lock(bridge);
3770 bridge->softmix.internal_mixing_interval = mixing_interval;
3771 ast_bridge_unlock(bridge);
3772}
3773
3774void ast_bridge_set_binaural_active(struct ast_bridge *bridge, unsigned int binaural_active)
3775{
3776 ast_bridge_lock(bridge);
3777 bridge->softmix.binaural_active = binaural_active;
3778 ast_bridge_unlock(bridge);
3779}
3780
3781void ast_bridge_set_internal_sample_rate(struct ast_bridge *bridge, unsigned int sample_rate)
3782{
3783 ast_bridge_lock(bridge);
3784 bridge->softmix.internal_sample_rate = sample_rate;
3785 ast_bridge_unlock(bridge);
3786}
3787
3788void ast_bridge_set_maximum_sample_rate(struct ast_bridge *bridge, unsigned int sample_rate)
3789{
3790 ast_bridge_lock(bridge);
3791 bridge->softmix.maximum_sample_rate = sample_rate;
3792 ast_bridge_unlock(bridge);
3793}
3794
3795static void cleanup_video_mode(struct ast_bridge *bridge)
3796{
3797 switch (bridge->softmix.video_mode.mode) {
3799 break;
3803 }
3804 break;
3808 }
3811 }
3813 break;
3814 }
3815 memset(&bridge->softmix.video_mode, 0, sizeof(bridge->softmix.video_mode));
3816}
3817
3818void ast_bridge_set_single_src_video_mode(struct ast_bridge *bridge, struct ast_channel *video_src_chan)
3819{
3820 ast_bridge_lock(bridge);
3821 cleanup_video_mode(bridge);
3823 if (video_src_chan) {
3825 ast_verb(5, "Video source in bridge '%s' (%s) is now '%s' (%s)\n",
3826 bridge->name, bridge->uniqueid,
3827 ast_channel_name(video_src_chan),
3828 ast_channel_uniqueid(video_src_chan));
3829 ast_indicate(video_src_chan, AST_CONTROL_VIDUPDATE);
3830 }
3832 ast_bridge_unlock(bridge);
3833}
3834
3836{
3837 ast_bridge_lock(bridge);
3838 cleanup_video_mode(bridge);
3840 ast_bridge_unlock(bridge);
3841}
3842
3844{
3845 ast_bridge_lock(bridge);
3846 cleanup_video_mode(bridge);
3848 ast_bridge_unlock(bridge);
3849}
3850
3851void ast_bridge_set_video_update_discard(struct ast_bridge *bridge, unsigned int video_update_discard)
3852{
3853 ast_bridge_lock(bridge);
3854 bridge->softmix.video_mode.video_update_discard = video_update_discard;
3855 ast_bridge_unlock(bridge);
3856}
3857
3858void ast_bridge_set_remb_send_interval(struct ast_bridge *bridge, unsigned int remb_send_interval)
3859{
3861
3862 ast_bridge_lock(bridge);
3863 bridge->softmix.video_mode.mode_data.sfu_data.remb_send_interval = remb_send_interval;
3864 ast_bridge_unlock(bridge);
3865}
3866
3868{
3870
3871 ast_bridge_lock(bridge);
3873 ast_bridge_unlock(bridge);
3874}
3875
3876void ast_bridge_set_remb_estimated_bitrate(struct ast_bridge *bridge, float estimated_bitrate)
3877{
3879
3880 ast_bridge_lock(bridge);
3881 bridge->softmix.video_mode.mode_data.sfu_data.estimated_bitrate = estimated_bitrate;
3882 ast_bridge_unlock(bridge);
3883}
3884
3885void ast_bridge_update_talker_src_video_mode(struct ast_bridge *bridge, struct ast_channel *chan, int talker_energy, int is_keyframe)
3886{
3888
3889 /* If the channel doesn't support video, we don't care about it */
3891 return;
3892 }
3893
3894 ast_bridge_lock(bridge);
3896
3897 if (data->chan_vsrc == chan) {
3898 data->average_talking_energy = talker_energy;
3899 } else if ((data->average_talking_energy < talker_energy) && is_keyframe) {
3900 if (data->chan_old_vsrc) {
3902 }
3903 if (data->chan_vsrc) {
3904 data->chan_old_vsrc = data->chan_vsrc;
3906 }
3907 data->chan_vsrc = ast_channel_ref(chan);
3908 data->average_talking_energy = talker_energy;
3909 ast_verb(5, "Video source in bridge '%s' (%s) is now '%s' (%s)\n",
3910 bridge->name, bridge->uniqueid,
3915 } else if ((data->average_talking_energy < talker_energy) && !is_keyframe) {
3917 } else if (!data->chan_vsrc && is_keyframe) {
3918 data->chan_vsrc = ast_channel_ref(chan);
3919 data->average_talking_energy = talker_energy;
3920 ast_verb(5, "Video source in bridge '%s' (%s) is now '%s' (%s)\n",
3921 bridge->name, bridge->uniqueid,
3926 } else if (!data->chan_old_vsrc && is_keyframe) {
3927 data->chan_old_vsrc = ast_channel_ref(chan);
3929 }
3930 ast_bridge_unlock(bridge);
3931}
3932
3934{
3935 int res = 0;
3936
3937 ast_bridge_lock(bridge);
3938 switch (bridge->softmix.video_mode.mode) {
3940 break;
3943 res = 1;
3944 }
3945 break;
3948 res++;
3949 }
3951 res++;
3952 }
3954 break;
3955 }
3956 ast_bridge_unlock(bridge);
3957 return res;
3958}
3959
3960int ast_bridge_is_video_src(struct ast_bridge *bridge, struct ast_channel *chan)
3961{
3962 int res = 0;
3963
3964 ast_bridge_lock(bridge);
3965 switch (bridge->softmix.video_mode.mode) {
3967 break;
3970 res = 1;
3971 }
3972 break;
3975 res = 1;
3976 } else if (bridge->softmix.video_mode.mode_data.talker_src_data.chan_old_vsrc == chan) {
3977 res = 2;
3978 }
3980 break;
3981 }
3982 ast_bridge_unlock(bridge);
3983 return res;
3984}
3985
3986void ast_bridge_remove_video_src(struct ast_bridge *bridge, struct ast_channel *chan)
3987{
3988 ast_bridge_lock(bridge);
3989 switch (bridge->softmix.video_mode.mode) {
3991 break;
3996 }
3998 }
3999 break;
4004 }
4007 }
4011 }
4013 }
4015 break;
4016 }
4017 ast_bridge_unlock(bridge);
4018}
4019
4021{
4022 switch (video_mode) {
4024 return "talker";
4026 return "single";
4028 return "sfu";
4030 default:
4031 return "none";
4032 }
4033}
4034
4035void ast_bridge_set_send_sdp_label(struct ast_bridge *bridge, unsigned int send_sdp_label)
4036{
4037 ast_bridge_lock(bridge);
4038 bridge->softmix.send_sdp_label = send_sdp_label;
4039 ast_bridge_unlock(bridge);
4040}
4041
4042static int channel_hash(const void *obj, int flags)
4043{
4044 const struct ast_channel *chan = obj;
4045 const char *name = obj;
4046 int hash;
4047
4048 switch (flags & (OBJ_POINTER | OBJ_KEY | OBJ_PARTIAL_KEY)) {
4049 default:
4050 case OBJ_POINTER:
4051 name = ast_channel_name(chan);
4052 /* Fall through */
4053 case OBJ_KEY:
4054 hash = ast_str_hash(name);
4055 break;
4056 case OBJ_PARTIAL_KEY:
4057 /* Should never happen in hash callback. */
4058 ast_assert(0);
4059 hash = 0;
4060 break;
4061 }
4062 return hash;
4063}
4064
4065static int channel_cmp(void *obj, void *arg, int flags)
4066{
4067 const struct ast_channel *left = obj;
4068 const struct ast_channel *right = arg;
4069 const char *right_name = arg;
4070 int cmp;
4071
4072 switch (flags & (OBJ_POINTER | OBJ_KEY | OBJ_PARTIAL_KEY)) {
4073 default:
4074 case OBJ_POINTER:
4075 right_name = ast_channel_name(right);
4076 /* Fall through */
4077 case OBJ_KEY:
4078 cmp = strcmp(ast_channel_name(left), right_name);
4079 break;
4080 case OBJ_PARTIAL_KEY:
4081 cmp = strncmp(ast_channel_name(left), right_name, strlen(right_name));
4082 break;
4083 }
4084 return cmp ? 0 : CMP_MATCH;
4085}
4086
4088{
4089 struct ao2_container *channels;
4090 struct ast_bridge_channel *iter;
4091
4094 if (!channels) {
4095 return NULL;
4096 }
4097
4099 ao2_link(channels, iter->chan);
4100 }
4101
4102 return channels;
4103}
4104
4106{
4107 struct ao2_container *channels;
4108
4109 ast_bridge_lock(bridge);
4111 ast_bridge_unlock(bridge);
4112
4113 return channels;
4114}
4115
4117{
4118 struct ast_channel *peer = NULL;
4119 struct ast_bridge_channel *iter;
4120
4121 /* Asking for the peer channel only makes sense on a two-party bridge. */
4122 if (bridge->num_channels == 2
4125 int in_bridge = 0;
4126
4128 if (iter->chan != chan) {
4129 peer = iter->chan;
4130 } else {
4131 in_bridge = 1;
4132 }
4133 }
4134 if (in_bridge && peer) {
4135 ast_channel_ref(peer);
4136 } else {
4137 peer = NULL;
4138 }
4139 }
4140
4141 return peer;
4142}
4143
4145{
4146 struct ast_channel *peer;
4147
4149 peer = ast_bridge_peer_nolock(bridge, chan);
4151
4152 return peer;
4153}
4154
4155/*!
4156 * \internal
4157 * \brief Transfer an entire bridge to a specific destination.
4158 *
4159 * This creates a local channel to dial out and swaps the called local channel
4160 * with the transferer channel. By doing so, all participants in the bridge are
4161 * connected to the specified destination.
4162 *
4163 * While this means of transferring would work for both two-party and multi-party
4164 * bridges, this method is only used for multi-party bridges since this method would
4165 * be less efficient for two-party bridges.
4166 *
4167 * \param is_external Whether the transfer is externally initiated
4168 * \param transferer The channel performing a transfer
4169 * \param bridge The bridge where the transfer is being performed
4170 * \param exten The destination extension for the blind transfer
4171 * \param context The destination context for the blind transfer
4172 * \param transferee The party being transferred if there is only one
4173 * \param new_channel_cb Callback to call on channel that is created to
4174 * facilitate the blind transfer.
4175 * \param user_data_wrapper User-provided data needed in new_channel_cb
4176 * \param transfer_message The Stasis publication for this transfer.
4177 *
4178 * \return The success or failure of the operation
4179 */
4180static enum ast_transfer_result blind_transfer_bridge(int is_external,
4181 struct ast_channel *transferer, struct ast_bridge *bridge,
4182 const char *exten, const char *context, struct ast_channel *transferee,
4183 transfer_channel_cb new_channel_cb,
4184 struct transfer_channel_data *user_data_wrapper,
4185 struct ast_blind_transfer_message *transfer_message)
4186{
4187 struct ast_channel *local;
4188 char chan_name[AST_MAX_EXTENSION + AST_MAX_CONTEXT + 2];
4189 int cause;
4190 struct ast_format_cap *caps;
4191
4192 ast_channel_lock(transferer);
4193 caps = ao2_bump(ast_channel_nativeformats(transferer));
4194 ast_channel_unlock(transferer);
4195
4196 snprintf(chan_name, sizeof(chan_name), "%s@%s", exten, context);
4197 local = ast_request("Local", caps, NULL, transferer,
4198 chan_name, &cause);
4199
4200 ao2_cleanup(caps);
4201
4202 if (!local) {
4204 }
4205
4206 ast_channel_lock_both(local, transferer);
4208
4210 if (!transfer_message->replace_channel) {
4211 ast_hangup(local);
4213 }
4214
4216 ast_channel_unlock(local);
4217 ast_channel_unlock(transferer);
4218
4219 if (new_channel_cb) {
4220 new_channel_cb(local, user_data_wrapper, AST_BRIDGE_TRANSFER_MULTI_PARTY);
4221 }
4222
4223 if (ast_call(local, chan_name, 0)) {
4224 ast_hangup(local);
4226 }
4227
4228 if (ast_bridge_impart(bridge, local, transferer, NULL,
4230 ast_hangup(local);
4232 }
4233
4235}
4236
4237/*!
4238 * \internal
4239 * \brief Get the transferee channel
4240 *
4241 * This is only applicable to cases where a transfer is occurring on a
4242 * two-party bridge. The channels container passed in is expected to only
4243 * contain two channels, the transferer and the transferee. The transferer
4244 * channel is passed in as a parameter to ensure we don't return it as
4245 * the transferee channel.
4246 *
4247 * \param channels A two-channel container containing the transferer and transferee
4248 * \param transferer The party that is transferring the call
4249 * \return The party that is being transferred
4250 */
4251static struct ast_channel *get_transferee(struct ao2_container *channels, struct ast_channel *transferer)
4252{
4253 struct ao2_iterator channel_iter;
4254 struct ast_channel *transferee;
4255
4256 for (channel_iter = ao2_iterator_init(channels, 0);
4257 (transferee = ao2_iterator_next(&channel_iter));
4258 ao2_cleanup(transferee)) {
4259 if (transferee != transferer) {
4260 break;
4261 }
4262 }
4263
4264 ao2_iterator_destroy(&channel_iter);
4265 return transferee;
4266}
4267
4268/*!
4269 * \brief Perform an attended transfer of a bridge
4270 *
4271 * This performs an attended transfer of an entire bridge to a target.
4272 * The target varies, depending on what bridges exist during the transfer
4273 * attempt.
4274 *
4275 * If two bridges exist, then a local channel is created to link the two
4276 * bridges together.
4277 *
4278 * If only one bridge exists, then a local channel is created with one end
4279 * placed into the existing bridge and the other end masquerading into
4280 * the unbridged channel.
4281 *
4282 * \param chan1 Transferer channel. Guaranteed to be bridged.
4283 * \param chan2 Other transferer channel. May or may not be bridged.
4284 * \param bridge1 Bridge that chan1 is in. Guaranteed to be non-NULL.
4285 * \param bridge2 Bridge that chan2 is in. If NULL, then chan2 is not bridged.
4286 * \param transfer_msg Data to publish for a stasis attended transfer message.
4287 * \retval AST_BRIDGE_TRANSFER_FAIL Internal error occurred
4288 * \retval AST_BRIDGE_TRANSFER_SUCCESS Successfully transferred the bridge
4289 */
4291 struct ast_channel *chan2, struct ast_bridge *bridge1, struct ast_bridge *bridge2,
4292 struct ast_attended_transfer_message *transfer_msg)
4293{
4294#define BRIDGE_LOCK_ONE_OR_BOTH(b1, b2) \
4295 do { \
4296 if (b2) { \
4297 ast_bridge_lock_both(b1, b2); \
4298 } else { \
4299 ast_bridge_lock(b1); \
4300 } \
4301 } while (0)
4302
4303 static const char *dest = "_attended@transfer/m";
4304 struct ast_channel *local_chan;
4305 int cause;
4306 int res;
4307 const char *app = NULL;
4308 struct ast_format_cap *caps;
4309
4310 ast_channel_lock(chan1);
4311 caps = ao2_bump(ast_channel_nativeformats(chan1));
4312 ast_channel_unlock(chan1);
4313
4314 local_chan = ast_request("Local", caps, NULL, chan1, dest, &cause);
4315
4316 ao2_cleanup(caps);
4317
4318 if (!local_chan) {
4320 }
4321
4322 ast_channel_lock_both(local_chan, chan1);
4325 ast_channel_unlock(local_chan);
4326 ast_channel_unlock(chan1);
4327
4328 if (bridge2) {
4329 res = ast_local_setup_bridge(local_chan, bridge2, chan2, NULL);
4330 } else {
4332 res = ast_local_setup_masquerade(local_chan, chan2);
4333 }
4334
4335 if (res) {
4336 ast_hangup(local_chan);
4338 }
4339
4340 /*
4341 * Since bridges need to be unlocked before entering ast_bridge_impart and
4342 * core_local may call into it then the bridges need to be unlocked here.
4343 */
4344 ast_bridge_unlock(bridge1);
4345 if (bridge2) {
4346 ast_bridge_unlock(bridge2);
4347 }
4348
4349 if (ast_call(local_chan, dest, 0)) {
4350 ast_hangup(local_chan);
4351 BRIDGE_LOCK_ONE_OR_BOTH(bridge1, bridge2);
4353 }
4354
4355 /* Get a ref for use later since this one is being stolen */
4356 ao2_ref(local_chan, +1);
4357 if (ast_bridge_impart(bridge1, local_chan, chan1, NULL,
4359 ast_hangup(local_chan);
4360 ao2_cleanup(local_chan);
4361 BRIDGE_LOCK_ONE_OR_BOTH(bridge1, bridge2);
4363 }
4364 BRIDGE_LOCK_ONE_OR_BOTH(bridge1, bridge2);
4365
4366 if (bridge2) {
4367 void *tech;
4368 struct ast_channel *locals[2];
4369
4370 /* Have to lock everything just in case a hangup comes in early */
4371 ast_local_lock_all(local_chan, &tech, &locals[0], &locals[1]);
4372 if (!locals[0] || !locals[1]) {
4373 ast_log(LOG_ERROR, "Transfer failed probably due to an early hangup - "
4374 "missing other half of '%s'\n", ast_channel_name(local_chan));
4376 ao2_cleanup(local_chan);
4378 }
4379
4380 /* Make sure the peer is properly set */
4381 if (local_chan != locals[0]) {
4382 SWAP(locals[0], locals[1]);
4383 }
4384
4387 } else {
4388 ast_attended_transfer_message_add_app(transfer_msg, app, local_chan);
4389 }
4390
4391 ao2_cleanup(local_chan);
4393}
4394
4395static enum ast_transfer_result try_parking(struct ast_channel *transferer,
4396 const char *context, const char *exten, transfer_channel_cb new_channel_cb,
4397 struct transfer_channel_data *user_data_wrapper)
4398{
4399 RAII_VAR(struct ast_bridge_channel *, transferer_bridge_channel, NULL, ao2_cleanup);
4400
4403 }
4404
4405 ast_channel_lock(transferer);
4406 transferer_bridge_channel = ast_channel_get_bridge_channel(transferer);
4407 ast_channel_unlock(transferer);
4408
4409 if (!transferer_bridge_channel) {
4411 }
4412
4413 if (ast_parking_blind_transfer_park(transferer_bridge_channel,
4414 context, exten, new_channel_cb, user_data_wrapper)) {
4416 }
4417
4419}
4420
4421void ast_bridge_set_transfer_variables(struct ast_channel *chan, const char *value, int attended)
4422{
4423 char *writevar;
4424 char *erasevar;
4425
4426 if (attended) {
4427 writevar = ATTENDEDTRANSFER;
4428 erasevar = BLINDTRANSFER;
4429 } else {
4430 writevar = BLINDTRANSFER;
4431 erasevar = ATTENDEDTRANSFER;
4432 }
4433
4434 pbx_builtin_setvar_helper(chan, writevar, value);
4435 pbx_builtin_setvar_helper(chan, erasevar, NULL);
4436}
4437
4438/*!
4439 * \internal
4440 * \brief Set the transfer variable as appropriate on channels involved in the transfer
4441 *
4442 * The transferer channel will have its variable set the same as its BRIDGEPEER
4443 * variable. This will account for all channels that it is bridged to. The other channels
4444 * involved in the transfer will have their variable set to the transferer
4445 * channel's name.
4446 *
4447 * \param transferer The channel performing the transfer
4448 * \param channels The channels belonging to the bridge
4449 * \param is_attended false set BLINDTRANSFER and unset ATTENDEDTRANSFER
4450 * true set ATTENDEDTRANSFER and unset BLINDTRANSFER
4451 */
4452static void set_transfer_variables_all(struct ast_channel *transferer, struct ao2_container *channels, int is_attended)
4453{
4454 struct ao2_iterator iter;
4455 struct ast_channel *chan;
4456 const char *transferer_name;
4457 const char *transferer_bridgepeer;
4458
4459 ast_channel_lock(transferer);
4460 transferer_name = ast_strdupa(ast_channel_name(transferer));
4461 transferer_bridgepeer = ast_strdupa(S_OR(pbx_builtin_getvar_helper(transferer, "BRIDGEPEER"), ""));
4462 ast_channel_unlock(transferer);
4463
4464 for (iter = ao2_iterator_init(channels, 0);
4465 (chan = ao2_iterator_next(&iter));
4466 ao2_cleanup(chan)) {
4467 if (chan == transferer) {
4468 ast_bridge_set_transfer_variables(chan, transferer_bridgepeer, is_attended);
4469 } else {
4470 ast_bridge_set_transfer_variables(chan, transferer_name, is_attended);
4471 }
4472 }
4473
4474 ao2_iterator_destroy(&iter);
4475}
4476
4478{
4479 struct ast_bridge *bridge;
4480
4481 ast_channel_lock(chan);
4482 bridge = ast_channel_get_bridge(chan);
4483 ast_channel_unlock(chan);
4484
4485 if (bridge && ast_test_flag(&bridge->feature_flags,
4487 ao2_ref(bridge, -1);
4488 bridge = NULL;
4489 }
4490
4491 return bridge;
4492}
4493
4495 struct ast_channel *transferer, const char *exten, const char *context,
4496 transfer_channel_cb new_channel_cb, void *user_data)
4497{
4498 RAII_VAR(struct ast_bridge *, bridge, NULL, ao2_cleanup);
4499 RAII_VAR(struct ast_bridge_channel *, bridge_channel, NULL, ao2_cleanup);
4501 RAII_VAR(struct ast_channel *, transferee, NULL, ast_channel_cleanup);
4502 RAII_VAR(struct transfer_channel_data *, user_data_wrapper, NULL, ao2_cleanup);
4503 RAII_VAR(struct ast_blind_transfer_message *, transfer_message, NULL, ao2_cleanup);
4504 int do_bridge_transfer;
4505 int transfer_prohibited;
4506 enum ast_transfer_result transfer_result;
4507
4508 transfer_message = ast_blind_transfer_message_create(is_external, transferer, exten, context);
4509 if (!transfer_message) {
4510 /* Out of memory. Not even possible to publish a Stasis message about the
4511 * failure
4512 */
4513 ast_log(LOG_ERROR, "Unable to allocate memory for blind transfer publication from %s\n",
4514 ast_channel_name(transferer));
4516 }
4517
4518 bridge = ast_bridge_transfer_acquire_bridge(transferer);
4519 if (!bridge) {
4520 transfer_result = AST_BRIDGE_TRANSFER_INVALID;
4521 goto publish;
4522 }
4523
4524 ast_bridge_lock(bridge);
4525 transfer_message->bridge = ast_bridge_snapshot_create(bridge);
4526 ast_bridge_unlock(bridge);
4527 if (!transfer_message->bridge) {
4528 transfer_result = AST_BRIDGE_TRANSFER_FAIL;
4529 goto publish;
4530 }
4531
4532 transferee = ast_bridge_peer(bridge, transferer);
4533 if (transferee) {
4534 transfer_message->transferee = ast_channel_snapshot_get_latest(ast_channel_uniqueid(transferee));
4535 if (!transfer_message->transferee) {
4536 transfer_result = AST_BRIDGE_TRANSFER_FAIL;
4537 goto publish;
4538 }
4539 }
4540
4541 ast_channel_lock(transferer);
4542 bridge_channel = ast_channel_get_bridge_channel(transferer);
4543 ast_channel_unlock(transferer);
4544 if (!bridge_channel) {
4545 transfer_result = AST_BRIDGE_TRANSFER_INVALID;
4546 goto publish;
4547 }
4548
4549 user_data_wrapper = ao2_alloc(sizeof(*user_data_wrapper), NULL);
4550 if (!user_data_wrapper) {
4551 transfer_result = AST_BRIDGE_TRANSFER_FAIL;
4552 goto publish;
4553 }
4554
4555 user_data_wrapper->data = user_data;
4556
4557 /* Take off hold if they are on hold. */
4558 ast_bridge_channel_write_unhold(bridge_channel);
4559
4560 transfer_result = try_parking(transferer, context, exten, new_channel_cb, user_data_wrapper);
4561 if (transfer_result == AST_BRIDGE_TRANSFER_SUCCESS) {
4562 goto publish;
4563 }
4564
4565 /* Since parking didn't take control of the user_data_wrapper, we are just going to raise the completed flag now. */
4566 user_data_wrapper->completed = 1;
4567
4568 {
4570
4572 if (!channels) {
4573 transfer_result = AST_BRIDGE_TRANSFER_FAIL;
4574 goto publish;
4575 }
4576 if (ao2_container_count(channels) <= 1) {
4577 transfer_result = AST_BRIDGE_TRANSFER_INVALID;
4578 goto publish;
4579 }
4580 transfer_prohibited = ast_test_flag(&bridge->feature_flags,
4582 do_bridge_transfer = ast_test_flag(&bridge->feature_flags,
4585 }
4586
4587 if (transfer_prohibited) {
4588 transfer_result = AST_BRIDGE_TRANSFER_NOT_PERMITTED;
4589 goto publish;
4590 }
4591
4592 set_transfer_variables_all(transferer, channels, 0);
4593
4594 if (do_bridge_transfer) {
4595 transfer_result = blind_transfer_bridge(is_external, transferer, bridge,
4596 exten, context, transferee, new_channel_cb, user_data_wrapper, transfer_message);
4597 goto publish;
4598 }
4599
4600 /* Reaching this portion means that we're dealing with a two-party bridge */
4601
4602 if (!transferee) {
4603 transfer_result = AST_BRIDGE_TRANSFER_FAIL;
4604 goto publish;
4605 }
4606
4608 new_channel_cb, user_data_wrapper)) {
4609 transfer_result = AST_BRIDGE_TRANSFER_FAIL;
4610 goto publish;
4611 }
4612
4613 ast_bridge_remove(bridge, transferer);
4614 transfer_result = AST_BRIDGE_TRANSFER_SUCCESS;
4615
4616publish:
4617 transfer_message->result = transfer_result;
4618 ast_bridge_publish_blind_transfer(transfer_message);
4619 return transfer_result;
4620}
4621
4622/*!
4623 * \internal
4624 * \brief Performs an attended transfer by moving a channel from one bridge to another
4625 *
4626 * The channel that is bridged to the source_channel is moved into the dest_bridge from
4627 * the source_bridge_channel's bridge. The swap_channel is swapped out of the dest_bridge and placed in
4628 * the source_bridge_channel's bridge.
4629 *
4630 * \note dest_bridge and source_bridge_channel's bridge MUST be locked before calling this function.
4631 *
4632 * \param dest_bridge The final bridge for the attended transfer
4633 * \param source_bridge_channel Channel who is bridged to the channel that will move
4634 * \param swap_channel Channel to be swapped out of the dest_bridge
4635 * \return The success or failure of the swap attempt
4636 */
4638 struct ast_bridge_channel *source_bridge_channel, struct ast_channel *swap_channel)
4639{
4640 struct ast_bridge_channel *bridged_to_source;
4641
4642 bridged_to_source = ast_bridge_channel_peer(source_bridge_channel);
4643 if (bridged_to_source
4644 && bridged_to_source->state == BRIDGE_CHANNEL_STATE_WAIT
4645 && !ast_test_flag(&bridged_to_source->features->feature_flags,
4647 bridged_to_source->swap = swap_channel;
4648 if (bridge_do_move(dest_bridge, bridged_to_source, 1, 0)) {
4650 }
4651 /* Must kick the source channel out of its bridge. */
4652 ast_bridge_channel_leave_bridge(source_bridge_channel,
4655 } else {
4657 }
4658}
4659
4660/*!
4661 * \internal
4662 * \brief Function that performs an attended transfer when both transferer channels are bridged
4663 *
4664 * The method by which the transfer is performed is dependent on whether the bridges allow for
4665 * optimization to occur between them. If no optimization is permitted, then an unreal channel
4666 * is placed as a link between the two bridges. If optimization is permitted, then that means
4667 * we are free to perform move or merge operations in order to perform the transfer.
4668 *
4669 * \note to_transferee_bridge and to_target_bridge MUST be locked before calling this function
4670 *
4671 * \param to_transferee The channel that is bridged to the transferee
4672 * \param to_transferee_bridge_channel to_transferee's bridge_channel
4673 * \param to_transfer_target The channel that is bridged to the transfer target
4674 * \param to_target_bridge_channel to_transfer_target's bridge_channel
4675 * \param to_transferee_bridge The bridge between to_transferee and the transferee
4676 * \param to_target_bridge The bridge between to_transfer_target and the transfer_target
4677 * \param transfer_msg Data to publish for a stasis attended transfer message
4678 * \return The success or failure of the attended transfer
4679 */
4681 struct ast_bridge_channel *to_transferee_bridge_channel,
4682 struct ast_channel *to_transfer_target,
4683 struct ast_bridge_channel *to_target_bridge_channel,
4684 struct ast_bridge *to_transferee_bridge, struct ast_bridge *to_target_bridge,
4685 struct ast_attended_transfer_message *transfer_msg)
4686{
4687 struct ast_bridge_channel *kick_me[] = {
4688 to_transferee_bridge_channel,
4689 to_target_bridge_channel,
4690 };
4691 enum ast_transfer_result res;
4692 struct ast_bridge *final_bridge = NULL;
4694
4695 channels = ast_bridge_peers_nolock(to_transferee_bridge);
4696
4697 if (!channels) {
4699 goto end;
4700 }
4701
4702 set_transfer_variables_all(to_transferee, channels, 1);
4703
4704 switch (ast_bridges_allow_optimization(to_transferee_bridge, to_target_bridge)) {
4706 final_bridge = to_transferee_bridge;
4707 res = bridge_swap_attended_transfer(to_transferee_bridge, to_target_bridge_channel, to_transferee);
4708 goto end;
4710 final_bridge = to_target_bridge;
4711 res = bridge_swap_attended_transfer(to_target_bridge, to_transferee_bridge_channel, to_transfer_target);
4712 goto end;
4714 final_bridge = to_transferee_bridge;
4715 bridge_do_merge(to_transferee_bridge, to_target_bridge, kick_me, ARRAY_LEN(kick_me), 0);
4717 goto end;
4719 final_bridge = to_target_bridge;
4720 bridge_do_merge(to_target_bridge, to_transferee_bridge, kick_me, ARRAY_LEN(kick_me), 0);
4722 goto end;
4724 default:
4725 /* Just because optimization wasn't doable doesn't necessarily mean
4726 * that we can actually perform the transfer. Some reasons for non-optimization
4727 * indicate bridge invalidity, so let's check those before proceeding.
4728 */
4729 if (to_transferee_bridge->inhibit_merge || to_transferee_bridge->dissolved ||
4730 to_target_bridge->inhibit_merge || to_target_bridge->dissolved) {
4732 }
4733
4734 return attended_transfer_bridge(to_transferee, to_transfer_target,
4735 to_transferee_bridge, to_target_bridge, transfer_msg);
4736 }
4737
4738end:
4739 if (res == AST_BRIDGE_TRANSFER_SUCCESS) {
4740 ast_attended_transfer_message_add_merge(transfer_msg, final_bridge);
4741 }
4742
4743 return res;
4744}
4745
4747 struct ast_channel *to_transfer_target)
4748{
4749 RAII_VAR(struct ast_bridge *, to_transferee_bridge, NULL, ao2_cleanup);
4750 RAII_VAR(struct ast_bridge *, to_target_bridge, NULL, ao2_cleanup);
4751 RAII_VAR(struct ast_bridge_channel *, to_transferee_bridge_channel, NULL, ao2_cleanup);
4752 RAII_VAR(struct ast_bridge_channel *, to_target_bridge_channel, NULL, ao2_cleanup);
4754 RAII_VAR(struct ast_channel *, transferee, NULL, ao2_cleanup);
4755 RAII_VAR(struct ast_attended_transfer_message *, transfer_msg, NULL, ao2_cleanup);
4756 struct ast_bridge *the_bridge = NULL;
4757 struct ast_channel *chan_bridged;
4758 struct ast_channel *chan_unbridged;
4759 int transfer_prohibited;
4760 int do_bridge_transfer;
4761 enum ast_transfer_result res;
4762 const char *app = NULL;
4763 int hangup_target = 0;
4764
4765 to_transferee_bridge = ast_bridge_transfer_acquire_bridge(to_transferee);
4766 to_target_bridge = ast_bridge_transfer_acquire_bridge(to_transfer_target);
4767
4768 transfer_msg = ast_attended_transfer_message_create(1, to_transferee, to_transferee_bridge,
4769 to_transfer_target, to_target_bridge, NULL, NULL);
4770 if (!transfer_msg) {
4771 ast_log(LOG_ERROR, "Unable to create Stasis publication for attended transfer from %s\n",
4772 ast_channel_name(to_transferee));
4774 }
4775
4776 /* They can't both be unbridged, you silly goose! */
4777 if (!to_transferee_bridge && !to_target_bridge) {
4779 goto end;
4780 }
4781
4782 ast_channel_lock(to_transferee);
4783 to_transferee_bridge_channel = ast_channel_get_bridge_channel(to_transferee);
4784 ast_channel_unlock(to_transferee);
4785
4786 ast_channel_lock(to_transfer_target);
4787 to_target_bridge_channel = ast_channel_get_bridge_channel(to_transfer_target);
4788 ast_channel_unlock(to_transfer_target);
4789
4790 if (to_transferee_bridge_channel) {
4791 /* Take off hold if they are on hold. */
4792 if (ast_bridge_channel_write_unhold(to_transferee_bridge_channel)) {
4793 ast_log(LOG_ERROR, "Transferee channel disappeared during transfer!\n");
4795 goto end;
4796 }
4797 }
4798
4799 if (to_target_bridge_channel) {
4800 const char *target_complete_sound;
4801
4802 /* Take off hold if they are on hold. */
4803 if (ast_bridge_channel_write_unhold(to_target_bridge_channel)) {
4804 ast_log(LOG_ERROR, "Target channel disappeared during transfer!\n");
4806 goto end;
4807 }
4808
4809 /* Is there a courtesy sound to play to the target? */
4810 ast_channel_lock(to_transfer_target);
4811 target_complete_sound = pbx_builtin_getvar_helper(to_transfer_target,
4812 "ATTENDED_TRANSFER_COMPLETE_SOUND");
4813 if (!ast_strlen_zero(target_complete_sound)) {
4814 target_complete_sound = ast_strdupa(target_complete_sound);
4815 } else {
4816 target_complete_sound = NULL;
4817 }
4818 ast_channel_unlock(to_transfer_target);
4819 if (!target_complete_sound) {
4820 ast_channel_lock(to_transferee);
4821 target_complete_sound = pbx_builtin_getvar_helper(to_transferee,
4822 "ATTENDED_TRANSFER_COMPLETE_SOUND");
4823 if (!ast_strlen_zero(target_complete_sound)) {
4824 target_complete_sound = ast_strdupa(target_complete_sound);
4825 } else {
4826 target_complete_sound = NULL;
4827 }
4828 ast_channel_unlock(to_transferee);
4829 }
4830 if (target_complete_sound) {
4831 ast_bridge_channel_write_playfile(to_target_bridge_channel, NULL,
4832 target_complete_sound, NULL);
4833 }
4834 }
4835
4836 /* Let's get the easy one out of the way first */
4837 if (to_transferee_bridge && to_target_bridge) {
4838
4839 if (!to_transferee_bridge_channel || !to_target_bridge_channel) {
4841 goto end;
4842 }
4843
4844 ast_bridge_lock_both(to_transferee_bridge, to_target_bridge);
4845 res = two_bridge_attended_transfer(to_transferee, to_transferee_bridge_channel,
4846 to_transfer_target, to_target_bridge_channel,
4847 to_transferee_bridge, to_target_bridge, transfer_msg);
4848 ast_bridge_unlock(to_transferee_bridge);
4849 ast_bridge_unlock(to_target_bridge);
4850
4851 hangup_target = 1;
4852 goto end;
4853 }
4854
4855 the_bridge = to_transferee_bridge ?: to_target_bridge;
4856 chan_bridged = to_transferee_bridge ? to_transferee : to_transfer_target;
4857 chan_unbridged = to_transferee_bridge ? to_transfer_target : to_transferee;
4858
4859 /*
4860 * Race condition makes it possible for app to be NULL, so get the app prior to
4861 * transferring with a fallback of "unknown".
4862 */
4863 app = ast_strdupa(ast_channel_appl(chan_unbridged) ?: "unknown");
4864
4865 {
4866 int chan_count;
4868
4869 channels = ast_bridge_peers_nolock(the_bridge);
4870 if (!channels) {
4872 goto end;
4873 }
4874 chan_count = ao2_container_count(channels);
4875 if (chan_count <= 1) {
4877 goto end;
4878 }
4879 transfer_prohibited = ast_test_flag(&the_bridge->feature_flags,
4881 do_bridge_transfer = ast_test_flag(&the_bridge->feature_flags,
4883 chan_count > 2;
4884 }
4885
4886 if (transfer_prohibited) {
4888 goto end;
4889 }
4890
4891 set_transfer_variables_all(to_transferee, channels, 1);
4892
4893 if (do_bridge_transfer) {
4894 /*
4895 * Hang up the target if it was bridged. Note, if it is not bridged
4896 * it is hung up during the masquerade.
4897 */
4898 hangup_target = chan_bridged == to_transfer_target;
4899 ast_bridge_lock(the_bridge);
4900 res = attended_transfer_bridge(chan_bridged, chan_unbridged, the_bridge, NULL, transfer_msg);
4901 ast_bridge_unlock(the_bridge);
4902 goto end;
4903 }
4904
4905 transferee = get_transferee(channels, chan_bridged);
4906 if (!transferee) {
4908 goto end;
4909 }
4910
4911 if (bridge_channel_internal_queue_attended_transfer(transferee, chan_unbridged)) {
4913 goto end;
4914 }
4915
4916 ast_bridge_remove(the_bridge, chan_bridged);
4917
4920
4921end:
4922 if ((res == AST_BRIDGE_TRANSFER_SUCCESS && hangup_target) || res == AST_BRIDGE_TRANSFER_FAIL) {
4923 ast_softhangup(to_transfer_target, AST_SOFTHANGUP_DEV);
4924 }
4925
4926 transfer_msg->result = res;
4928 return res;
4929}
4930
4931/*!
4932 * \internal
4933 * \brief Service the bridge manager request.
4934 * \since 12.0.0
4935 *
4936 * \param bridge requesting service.
4937 */
4939{
4941 if (bridge->callid) {
4943 }
4944
4945 /* Do any pending bridge actions. */
4948}
4949
4950/*!
4951 * \internal
4952 * \brief Bridge manager service thread.
4953 * \since 12.0.0
4954 */
4955static void *bridge_manager_thread(void *data)
4956{
4957 struct bridge_manager_controller *manager = data;
4959
4960 ao2_lock(manager);
4961 while (!manager->stop) {
4963 if (!request) {
4964 ast_cond_wait(&manager->cond, ao2_object_get_lockaddr(manager));
4965 continue;
4966 }
4967 ao2_unlock(manager);
4968
4969 /* Service the bridge. */
4971 ao2_ref(request->bridge, -1);
4973
4974 ao2_lock(manager);
4975 }
4976 ao2_unlock(manager);
4977
4978 return NULL;
4979}
4980
4981/*!
4982 * \internal
4983 * \brief Destroy the bridge manager controller.
4984 * \since 12.0.0
4985 *
4986 * \param obj Bridge manager to destroy.
4987 */
4988static void bridge_manager_destroy(void *obj)
4989{
4990 struct bridge_manager_controller *manager = obj;
4992
4993 if (manager->thread != AST_PTHREADT_NULL) {
4994 /* Stop the manager thread. */
4995 ao2_lock(manager);
4996 manager->stop = 1;
4997 ast_cond_signal(&manager->cond);
4998 ao2_unlock(manager);
4999 ast_debug(1, "Waiting for bridge manager thread to die.\n");
5000 pthread_join(manager->thread, NULL);
5001 }
5002
5003 /* Destroy the service request queue. */
5004 while ((request = AST_LIST_REMOVE_HEAD(&manager->service_requests, node))) {
5005 ao2_ref(request->bridge, -1);
5007 }
5008
5009 ast_cond_destroy(&manager->cond);
5010}
5011
5012/*!
5013 * \internal
5014 * \brief Create the bridge manager controller.
5015 * \since 12.0.0
5016 *
5017 * \return manager on success.
5018 * \retval NULL on error.
5019 */
5021{
5022 struct bridge_manager_controller *manager;
5023
5024 manager = ao2_alloc(sizeof(*manager), bridge_manager_destroy);
5025 if (!manager) {
5026 /* Well. This isn't good. */
5027 return NULL;
5028 }
5029 ast_cond_init(&manager->cond, NULL);
5031
5032 /* Create the bridge manager thread. */
5033 if (ast_pthread_create(&manager->thread, NULL, bridge_manager_thread, manager)) {
5034 /* Well. This isn't good either. */
5035 manager->thread = AST_PTHREADT_NULL;
5036 ao2_ref(manager, -1);
5037 manager = NULL;
5038 }
5039
5040 return manager;
5041}
5042
5043/*!
5044 * \internal
5045 * \brief Bridge ao2 container sort function.
5046 * \since 12.0.0
5047 *
5048 * \param obj_left pointer to the (user-defined part) of an object.
5049 * \param obj_right pointer to the (user-defined part) of an object.
5050 * \param flags flags from ao2_callback()
5051 * OBJ_POINTER - if set, 'obj_right', is an object.
5052 * OBJ_KEY - if set, 'obj_right', is a search key item that is not an object.
5053 * OBJ_PARTIAL_KEY - if set, 'obj_right', is a partial search key item that is not an object.
5054 *
5055 * \retval <0 if obj_left < obj_right
5056 * \retval =0 if obj_left == obj_right
5057 * \retval >0 if obj_left > obj_right
5058 */
5059static int bridge_sort_cmp(const void *obj_left, const void *obj_right, int flags)
5060{
5061 const struct ast_bridge *bridge_left = obj_left;
5062 const struct ast_bridge *bridge_right = obj_right;
5063 const char *right_key = obj_right;
5064 int cmp;
5065
5066 switch (flags & (OBJ_POINTER | OBJ_KEY | OBJ_PARTIAL_KEY)) {
5067 default:
5068 case OBJ_POINTER:
5069 right_key = bridge_right->uniqueid;
5070 /* Fall through */
5071 case OBJ_KEY:
5072 cmp = strcmp(bridge_left->uniqueid, right_key);
5073 break;
5074 case OBJ_PARTIAL_KEY:
5075 cmp = strncmp(bridge_left->uniqueid, right_key, strlen(right_key));
5076 break;
5077 }
5078 return cmp;
5079}
5080
5081struct ast_bridge *ast_bridge_find_by_id(const char *bridge_id)
5082{
5083 return ao2_find(bridges, bridge_id, OBJ_SEARCH_KEY);
5084}
5085
5086static int complete_bridge_live_search(void *obj, void *arg, int flags)
5087{
5088 struct ast_bridge *bridge = obj;
5089
5091 return CMP_STOP;
5092 }
5093
5094 return 0;
5095}
5096
5097static char *complete_bridge_live(const char *word)
5098{
5101
5102 return NULL;
5103}
5104
5105static char *handle_bridge_show_all(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
5106{
5107#define FORMAT_HDR "%-36s %-36s %5s %-15s %-15s %s\n"
5108#define FORMAT_ROW "%-36s %-36s %5u %-15s %-15s %s\n"
5109
5110 struct ao2_iterator iter;
5111 struct ast_bridge *bridge;
5112
5113 switch (cmd) {
5114 case CLI_INIT:
5115 e->command = "bridge show all";
5116 e->usage =
5117 "Usage: bridge show all\n"
5118 " List all bridges\n";
5119 return NULL;
5120 case CLI_GENERATE:
5121 return NULL;
5122 }
5123
5124 ast_cli(a->fd, FORMAT_HDR, "Bridge-ID", "Name", "Chans", "Type", "Technology", "Duration");
5125
5126 iter = ao2_iterator_init(bridges, 0);
5127 for (; (bridge = ao2_iterator_next(&iter)); ao2_ref(bridge, -1)) {
5128 struct ast_bridge_snapshot *snapshot = ast_bridge_get_snapshot(bridge);
5129 char print_time[32];
5130
5131 if (snapshot) {
5132 ast_format_duration_hh_mm_ss(ast_tvnow().tv_sec - snapshot->creationtime.tv_sec, print_time, sizeof(print_time));
5133 ast_cli(a->fd, FORMAT_ROW,
5134 bridge->uniqueid,
5135 S_OR(bridge->name, "<unknown>"),
5136 snapshot->num_channels,
5137 S_OR(snapshot->subclass, "<unknown>"),
5138 S_OR(snapshot->technology, "<unknown>"),
5139 print_time);
5140 ao2_ref(snapshot, -1);
5141 }
5142 }
5143 ao2_iterator_destroy(&iter);
5144
5145 return CLI_SUCCESS;
5146
5147#undef FORMAT_HDR
5148#undef FORMAT_ROW
5149}
5150
5151/*! \brief Internal callback function for sending channels in a bridge to the CLI */
5152static int bridge_show_specific_print_channel(void *obj, void *arg, int flags)
5153{
5154 const char *uniqueid = obj;
5155 struct ast_cli_args *a = arg;
5156 struct ast_channel_snapshot *snapshot;
5157
5158 snapshot = ast_channel_snapshot_get_latest(uniqueid);
5159 if (!snapshot) {
5160 return 0;
5161 }
5162
5163 ast_cli(a->fd, "Channel: %s\n", snapshot->base->name);
5164 ao2_ref(snapshot, -1);
5165
5166 return 0;
5167}
5168
5169static char *handle_bridge_show_specific(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
5170{
5171 struct ast_bridge_snapshot *snapshot;
5172 char print_time[32];
5173
5174 switch (cmd) {
5175 case CLI_INIT:
5176 e->command = "bridge show";
5177 e->usage =
5178 "Usage: bridge show <bridge-id>\n"
5179 " Show information about the <bridge-id> bridge\n";
5180 return NULL;
5181 case CLI_GENERATE:
5182 if (a->pos == 2) {
5183 return complete_bridge_live(a->word);
5184 }
5185 return NULL;
5186 }
5187
5188 if (a->argc != 3) {
5189 return CLI_SHOWUSAGE;
5190 }
5191
5192 snapshot = ast_bridge_get_snapshot_by_uniqueid(a->argv[2]);
5193 if (!snapshot) {
5194 ast_cli(a->fd, "Bridge '%s' not found\n", a->argv[2]);
5195 return CLI_SUCCESS;
5196 }
5197
5198 ast_format_duration_hh_mm_ss(ast_tvnow().tv_sec - snapshot->creationtime.tv_sec, print_time, sizeof(print_time));
5199
5200 ast_cli(a->fd, "Id: %s\n", snapshot->uniqueid);
5201 ast_cli(a->fd, "Type: %s\n", S_OR(snapshot->subclass, "<unknown>"));
5202 ast_cli(a->fd, "Technology: %s\n", S_OR(snapshot->technology, "<unknown>"));
5203 ast_cli(a->fd, "Subclass: %s\n", snapshot->subclass);
5204 ast_cli(a->fd, "Creator: %s\n", snapshot->creator);
5205 ast_cli(a->fd, "Name: %s\n", snapshot->name);
5206 ast_cli(a->fd, "Video-Mode: %s\n", ast_bridge_video_mode_to_string(snapshot->video_mode));
5207 ast_cli(a->fd, "Video-Source-Id: %s\n", snapshot->video_source_id);
5208 ast_cli(a->fd, "Num-Channels: %u\n", snapshot->num_channels);
5209 ast_cli(a->fd, "Num-Active: %u\n", snapshot->num_active);
5210 ast_cli(a->fd, "Duration: %s\n", print_time);
5212 ao2_ref(snapshot, -1);
5213
5214 return CLI_SUCCESS;
5215}
5216
5217#ifdef AST_DEVMODE
5218static char *handle_bridge_destroy_specific(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
5219{
5220 struct ast_bridge *bridge;
5221
5222 switch (cmd) {
5223 case CLI_INIT:
5224 e->command = "bridge destroy";
5225 e->usage =
5226 "Usage: bridge destroy <bridge-id>\n"
5227 " Destroy the <bridge-id> bridge\n";
5228 return NULL;
5229 case CLI_GENERATE:
5230 if (a->pos == 2) {
5231 return complete_bridge_live(a->word);
5232 }
5233 return NULL;
5234 }
5235
5236 if (a->argc != 3) {
5237 return CLI_SHOWUSAGE;
5238 }
5239
5240 bridge = ast_bridge_find_by_id(a->argv[2]);
5241 if (!bridge) {
5242 ast_cli(a->fd, "Bridge '%s' not found\n", a->argv[2]);
5243 return CLI_SUCCESS;
5244 }
5245
5246 ast_cli(a->fd, "Destroying bridge '%s'\n", a->argv[2]);
5247 ast_bridge_destroy(bridge, 0);
5248
5249 return CLI_SUCCESS;
5250}
5251#endif
5252
5253static char *complete_bridge_participant(const char *bridge_name, const char *word)
5254{
5255 struct ast_bridge *bridge;
5256 struct ast_bridge_channel *bridge_channel;
5257 int wordlen;
5258
5259 bridge = ast_bridge_find_by_id(bridge_name);
5260 if (!bridge) {
5261 return NULL;
5262 }
5263
5264 wordlen = strlen(word);
5265
5267 AST_LIST_TRAVERSE(&bridge->channels, bridge_channel, entry) {
5268 if (!strncasecmp(ast_channel_name(bridge_channel->chan), word, wordlen)) {
5269 if (ast_cli_completion_add(ast_strdup(ast_channel_name(bridge_channel->chan)))) {
5270 break;
5271 }
5272 }
5273 }
5275
5276 ao2_ref(bridge, -1);
5277
5278 return NULL;
5279}
5280
5281static char *handle_bridge_kick_channel(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
5282{
5283 static const char * const completions[] = { "all", NULL };
5284 struct ast_bridge *bridge;
5285
5286 switch (cmd) {
5287 case CLI_INIT:
5288 e->command = "bridge kick";
5289 e->usage =
5290 "Usage: bridge kick <bridge-id> <channel-name | all>\n"
5291 " Kick the <channel-name> channel out of the <bridge-id> bridge\n"
5292 " If all is specified as the channel name then all channels will be\n"
5293 " kicked out of the bridge.\n";
5294 return NULL;
5295 case CLI_GENERATE:
5296 if (a->pos == 2) {
5297 return complete_bridge_live(a->word);
5298 }
5299 if (a->pos == 3) {
5300 ast_cli_complete(a->word, completions, -1);
5301 return complete_bridge_participant(a->argv[2], a->word);
5302 }
5303 return NULL;
5304 }
5305
5306 if (a->argc != 4) {
5307 return CLI_SHOWUSAGE;
5308 }
5309
5310 bridge = ast_bridge_find_by_id(a->argv[2]);
5311 if (!bridge) {
5312 ast_cli(a->fd, "Bridge '%s' not found\n", a->argv[2]);
5313 return CLI_SUCCESS;
5314 }
5315
5316 if (!strcasecmp(a->argv[3], "all")) {
5317 struct ast_bridge_channel *bridge_channel;
5318
5319 ast_cli(a->fd, "Kicking all channels from bridge '%s'\n", a->argv[2]);
5320
5322 AST_LIST_TRAVERSE(&bridge->channels, bridge_channel, entry) {
5323 ast_bridge_channel_queue_callback(bridge_channel, 0, kick_it, NULL, 0);
5324 }
5326 } else {
5327 struct ast_channel *chan;
5328
5329 chan = ast_channel_get_by_name_prefix(a->argv[3], strlen(a->argv[3]));
5330 if (!chan) {
5331 ast_cli(a->fd, "Channel '%s' not found\n", a->argv[3]);
5332 ao2_ref(bridge, -1);
5333 return CLI_SUCCESS;
5334 }
5335
5336 ast_cli(a->fd, "Kicking channel '%s' from bridge '%s'\n",
5337 ast_channel_name(chan), a->argv[2]);
5338 ast_bridge_kick(bridge, chan);
5339 ast_channel_unref(chan);
5340 }
5341
5342 ao2_ref(bridge, -1);
5343 return CLI_SUCCESS;
5344}
5345
5346/*! Bridge technology capabilities to string. */
5347static const char *tech_capability2str(uint32_t capabilities)
5348{
5349 const char *type;
5350
5351 if (capabilities & AST_BRIDGE_CAPABILITY_HOLDING) {
5352 type = "Holding";
5353 } else if (capabilities & AST_BRIDGE_CAPABILITY_EARLY) {
5354 type = "Early";
5355 } else if (capabilities & AST_BRIDGE_CAPABILITY_NATIVE) {
5356 type = "Native";
5357 } else if (capabilities & AST_BRIDGE_CAPABILITY_1TO1MIX) {
5358 type = "1to1Mix";
5359 } else if (capabilities & AST_BRIDGE_CAPABILITY_MULTIMIX) {
5360 type = "MultiMix";
5361 } else {
5362 type = "<Unknown>";
5363 }
5364 return type;
5365}
5366
5367static char *handle_bridge_technology_show(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
5368{
5369#define FORMAT_HDR "%-20s %-20s %8s %s\n"
5370#define FORMAT_ROW "%-20s %-20s %8u %s\n"
5371
5372 struct ast_bridge_technology *cur;
5373
5374 switch (cmd) {
5375 case CLI_INIT:
5376 e->command = "bridge technology show";
5377 e->usage =
5378 "Usage: bridge technology show\n"
5379 " List registered bridge technologies\n";
5380 return NULL;
5381 case CLI_GENERATE:
5382 return NULL;
5383 }
5384
5385 ast_cli(a->fd, FORMAT_HDR, "Name", "Type", "Priority", "Suspended");
5388 const char *type;
5389
5390 /* Decode type for display */
5392
5393 ast_cli(a->fd, FORMAT_ROW, cur->name, type, cur->preference,
5394 AST_CLI_YESNO(cur->suspended));
5395 }
5397 return CLI_SUCCESS;
5398
5399#undef FORMAT
5400}
5401
5402static char *complete_bridge_technology(const char *word)
5403{
5404 struct ast_bridge_technology *cur;
5405 int wordlen;
5406
5407 wordlen = strlen(word);
5410 if (!strncasecmp(cur->name, word, wordlen)) {
5412 break;
5413 }
5414 }
5415 }
5417
5418 return NULL;
5419}
5420
5421static char *handle_bridge_technology_suspend(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
5422{
5423 struct ast_bridge_technology *cur;
5424 int suspend;
5425 int successful;
5426
5427 switch (cmd) {
5428 case CLI_INIT:
5429 e->command = "bridge technology {suspend|unsuspend}";
5430 e->usage =
5431 "Usage: bridge technology {suspend|unsuspend} <technology-name>\n"
5432 " Suspend or unsuspend a bridge technology.\n";
5433 return NULL;
5434 case CLI_GENERATE:
5435 if (a->pos == 3) {
5436 return complete_bridge_technology(a->word);
5437 }
5438 return NULL;
5439 }
5440
5441 if (a->argc != 4) {
5442 return CLI_SHOWUSAGE;
5443 }
5444
5445 suspend = !strcasecmp(a->argv[2], "suspend");
5446 successful = 0;
5449 if (!strcasecmp(cur->name, a->argv[3])) {
5450 successful = 1;
5451 if (suspend) {
5453 } else {
5455 }
5456 break;
5457 }
5458 }
5460
5461 if (successful) {
5462 if (suspend) {
5463 ast_cli(a->fd, "Suspended bridge technology '%s'\n", a->argv[3]);
5464 } else {
5465 ast_cli(a->fd, "Unsuspended bridge technology '%s'\n", a->argv[3]);
5466 }
5467 } else {
5468 ast_cli(a->fd, "Bridge technology '%s' not found\n", a->argv[3]);
5469 }
5470
5471 return CLI_SUCCESS;
5472}
5473
5474static struct ast_cli_entry bridge_cli[] = {
5475 AST_CLI_DEFINE(handle_bridge_show_all, "List all bridges"),
5476 AST_CLI_DEFINE(handle_bridge_show_specific, "Show information about a bridge"),
5477#ifdef AST_DEVMODE
5478 AST_CLI_DEFINE(handle_bridge_destroy_specific, "Destroy a bridge"),
5479#endif
5480 AST_CLI_DEFINE(handle_bridge_kick_channel, "Kick a channel from a bridge"),
5481 AST_CLI_DEFINE(handle_bridge_technology_show, "List registered bridge technologies"),
5482 AST_CLI_DEFINE(handle_bridge_technology_suspend, "Suspend/unsuspend a bridge technology"),
5483};
5484
5485
5486static int handle_manager_bridge_tech_suspend(struct mansession *s, const struct message *m, int suspend)
5487{
5488 const char *name = astman_get_header(m, "BridgeTechnology");
5489 struct ast_bridge_technology *cur;
5490 int successful = 0;
5491
5492 if (ast_strlen_zero(name)) {
5493 astman_send_error(s, m, "BridgeTechnology must be provided");
5494 return 0;
5495 }
5496
5499
5500 if (!strcasecmp(cur->name, name)) {
5501 successful = 1;
5502 if (suspend) {
5504 } else {
5506 }
5507 break;
5508 }
5509 }
5511 if (!successful) {
5512 astman_send_error(s, m, "BridgeTechnology not found");
5513 return 0;
5514 }
5515
5516 astman_send_ack(s, m, (suspend ? "Suspended bridge technology" : "Unsuspended bridge technology"));
5517 return 0;
5518}
5519
5520static int manager_bridge_tech_suspend(struct mansession *s, const struct message *m)
5521{
5522 return handle_manager_bridge_tech_suspend(s, m, 1);
5523}
5524
5525static int manager_bridge_tech_unsuspend(struct mansession *s, const struct message *m)
5526{
5527 return handle_manager_bridge_tech_suspend(s, m, 0);
5528}
5529
5530static int manager_bridge_tech_list(struct mansession *s, const struct message *m)
5531{
5532 const char *id = astman_get_header(m, "ActionID");
5533 RAII_VAR(struct ast_str *, id_text, ast_str_create(128), ast_free);
5534 struct ast_bridge_technology *cur;
5535 int num_items = 0;
5536
5537 if (!id_text) {
5538 astman_send_error(s, m, "Internal error");
5539 return -1;
5540 }
5541
5542 if (!ast_strlen_zero(id)) {
5543 ast_str_set(&id_text, 0, "ActionID: %s\r\n", id);
5544 }
5545
5546 astman_send_listack(s, m, "Bridge technology listing will follow", "start");
5547
5550 const char *type;
5551
5553
5554 astman_append(s,
5555 "Event: BridgeTechnologyListItem\r\n"
5556 "BridgeTechnology: %s\r\n"
5557 "BridgeType: %s\r\n"
5558 "BridgePriority: %u\r\n"
5559 "BridgeSuspended: %s\r\n"
5560 "%s"
5561 "\r\n",
5562 cur->name, type, cur->preference, AST_YESNO(cur->suspended),
5563 ast_str_buffer(id_text));
5564 ++num_items;
5565 }
5567
5568 astman_send_list_complete_start(s, m, "BridgeTechnologyListComplete", num_items);
5570
5571 return 0;
5572}
5573
5574/*!
5575 * \internal
5576 * \brief Print bridge object key (name).
5577 * \since 12.0.0
5578 *
5579 * \param v_obj A pointer to the object we want the key printed.
5580 * \param where User data needed by prnt to determine where to put output.
5581 * \param prnt Print output callback function to use.
5582 */
5583static void bridge_prnt_obj(void *v_obj, void *where, ao2_prnt_fn *prnt)
5584{
5585 struct ast_bridge *bridge = v_obj;
5586
5587 if (!bridge) {
5588 return;
5589 }
5590 prnt(where, "%s %s chans:%u",
5591 bridge->uniqueid, bridge->v_table->name, bridge->num_channels);
5592}
5593
5594/*!
5595 * \internal
5596 * \brief Shutdown the bridging system. Stuff to do on graceful shutdown.
5597 * \since 13.3.0
5598 */
5599static void bridge_cleanup(void)
5600{
5601 ast_manager_unregister("BridgeTechnologyList");
5602 ast_manager_unregister("BridgeTechnologySuspend");
5603 ast_manager_unregister("BridgeTechnologyUnsuspend");
5605 ao2_container_unregister("bridges");
5606
5608 bridges = NULL;
5611}
5612
5614{
5616
5618 return -1;
5619 }
5620
5622 if (!bridge_manager) {
5623 return -1;
5624 }
5625
5628 if (!bridges) {
5629 return -1;
5630 }
5632
5634
5636
5637 ast_manager_register_xml_core("BridgeTechnologyList", 0, manager_bridge_tech_list);
5638 ast_manager_register_xml_core("BridgeTechnologySuspend", 0, manager_bridge_tech_suspend);
5639 ast_manager_register_xml_core("BridgeTechnologyUnsuspend", 0, manager_bridge_tech_unsuspend);
5640
5641 return 0;
5642}
Prototypes for public functions only of internal interest,.
static const char app[]
Definition: app_adsiprog.c:56
static int play_file(struct ast_bridge_channel *bridge_channel, struct ast_channel *channel, const char *filename)
Playback the given filename and monitor for any dtmf interrupts.
enum queue_result id
Definition: app_queue.c:1808
ast_cond_t cond
Definition: app_sla.c:336
ast_mutex_t lock
Definition: app_sla.c:337
Asterisk main include file. File version handling, generic pbx functions.
int ast_register_cleanup(void(*func)(void))
Register a function to be executed before Asterisk gracefully exits.
Definition: clicompat.c:19
#define ast_alloca(size)
call __builtin_alloca to ensure we get gcc builtin semantics
Definition: astmm.h:288
#define ast_free(a)
Definition: astmm.h:180
#define ast_strdup(str)
A wrapper for strdup()
Definition: astmm.h:241
#define ast_strdupa(s)
duplicate a string in memory from the stack
Definition: astmm.h:298
#define ast_calloc(num, len)
A wrapper for calloc()
Definition: astmm.h:202
#define ast_malloc(len)
A wrapper for malloc()
Definition: astmm.h:191
#define ast_log
Definition: astobj2.c:42
#define ao2_iterator_next(iter)
Definition: astobj2.h:1911
#define ao2_link(container, obj)
Add an object to a container.
Definition: astobj2.h:1532
@ CMP_MATCH
Definition: astobj2.h:1027
@ CMP_STOP
Definition: astobj2.h:1028
#define OBJ_KEY
Definition: astobj2.h:1151
#define OBJ_POINTER
Definition: astobj2.h:1150
@ AO2_ALLOC_OPT_LOCK_NOLOCK
Definition: astobj2.h:367
@ AO2_ALLOC_OPT_LOCK_MUTEX
Definition: astobj2.h:363
#define ao2_callback(c, flags, cb_fn, arg)
ao2_callback() is a generic function that applies cb_fn() to all objects in a container,...
Definition: astobj2.h:1693
void ao2_container_unregister(const char *name)
Unregister a container for CLI stats and integrity check.
int ao2_container_count(struct ao2_container *c)
Returns the number of elements in a container.
#define ao2_cleanup(obj)
Definition: astobj2.h:1934
#define ao2_unlink(container, obj)
Remove an object from a container.
Definition: astobj2.h:1578
#define ao2_find(container, arg, flags)
Definition: astobj2.h:1736
struct ao2_iterator ao2_iterator_init(struct ao2_container *c, int flags) attribute_warn_unused_result
Create an iterator for a container.
#define ao2_container_alloc_rbtree(ao2_options, container_options, sort_fn, cmp_fn)
Allocate and initialize a red-black tree container.
Definition: astobj2.h:1349
#define ao2_unlock(a)
Definition: astobj2.h:729
#define ao2_lock(a)
Definition: astobj2.h:717
#define ao2_ref(o, delta)
Reference/unreference an object and return the old refcount.
Definition: astobj2.h:459
#define ao2_t_bump(obj, tag)
Definition: astobj2.h:483
#define OBJ_PARTIAL_KEY
Definition: astobj2.h:1152
#define ao2_alloc_options(data_size, destructor_fn, options)
Definition: astobj2.h:404
#define ao2_t_cleanup(obj, tag)
Definition: astobj2.h:1935
int ao2_container_register(const char *name, struct ao2_container *self, ao2_prnt_obj_fn *prnt_obj)
Register a container for CLI stats and integrity check.
void * ao2_object_get_lockaddr(void *obj)
Return the mutex lock address of an object.
Definition: astobj2.c:476
#define ao2_bump(obj)
Bump refcount on an AO2 object by one, returning the object.
Definition: astobj2.h:480
void ao2_iterator_destroy(struct ao2_iterator *iter)
Destroy a container iterator.
@ OBJ_NODATA
Definition: astobj2.h:1044
@ OBJ_MULTIPLE
Definition: astobj2.h:1049
@ OBJ_UNLINK
Definition: astobj2.h:1039
@ OBJ_SEARCH_KEY
The arg parameter is a search key, but is not an object.
Definition: astobj2.h:1101
#define ao2_container_alloc_list(ao2_options, container_options, sort_fn, cmp_fn)
Allocate and initialize a list container.
Definition: astobj2.h:1327
#define ao2_alloc(data_size, destructor_fn)
Definition: astobj2.h:409
#define ao2_container_alloc_hash(ao2_options, container_options, n_buckets, hash_fn, sort_fn, cmp_fn)
Allocate and initialize a hash container with the desired number of buckets.
Definition: astobj2.h:1303
void() ao2_prnt_fn(void *where, const char *fmt,...)
Print output.
Definition: astobj2.h:1435
@ AO2_CONTAINER_ALLOC_OPT_DUPS_REPLACE
Replace objects with duplicate keys in container.
Definition: astobj2.h:1211
int ast_bridge_depart(struct ast_channel *chan)
Depart a channel from a bridge.
Definition: bridge.c:1975
void ast_bridge_set_transfer_variables(struct ast_channel *chan, const char *value, int attended)
Set the relevant transfer variables for a single channel.
Definition: bridge.c:4421
void ast_bridge_set_remb_estimated_bitrate(struct ast_bridge *bridge, float estimated_bitrate)
Force the REMB report estimated bitrate to a specific max value.
Definition: bridge.c:3876
static struct ast_channel * get_transferee(struct ao2_container *channels, struct ast_channel *transferer)
Definition: bridge.c:4251
struct ao2_container * ast_bridges(void)
Returns the global bridges container.
Definition: bridge.c:185
static struct bridge_manager_controller * bridge_manager
Definition: bridge.c:183
void ast_bridge_set_talker_src_video_mode(struct ast_bridge *bridge)
Set the bridge to pick the strongest talker supporting video as the single source video feed.
Definition: bridge.c:3835
int ast_bridging_init(void)
Initialize the bridging system.
Definition: bridge.c:5613
struct ast_bridge * ast_bridge_base_new(uint32_t capabilities, unsigned int flags, const char *creator, const char *name, const char *id)
Create a new base class bridge.
Definition: bridge.c:999
static void bridge_channel_complete_join(struct ast_bridge *bridge, struct ast_bridge_channel *bridge_channel)
Definition: bridge.c:452
int ast_bridge_join(struct ast_bridge *bridge, struct ast_channel *chan, struct ast_channel *swap, struct ast_bridge_features *features, struct ast_bridge_tech_optimizations *tech_args, enum ast_bridge_join_flags flags)
Join a channel to a bridge (blocking)
Definition: bridge.c:1690
static int bridge_base_push_peek(struct ast_bridge *self, struct ast_bridge_channel *bridge_channel, struct ast_bridge_channel *swap)
Definition: bridge.c:983
static enum ast_transfer_result two_bridge_attended_transfer(struct ast_channel *to_transferee, struct ast_bridge_channel *to_transferee_bridge_channel, struct ast_channel *to_transfer_target, struct ast_bridge_channel *to_target_bridge_channel, struct ast_bridge *to_transferee_bridge, struct ast_bridge *to_target_bridge, struct ast_attended_transfer_message *transfer_msg)
Definition: bridge.c:4680
static int manager_bridge_tech_list(struct mansession *s, const struct message *m)
Definition: bridge.c:5530
static void bridge_channel_impart_ds_head_signal(struct bridge_channel_impart_ds_head *ds_head)
Definition: bridge.c:1563
static int channel_hash(const void *obj, int flags)
Definition: bridge.c:4042
int ast_bridge_hangup_hook(struct ast_bridge_features *features, ast_bridge_hook_callback callback, void *hook_pvt, ast_bridge_hook_pvt_destructor destructor, enum ast_bridge_hook_remove_flags remove_flags)
Attach a hangup hook to a bridge features structure.
Definition: bridge.c:3334
void ast_bridge_set_binaural_active(struct ast_bridge *bridge, unsigned int binaural_active)
Activates the use of binaural signals in a conference bridge.
Definition: bridge.c:3774
void ast_bridge_technology_unsuspend(struct ast_bridge_technology *technology)
Unsuspend a bridge technology.
Definition: bridge.c:3121
static void hooks_remove_heap(struct ast_heap *hooks, enum ast_bridge_hook_remove_flags remove_flags)
Definition: bridge.c:3548
struct ast_channel * ast_bridge_peer_nolock(struct ast_bridge *bridge, struct ast_channel *chan)
Get the channel's bridge peer only if the bridge is two-party.
Definition: bridge.c:4116
int ast_bridge_features_set_limits(struct ast_bridge_features *features, struct ast_bridge_features_limits *limits, enum ast_bridge_hook_remove_flags remove_flags)
Limit the amount of time a channel may stay in the bridge and optionally play warning messages as tim...
Definition: bridge.c:3481
int ast_bridge_number_video_src(struct ast_bridge *bridge)
Returns the number of video sources currently active in the bridge.
Definition: bridge.c:3933
struct ao2_container * ast_bridge_peers_nolock(struct ast_bridge *bridge)
Get a container of all channels in the bridge.
Definition: bridge.c:4087
static void set_bridge_peer_vars_2party(struct ast_channel *c0, struct ast_channel *c1)
Definition: bridge.c:1300
static char builtin_features_dtmf[AST_BRIDGE_BUILTIN_END][MAXIMUM_DTMF_FEATURE_STRING]
Definition: bridge.c:155
static void bridge_channel_impart_ds_head_fixup(void *data, struct ast_channel *old_chan, struct ast_channel *new_chan)
Definition: bridge.c:1592
#define UPDATE_BRIDGE_VARS_GET(chan, name, pvtid)
int ast_bridge_features_init(struct ast_bridge_features *features)
Initialize bridge features structure.
Definition: bridge.c:3689
void bridge_do_merge(struct ast_bridge *dst_bridge, struct ast_bridge *src_bridge, struct ast_bridge_channel **kick_me, unsigned int num_kick, unsigned int optimized)
Definition: bridge.c:2117
static void bridge_queue_action_nodup(struct ast_bridge *bridge, struct ast_frame *action)
Definition: bridge.c:303
void ast_bridge_set_sfu_video_mode(struct ast_bridge *bridge)
Set the bridge to be a selective forwarding unit.
Definition: bridge.c:3843
static int manager_bridge_tech_suspend(struct mansession *s, const struct message *m)
Definition: bridge.c:5520
static enum ast_transfer_result bridge_swap_attended_transfer(struct ast_bridge *dest_bridge, struct ast_bridge_channel *source_bridge_channel, struct ast_channel *swap_channel)
Definition: bridge.c:4637
static void bridge_manager_service(struct ast_bridge *bridge)
Definition: bridge.c:4938
int ast_bridge_features_unregister(enum ast_bridge_builtin_feature feature)
Unregister a handler for a built in feature.
Definition: bridge.c:3147
static unsigned int optimization_id
Definition: bridge.c:138
static int bridge_other_hook(struct ast_bridge_features *features, ast_bridge_hook_callback callback, void *hook_pvt, ast_bridge_hook_pvt_destructor destructor, enum ast_bridge_hook_remove_flags remove_flags, enum ast_bridge_hook_type type)
Definition: bridge.c:3300
static void bridge_base_dissolving(struct ast_bridge *self)
Definition: bridge.c:893
int ast_bridge_features_limits_construct(struct ast_bridge_features_limits *limits)
Constructor function for ast_bridge_features_limits.
Definition: bridge.c:3465
void ast_bridge_set_maximum_sample_rate(struct ast_bridge *bridge, unsigned int sample_rate)
Adjust the maximum mixing sample rate of a bridge used during multimix mode.
Definition: bridge.c:3788
static int hook_remove_match(void *obj, void *arg, int flags)
Definition: bridge.c:3514
void bridge_dissolve(struct ast_bridge *bridge, int cause)
Definition: bridge.c:326
static int manager_bridge_tech_unsuspend(struct mansession *s, const struct message *m)
Definition: bridge.c:5525
int ast_bridge_interval_hook(struct ast_bridge_features *features, enum ast_bridge_hook_timer_option flags, unsigned int interval, ast_bridge_hook_callback callback, void *hook_pvt, ast_bridge_hook_pvt_destructor destructor, enum ast_bridge_hook_remove_flags remove_flags)
Attach an interval hook to a bridge features structure.
Definition: bridge.c:3388
static void bridge_channel_impart_wait(struct bridge_channel_impart_cond *cond)
Definition: bridge.c:1670
static struct ast_cli_entry bridge_cli[]
Definition: bridge.c:5474
#define FORMAT_ROW
static int interval_hook_time_cmp(void *a, void *b)
Definition: bridge.c:3577
#define BLINDTRANSFER
Definition: bridge.c:147
void ast_bridge_set_video_update_discard(struct ast_bridge *bridge, unsigned int video_update_discard)
Set the amount of time to discard subsequent video updates after a video update has been sent.
Definition: bridge.c:3851
int ast_bridge_move_hook(struct ast_bridge_features *features, ast_bridge_move_indicate_callback callback, void *hook_pvt, ast_bridge_hook_pvt_destructor destructor, enum ast_bridge_hook_remove_flags remove_flags)
Attach a bridge channel move detection hook to a bridge features structure.
Definition: bridge.c:3376
static const char * tech_capability2str(uint32_t capabilities)
Definition: bridge.c:5347
int ast_bridge_talk_detector_hook(struct ast_bridge_features *features, ast_bridge_talking_indicate_callback callback, void *hook_pvt, ast_bridge_hook_pvt_destructor destructor, enum ast_bridge_hook_remove_flags remove_flags)
Attach a bridge channel talk detection hook to a bridge features structure.
Definition: bridge.c:3364
void ast_bridge_features_remove(struct ast_bridge_features *features, enum ast_bridge_hook_remove_flags remove_flags)
Remove marked bridge channel feature hooks.
Definition: bridge.c:3570
int ast_bridge_dtmf_hook(struct ast_bridge_features *features, const char *dtmf, ast_bridge_hook_callback callback, void *hook_pvt, ast_bridge_hook_pvt_destructor destructor, enum ast_bridge_hook_remove_flags remove_flags)
Attach a DTMF hook to a bridge features structure.
Definition: bridge.c:3251
static void bridge_hook_destroy(void *vhook)
Definition: bridge.c:3208
static int channel_cmp(void *obj, void *arg, int flags)
Definition: bridge.c:4065
int ast_bridge_impart(struct ast_bridge *bridge, struct ast_channel *chan, struct ast_channel *swap, struct ast_bridge_features *features, enum ast_bridge_impart_flags flags)
Impart a channel to a bridge (non-blocking)
Definition: bridge.c:1947
int ast_bridge_queue_action(struct ast_bridge *bridge, struct ast_frame *action)
Put an action onto the specified bridge.
Definition: bridge.c:314
int ast_bridge_destroy(struct ast_bridge *bridge, int cause)
Destroy a bridge.
Definition: bridge.c:1009
static int bridge_sort_cmp(const void *obj_left, const void *obj_right, int flags)
Definition: bridge.c:5059
static enum ast_transfer_result attended_transfer_bridge(struct ast_channel *chan1, struct ast_channel *chan2, struct ast_bridge *bridge1, struct ast_bridge *bridge2, struct ast_attended_transfer_message *transfer_msg)
Perform an attended transfer of a bridge.
Definition: bridge.c:4290
static int handle_manager_bridge_tech_suspend(struct mansession *s, const struct message *m, int suspend)
Definition: bridge.c:5486
static void bridge_manager_destroy(void *obj)
Definition: bridge.c:4988
static int bridge_dtmf_hook_sort(const void *obj_left, const void *obj_right, int flags)
Definition: bridge.c:3608
static void check_bridge_play_sounds(struct ast_bridge *bridge)
Definition: bridge.c:1272
static int try_merge_optimize_out(struct ast_bridge *chan_bridge, struct ast_bridge_channel *chan_bridge_channel, struct ast_bridge *peer_bridge, struct ast_bridge_channel *peer_bridge_channel, struct ast_unreal_pvt *pvt)
Definition: bridge.c:2938
void ast_bridge_features_set_flag(struct ast_bridge_features *features, unsigned int flag)
Set a flag on a bridge channel features structure.
Definition: bridge.c:3496
struct ast_bridge_methods ast_bridge_base_v_table
Bridge base class virtual method table.
Definition: bridge.c:988
int ast_bridge_features_do(enum ast_bridge_builtin_feature feature, struct ast_bridge_channel *bridge_channel, void *hook_pvt)
Invoke a built in feature hook now.
Definition: bridge.c:3159
void ast_brige_set_remb_behavior(struct ast_bridge *bridge, enum ast_bridge_video_sfu_remb_behavior behavior)
Set the REMB report generation behavior on a bridge.
Definition: bridge.c:3867
static void * bridge_manager_thread(void *data)
Definition: bridge.c:4955
struct ast_bridge * ast_bridge_transfer_acquire_bridge(struct ast_channel *chan)
Acquire the channel's bridge for transfer purposes.
Definition: bridge.c:4477
int ast_bridge_join_hook(struct ast_bridge_features *features, ast_bridge_hook_callback callback, void *hook_pvt, ast_bridge_hook_pvt_destructor destructor, enum ast_bridge_hook_remove_flags remove_flags)
Attach a bridge channel join hook to a bridge features structure.
Definition: bridge.c:3344
static struct ast_bridge * optimize_lock_chan_stack(struct ast_channel *chan)
Definition: bridge.c:2648
static int complete_bridge_live_search(void *obj, void *arg, int flags)
Definition: bridge.c:5086
struct ast_bridge * bridge_register(struct ast_bridge *bridge)
Register the new bridge with the system.
Definition: bridge.c:713
static int bridge_merge_locked(struct ast_bridge *dst_bridge, struct ast_bridge *src_bridge, int merge_best_direction, struct ast_channel **kick_me, unsigned int num_kick)
Definition: bridge.c:2285
static enum bridge_allow_merge bridges_allow_merge_optimization(struct ast_bridge *chan_bridge, struct ast_bridge *peer_bridge, int num_kick_channels, struct merge_direction *merge)
Definition: bridge.c:2904
static int bridge_move_locked(struct ast_bridge *dst_bridge, struct ast_bridge *src_bridge, struct ast_channel *chan, struct ast_channel *swap, int attempt_recovery)
Definition: bridge.c:2468
struct ast_bridge_features * ast_bridge_features_new(void)
Allocate a new bridge features struct.
Definition: bridge.c:3752
static void bridge_channel_impart_ds_head_dtor(void *doomed)
Definition: bridge.c:1577
int ast_bridge_remove(struct ast_bridge *bridge, struct ast_channel *chan)
Remove a channel from a bridge.
Definition: bridge.c:2020
void ast_bridge_vars_set(struct ast_channel *chan, const char *name, const char *pvtid)
Sets BRIDGECHANNEL and BRIDGEPVTCALLID for a channel.
Definition: bridge.c:1281
struct ast_bridge * bridge_base_init(struct ast_bridge *self, uint32_t capabilities, unsigned int flags, const char *creator, const char *name, const char *id)
Initialize the base class of the bridge.
Definition: bridge.c:783
void ast_bridge_merge_inhibit(struct ast_bridge *bridge, int request)
Adjust the bridge merge inhibit request count.
Definition: bridge.c:3069
static void fill_bridgepeer_buf(char *buf, unsigned int cur_idx, const char *names[], unsigned int num_names)
Definition: bridge.c:1338
void bridge_reconfigured(struct ast_bridge *bridge, unsigned int colp_update)
Definition: bridge.c:1472
static char * handle_bridge_technology_suspend(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
Definition: bridge.c:5421
int ast_bridge_kick(struct ast_bridge *bridge, struct ast_channel *chan)
Kick a channel from a bridge.
Definition: bridge.c:2048
static int smart_bridge_operation(struct ast_bridge *bridge)
Definition: bridge.c:1041
void bridge_channel_impart_signal(struct ast_channel *chan)
Definition: bridge.c:1651
static int bridge_base_push(struct ast_bridge *self, struct ast_bridge_channel *bridge_channel, struct ast_bridge_channel *swap)
Definition: bridge.c:917
static int bridge_base_get_merge_priority(struct ast_bridge *self)
Definition: bridge.c:963
static ast_bridge_builtin_set_limits_fn builtin_interval_handlers[AST_BRIDGE_BUILTIN_INTERVAL_END]
Definition: bridge.c:161
static ast_bridge_hook_callback builtin_features_handlers[AST_BRIDGE_BUILTIN_END]
Definition: bridge.c:158
static int merge_container_cb(void *obj, void *data, int flags)
Callback for merging hook ao2_containers.
Definition: bridge.c:3631
static char * handle_bridge_technology_show(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
Definition: bridge.c:5367
struct ast_bridge * ast_bridge_find_by_id(const char *bridge_id)
Find bridge by id.
Definition: bridge.c:5081
struct ast_channel * ast_bridge_peer(struct ast_bridge *bridge, struct ast_channel *chan)
Get the channel's bridge peer only if the bridge is two-party.
Definition: bridge.c:4144
struct ast_bridge_channel * bridge_find_channel(struct ast_bridge *bridge, struct ast_channel *chan)
Definition: bridge.c:1498
static char * handle_bridge_kick_channel(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
Definition: bridge.c:5281
int ast_bridge_suspend(struct ast_bridge *bridge, struct ast_channel *chan)
Suspend a channel temporarily from a bridge.
Definition: bridge.c:3076
static void bridge_prnt_obj(void *v_obj, void *where, ao2_prnt_fn *prnt)
Definition: bridge.c:5583
static const struct ast_datastore_info bridge_channel_impart_ds_info
Definition: bridge.c:1601
void ast_bridge_set_single_src_video_mode(struct ast_bridge *bridge, struct ast_channel *video_src_chan)
Set a bridge to feed a single video source to all participants.
Definition: bridge.c:3818
void ast_bridge_set_mixing_interval(struct ast_bridge *bridge, unsigned int mixing_interval)
Adjust the internal mixing interval of a bridge used during multimix mode.
Definition: bridge.c:3767
static struct ast_bridge * optimize_lock_peer_stack(struct ast_channel *peer)
Definition: bridge.c:2693
struct ao2_container * ast_bridge_peers(struct ast_bridge *bridge)
Get a container of all channels in the bridge.
Definition: bridge.c:4105
#define MAX_BRIDGEPEER_CHANS
static void set_transfer_variables_all(struct ast_channel *transferer, struct ao2_container *channels, int is_attended)
Definition: bridge.c:4452
static void bridge_base_destroy(struct ast_bridge *self)
Definition: bridge.c:880
void ast_bridge_features_merge(struct ast_bridge_features *into, const struct ast_bridge_features *from)
Merge one ast_bridge_features into another.
Definition: bridge.c:3664
static int try_swap_optimize_out(struct ast_bridge *chan_bridge, struct ast_bridge_channel *chan_bridge_channel, struct ast_bridge *peer_bridge, struct ast_bridge_channel *peer_bridge_channel, struct ast_unreal_pvt *pvt)
Definition: bridge.c:2814
static void wrap_hook(struct ast_bridge_features *features, struct ast_bridge_hook_timer *hook)
Wrap the provided interval hook and add it to features.
Definition: bridge.c:3652
struct ast_bridge * bridge_alloc(size_t size, const struct ast_bridge_methods *v_table)
Definition: bridge.c:747
void ast_bridge_remove_video_src(struct ast_bridge *bridge, struct ast_channel *chan)
remove a channel as a source of video for the bridge.
Definition: bridge.c:3986
enum ast_transfer_result ast_bridge_transfer_blind(int is_external, struct ast_channel *transferer, const char *exten, const char *context, transfer_channel_cb new_channel_cb, void *user_data)
Blind transfer target to the extension and context provided.
Definition: bridge.c:4494
static void destroy_bridge(void *obj)
Definition: bridge.c:659
bridge_allow_swap
Definition: bridge.c:2741
@ SWAP_PROHIBITED
Definition: bridge.c:2743
@ SWAP_TO_PEER_BRIDGE
Definition: bridge.c:2747
@ SWAP_TO_CHAN_BRIDGE
Definition: bridge.c:2745
static int interval_wrapper_cb(struct ast_bridge_channel *bridge_channel, void *obj)
Wrapper for interval hooks that calls into the wrapped hook.
Definition: bridge.c:3638
const char * ast_bridge_video_mode_to_string(enum ast_bridge_video_mode_type video_mode)
Converts an enum representation of a bridge video mode to string.
Definition: bridge.c:4020
static void hooks_remove_container(struct ao2_container *hooks, enum ast_bridge_hook_remove_flags remove_flags)
Definition: bridge.c:3534
static void bridge_reconfigured_connected_line_update(struct ast_bridge *bridge)
Definition: bridge.c:404
static void cleanup_video_mode(struct ast_bridge *bridge)
Definition: bridge.c:3795
int ast_bridge_merge(struct ast_bridge *dst_bridge, struct ast_bridge *src_bridge, int merge_best_direction, struct ast_channel **kick_me, unsigned int num_kick)
Merge two bridges together.
Definition: bridge.c:2369
#define BRIDGE_LOCK_ONE_OR_BOTH(b1, b2)
static enum ast_transfer_result try_parking(struct ast_channel *transferer, const char *context, const char *exten, transfer_channel_cb new_channel_cb, struct transfer_channel_data *user_data_wrapper)
Definition: bridge.c:4395
static struct ao2_container * bridges
Definition: bridge.c:132
int ast_bridge_leave_hook(struct ast_bridge_features *features, ast_bridge_hook_callback callback, void *hook_pvt, ast_bridge_hook_pvt_destructor destructor, enum ast_bridge_hook_remove_flags remove_flags)
Attach a bridge channel leave hook to a bridge features structure.
Definition: bridge.c:3354
int ast_bridge_unsuspend(struct ast_bridge *bridge, struct ast_channel *chan)
Unsuspend a channel from a bridge.
Definition: bridge.c:3097
void ast_bridge_set_send_sdp_label(struct ast_bridge *bridge, unsigned int send_sdp_label)
Controls whether to send a "label" attribute in each stream in an SDP.
Definition: bridge.c:4035
int ast_bridge_add_channel(struct ast_bridge *bridge, struct ast_channel *chan, struct ast_bridge_features *features, int play_tone, const char *xfersound)
Add an arbitrary channel to a bridge.
Definition: bridge.c:2540
int ast_bridge_interval_register(enum ast_bridge_builtin_interval interval, ast_bridge_builtin_set_limits_fn callback)
Register a handler for a built in interval feature.
Definition: bridge.c:3176
static void set_bridge_peer_vars_multiparty(struct ast_bridge *bridge)
Definition: bridge.c:1375
static char * complete_bridge_live(const char *word)
Definition: bridge.c:5097
void ast_bridge_features_cleanup(struct ast_bridge_features *features)
Clean up the contents of a bridge features structure.
Definition: bridge.c:3722
static void bridge_action_bridge(struct ast_bridge *bridge, struct ast_frame *action)
Definition: bridge.c:607
bridge_allow_merge
Definition: bridge.c:2880
@ MERGE_ALLOWED
Definition: bridge.c:2888
@ MERGE_NOT_ENOUGH_CHANNELS
Definition: bridge.c:2884
@ MERGE_NO_MULTIMIX
Definition: bridge.c:2886
@ MERGE_PROHIBITED
Definition: bridge.c:2882
static enum ast_transfer_result blind_transfer_bridge(int is_external, struct ast_channel *transferer, struct ast_bridge *bridge, const char *exten, const char *context, struct ast_channel *transferee, transfer_channel_cb new_channel_cb, struct transfer_channel_data *user_data_wrapper, struct ast_blind_transfer_message *transfer_message)
Definition: bridge.c:4180
static struct ast_bridge_hook * bridge_hook_generic(size_t size, ast_bridge_hook_callback callback, void *hook_pvt, ast_bridge_hook_pvt_destructor destructor, enum ast_bridge_hook_remove_flags remove_flags)
Definition: bridge.c:3231
void ast_bridge_update_talker_src_video_mode(struct ast_bridge *bridge, struct ast_channel *chan, int talker_energy, int is_keyframe)
Update information about talker energy for talker src video mode.
Definition: bridge.c:3885
static void bridge_cleanup(void)
Definition: bridge.c:5599
static void bridge_channel_change_bridge(struct ast_bridge_channel *bridge_channel, struct ast_bridge *new_bridge)
Definition: bridge.c:2076
static struct bridge_manager_controller * bridge_manager_create(void)
Definition: bridge.c:5020
static char * handle_bridge_show_all(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
Definition: bridge.c:5105
static void bridge_handle_actions(struct ast_bridge *bridge)
Definition: bridge.c:641
static int bridge_impart_internal(struct ast_bridge *bridge, struct ast_channel *chan, struct ast_channel *swap, struct ast_bridge_features *features, enum ast_bridge_impart_flags flags, struct bridge_channel_impart_cond *cond)
Definition: bridge.c:1846
static void * bridge_channel_depart_thread(void *data)
Thread responsible for imparted bridged channels to be departed.
Definition: bridge.c:1780
int ast_bridge_technology_unregister(struct ast_bridge_technology *technology)
Unregister a bridge technology from use.
Definition: bridge.c:274
static void bridge_complete_join(struct ast_bridge *bridge)
Definition: bridge.c:493
int ast_bridge_interval_unregister(enum ast_bridge_builtin_interval interval)
Unregisters a handler for a built in interval feature.
Definition: bridge.c:3188
#define ATTENDEDTRANSFER
Definition: bridge.c:150
int ast_bridge_unreal_optimize_out(struct ast_channel *chan, struct ast_channel *peer, struct ast_unreal_pvt *pvt)
Check and optimize out the unreal channels between bridges.
Definition: bridge.c:2989
static void kick_it(struct ast_bridge_channel *bridge_channel, const void *payload, size_t payload_size)
Definition: bridge.c:2043
static char * complete_bridge_participant(const char *bridge_name, const char *word)
Definition: bridge.c:5253
void ast_bridge_technology_suspend(struct ast_bridge_technology *technology)
Suspend a bridge technology from consideration.
Definition: bridge.c:3116
int __ast_bridge_technology_register(struct ast_bridge_technology *technology, struct ast_module *module)
Register a bridge technology for use.
Definition: bridge.c:223
void ast_bridge_features_destroy(struct ast_bridge_features *features)
Destroy an allocated bridge features struct.
Definition: bridge.c:3743
int ast_bridge_features_enable(struct ast_bridge_features *features, enum ast_bridge_builtin_feature feature, const char *dtmf, void *config, ast_bridge_hook_pvt_destructor destructor, enum ast_bridge_hook_remove_flags remove_flags)
Enable a built in feature on a bridge features structure.
Definition: bridge.c:3434
enum ast_bridge_optimization ast_bridges_allow_optimization(struct ast_bridge *chan_bridge, struct ast_bridge *peer_bridge)
Determine if bridges allow for optimization to occur betweem them.
Definition: bridge.c:3029
static void check_bridge_play_sound(struct ast_bridge_channel *bridge_channel)
Definition: bridge.c:1244
int bridge_do_move(struct ast_bridge *dst_bridge, struct ast_bridge_channel *bridge_channel, int attempt_recovery, unsigned int optimized)
Definition: bridge.c:2383
static void set_bridge_peer_vars(struct ast_bridge *bridge)
Definition: bridge.c:1455
static int bridge_channel_impart_add(struct ast_channel *chan, struct bridge_channel_impart_cond *cond)
Definition: bridge.c:1618
int ast_bridge_is_video_src(struct ast_bridge *bridge, struct ast_channel *chan)
Determine if a channel is a video src for the bridge.
Definition: bridge.c:3960
static void bridge_channel_moving(struct ast_bridge_channel *bridge_channel, struct ast_bridge *src, struct ast_bridge *dst)
Definition: bridge.c:2091
static struct ast_bridge_technology * find_best_technology(uint32_t capabilities, struct ast_bridge *bridge)
Helper function used to find the "best" bridge technology given specified capabilities.
Definition: bridge.c:518
static void bridge_manager_service_req(struct ast_bridge *bridge)
Definition: bridge.c:197
static char * complete_bridge_technology(const char *word)
Definition: bridge.c:5402
void ast_bridge_features_limits_destroy(struct ast_bridge_features_limits *limits)
Destructor function for ast_bridge_features_limits.
Definition: bridge.c:3476
void bridge_merge_inhibit_nolock(struct ast_bridge *bridge, int request)
Definition: bridge.c:3060
int ast_bridge_features_register(enum ast_bridge_builtin_feature feature, ast_bridge_hook_callback callback, const char *dtmf)
Register a handler for a built in feature.
Definition: bridge.c:3131
static struct merge_direction bridge_merge_determine_direction(struct ast_bridge *bridge1, struct ast_bridge *bridge2)
Definition: bridge.c:2222
static void bridge_base_pull(struct ast_bridge *self, struct ast_bridge_channel *bridge_channel)
Definition: bridge.c:932
static void bridge_dissolve_check_stolen(struct ast_bridge *bridge, struct ast_bridge_channel *bridge_channel)
Definition: bridge.c:374
void ast_bridge_set_remb_send_interval(struct ast_bridge *bridge, unsigned int remb_send_interval)
Set the interval at which a combined REMB frame will be sent to video sources.
Definition: bridge.c:3858
static enum bridge_allow_swap bridges_allow_swap_optimization(struct ast_bridge *chan_bridge, struct ast_bridge *peer_bridge)
Definition: bridge.c:2758
static char * handle_bridge_show_specific(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
Definition: bridge.c:5169
void ast_bridge_notify_masquerade(struct ast_channel *chan)
Notify bridging that this channel was just masqueraded.
Definition: bridge.c:1511
enum ast_transfer_result ast_bridge_transfer_attended(struct ast_channel *to_transferee, struct ast_channel *to_transfer_target)
Attended transfer.
Definition: bridge.c:4746
static int bridge_show_specific_print_channel(void *obj, void *arg, int flags)
Internal callback function for sending channels in a bridge to the CLI.
Definition: bridge.c:5152
int ast_bridge_move(struct ast_bridge *dst_bridge, struct ast_bridge *src_bridge, struct ast_channel *chan, struct ast_channel *swap, int attempt_recovery)
Move a channel from one bridge to another.
Definition: bridge.c:2529
static void bridge_tech_deferred_destroy(struct ast_bridge *bridge, struct ast_frame *action)
Definition: bridge.c:579
static void bridge_base_notify_masquerade(struct ast_bridge *self, struct ast_bridge_channel *bridge_channel)
Definition: bridge.c:947
static int bridge_allows_optimization(struct ast_bridge *bridge)
Definition: bridge.c:2629
void ast_bridge_set_internal_sample_rate(struct ast_bridge *bridge, unsigned int sample_rate)
Adjust the internal mixing sample rate of a bridge used during multimix mode.
Definition: bridge.c:3781
static ast_mutex_t bridge_init_lock
Definition: bridge.c:136
static void interval_wrapper_pvt_dtor(void *obj)
Destructor for the hook wrapper.
Definition: bridge.c:3646
#define FORMAT_HDR
static void * bridge_channel_ind_thread(void *data)
Thread responsible for independent imparted bridged channels.
Definition: bridge.c:1811
static void set_bridge_peer_vars_holding(struct ast_bridge *bridge)
Definition: bridge.c:1435
Bridging API.
#define ast_bridge_lock_both(bridge1, bridge2)
Lock two bridges.
Definition: bridge.h:492
#define ast_bridge_unlock(bridge)
Unlock the bridge.
Definition: bridge.h:485
ast_bridge_optimization
Tells, if optimization is allowed, how the optimization would be performed.
Definition: bridge.h:878
@ AST_BRIDGE_OPTIMIZE_PROHIBITED
Definition: bridge.h:888
@ AST_BRIDGE_OPTIMIZE_MERGE_TO_CHAN_BRIDGE
Definition: bridge.h:884
@ AST_BRIDGE_OPTIMIZE_SWAP_TO_PEER_BRIDGE
Definition: bridge.h:882
@ AST_BRIDGE_OPTIMIZE_MERGE_TO_PEER_BRIDGE
Definition: bridge.h:886
@ AST_BRIDGE_OPTIMIZE_SWAP_TO_CHAN_BRIDGE
Definition: bridge.h:880
ast_bridge_video_sfu_remb_behavior
REMB report behaviors.
Definition: bridge.h:135
#define ast_bridge_trylock(bridge)
Try locking the bridge.
Definition: bridge.h:463
@ AST_BRIDGE_CAPABILITY_EARLY
Definition: bridge.h:92
@ AST_BRIDGE_CAPABILITY_MULTIMIX
Definition: bridge.h:98
@ AST_BRIDGE_CAPABILITY_NATIVE
Definition: bridge.h:94
@ AST_BRIDGE_CAPABILITY_1TO1MIX
Definition: bridge.h:96
@ AST_BRIDGE_CAPABILITY_HOLDING
Definition: bridge.h:90
@ AST_BRIDGE_TRANSFER_MULTI_PARTY
Definition: bridge.h:1117
void(* transfer_channel_cb)(struct ast_channel *chan, struct transfer_channel_data *user_data, enum ast_transfer_type transfer_type)
Callback function type called during blind transfers.
Definition: bridge.h:1147
ast_transfer_result
Definition: bridge.h:1102
@ AST_BRIDGE_TRANSFER_NOT_PERMITTED
Definition: bridge.h:1106
@ AST_BRIDGE_TRANSFER_SUCCESS
Definition: bridge.h:1104
@ AST_BRIDGE_TRANSFER_INVALID
Definition: bridge.h:1108
@ AST_BRIDGE_TRANSFER_FAIL
Definition: bridge.h:1110
ast_bridge_video_mode_type
Video source modes.
Definition: bridge.h:102
@ AST_BRIDGE_VIDEO_MODE_SINGLE_SRC
Definition: bridge.h:106
@ AST_BRIDGE_VIDEO_MODE_TALKER_SRC
Definition: bridge.h:109
@ AST_BRIDGE_VIDEO_MODE_NONE
Definition: bridge.h:104
@ AST_BRIDGE_VIDEO_MODE_SFU
Definition: bridge.h:113
#define ast_bridge_lock(bridge)
Lock the bridge.
Definition: bridge.h:474
ast_bridge_impart_flags
Definition: bridge.h:588
@ AST_BRIDGE_IMPART_CHAN_DEPARTABLE
Definition: bridge.h:592
@ AST_BRIDGE_IMPART_CHAN_MASK
Definition: bridge.h:590
@ AST_BRIDGE_IMPART_INHIBIT_JOIN_COLP
Definition: bridge.h:596
@ AST_BRIDGE_IMPART_CHAN_INDEPENDENT
Definition: bridge.h:594
#define BRIDGE_PRINTF_VARS(bridge)
Definition: bridge.h:80
ast_bridge_join_flags
Definition: bridge.h:537
@ AST_BRIDGE_JOIN_INHIBIT_JOIN_COLP
Definition: bridge.h:541
@ AST_BRIDGE_JOIN_PASS_REFERENCE
Definition: bridge.h:539
#define BRIDGE_PRINTF_SPEC
Definition: bridge.h:79
After Bridge Execution API.
void ast_bridge_discard_after_callback(struct ast_channel *chan, enum ast_bridge_after_cb_reason reason)
Run discarding any after bridge callbacks.
Definition: bridge_after.c:239
@ AST_BRIDGE_AFTER_CB_REASON_IMPART_FAILED
Definition: bridge_after.h:49
@ AST_BRIDGE_AFTER_CB_REASON_DEPART
Definition: bridge_after.h:45
void ast_bridge_run_after_goto(struct ast_channel *chan)
Run a PBX on any after bridge goto location.
Definition: bridge_after.c:525
int ast_bridge_setup_after_goto(struct ast_channel *chan)
Setup any after bridge goto location to begin execution.
Definition: bridge_after.c:435
void ast_bridge_run_after_callback(struct ast_channel *chan)
Run any after bridge callback.
Definition: bridge_after.c:212
void ast_bridge_discard_after_goto(struct ast_channel *chan)
Discard channel after bridge goto location.
Definition: bridge_after.c:384
Basic bridge subclass API.
void ast_bridging_init_basic(void)
#define ast_bridge_channel_unlock(bridge_channel)
Unlock the bridge_channel.
int ast_bridge_channel_write_unhold(struct ast_bridge_channel *bridge_channel)
Write an unhold frame into the bridge.
void ast_bridge_channel_lock_bridge(struct ast_bridge_channel *bridge_channel)
Lock the bridge associated with the bridge channel.
void ast_bridge_channel_kick(struct ast_bridge_channel *bridge_channel, int cause)
Kick the channel out of the bridge.
void ast_bridge_channel_stream_map(struct ast_bridge_channel *bridge_channel)
Maps a channel's stream topology to and from the bridge.
#define ast_bridge_channel_lock(bridge_channel)
Lock the bridge_channel.
#define ast_bridge_channel_trylock(bridge_channel)
Try locking the bridge_channel.
struct ast_bridge_channel * ast_bridge_channel_peer(struct ast_bridge_channel *bridge_channel)
Get the peer bridge channel of a two party bridge.
void ast_bridge_channel_leave_bridge_nolock(struct ast_bridge_channel *bridge_channel, enum bridge_channel_state new_state, int cause)
Set bridge channel state to leave bridge (if not leaving already).
@ BRIDGE_CHANNEL_STATE_END_NO_DISSOLVE
@ BRIDGE_CHANNEL_STATE_WAIT
@ BRIDGE_CHANNEL_STATE_END
int ast_bridge_channel_queue_control_data(struct ast_bridge_channel *bridge_channel, enum ast_control_frame_type control, const void *data, size_t datalen)
Queue a control frame onto the bridge channel with data.
int ast_bridge_channel_queue_playfile(struct ast_bridge_channel *bridge_channel, ast_bridge_custom_play_fn custom_play, const char *playfile, const char *moh_class)
Queue a bridge action play file frame onto the bridge channel.
int ast_bridge_channel_write_playfile(struct ast_bridge_channel *bridge_channel, ast_bridge_custom_play_fn custom_play, const char *playfile, const char *moh_class)
Write a bridge action play file frame into the bridge.
@ BRIDGE_CHANNEL_THREAD_SIMPLE
@ BRIDGE_CHANNEL_THREAD_IDLE
void ast_bridge_channel_leave_bridge(struct ast_bridge_channel *bridge_channel, enum bridge_channel_state new_state, int cause)
Set bridge channel state to leave bridge (if not leaving already).
int ast_bridge_channel_queue_callback(struct ast_bridge_channel *bridge_channel, enum ast_bridge_channel_custom_callback_option flags, ast_bridge_custom_callback_fn callback, const void *payload, size_t payload_size)
Queue a bridge action custom callback frame onto the bridge channel.
Private Bridging Channel API.
void bridge_channel_internal_unsuspend_nolock(struct ast_bridge_channel *bridge_channel)
void bridge_channel_internal_suspend_nolock(struct ast_bridge_channel *bridge_channel)
void bridge_channel_settle_owed_events(struct ast_bridge *orig_bridge, struct ast_bridge_channel *bridge_channel)
int bridge_channel_internal_push_full(struct ast_bridge_channel *bridge_channel, int optimized)
int bridge_channel_internal_queue_blind_transfer(struct ast_channel *transferee, const char *exten, const char *context, transfer_channel_cb new_channel_cb, void *user_data)
int bridge_channel_internal_push(struct ast_bridge_channel *bridge_channel)
int bridge_channel_internal_allows_optimization(struct ast_bridge_channel *bridge_channel)
int bridge_channel_internal_queue_attended_transfer(struct ast_channel *transferee, struct ast_channel *unbridged_chan)
struct ast_bridge_channel * bridge_channel_internal_alloc(struct ast_bridge *bridge)
void bridge_channel_internal_pull(struct ast_bridge_channel *bridge_channel)
int bridge_channel_internal_join(struct ast_bridge_channel *bridge_channel)
@ BRIDGE_CHANNEL_ACTION_DEFERRED_TECH_DESTROY
@ BRIDGE_CHANNEL_ACTION_DEFERRED_DISSOLVING
void bridge_channel_queue_deferred_frames(struct ast_bridge_channel *bridge_channel)
Channel Bridging API.
int(* ast_bridge_move_indicate_callback)(struct ast_bridge_channel *bridge_channel, void *hook_pvt, struct ast_bridge *src, struct ast_bridge *dst)
Move indicator callback.
ast_bridge_hook_type
@ AST_BRIDGE_HOOK_TYPE_JOIN
@ AST_BRIDGE_HOOK_TYPE_HANGUP
@ AST_BRIDGE_HOOK_TYPE_MOVE
@ AST_BRIDGE_HOOK_TYPE_DTMF
@ AST_BRIDGE_HOOK_TYPE_LEAVE
@ AST_BRIDGE_HOOK_TYPE_TALK
@ AST_BRIDGE_HOOK_TYPE_TIMER
ast_bridge_hook_remove_flags
@ AST_BRIDGE_HOOK_REMOVE_ON_PULL
ast_bridge_builtin_feature
Built in DTMF features.
@ AST_BRIDGE_BUILTIN_END
@ AST_BRIDGE_FLAG_TRANSFER_BRIDGE_ONLY
@ AST_BRIDGE_FLAG_SWAP_INHIBIT_TO
@ AST_BRIDGE_FLAG_SWAP_INHIBIT_FROM
@ AST_BRIDGE_FLAG_TRANSFER_PROHIBITED
@ AST_BRIDGE_FLAG_MERGE_INHIBIT_TO
@ AST_BRIDGE_FLAG_SMART
@ AST_BRIDGE_FLAG_MASQUERADE_ONLY
@ AST_BRIDGE_FLAG_DISSOLVE_HANGUP
@ AST_BRIDGE_FLAG_MERGE_INHIBIT_FROM
@ AST_BRIDGE_FLAG_INVISIBLE
#define MAXIMUM_DTMF_FEATURE_STRING
Maximum length of a DTMF feature string.
ast_bridge_hook_timer_option
int(* ast_bridge_builtin_set_limits_fn)(struct ast_bridge_features *features, struct ast_bridge_features_limits *limits, enum ast_bridge_hook_remove_flags remove_flags)
Attach interval hooks to a bridge features structure.
int(* ast_bridge_talking_indicate_callback)(struct ast_bridge_channel *bridge_channel, void *hook_pvt, int talking)
Talking indicator callback.
@ AST_BRIDGE_CHANNEL_FLAG_IMMOVABLE
@ AST_BRIDGE_CHANNEL_FLAG_LONELY
@ AST_BRIDGE_CHANNEL_FLAG_DISSOLVE_HANGUP
int(* ast_bridge_hook_callback)(struct ast_bridge_channel *bridge_channel, void *hook_pvt)
Hook callback type.
void(* ast_bridge_hook_pvt_destructor)(void *hook_pvt)
Hook pvt destructor callback.
ast_bridge_builtin_interval
@ AST_BRIDGE_BUILTIN_INTERVAL_LIMITS
@ AST_BRIDGE_BUILTIN_INTERVAL_END
static void deferred_action(struct ast_bridge_channel *bridge_channel, const void *payload, size_t payload_size)
Private Bridging API.
Channel Bridging API.
Internal Asterisk hangup causes.
#define AST_CAUSE_NORMAL_CLEARING
Definition: causes.h:106
static void suspend(struct cc_core_instance *core_instance)
Definition: ccss.c:3166
static struct ast_timer * timer
Definition: chan_iax2.c:388
static const char type[]
Definition: chan_ooh323.c:109
static const char config[]
Definition: chan_ooh323.c:111
static int request(void *obj)
Definition: chan_pjsip.c:2605
General Asterisk PBX channel definitions.
const char * ast_channel_name(const struct ast_channel *chan)
struct ast_bridge * ast_channel_internal_bridge(const struct ast_channel *chan)
int ast_call(struct ast_channel *chan, const char *addr, int timeout)
Make a call.
Definition: channel.c:6478
int ast_channel_datastore_add(struct ast_channel *chan, struct ast_datastore *datastore)
Add a datastore to a channel.
Definition: channel.c:2414
void ast_hangup(struct ast_channel *chan)
Hang up a channel.
Definition: channel.c:2570
@ AST_CHANNEL_REQUESTOR_REPLACEMENT
Definition: channel.h:1525
void ast_party_connected_line_free(struct ast_party_connected_line *doomed)
Destroy the connected line information contents.
Definition: channel.c:2099
void ast_channel_internal_bridge_channel_set(struct ast_channel *chan, struct ast_bridge_channel *value)
#define ast_channel_lock(chan)
Definition: channel.h:2970
struct ast_format_cap * ast_channel_nativeformats(const struct ast_channel *chan)
struct ast_channel * ast_channel_yank(struct ast_channel *yankee)
Gain control of a channel in the system.
Definition: channel.c:10619
struct ast_flags * ast_channel_flags(struct ast_channel *chan)
#define ast_channel_ref(c)
Increase channel reference count.
Definition: channel.h:2995
#define ast_channel_lock_both(chan1, chan2)
Lock two channels.
Definition: channel.h:2977
const char * ast_channel_uniqueid(const struct ast_channel *chan)
void ast_channel_req_accountcodes(struct ast_channel *chan, const struct ast_channel *requestor, enum ast_channel_requestor_relationship relationship)
Setup new channel accountcodes from the requestor channel after ast_request().
Definition: channel.c:6451
int ast_check_hangup_locked(struct ast_channel *chan)
Definition: channel.c:459
struct ast_channel * ast_channel_get_by_name_prefix(const char *name, size_t name_len)
Find a channel by a name prefix.
Definition: channel.c:1461
#define ast_channel_trylock(chan)
Definition: channel.h:2972
const char * ast_channel_appl(const struct ast_channel *chan)
struct ast_bridge_channel * ast_channel_internal_bridge_channel(const struct ast_channel *chan)
void ast_channel_internal_bridge_set(struct ast_channel *chan, struct ast_bridge *value)
struct ast_bridge * ast_channel_get_bridge(const struct ast_channel *chan)
Get the bridge associated with a channel.
Definition: channel.c:10560
int ast_softhangup(struct ast_channel *chan, int cause)
Softly hangup up a channel.
Definition: channel.c:2500
struct ast_readq_list * ast_channel_readq(struct ast_channel *chan)
int ast_connected_line_build_data(unsigned char *data, size_t datalen, const struct ast_party_connected_line *connected, const struct ast_set_party_connected_line *update)
Build the connected line information data frame.
Definition: channel.c:8723
#define ast_channel_unref(c)
Decrease channel reference count.
Definition: channel.h:3006
@ AST_FLAG_ZOMBIE
Definition: channel.h:1007
@ AST_FLAG_EMULATE_DTMF
Definition: channel.h:1024
#define AST_MAX_CONTEXT
Definition: channel.h:135
void ast_party_connected_line_init(struct ast_party_connected_line *init)
Initialize the given connected line structure.
Definition: channel.c:2049
struct ast_bridge_channel * ast_channel_get_bridge_channel(struct ast_channel *chan)
Get a reference to the channel's bridge pointer.
Definition: channel.c:10608
const char * ast_cause2str(int cause) attribute_pure
Gives the string form of a given cause code.
Definition: channel.c:612
void ast_connected_line_copy_from_caller(struct ast_party_connected_line *dest, const struct ast_party_caller *src)
Copy the caller information to the connected line information.
Definition: channel.c:8319
int ast_softhangup_nolock(struct ast_channel *chan, int cause)
Softly hangup up a channel (no channel lock)
Definition: channel.c:2487
struct ast_pbx * ast_channel_pbx(const struct ast_channel *chan)
int ast_channel_softhangup_internal_flag(struct ast_channel *chan)
struct ast_party_caller * ast_channel_caller(struct ast_channel *chan)
#define ast_channel_cleanup(c)
Cleanup a channel reference.
Definition: channel.h:3017
int ast_answer(struct ast_channel *chan)
Answer a channel.
Definition: channel.c:2834
int ast_indicate(struct ast_channel *chan, int condition)
Indicates condition of channel.
Definition: channel.c:4294
struct ast_channel * ast_request(const char *type, struct ast_format_cap *request_cap, const struct ast_assigned_ids *assignedids, const struct ast_channel *requestor, const char *addr, int *cause)
Requests a channel.
Definition: channel.c:6371
#define ast_channel_unlock(chan)
Definition: channel.h:2971
#define AST_MAX_EXTENSION
Definition: channel.h:134
struct ast_datastore * ast_channel_datastore_find(struct ast_channel *chan, const struct ast_datastore_info *info, const char *uid)
Find a datastore on a channel.
Definition: channel.c:2428
@ AST_SOFTHANGUP_ASYNCGOTO
Definition: channel.h:1146
@ AST_SOFTHANGUP_DEV
Definition: channel.h:1141
int ast_channel_has_audio_frame_or_monitor(struct ast_channel *chan)
Check if the channel has active audiohooks, active framehooks, or a monitor.
Definition: channel.c:2547
ast_channel_state
ast_channel states
Definition: channelstate.h:35
@ AST_STATE_UP
Definition: channelstate.h:42
Standard Command Line Interface.
#define CLI_SHOWUSAGE
Definition: cli.h:45
#define AST_CLI_YESNO(x)
Return Yes or No depending on the argument.
Definition: cli.h:71
#define CLI_SUCCESS
Definition: cli.h:44
int ast_cli_unregister_multiple(struct ast_cli_entry *e, int len)
Unregister multiple commands.
Definition: clicompat.c:30
#define AST_CLI_DEFINE(fn, txt,...)
Definition: cli.h:197
int ast_cli_completion_add(char *value)
Add a result to a request for completion options.
Definition: main/cli.c:2768
void ast_cli(int fd, const char *fmt,...)
Definition: clicompat.c:6
char * ast_cli_complete(const char *word, const char *const choices[], int pos)
Definition: main/cli.c:1853
@ CLI_INIT
Definition: cli.h:152
@ CLI_GENERATE
Definition: cli.h:153
#define ast_cli_register_multiple(e, len)
Register multiple commands.
Definition: cli.h:265
@ AST_MEDIA_TYPE_VIDEO
Definition: codec.h:33
@ AST_MEDIA_TYPE_END
Definition: codec.h:36
static struct channel_usage channels
short word
static struct ao2_container * locals
Definition: core_local.c:150
Local proxy channel special access.
void ast_local_unlock_all(void *tech_pvt, struct ast_channel *base_chan, struct ast_channel *base_owner)
Remove a reference to the given local channel's private tech, unlock the given local channel's privat...
Definition: core_local.c:268
int ast_local_setup_bridge(struct ast_channel *ast, struct ast_bridge *bridge, struct ast_channel *swap, struct ast_bridge_features *features)
Setup the outgoing local channel to join a bridge on ast_call().
Definition: core_local.c:613
void ast_local_lock_all(struct ast_channel *chan, void **tech_pvt, struct ast_channel **base_chan, struct ast_channel **base_owner)
Add a reference to the local channel's private tech, lock the local channel's private base,...
Definition: core_local.c:253
int ast_local_setup_masquerade(struct ast_channel *ast, struct ast_channel *masq)
Setup the outgoing local channel to masquerade into a channel on ast_call().
Definition: core_local.c:655
Unreal channel derivative framework.
@ AST_UNREAL_CHAN
Definition: core_unreal.h:51
@ AST_UNREAL_OWNER
Definition: core_unreal.h:50
#define AST_UNREAL_OPTIMIZE_BEGUN
Definition: core_unreal.h:110
#define ast_datastore_alloc(info, uid)
Definition: datastore.h:85
int ast_datastore_free(struct ast_datastore *datastore)
Free a data store object.
Definition: datastore.c:68
char connected
Definition: eagi_proxy.c:82
char * end
Definition: eagi_proxy.c:73
char buf[BUFSIZE]
Definition: eagi_proxy.c:66
long int flag
Definition: f2c.h:83
Call Parking and Pickup API Includes code and algorithms from the Zapata library.
Generic File Format Support. Should be included by clients of the file handling routines....
int ast_format_cap_has_type(const struct ast_format_cap *cap, enum ast_media_type type)
Find out if the capabilities structure has any formats of a specific type.
Definition: format_cap.c:613
static const char name[]
Definition: format_mp3.c:68
static int len(struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t buflen)
void astman_send_listack(struct mansession *s, const struct message *m, char *msg, char *listflag)
Send ack in manager transaction to begin a list.
Definition: manager.c:2028
void astman_send_error(struct mansession *s, const struct message *m, char *error)
Send error in manager transaction.
Definition: manager.c:1986
void astman_send_list_complete_start(struct mansession *s, const struct message *m, const char *event_name, int count)
Start the list complete event.
Definition: manager.c:2064
void astman_send_ack(struct mansession *s, const struct message *m, char *msg)
Send ack in manager transaction.
Definition: manager.c:2018
const char * astman_get_header(const struct message *m, char *var)
Get header from manager transaction.
Definition: manager.c:1647
void astman_send_list_complete_end(struct mansession *s)
End the list complete event.
Definition: manager.c:2072
void astman_append(struct mansession *s, const char *fmt,...)
Definition: manager.c:1907
int ast_manager_unregister(const char *action)
Unregister a registered manager command.
Definition: manager.c:7697
#define SCOPE_TRACE(__level,...)
struct ast_channel_snapshot * ast_channel_snapshot_get_latest(const char *uniqueid)
Obtain the latest ast_channel_snapshot from the Stasis Message Bus API cache. This is an ao2 object,...
void ast_channel_stage_snapshot_done(struct ast_channel *chan)
Clear flag to indicate channel snapshot is being staged, and publish snapshot.
void ast_channel_stage_snapshot(struct ast_channel *chan)
Set flag to indicate channel snapshot is being staged.
Max Heap data structure.
struct ast_heap * ast_heap_destroy(struct ast_heap *h)
Destroy a max heap.
Definition: heap.c:146
#define ast_heap_create(init_height, cmp_fn, index_offset)
Create a max heap.
Definition: heap.h:100
#define ast_heap_unlock(h)
Definition: heap.h:249
void * ast_heap_pop(struct ast_heap *h)
Pop the max element off of the heap.
Definition: heap.c:262
void * ast_heap_remove(struct ast_heap *h, void *elm)
Remove a specific element from a heap.
Definition: heap.c:251
size_t ast_heap_size(struct ast_heap *h)
Get the current size of a heap.
Definition: heap.c:276
#define ast_heap_push(h, elm)
Push an element on to a heap.
Definition: heap.h:125
#define ast_heap_wrlock(h)
Definition: heap.h:247
void * ast_heap_peek(struct ast_heap *h, unsigned int index)
Peek at an element on a heap.
Definition: heap.c:267
Application convenience functions, designed to give consistent look and feel to Asterisk apps.
#define ast_frdup(fr)
Copies a frame.
#define ast_frfree(fr)
@ AST_FRAME_BRIDGE_ACTION
@ AST_CONTROL_VIDUPDATE
@ AST_CONTROL_CONNECTED_LINE
Support for logging to various files, console and syslog Configuration in file logger....
#define AST_LOG_WARNING
int ast_callid_threadassoc_change(ast_callid callid)
Sets what is stored in the thread storage to the given callid if it does not match what is already th...
Definition: logger.c:2282
#define ast_debug(level,...)
Log a DEBUG message.
ast_callid ast_read_threadstorage_callid(void)
extracts the callerid from the thread
Definition: logger.c:2273
int ast_callid_threadassoc_add(ast_callid callid)
Adds a known callid to thread storage of the calling thread.
Definition: logger.c:2295
#define LOG_ERROR
#define AST_LOG_NOTICE
#define ast_verb(level,...)
#define LOG_WARNING
A set of macros to manage forward-linked lists.
#define AST_RWLIST_REMOVE_CURRENT
Definition: linkedlists.h:570
#define AST_RWLIST_RDLOCK(head)
Read locks a list.
Definition: linkedlists.h:78
#define AST_LIST_HEAD_INIT_NOLOCK(head)
Initializes a list head structure.
Definition: linkedlists.h:681
#define AST_LIST_HEAD_NOLOCK(name, type)
Defines a structure to be used to hold a list of specified type (with no lock).
Definition: linkedlists.h:225
#define AST_LIST_LAST(head)
Returns the last entry contained in a list.
Definition: linkedlists.h:429
#define AST_RWLIST_TRAVERSE_SAFE_BEGIN
Definition: linkedlists.h:545
#define AST_RWLIST_WRLOCK(head)
Write locks a list.
Definition: linkedlists.h:52
#define AST_RWLIST_UNLOCK(head)
Attempts to unlock a read/write based list.
Definition: linkedlists.h:151
#define AST_LIST_TRAVERSE(head, var, field)
Loops over (traverses) the entries in a list.
Definition: linkedlists.h:491
#define AST_RWLIST_HEAD_STATIC(name, type)
Defines a structure to be used to hold a read/write list of specified type, statically initialized.
Definition: linkedlists.h:333
#define AST_LIST_EMPTY(head)
Checks whether the specified list contains any entries.
Definition: linkedlists.h:450
#define AST_LIST_INSERT_TAIL(head, elm, field)
Appends a list entry to the tail of a list.
Definition: linkedlists.h:731
#define AST_LIST_ENTRY(type)
Declare a forward link structure inside a list entry.
Definition: linkedlists.h:410
#define AST_RWLIST_TRAVERSE_SAFE_END
Definition: linkedlists.h:617
#define AST_LIST_TRAVERSE_SAFE_END
Closes a safe loop traversal block.
Definition: linkedlists.h:615
#define AST_RWLIST_TRAVERSE
Definition: linkedlists.h:494
#define AST_LIST_TRAVERSE_SAFE_BEGIN(head, var, field)
Loops safely over (traverses) the entries in a list.
Definition: linkedlists.h:529
#define AST_LIST_REMOVE_CURRENT(field)
Removes the current entry from a list during a traversal.
Definition: linkedlists.h:557
#define AST_RWLIST_INSERT_TAIL
Definition: linkedlists.h:741
#define AST_LIST_REMOVE_HEAD(head, field)
Removes and returns the head entry from a list.
Definition: linkedlists.h:833
#define AST_RWLIST_INSERT_BEFORE_CURRENT
Definition: linkedlists.h:610
#define AST_LIST_FIRST(head)
Returns the first entry contained in a list.
Definition: linkedlists.h:421
Asterisk locking-related definitions:
#define ast_cond_destroy(cond)
Definition: lock.h:206
#define ast_cond_wait(cond, mutex)
Definition: lock.h:209
#define AST_PTHREADT_NULL
Definition: lock.h:70
#define ast_cond_init(cond, attr)
Definition: lock.h:205
#define ast_mutex_init(pmutex)
Definition: lock.h:190
#define ast_mutex_unlock(a)
Definition: lock.h:194
int ast_atomic_fetchadd_int(volatile int *p, int v)
Atomically add v to *p and return the previous value of *p.
Definition: lock.h:761
#define SCOPED_LOCK(varname, lock, lockfunc, unlockfunc)
Scoped Locks.
Definition: lock.h:587
pthread_cond_t ast_cond_t
Definition: lock.h:182
#define SCOPED_MUTEX(varname, lock)
scoped lock specialization for mutexes
Definition: lock.h:593
#define ast_mutex_destroy(a)
Definition: lock.h:192
#define ast_mutex_lock(a)
Definition: lock.h:193
#define AST_MUTEX_DEFINE_STATIC(mutex)
Definition: lock.h:524
#define ast_cond_signal(cond)
Definition: lock.h:207
size_t current
Definition: main/cli.c:113
#define ast_manager_register_xml_core(action, authority, func)
Register a manager callback using XML documentation to describe the manager.
Definition: manager.h:203
Asterisk module definitions.
#define ast_module_unref(mod)
Release a reference to the module.
Definition: module.h:483
#define ast_module_running_ref(mod)
Hold a reference to the module if it is running.
Definition: module.h:469
Music on hold handling.
void ast_moh_stop(struct ast_channel *chan)
Turn off music on hold on a given channel.
Definition: channel.c:7797
Options provided by main asterisk program.
Call Parking API.
int ast_parking_blind_transfer_park(struct ast_bridge_channel *parker, const char *context, const char *exten, transfer_channel_cb parked_channel_cb, struct transfer_channel_data *parked_channel_data)
Perform a blind transfer to a parking extension.
Definition: parking.c:143
int ast_parking_provider_registered(void)
Check whether a parking provider is registered.
Definition: parking.c:241
Core PBX routines and definitions.
const char * pbx_builtin_getvar_helper(struct ast_channel *chan, const char *name)
Return a pointer to the value of the corresponding channel variable.
int pbx_builtin_setvar_helper(struct ast_channel *chan, const char *name, const char *value)
Add a variable to the channel variable stack, removing the most recently set value for the same name.
unsigned char publish
Definition: res_corosync.c:241
#define NULL
Definition: resample.c:96
Say numbers and dates (maybe words one day too)
void ast_bridge_publish_merge(struct ast_bridge *to, struct ast_bridge *from)
Publish a bridge merge.
void ast_bridge_publish_attended_transfer(struct ast_attended_transfer_message *transfer_msg)
Publish an attended transfer.
void ast_bridge_publish_blind_transfer(struct ast_blind_transfer_message *transfer_message)
Publish a blind transfer event.
int ast_bridge_topic_exists(const char *uniqueid)
Check if a stasis topic exists for a bridge uniqueid.
int ast_attended_transfer_message_add_app(struct ast_attended_transfer_message *transfer_msg, const char *app, struct ast_channel *replace_channel)
Add details for an attended transfer to an application.
struct ast_bridge_snapshot * ast_bridge_get_snapshot(struct ast_bridge *bridge)
Returns the current snapshot for the bridge.
int bridge_topics_init(struct ast_bridge *bridge)
struct ast_bridge_snapshot * ast_bridge_get_snapshot_by_uniqueid(const char *bridge_id)
Returns the current snapshot for the bridge.
struct ast_bridge_snapshot * ast_bridge_snapshot_create(struct ast_bridge *bridge)
Generate a snapshot of the bridge state. This is an ao2 object, so ao2_cleanup() to deallocate.
void ast_bridge_publish_state(struct ast_bridge *bridge)
Publish the state of a bridge.
struct ast_attended_transfer_message * ast_attended_transfer_message_create(int is_external, struct ast_channel *to_transferee, struct ast_bridge *transferee_bridge, struct ast_channel *to_transfer_target, struct ast_bridge *target_bridge, struct ast_channel *transferee, struct ast_channel *transfer_target)
Create an Attended transfer message to be published.
int ast_attended_transfer_message_add_merge(struct ast_attended_transfer_message *transfer_msg, struct ast_bridge *final_bridge)
Add details for a bridge merge to an attended transfer message.
int ast_attended_transfer_message_add_link(struct ast_attended_transfer_message *transfer_msg, struct ast_channel *locals[2])
Add details for an attended transfer that has a link between bridges.
struct stasis_topic * ast_bridge_topic(struct ast_bridge *bridge)
A topic which publishes the events for a particular bridge.
int ast_stasis_bridging_init(void)
void bridge_topics_destroy(struct ast_bridge *bridge)
struct ast_blind_transfer_message * ast_blind_transfer_message_create(int is_external, struct ast_channel *transferer, const char *exten, const char *context)
Create a blind transfer message to be published.
Caching pattern for Stasis Message Bus API topics.
#define ast_string_field_set(x, field, data)
Set a field to a simple string value.
Definition: stringfields.h:521
#define ast_string_field_init(x, size)
Initialize a field pool and fields.
Definition: stringfields.h:359
#define ast_string_field_free_memory(x)
free all memory - to be called before destroying the object
Definition: stringfields.h:374
char * ast_str_buffer(const struct ast_str *buf)
Returns the string buffer within the ast_str buf.
Definition: strings.h:761
#define S_OR(a, b)
returns the equivalent of logic or for strings: first one if not empty, otherwise second one.
Definition: strings.h:80
static force_inline int attribute_pure ast_str_hash(const char *str)
Compute a hash value on a string.
Definition: strings.h:1259
static force_inline int attribute_pure ast_strlen_zero(const char *s)
Definition: strings.h:65
#define ast_str_create(init_len)
Create a malloc'ed dynamic length string.
Definition: strings.h:659
int ast_str_set(struct ast_str **buf, ssize_t max_len, const char *fmt,...)
Set a dynamic string using variable arguments.
Definition: strings.h:1113
#define AST_YESNO(x)
return Yes or No depending on the argument.
Definition: strings.h:143
void ast_copy_string(char *dst, const char *src, size_t size)
Size-limited null-terminating string copy.
Definition: strings.h:425
Generic container type.
When we need to walk through a container, we use an ao2_iterator to keep track of the current positio...
Definition: astobj2.h:1821
Message representing attended transfer.
Message published during a blind transfer.
struct ast_channel_snapshot * replace_channel
Structure that contains information regarding a channel in a bridge.
unsigned int suspended
struct ast_channel * swap
struct ast_bridge * bridge
Bridge this channel is participating in.
struct ast_bridge_channel::@193 entry
struct ast_bridge_features * features
unsigned int just_joined
struct ast_channel * chan
enum bridge_channel_state state
unsigned int inhibit_colp
unsigned int depart_wait
enum bridge_channel_thread_state activity
The bridge channel thread activity.
struct ast_bridge_tech_optimizations tech_args
unsigned int in_bridge
Structure that contains configuration information for the limits feature.
Structure that contains features information.
struct ao2_container * other_hooks
struct ao2_container * dtmf_hooks
unsigned int interval_sequence
unsigned int dtmf_passthrough
struct ast_heap * interval_hooks
unsigned int text_messaging
struct ast_flags feature_flags
char code[MAXIMUM_DTMF_FEATURE_STRING]
struct ast_bridge_hook generic
struct ast_bridge_hook_dtmf_parms dtmf
struct ast_bridge_hook generic
struct ast_bridge_hook_timer_parms timer
Structure that is the essence of a feature hook.
struct ast_flags remove_flags
ast_bridge_hook_pvt_destructor destructor
enum ast_bridge_hook_type type
ast_bridge_hook_callback callback
Bridge virtual methods table definition.
Definition: bridge.h:261
ast_bridge_dissolving_fn dissolving
Definition: bridge.h:267
ast_bridge_push_channel_fn push
Definition: bridge.h:269
const char * name
Definition: bridge.h:263
ast_bridge_notify_masquerade_fn notify_masquerade
Definition: bridge.h:273
ast_bridge_destructor_fn destroy
Definition: bridge.h:265
ast_bridge_merge_priority_fn get_merge_priority
Definition: bridge.h:275
ast_bridge_pull_channel_fn pull
Definition: bridge.h:271
ast_bridge_push_channel_fn push_peek
Definition: bridge.h:277
Structure that contains a snapshot of information about a bridge.
Definition: bridge.h:318
enum ast_bridge_video_mode_type video_mode
Definition: bridge.h:345
struct timeval creationtime
Definition: bridge.h:347
unsigned int num_active
Definition: bridge.h:343
const ast_string_field video_source_id
Definition: bridge.h:332
const ast_string_field creator
Definition: bridge.h:332
const ast_string_field uniqueid
Definition: bridge.h:332
unsigned int num_channels
Definition: bridge.h:341
const ast_string_field technology
Definition: bridge.h:332
const ast_string_field name
Definition: bridge.h:332
struct ao2_container * channels
Definition: bridge.h:335
const ast_string_field subclass
Definition: bridge.h:332
unsigned int send_sdp_label
Definition: bridge.h:304
unsigned int maximum_sample_rate
The maximum sample rate softmix uses to mix channels.
Definition: bridge.h:310
unsigned int internal_sample_rate
The internal sample rate softmix uses to mix channels.
Definition: bridge.h:289
unsigned int binaural_active
Definition: bridge.h:299
struct ast_bridge_video_mode video_mode
Definition: bridge.h:283
unsigned int internal_mixing_interval
The mixing interval indicates how quickly softmix mixing should occur to mix audio.
Definition: bridge.h:297
Structure specific to bridge technologies capable of performing talking optimizations.
Structure that is the essence of a bridge technology.
void(* destroy)(struct ast_bridge *bridge)
Destroy a bridging technology instance for a bridge.
int(* start)(struct ast_bridge *bridge)
Request a bridge technology instance start operations.
void(* stream_topology_changed)(struct ast_bridge *bridge, struct ast_bridge_channel *bridge_channel)
Callback for when a stream topology changes on the channel.
struct ast_module * mod
int(* write)(struct ast_bridge *bridge, struct ast_bridge_channel *bridge_channel, struct ast_frame *frame)
Write a frame into the bridging technology instance for a bridge.
int(* compatible)(struct ast_bridge *bridge)
Check if a bridge is compatible with the bridging technology.
void(* stop)(struct ast_bridge *bridge)
Request a bridge technology instance stop in preparation for being destroyed.
int(* join)(struct ast_bridge *bridge, struct ast_bridge_channel *bridge_channel)
Add a channel to a bridging technology instance for a bridge.
int(* create)(struct ast_bridge *bridge)
Create a bridge technology instance for a bridge.
enum ast_bridge_preference preference
void(* leave)(struct ast_bridge *bridge, struct ast_bridge_channel *bridge_channel)
Remove a channel from a bridging technology instance for a bridge.
struct ast_bridge_video_single_src_data single_src_data
Definition: bridge.h:167
struct ast_bridge_video_talker_src_data talker_src_data
Definition: bridge.h:168
unsigned int video_update_discard
Definition: bridge.h:172
union ast_bridge_video_mode::@191 mode_data
enum ast_bridge_video_mode_type mode
Definition: bridge.h:164
struct ast_bridge_video_sfu_data sfu_data
Definition: bridge.h:169
unsigned int remb_send_interval
Definition: bridge.h:155
enum ast_bridge_video_sfu_remb_behavior remb_behavior
Definition: bridge.h:157
struct ast_channel * chan_vsrc
Definition: bridge.h:120
This is used for both SINGLE_SRC_TALKER mode to set what channel should be the current single video f...
Definition: bridge.h:125
struct ast_channel * chan_old_vsrc
Definition: bridge.h:131
struct ast_channel * chan_vsrc
Definition: bridge.h:127
Structure that contains information about a bridge.
Definition: bridge.h:353
struct ast_bridge_softmix softmix
Definition: bridge.h:371
void * tech_pvt
Definition: bridge.h:361
struct ast_vector_int media_types
Definition: bridge.h:408
struct timeval creationtime
Definition: bridge.h:412
const struct ast_bridge_methods * v_table
Definition: bridge.h:355
unsigned int reconfigured
Definition: bridge.h:392
unsigned int num_active
Definition: bridge.h:379
ast_callid callid
Definition: bridge.h:365
const ast_string_field creator
Definition: bridge.h:405
const ast_string_field uniqueid
Definition: bridge.h:405
struct ast_bridge_channels_list channels
Definition: bridge.h:367
struct ast_bridge_snapshot * current_snapshot
Definition: bridge.h:410
unsigned int num_channels
Definition: bridge.h:377
unsigned int dissolved
Definition: bridge.h:394
int cause
Definition: bridge.h:390
struct ast_bridge_technology * technology
Definition: bridge.h:359
unsigned int construction_completed
Definition: bridge.h:396
const ast_string_field name
Definition: bridge.h:405
unsigned int num_lonely
Definition: bridge.h:381
struct ast_bridge::@192 action_queue
unsigned int inhibit_merge
Count of the active temporary requests to inhibit bridge merges. Zero if merges are allowed.
Definition: bridge.h:388
struct ast_flags feature_flags
Definition: bridge.h:373
uint32_t allowed_capabilities
Definition: bridge.h:375
const ast_string_field name
Structure representing a snapshot of channel state.
struct ast_channel_snapshot_base * base
Main Channel structure associated with a channel.
struct ast_bridge_channel * bridge_channel
struct ast_bridge * bridge
char exten[AST_MAX_EXTENSION]
const char * data
const struct ast_channel_tech * tech
struct ast_flags flags
descriptor for a cli entry.
Definition: cli.h:171
char * command
Definition: cli.h:186
const char * usage
Definition: cli.h:177
Structure for a data store type.
Definition: datastore.h:31
const char * type
Definition: datastore.h:32
Structure for a data store object.
Definition: datastore.h:64
void * data
Definition: datastore.h:66
unsigned int flags
Definition: utils.h:200
Format capabilities structure, holds formats + preference order + etc.
Definition: format_cap.c:54
Data structure associated with a single frame of data.
union ast_frame::@228 data
struct ast_frame_subclass subclass
enum ast_frame_type frametype
Definition: heap.c:36
Structure for mutex and tracking information.
Definition: lock.h:139
Connected Line/Party information.
Definition: channel.h:458
Support for dynamic strings.
Definition: strings.h:623
void(*const optimization_started)(struct ast_unreal_pvt *p, struct ast_channel *source, enum ast_unreal_channel_indicator dest, unsigned int id)
Called when an optimization attempt has started.
Definition: core_unreal.h:69
void(*const optimization_finished)(struct ast_unreal_pvt *p, int success, unsigned int id)
Called when an optimization attempt completed successfully.
Definition: core_unreal.h:81
The base pvt structure for local channel derivatives.
Definition: core_unreal.h:91
struct ast_unreal_pvt_callbacks * callbacks
Definition: core_unreal.h:92
struct ast_channel * owner
Definition: core_unreal.h:93
Internal bridge impart wait condition and associated conditional.
Definition: bridge.c:1544
struct bridge_channel_impart_cond::@311 node
unsigned int stop
Definition: bridge.c:179
struct bridge_manager_controller::@310 service_requests
struct ast_bridge * bridge
Definition: bridge.c:168
struct bridge_manager_request::@309 node
In case you didn't read that giant block of text above the mansession_session struct,...
Definition: manager.c:327
struct ast_bridge * src
Definition: bridge.c:2207
struct ast_bridge * dest
Definition: bridge.c:2205
Definition: test_heap.c:38
struct ast_bridge_technology * tech
Definition: bridge.c:565
AO2 object that wraps data for transfer_channel_cb.
Definition: bridge.h:1123
int value
Definition: syslog.c:37
Test Framework API.
static int hook_cb(struct ast_config *cfg)
Definition: test_config.c:875
static struct test_val b
static struct test_val a
struct timeval ast_samp2tv(unsigned int _nsamp, unsigned int _rate)
Returns a timeval corresponding to the duration of n samples at rate r. Useful to convert samples to ...
Definition: time.h:282
void ast_format_duration_hh_mm_ss(int duration, char *buf, size_t length)
Formats a duration into HH:MM:SS.
Definition: utils.c:2297
int ast_tvcmp(struct timeval _a, struct timeval _b)
Compress two struct timeval instances returning -1, 0, 1 if the first arg is smaller,...
Definition: time.h:137
struct timeval ast_tvadd(struct timeval a, struct timeval b)
Returns the sum of two timevals a + b.
Definition: extconf.c:2282
struct timeval ast_tvnow(void)
Returns current timeval. Meant to replace calls to gettimeofday().
Definition: time.h:159
Timing source management.
Utility functions.
#define ast_test_flag(p, flag)
Definition: utils.h:63
#define RAII_VAR(vartype, varname, initval, dtor)
Declare a variable that will call a destructor function when it goes out of scope.
Definition: utils.h:941
#define ast_assert(a)
Definition: utils.h:739
#define MIN(a, b)
Definition: utils.h:231
#define ast_pthread_create(a, b, c, d)
Definition: utils.h:584
#define ast_pthread_create_detached(a, b, c, d)
Definition: utils.h:588
#define SWAP(a, b)
Definition: utils.h:235
#define ast_set_flag(p, flag)
Definition: utils.h:70
#define ARRAY_LEN(a)
Definition: utils.h:666
#define AST_UUID_STR_LEN
Definition: uuid.h:27
char * ast_uuid_generate_str(char *buf, size_t size)
Generate a UUID string.
Definition: uuid.c:141
#define AST_VECTOR_FREE(vec)
Deallocates this vector.
Definition: vector.h:174
#define AST_VECTOR_INIT(vec, size)
Initialize a vector.
Definition: vector.h:113