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