Asterisk - The Open Source Telephony Project  21.4.1
control.c
Go to the documentation of this file.
1 /*
2  * Asterisk -- An open source telephony toolkit.
3  *
4  * Copyright (C) 2013, Digium, Inc.
5  *
6  * David M. Lee, II <dlee@digium.com>
7  *
8  * See http://www.asterisk.org for more information about
9  * the Asterisk project. Please do not directly contact
10  * any of the maintainers of this project for assistance;
11  * the project provides a web site, mailing lists and IRC
12  * channels for your use.
13  *
14  * This program is free software, distributed under the terms of
15  * the GNU General Public License Version 2. See the LICENSE file
16  * at the top of the source tree.
17  */
18 
19 /*! \file
20  *
21  * \brief Stasis application control support.
22  *
23  * \author David M. Lee, II <dlee@digium.com>
24  */
25 
26 #include "asterisk.h"
27 
28 #include "asterisk/stasis_channels.h"
29 #include "asterisk/stasis_app.h"
30 
31 #include "command.h"
32 #include "control.h"
33 #include "app.h"
34 #include "asterisk/dial.h"
35 #include "asterisk/bridge.h"
36 #include "asterisk/bridge_after.h"
37 #include "asterisk/bridge_basic.h"
39 #include "asterisk/frame.h"
40 #include "asterisk/pbx.h"
41 #include "asterisk/musiconhold.h"
42 #include "asterisk/app.h"
43 
44 #include <signal.h>
45 
47 
48 /*!
49  * \brief Indicates if the Stasis app internals are being shut down
50  */
51 static int shutting_down;
52 
54  ast_cond_t wait_cond;
55  /*! Queue of commands to dispatch on the channel */
57  /*!
58  * The associated channel.
59  * Be very careful with the threading associated w/ manipulating
60  * the channel.
61  */
63  /*!
64  * When a channel is in a bridge, the bridge that it is in.
65  */
66  struct ast_bridge *bridge;
67  /*!
68  * Bridge features which should be applied to the channel when it enters the next bridge. These only apply to the next bridge and will be emptied thereafter.
69  */
71  /*!
72  * Holding place for channel's PBX while imparted to a bridge.
73  */
74  struct ast_pbx *pbx;
75  /*!
76  * A list of rules to check before adding a channel to a bridge.
77  */
79  /*!
80  * A list of rules to check before removing a channel from a bridge.
81  */
83  /*!
84  * Silence generator, when silence is being generated.
85  */
87  /*!
88  * The app for which this control is currently controlling.
89  * This can change through the use of the /channels/{channelId}/move
90  * command.
91  */
92  struct stasis_app *app;
93  /*!
94  * The name of the next Stasis application to move to.
95  */
96  char *next_app;
97  /*!
98  * The thread currently blocking on the channel.
99  */
100  pthread_t control_thread;
101  /*!
102  * The list of arguments to pass to StasisStart when moving to another app.
103  */
104  AST_VECTOR(, char *) next_app_args;
105  /*!
106  * When set, /c app_stasis should exit and continue in the dialplan.
107  */
108  unsigned int is_done:1;
109 };
110 
111 static void control_dtor(void *obj)
112 {
113  struct stasis_app_control *control = obj;
114 
115  ao2_cleanup(control->command_queue);
116 
117  ast_channel_cleanup(control->channel);
118  ao2_cleanup(control->app);
119 
120  control_move_cleanup(control);
121 
122  ast_cond_destroy(&control->wait_cond);
123  AST_LIST_HEAD_DESTROY(&control->add_rules);
126 
127 }
128 
129 struct stasis_app_control *control_create(struct ast_channel *channel, struct stasis_app *app)
130 {
131  struct stasis_app_control *control;
132  int res;
133 
134  control = ao2_alloc(sizeof(*control), control_dtor);
135  if (!control) {
136  return NULL;
137  }
138 
139  AST_LIST_HEAD_INIT(&control->add_rules);
140  AST_LIST_HEAD_INIT(&control->remove_rules);
141 
142  res = ast_cond_init(&control->wait_cond, NULL);
143  if (res != 0) {
144  ast_log(LOG_ERROR, "Error initializing ast_cond_t: %s\n",
145  strerror(errno));
146  ao2_ref(control, -1);
147  return NULL;
148  }
149 
150  control->app = ao2_bump(app);
151 
152  ast_channel_ref(channel);
153  control->channel = channel;
154 
156  AO2_ALLOC_OPT_LOCK_MUTEX, 0, NULL, NULL);
157  if (!control->command_queue) {
158  ao2_ref(control, -1);
159  return NULL;
160  }
161 
162  control->next_app = NULL;
163  AST_VECTOR_INIT(&control->next_app_args, 0);
164 
165  control_set_thread(control, AST_PTHREADT_NULL);
166 
167  return control;
168 }
169 
170 static void app_control_register_rule(
171  struct stasis_app_control *control,
172  struct app_control_rules *list, struct stasis_app_control_rule *obj)
173 {
174  ao2_lock(control->command_queue);
175  AST_LIST_INSERT_TAIL(list, obj, next);
176  ao2_unlock(control->command_queue);
177 }
178 
179 static void app_control_unregister_rule(
180  struct stasis_app_control *control,
181  struct app_control_rules *list, struct stasis_app_control_rule *obj)
182 {
184 
185  ao2_lock(control->command_queue);
186  AST_RWLIST_TRAVERSE_SAFE_BEGIN(list, rule, next) {
187  if (rule == obj) {
188  AST_RWLIST_REMOVE_CURRENT(next);
189  break;
190  }
191  }
192  AST_RWLIST_TRAVERSE_SAFE_END;
193  ao2_unlock(control->command_queue);
194 }
195 
196 void control_set_thread(struct stasis_app_control *control, pthread_t threadid)
197 {
198  ao2_lock(control->command_queue);
199  control->control_thread = threadid;
200  ao2_unlock(control->command_queue);
201 }
202 
203 /*!
204  * \internal
205  * \brief Checks to make sure each rule in the given list passes.
206  *
207  * \details Loops over a list of rules checking for rejections or failures.
208  * If one rule fails its resulting error code is returned.
209  *
210  * \note Command queue should be locked before calling this function.
211  *
212  * \param control The stasis application control
213  * \param list The list of rules to check
214  *
215  * \retval 0 if all rules pass
216  * \retval non-zero error code if a rule fails
217  */
218 static enum stasis_app_control_channel_result app_control_check_rules(
219  const struct stasis_app_control *control,
220  struct app_control_rules *list)
221 {
222  int res = 0;
223  struct stasis_app_control_rule *rule;
224  AST_LIST_TRAVERSE(list, rule, next) {
225  if ((res = rule->check_rule(control))) {
226  return res;
227  }
228  }
229  return res;
230 }
231 
233  struct stasis_app_control *control,
234  struct stasis_app_control_rule *rule)
235 {
236  return app_control_register_rule(control, &control->add_rules, rule);
237 }
238 
240  struct stasis_app_control *control,
241  struct stasis_app_control_rule *rule)
242 {
243  app_control_unregister_rule(control, &control->add_rules, rule);
244 }
245 
247  struct stasis_app_control *control,
248  struct stasis_app_control_rule *rule)
249 {
250  return app_control_register_rule(control, &control->remove_rules, rule);
251 }
252 
254  struct stasis_app_control *control,
255  struct stasis_app_control_rule *rule)
256 {
257  app_control_unregister_rule(control, &control->remove_rules, rule);
258 }
259 
260 static int app_control_can_add_channel_to_bridge(
261  struct stasis_app_control *control)
262 {
263  return app_control_check_rules(control, &control->add_rules);
264 }
265 
266 static int app_control_can_remove_channel_from_bridge(
267  struct stasis_app_control *control)
268 {
269  return app_control_check_rules(control, &control->remove_rules);
270 }
271 
272 static int noop_cb(struct stasis_app_control *control,
273  struct ast_channel *chan, void *data)
274 {
275  return 0;
276 }
277 
278 /*! Callback type to see if the command can execute
279  note: command_queue is locked during callback */
280 typedef int (*app_command_can_exec_cb)(struct stasis_app_control *control);
281 
282 static struct stasis_app_command *exec_command_on_condition(
283  struct stasis_app_control *control, stasis_app_command_cb command_fn,
284  void *data, command_data_destructor_fn data_destructor,
285  app_command_can_exec_cb can_exec_fn)
286 {
287  int retval;
288  struct stasis_app_command *command;
289 
290  command_fn = command_fn ? : noop_cb;
291 
292  command = command_create(command_fn, data, data_destructor);
293  if (!command) {
294  return NULL;
295  }
296 
297  ao2_lock(control->command_queue);
298  if (control->is_done) {
299  ao2_unlock(control->command_queue);
300  ao2_ref(command, -1);
301  return NULL;
302  }
303  if (can_exec_fn && (retval = can_exec_fn(control))) {
304  ao2_unlock(control->command_queue);
305  command_complete(command, retval);
306  return command;
307  }
308 
309  ao2_link_flags(control->command_queue, command, OBJ_NOLOCK);
310  ast_cond_signal(&control->wait_cond);
311 
312  if (control->control_thread != AST_PTHREADT_NULL) {
313  /* if the control thread is waiting on the channel, send the SIGURG
314  to let it know there is a new command */
315  pthread_kill(control->control_thread, SIGURG);
316  }
317 
318  ao2_unlock(control->command_queue);
319 
320  return command;
321 }
322 
323 static struct stasis_app_command *exec_command(
324  struct stasis_app_control *control, stasis_app_command_cb command_fn,
325  void *data, command_data_destructor_fn data_destructor)
326 {
327  return exec_command_on_condition(control, command_fn, data, data_destructor, NULL);
328 }
329 
330 static int app_control_add_role(struct stasis_app_control *control,
331  struct ast_channel *chan, void *data)
332 {
333  char *role = data;
334 
335  return ast_channel_add_bridge_role(chan, role);
336 }
337 
338 int stasis_app_control_add_role(struct stasis_app_control *control, const char *role)
339 {
340  char *role_dup;
341 
342  role_dup = ast_strdup(role);
343  if (!role_dup) {
344  return -1;
345  }
346 
347  stasis_app_send_command_async(control, app_control_add_role, role_dup, ast_free_ptr);
348 
349  return 0;
350 }
351 
352 static int app_control_clear_roles(struct stasis_app_control *control,
353  struct ast_channel *chan, void *data)
354 {
356 
357  return 0;
358 }
359 
361 {
362  stasis_app_send_command_async(control, app_control_clear_roles, NULL, NULL);
363 }
364 
366 {
367  return ao2_container_count(control->command_queue);
368 }
369 
371 {
372  /* Called from stasis_app_exec thread; no lock needed */
373  return control->is_done;
374 }
375 
376 void control_mark_done(struct stasis_app_control *control)
377 {
378  /* Locking necessary to sync with other threads adding commands to the queue. */
379  ao2_lock(control->command_queue);
380  control->is_done = 1;
381  ao2_unlock(control->command_queue);
382 }
383 
385  char context[AST_MAX_CONTEXT];
387  int priority;
388 };
389 
390 static int app_control_continue(struct stasis_app_control *control,
391  struct ast_channel *chan, void *data)
392 {
393  struct stasis_app_control_continue_data *continue_data = data;
394 
395  ast_assert(control->channel != NULL);
396 
397  /* If we're in a Stasis bridge, depart it before going back to the
398  * dialplan */
399  if (stasis_app_get_bridge(control)) {
400  ast_bridge_depart(control->channel);
401  }
402 
403  /* Called from stasis_app_exec thread; no lock needed */
404  ast_explicit_goto(control->channel, continue_data->context, continue_data->extension, continue_data->priority);
405 
406  control_mark_done(control);
407 
408  return 0;
409 }
410 
411 int stasis_app_control_continue(struct stasis_app_control *control, const char *context, const char *extension, int priority)
412 {
413  struct stasis_app_control_continue_data *continue_data;
414 
415  if (!(continue_data = ast_calloc(1, sizeof(*continue_data)))) {
416  return -1;
417  }
418  ast_copy_string(continue_data->context, S_OR(context, ""), sizeof(continue_data->context));
419  ast_copy_string(continue_data->extension, S_OR(extension, ""), sizeof(continue_data->extension));
420  if (priority > 0) {
421  continue_data->priority = priority;
422  } else {
423  continue_data->priority = -1;
424  }
425 
426  stasis_app_send_command_async(control, app_control_continue, continue_data, ast_free_ptr);
427 
428  return 0;
429 }
430 
432  char *app_name;
433  char *app_args;
434 };
435 
436 static int app_control_move(struct stasis_app_control *control,
437  struct ast_channel *chan, void *data)
438 {
439  struct stasis_app_control_move_data *move_data = data;
440 
441  control->next_app = ast_strdup(move_data->app_name);
442  if (!control->next_app) {
443  ast_log(LOG_ERROR, "Allocation failed for next app\n");
444  return -1;
445  }
446 
447  if (move_data->app_args) {
448  char *token;
449 
450  while ((token = strtok_r(move_data->app_args, ",", &move_data->app_args))) {
451  int res;
452  char *arg;
453 
454  if (!(arg = ast_strdup(token))) {
455  ast_log(LOG_ERROR, "Allocation failed for next app arg\n");
456  control_move_cleanup(control);
457  return -1;
458  }
459 
460  res = AST_VECTOR_APPEND(&control->next_app_args, arg);
461  if (res) {
462  ast_log(LOG_ERROR, "Failed to append arg to next app args\n");
463  ast_free(arg);
464  control_move_cleanup(control);
465  return -1;
466  }
467  }
468  }
469 
470  return 0;
471 }
472 
473 int stasis_app_control_move(struct stasis_app_control *control, const char *app_name, const char *app_args)
474 {
475  struct stasis_app_control_move_data *move_data;
476  size_t size;
477 
478  size = sizeof(*move_data) + strlen(app_name) + 1;
479  if (app_args) {
480  /* Application arguments are optional */
481  size += strlen(app_args) + 1;
482  }
483 
484  if (!(move_data = ast_calloc(1, size))) {
485  return -1;
486  }
487 
488  move_data->app_name = (char *)move_data + sizeof(*move_data);
489  strcpy(move_data->app_name, app_name); /* Safe */
490 
491  if (app_args) {
492  move_data->app_args = move_data->app_name + strlen(app_name) + 1;
493  strcpy(move_data->app_args, app_args); /* Safe */
494  } else {
495  move_data->app_args = NULL;
496  }
497 
498  stasis_app_send_command_async(control, app_control_move, move_data, ast_free_ptr);
499 
500  return 0;
501 }
502 
503 static int app_control_redirect(struct stasis_app_control *control,
504  struct ast_channel *chan, void *data)
505 {
506  char *endpoint = data;
507  int res;
508 
509  ast_assert(control->channel != NULL);
510  ast_assert(endpoint != NULL);
511 
512  res = ast_transfer(control->channel, endpoint);
513  if (!res) {
514  ast_log(LOG_NOTICE, "Unsupported transfer requested on channel '%s'\n",
515  ast_channel_name(control->channel));
516  return 0;
517  }
518 
519  return 0;
520 }
521 
522 int stasis_app_control_redirect(struct stasis_app_control *control, const char *endpoint)
523 {
524  char *endpoint_data = ast_strdup(endpoint);
525 
526  if (!endpoint_data) {
527  return -1;
528  }
529 
530  stasis_app_send_command_async(control, app_control_redirect, endpoint_data, ast_free_ptr);
531 
532  return 0;
533 }
534 
536  int before;
537  int between;
538  unsigned int duration;
539  int after;
540  char dtmf[];
541 };
542 
543 static void dtmf_in_bridge(struct ast_channel *chan, struct stasis_app_control_dtmf_data *dtmf_data)
544 {
545  if (dtmf_data->before) {
546  usleep(dtmf_data->before * 1000);
547  }
548 
549  ast_dtmf_stream_external(chan, dtmf_data->dtmf, dtmf_data->between, dtmf_data->duration);
550 
551  if (dtmf_data->after) {
552  usleep(dtmf_data->after * 1000);
553  }
554 }
555 
556 static void dtmf_no_bridge(struct ast_channel *chan, struct stasis_app_control_dtmf_data *dtmf_data)
557 {
558  if (dtmf_data->before) {
559  ast_safe_sleep(chan, dtmf_data->before);
560  }
561 
562  ast_dtmf_stream(chan, NULL, dtmf_data->dtmf, dtmf_data->between, dtmf_data->duration);
563 
564  if (dtmf_data->after) {
565  ast_safe_sleep(chan, dtmf_data->after);
566  }
567 }
568 
569 static int app_control_dtmf(struct stasis_app_control *control,
570  struct ast_channel *chan, void *data)
571 {
572  struct stasis_app_control_dtmf_data *dtmf_data = data;
573 
574  if (ast_channel_state(chan) != AST_STATE_UP) {
576  }
577 
578  if (stasis_app_get_bridge(control)) {
579  dtmf_in_bridge(chan, dtmf_data);
580  } else {
581  dtmf_no_bridge(chan, dtmf_data);
582  }
583 
584  return 0;
585 }
586 
587 int stasis_app_control_dtmf(struct stasis_app_control *control, const char *dtmf, int before, int between, unsigned int duration, int after)
588 {
589  struct stasis_app_control_dtmf_data *dtmf_data;
590 
591  if (!(dtmf_data = ast_calloc(1, sizeof(*dtmf_data) + strlen(dtmf) + 1))) {
592  return -1;
593  }
594 
595  dtmf_data->before = before;
596  dtmf_data->between = between;
597  dtmf_data->duration = duration;
598  dtmf_data->after = after;
599  strcpy(dtmf_data->dtmf, dtmf);
600 
601  stasis_app_send_command_async(control, app_control_dtmf, dtmf_data, ast_free_ptr);
602 
603  return 0;
604 }
605 
606 static int app_control_ring(struct stasis_app_control *control,
607  struct ast_channel *chan, void *data)
608 {
610 
611  return 0;
612 }
613 
615 {
616  stasis_app_send_command_async(control, app_control_ring, NULL, NULL);
617 
618  return 0;
619 }
620 
621 static int app_control_ring_stop(struct stasis_app_control *control,
622  struct ast_channel *chan, void *data)
623 {
624  ast_indicate(control->channel, -1);
625 
626  return 0;
627 }
628 
630 {
631  stasis_app_send_command_async(control, app_control_ring_stop, NULL, NULL);
632 
633  return 0;
634 }
635 
637  enum ast_frame_type frametype;
638  unsigned int direction;
639 };
640 
641 static int app_control_mute(struct stasis_app_control *control,
642  struct ast_channel *chan, void *data)
643 {
644  struct stasis_app_control_mute_data *mute_data = data;
645 
646  ast_channel_lock(chan);
647  ast_channel_suppress(control->channel, mute_data->direction, mute_data->frametype);
648  ast_channel_unlock(chan);
649 
650  return 0;
651 }
652 
653 int stasis_app_control_mute(struct stasis_app_control *control, unsigned int direction, enum ast_frame_type frametype)
654 {
655  struct stasis_app_control_mute_data *mute_data;
656 
657  if (!(mute_data = ast_calloc(1, sizeof(*mute_data)))) {
658  return -1;
659  }
660 
661  mute_data->direction = direction;
662  mute_data->frametype = frametype;
663 
664  stasis_app_send_command_async(control, app_control_mute, mute_data, ast_free_ptr);
665 
666  return 0;
667 }
668 
669 static int app_control_unmute(struct stasis_app_control *control,
670  struct ast_channel *chan, void *data)
671 {
672  struct stasis_app_control_mute_data *mute_data = data;
673 
674  ast_channel_lock(chan);
675  ast_channel_unsuppress(control->channel, mute_data->direction, mute_data->frametype);
676  ast_channel_unlock(chan);
677 
678  return 0;
679 }
680 
681 int stasis_app_control_unmute(struct stasis_app_control *control, unsigned int direction, enum ast_frame_type frametype)
682 {
683  struct stasis_app_control_mute_data *mute_data;
684 
685  if (!(mute_data = ast_calloc(1, sizeof(*mute_data)))) {
686  return -1;
687  }
688 
689  mute_data->direction = direction;
690  mute_data->frametype = frametype;
691 
692  stasis_app_send_command_async(control, app_control_unmute, mute_data, ast_free_ptr);
693 
694  return 0;
695 }
696 
697 /*!
698  * \brief structure for queuing ARI channel variable setting
699  *
700  * It may seem weird to define this custom structure given that we already have
701  * ast_var_t and ast_variable defined elsewhere. The problem with those is that
702  * they are not tolerant of NULL channel variable value pointers. In fact, in both
703  * cases, the best they could do is to have a zero-length variable value. However,
704  * when un-setting a channel variable, it is important to pass a NULL value, not
705  * a zero-length string.
706  */
707 struct chanvar {
708  /*! Name of variable to set/unset */
709  char *name;
710  /*! Value of variable to set. If unsetting, this will be NULL */
711  char *value;
712 };
713 
714 static void free_chanvar(void *data)
715 {
716  struct chanvar *var = data;
717 
718  ast_free(var->name);
719  ast_free(var->value);
720  ast_free(var);
721 }
722 
723 static int app_control_set_channel_var(struct stasis_app_control *control,
724  struct ast_channel *chan, void *data)
725 {
726  struct chanvar *var = data;
727 
728  pbx_builtin_setvar_helper(control->channel, var->name, var->value);
729 
730  return 0;
731 }
732 
733 int stasis_app_control_set_channel_var(struct stasis_app_control *control, const char *variable, const char *value)
734 {
735  struct chanvar *var;
736 
737  var = ast_calloc(1, sizeof(*var));
738  if (!var) {
739  return -1;
740  }
741 
742  var->name = ast_strdup(variable);
743  if (!var->name) {
744  free_chanvar(var);
745  return -1;
746  }
747 
748  /* It's kosher for value to be NULL. It means the variable is being unset */
749  if (value) {
750  var->value = ast_strdup(value);
751  if (!var->value) {
752  free_chanvar(var);
753  return -1;
754  }
755  }
756 
757  stasis_app_send_command_async(control, app_control_set_channel_var, var, free_chanvar);
758 
759  return 0;
760 }
761 
762 static int app_control_hold(struct stasis_app_control *control,
763  struct ast_channel *chan, void *data)
764 {
766 
767  return 0;
768 }
769 
771 {
772  stasis_app_send_command_async(control, app_control_hold, NULL, NULL);
773 }
774 
775 static int app_control_unhold(struct stasis_app_control *control,
776  struct ast_channel *chan, void *data)
777 {
779 
780  return 0;
781 }
782 
784 {
785  stasis_app_send_command_async(control, app_control_unhold, NULL, NULL);
786 }
787 
788 static int app_control_moh_start(struct stasis_app_control *control,
789  struct ast_channel *chan, void *data)
790 {
791  char *moh_class = data;
792 
793  if (ast_channel_state(chan) != AST_STATE_UP) {
795  }
796 
797  ast_moh_start(chan, moh_class, NULL);
798 
799  return 0;
800 }
801 
802 void stasis_app_control_moh_start(struct stasis_app_control *control, const char *moh_class)
803 {
804  char *data = NULL;
805 
806  if (!ast_strlen_zero(moh_class)) {
807  data = ast_strdup(moh_class);
808  }
809 
810  stasis_app_send_command_async(control, app_control_moh_start, data, ast_free_ptr);
811 }
812 
813 static int app_control_moh_stop(struct stasis_app_control *control,
814  struct ast_channel *chan, void *data)
815 {
816  ast_moh_stop(chan);
817  return 0;
818 }
819 
821 {
822  stasis_app_send_command_async(control, app_control_moh_stop, NULL, NULL);
823 }
824 
825 static int app_control_silence_start(struct stasis_app_control *control,
826  struct ast_channel *chan, void *data)
827 {
828  if (ast_channel_state(chan) != AST_STATE_UP) {
830  }
831 
832  if (control->silgen) {
833  /* We have a silence generator, but it may have been implicitly
834  * disabled by media actions (music on hold, playing media,
835  * etc.) Just stop it and restart a new one.
836  */
838  control->channel, control->silgen);
839  }
840 
841  ast_debug(3, "%s: Starting silence generator\n",
844 
845  if (!control->silgen) {
846  ast_log(LOG_WARNING,
847  "%s: Failed to start silence generator.\n",
849  }
850 
851  return 0;
852 }
853 
855 {
856  stasis_app_send_command_async(control, app_control_silence_start, NULL, NULL);
857 }
858 
860 {
861  if (control->silgen) {
862  ast_debug(3, "%s: Stopping silence generator\n",
865  control->channel, control->silgen);
866  control->silgen = NULL;
867  }
868 }
869 
870 static int app_control_silence_stop(struct stasis_app_control *control,
871  struct ast_channel *chan, void *data)
872 {
873  control_silence_stop_now(control);
874  return 0;
875 }
876 
878 {
879  stasis_app_send_command_async(control, app_control_silence_stop, NULL, NULL);
880 }
881 
883  const struct stasis_app_control *control)
884 {
886 }
887 
888 static int app_send_command_on_condition(struct stasis_app_control *control,
889  stasis_app_command_cb command_fn, void *data,
890  command_data_destructor_fn data_destructor,
891  app_command_can_exec_cb can_exec_fn)
892 {
893  int ret;
894  struct stasis_app_command *command;
895 
896  if (control == NULL || control->is_done) {
897  /* If exec_command_on_condition fails, it calls the data_destructor.
898  * In order to provide consistent behavior, we'll also call the data_destructor
899  * on this error path. This way, callers never have to call the
900  * data_destructor themselves.
901  */
902  if (data_destructor) {
903  data_destructor(data);
904  }
905  return -1;
906  }
907 
908  command = exec_command_on_condition(
909  control, command_fn, data, data_destructor, can_exec_fn);
910  if (!command) {
911  return -1;
912  }
913 
914  ret = command_join(command);
915  ao2_ref(command, -1);
916 
917  return ret;
918 }
919 
921  stasis_app_command_cb command_fn, void *data, command_data_destructor_fn data_destructor)
922 {
923  return app_send_command_on_condition(control, command_fn, data, data_destructor, NULL);
924 }
925 
927  stasis_app_command_cb command_fn, void *data,
928  command_data_destructor_fn data_destructor)
929 {
930  struct stasis_app_command *command;
931 
932  if (control == NULL || control->is_done) {
933  /* If exec_command fails, it calls the data_destructor. In order to
934  * provide consistent behavior, we'll also call the data_destructor
935  * on this error path. This way, callers never have to call the
936  * data_destructor themselves.
937  */
938  if (data_destructor) {
939  data_destructor(data);
940  }
941  return -1;
942  }
943 
944  command = exec_command(control, command_fn, data, data_destructor);
945  if (!command) {
946  return -1;
947  }
948  ao2_ref(command, -1);
949 
950  return 0;
951 }
952 
954 {
955  struct ast_bridge *ret;
956 
957  if (!control) {
958  return NULL;
959  }
960 
961  ao2_lock(control);
962  ret = control->bridge;
963  ao2_unlock(control);
964 
965  return ret;
966 }
967 
968 /*!
969  * \brief Singleton dial bridge
970  *
971  * The dial bridge is a holding bridge used to hold all
972  * outbound dialed channels that are not in any "real" ARI-created
973  * bridge. The dial bridge is invisible, meaning that it does not
974  * show up in channel snapshots, AMI or ARI output, and no events
975  * get raised for it.
976  *
977  * This is used to keep dialed channels confined to the bridging system
978  * and unify the threading model used for dialing outbound channels.
979  */
980 static struct ast_bridge *dial_bridge;
981 AST_MUTEX_DEFINE_STATIC(dial_bridge_lock);
982 
983 /*!
984  * \brief Retrieve a reference to the dial bridge.
985  *
986  * If the dial bridge has not been created yet, it will
987  * be created, otherwise, a reference to the existing bridge
988  * will be returned.
989  *
990  * The caller will need to unreference the dial bridge once
991  * they are finished with it.
992  *
993  * \retval NULL Unable to find/create the dial bridge
994  * \retval non-NULL A reference to the dial bridge
995  */
996 static struct ast_bridge *get_dial_bridge(void)
997 {
998  struct ast_bridge *ret_bridge = NULL;
999 
1000  ast_mutex_lock(&dial_bridge_lock);
1001 
1002  if (shutting_down) {
1003  goto end;
1004  }
1005 
1006  if (dial_bridge) {
1007  ret_bridge = ao2_bump(dial_bridge);
1008  goto end;
1009  }
1010 
1011  dial_bridge = stasis_app_bridge_create_invisible("holding", "dial_bridge", NULL);
1012  if (!dial_bridge) {
1013  goto end;
1014  }
1015  ret_bridge = ao2_bump(dial_bridge);
1016 
1017 end:
1018  ast_mutex_unlock(&dial_bridge_lock);
1019  return ret_bridge;
1020 }
1021 
1022 static int bridge_channel_depart(struct stasis_app_control *control,
1023  struct ast_channel *chan, void *data);
1024 
1025 /*!
1026  * \brief after bridge callback for the dial bridge
1027  *
1028  * The only purpose of this callback is to ensure that the control structure's
1029  * bridge pointer is NULLed
1030  */
1031 static void dial_bridge_after_cb(struct ast_channel *chan, void *data)
1032 {
1033  struct stasis_app_control *control = data;
1034  struct ast_bridge_channel *bridge_channel;
1035 
1036  ast_channel_lock(chan);
1037  bridge_channel = ast_channel_get_bridge_channel(chan);
1038  ast_channel_unlock(chan);
1039 
1040  ast_debug(3, "Channel: <%s> Reason: %d\n", ast_channel_name(control->channel), ast_channel_hangupcause(chan));
1041 
1042  stasis_app_send_command_async(control, bridge_channel_depart, bridge_channel, __ao2_cleanup);
1043 
1044  control->bridge = NULL;
1045 }
1046 
1047 static void dial_bridge_after_cb_failed(enum ast_bridge_after_cb_reason reason, void *data)
1048 {
1049  struct stasis_app_control *control = data;
1050 
1051  ast_debug(3, "Channel: <%s> Reason: %d\n", ast_channel_name(control->channel), reason);
1052  dial_bridge_after_cb(control->channel, data);
1053 }
1054 
1055 /*!
1056  * \brief Add a channel to the singleton dial bridge.
1057  *
1058  * \param control The Stasis control structure
1059  * \param chan The channel to add to the bridge
1060  * \retval -1 Failed
1061  * \retval 0 Success
1062  */
1063 static int add_to_dial_bridge(struct stasis_app_control *control, struct ast_channel *chan)
1064 {
1065  struct ast_bridge *bridge;
1066 
1067  bridge = get_dial_bridge();
1068  if (!bridge) {
1069  return -1;
1070  }
1071 
1072  control->bridge = bridge;
1073  ast_bridge_set_after_callback(chan, dial_bridge_after_cb, dial_bridge_after_cb_failed, control);
1074  if (ast_bridge_impart(bridge, chan, NULL, NULL, AST_BRIDGE_IMPART_CHAN_DEPARTABLE)) {
1075  control->bridge = NULL;
1076  ao2_ref(bridge, -1);
1077  return -1;
1078  }
1079 
1080  ao2_ref(bridge, -1);
1081 
1082  return 0;
1083 }
1084 
1085 /*!
1086  * \brief Depart a channel from a bridge, and potentially add it back to the dial bridge
1087  *
1088  * \param control Take a guess
1089  * \param chan Take another guess
1090  */
1091 static int depart_channel(struct stasis_app_control *control, struct ast_channel *chan)
1092 {
1093  ast_bridge_depart(chan);
1094 
1095  /* Channels which have a PBX are not ones that have been created and dialed from ARI. They
1096  * have externally come in from the dialplan, and thus should not be placed into the dial
1097  * bridge. Only channels which are created and dialed in ARI should go into the dial bridge.
1098  */
1099  if (!ast_check_hangup(chan) && ast_channel_state(chan) != AST_STATE_UP && !ast_channel_pbx(chan)) {
1100  /* Channel is still being dialed, so put it back in the dialing bridge */
1101  add_to_dial_bridge(control, chan);
1102  }
1103 
1104  return 0;
1105 }
1106 
1107 static int bridge_channel_depart(struct stasis_app_control *control,
1108  struct ast_channel *chan, void *data)
1109 {
1110  struct ast_bridge_channel *bridge_channel;
1111 
1112  ast_channel_lock(chan);
1113  bridge_channel = ast_channel_internal_bridge_channel(chan);
1114  ast_channel_unlock(chan);
1115 
1116  if (bridge_channel != data) {
1117  ast_debug(3, "%s: Channel is no longer in departable state\n",
1118  ast_channel_uniqueid(chan));
1119  return -1;
1120  }
1121 
1122  ast_debug(3, "%s: Channel departing bridge\n",
1123  ast_channel_uniqueid(chan));
1124 
1125  depart_channel(control, chan);
1126 
1127  return 0;
1128 }
1129 
1130 static void internal_bridge_after_cb(struct ast_channel *chan, void *data,
1131  enum ast_bridge_after_cb_reason reason)
1132 {
1133  struct stasis_app_control *control = data;
1134  struct ast_bridge_channel *bridge_channel;
1135 
1136  ao2_lock(control);
1137  ast_debug(3, "%s, %s: %s\n",
1138  ast_channel_uniqueid(chan), control->bridge ? control->bridge->uniqueid : "unknown",
1140 
1142  /* The impart actually failed so control->bridge isn't valid. */
1143  control->bridge = NULL;
1144  }
1145 
1146  ast_assert(chan == control->channel);
1147 
1148  /* Restore the channel's PBX */
1149  ast_channel_pbx_set(control->channel, control->pbx);
1150  control->pbx = NULL;
1151 
1152  if (control->bridge) {
1153  app_unsubscribe_bridge(control->app, control->bridge);
1154 
1155  /* No longer in the bridge */
1156  control->bridge = NULL;
1157 
1158  /* Get the bridge channel so we don't depart from the wrong bridge */
1159  ast_channel_lock(chan);
1160  bridge_channel = ast_channel_get_bridge_channel(chan);
1161  ast_channel_unlock(chan);
1162 
1163  /* Depart this channel from the bridge using the command queue if possible */
1164  stasis_app_send_command_async(control, bridge_channel_depart, bridge_channel, __ao2_cleanup);
1165  }
1166 
1168  /* The channel has had a StasisEnd published on it, but until now had remained in
1169  * the bridging system. This means that the channel moved from a Stasis bridge to a
1170  * non-Stasis bridge and is now exiting the bridging system. Because of this, the
1171  * channel needs to exit the Stasis application and go to wherever the non-Stasis
1172  * bridge has directed it to go. If the non-Stasis bridge has not set up an after
1173  * bridge destination, then the channel should be hung up.
1174  */
1175  int hangup_flag;
1176 
1178  ast_channel_lock(chan);
1179  ast_softhangup_nolock(chan, hangup_flag);
1180  ast_channel_unlock(chan);
1181  }
1182  ao2_unlock(control);
1183 }
1184 
1185 static void bridge_after_cb(struct ast_channel *chan, void *data)
1186 {
1187  struct stasis_app_control *control = data;
1188 
1189  internal_bridge_after_cb(control->channel, data, AST_BRIDGE_AFTER_CB_REASON_DEPART);
1190 }
1191 
1192 static void bridge_after_cb_failed(enum ast_bridge_after_cb_reason reason,
1193  void *data)
1194 {
1195  struct stasis_app_control *control = data;
1196 
1197  internal_bridge_after_cb(control->channel, data, reason);
1198 
1199  ast_debug(3, " reason: %s\n",
1201 }
1202 
1203 /*!
1204  * \brief Dial timeout datastore
1205  *
1206  * A datastore is used because a channel may change
1207  * bridges during the course of a dial attempt. This
1208  * may be because the channel changes from the dial bridge
1209  * to a standard bridge, or it may move between standard
1210  * bridges. In order to keep the dial timeout, we need
1211  * to keep the timeout information local to the channel.
1212  * That is what this datastore is for
1213  */
1215  .type = "ARI dial timeout",
1216 };
1217 
1218 static int hangup_channel(struct stasis_app_control *control,
1219  struct ast_channel *chan, void *data)
1220 {
1222  return 0;
1223 }
1224 
1225 /*!
1226  * \brief Dial timeout
1227  *
1228  * This is a bridge interval hook callback. The interval hook triggering
1229  * means that the dial timeout has been reached. If the channel has not
1230  * been answered by the time this callback is called, then the channel
1231  * is hung up
1232  *
1233  * \param bridge_channel Bridge channel on which interval hook has been called
1234  * \param ignore Ignored
1235  * \return -1 (i.e. remove the interval hook)
1236  */
1237 static int bridge_timeout(struct ast_bridge_channel *bridge_channel, void *ignore)
1238 {
1239  struct ast_datastore *datastore;
1240  RAII_VAR(struct stasis_app_control *, control, NULL, ao2_cleanup);
1241 
1242  control = stasis_app_control_find_by_channel(bridge_channel->chan);
1243 
1244  ast_channel_lock(bridge_channel->chan);
1245  if (ast_channel_state(bridge_channel->chan) != AST_STATE_UP) {
1246  /* Don't bother removing the datastore because it will happen when the channel is hung up */
1247  ast_channel_unlock(bridge_channel->chan);
1248  stasis_app_send_command_async(control, hangup_channel, NULL, NULL);
1249  return -1;
1250  }
1251 
1252  datastore = ast_channel_datastore_find(bridge_channel->chan, &timeout_datastore, NULL);
1253  if (!datastore) {
1254  ast_channel_unlock(bridge_channel->chan);
1255  return -1;
1256  }
1257  ast_channel_datastore_remove(bridge_channel->chan, datastore);
1258  ast_channel_unlock(bridge_channel->chan);
1259  ast_datastore_free(datastore);
1260 
1261  return -1;
1262 }
1263 
1264 /*!
1265  * \brief Set a dial timeout interval hook on the channel.
1266  *
1267  * The absolute time that the timeout should occur is stored on
1268  * a datastore on the channel. This time is converted into a relative
1269  * number of milliseconds in the future. Then an interval hook is set
1270  * to trigger in that number of milliseconds.
1271  *
1272  * \pre chan is locked
1273  *
1274  * \param chan The channel on which to set the interval hook
1275  */
1276 static void set_interval_hook(struct ast_channel *chan)
1277 {
1278  struct ast_datastore *datastore;
1279  struct timeval *hangup_time;
1280  int64_t ms;
1281  struct ast_bridge_channel *bridge_channel;
1282 
1283  datastore = ast_channel_datastore_find(chan, &timeout_datastore, NULL);
1284  if (!datastore) {
1285  return;
1286  }
1287 
1288  hangup_time = datastore->data;
1289 
1290  ms = ast_tvdiff_ms(*hangup_time, ast_tvnow());
1291  bridge_channel = ast_channel_get_bridge_channel(chan);
1292  if (!bridge_channel) {
1293  return;
1294  }
1295 
1296  if (ast_bridge_interval_hook(bridge_channel->features, 0, ms > 0 ? ms : 1,
1297  bridge_timeout, NULL, NULL, 0)) {
1298  ao2_ref(bridge_channel, -1);
1299  return;
1300  }
1301 
1302  ast_queue_frame(bridge_channel->chan, &ast_null_frame);
1303  ao2_ref(bridge_channel, -1);
1304 }
1305 
1306 int control_swap_channel_in_bridge(struct stasis_app_control *control, struct ast_bridge *bridge, struct ast_channel *chan, struct ast_channel *swap)
1307 {
1308  int res;
1309  struct ast_bridge_features *features;
1311 
1312  if (!control || !bridge) {
1313  return -1;
1314  }
1315 
1316  ast_debug(3, "%s: Adding to bridge %s\n",
1318  bridge->uniqueid);
1319 
1320  ast_assert(chan != NULL);
1321 
1322  /* Depart whatever Stasis bridge we're currently in. */
1323  if (stasis_app_get_bridge(control)) {
1324  /* Note that it looks like there's a race condition here, since
1325  * we don't have control locked. But this happens from the
1326  * control callback thread, so there won't be any other
1327  * concurrent attempts to bridge.
1328  */
1329  ast_bridge_depart(chan);
1330  }
1331 
1332 
1333  res = ast_bridge_set_after_callback(chan, bridge_after_cb,
1334  bridge_after_cb_failed, control);
1335  if (res != 0) {
1336  ast_log(LOG_ERROR, "Error setting after-bridge callback\n");
1337  return -1;
1338  }
1339 
1340  ao2_lock(control);
1341 
1342  /* Ensure the controlling application is subscribed early enough
1343  * to receive the ChannelEnteredBridge message. This works in concert
1344  * with the subscription handled in the Stasis application execution
1345  * loop */
1346  app_subscribe_bridge(control->app, bridge);
1347 
1348  /* Save off the channel's PBX */
1349  ast_assert(control->pbx == NULL);
1350  if (!control->pbx) {
1351  control->pbx = ast_channel_pbx(chan);
1352  ast_channel_pbx_set(chan, NULL);
1353  }
1354 
1355  /* Pull bridge features from the control */
1356  features = control->bridge_features;
1357  control->bridge_features = NULL;
1358  if (features && features->inhibit_colp) {
1360  }
1361 
1362  ast_assert(stasis_app_get_bridge(control) == NULL);
1363  /* We need to set control->bridge here since bridge_after_cb may be run
1364  * before ast_bridge_impart returns. bridge_after_cb gets a reason
1365  * code so it can tell if the bridge is actually valid or not.
1366  */
1367  control->bridge = bridge;
1368 
1369  /* We can't be holding the control lock while impart is running
1370  * or we could create a deadlock with bridge_after_cb which also
1371  * tries to lock control.
1372  */
1373  ao2_unlock(control);
1374  res = ast_bridge_impart(bridge,
1375  chan,
1376  swap,
1377  features, /* features */
1378  flags);
1379  if (res != 0) {
1380  /* ast_bridge_impart failed before it could spawn the depart
1381  * thread. The callbacks aren't called in this case.
1382  * The impart could still fail even if ast_bridge_impart returned
1383  * ok but that's handled by bridge_after_cb.
1384  */
1385  ast_log(LOG_ERROR, "Error adding channel to bridge\n");
1386  ao2_lock(control);
1387  ast_channel_pbx_set(chan, control->pbx);
1388  control->pbx = NULL;
1389  control->bridge = NULL;
1390  ao2_unlock(control);
1391  } else {
1392  ast_channel_lock(chan);
1393  set_interval_hook(chan);
1394  ast_channel_unlock(chan);
1395  }
1396 
1397  return res;
1398 }
1399 
1400 int control_add_channel_to_bridge(struct stasis_app_control *control, struct ast_channel *chan, void *data)
1401 {
1402  return control_swap_channel_in_bridge(control, data, chan, NULL);
1403 }
1404 
1406  struct stasis_app_control *control, struct ast_bridge *bridge)
1407 {
1408  ast_debug(3, "%s: Sending channel add_to_bridge command\n",
1410 
1411  return app_send_command_on_condition(
1412  control, control_add_channel_to_bridge, bridge, NULL,
1413  app_control_can_add_channel_to_bridge);
1414 }
1415 
1416 static int app_control_remove_channel_from_bridge(
1417  struct stasis_app_control *control,
1418  struct ast_channel *chan, void *data)
1419 {
1420  struct ast_bridge *bridge = data;
1421 
1422  if (!control) {
1423  return -1;
1424  }
1425 
1426  /* We should only depart from our own bridge */
1427  ast_debug(3, "%s: Departing bridge %s\n",
1429  bridge->uniqueid);
1430 
1431  if (bridge != stasis_app_get_bridge(control)) {
1432  ast_log(LOG_WARNING, "%s: Not in bridge %s; not removing\n",
1434  bridge->uniqueid);
1435  return -1;
1436  }
1437 
1438  depart_channel(control, chan);
1439  return 0;
1440 }
1441 
1443  struct stasis_app_control *control, struct ast_bridge *bridge)
1444 {
1445  ast_debug(3, "%s: Sending channel remove_from_bridge command\n",
1447  return app_send_command_on_condition(
1448  control, app_control_remove_channel_from_bridge, bridge, NULL,
1449  app_control_can_remove_channel_from_bridge);
1450 }
1451 
1453  const struct stasis_app_control *control)
1454 {
1455  return ast_channel_uniqueid(control->channel);
1456 }
1457 
1459  struct stasis_app_control *control, struct stasis_message *message)
1460 {
1461  if (!control || !control->channel || !message) {
1462  return;
1463  }
1464  stasis_publish(ast_channel_topic(control->channel), message);
1465 }
1466 
1468  enum ast_control_frame_type frame_type)
1469 {
1470  return ast_queue_control(control->channel, frame_type);
1471 }
1472 
1474  struct stasis_app_control *control)
1475 {
1476  struct ast_bridge_features *features;
1477 
1478  features = ast_bridge_features_new();
1479  if (!features) {
1480  return 1;
1481  }
1482  control->bridge_features = features;
1483  return 0;
1484 }
1485 
1487  struct stasis_app_control *control, int absorb)
1488 {
1489  control->bridge_features->dtmf_passthrough = !absorb;
1490 }
1491 
1493  struct stasis_app_control *control, int mute)
1494 {
1495  control->bridge_features->mute = mute;
1496 }
1497 
1499  struct stasis_app_control *control, int inhibit_colp)
1500 {
1502 }
1503 
1505 {
1506  struct ao2_iterator iter;
1507  struct stasis_app_command *command;
1508 
1510  while ((command = ao2_iterator_next(&iter))) {
1511  command_complete(command, -1);
1512  ao2_ref(command, -1);
1513  }
1514  ao2_iterator_destroy(&iter);
1515 }
1516 
1518  struct ast_channel *chan)
1519 {
1520  int count = 0;
1521  struct ao2_iterator iter;
1522  struct stasis_app_command *command;
1523 
1524  ast_assert(control->channel == chan);
1525 
1527  while ((command = ao2_iterator_next(&iter))) {
1528  command_invoke(command, control, chan);
1529  ao2_ref(command, -1);
1530  ++count;
1531  }
1532  ao2_iterator_destroy(&iter);
1533 
1534  return count;
1535 }
1536 
1537 void control_wait(struct stasis_app_control *control)
1538 {
1539  if (!control) {
1540  return;
1541  }
1542 
1543  ast_assert(control->command_queue != NULL);
1544 
1545  ao2_lock(control->command_queue);
1546  while (ao2_container_count(control->command_queue) == 0) {
1547  int res = ast_cond_wait(&control->wait_cond,
1549  if (res < 0) {
1550  ast_log(LOG_ERROR, "Error waiting on command queue\n");
1551  break;
1552  }
1553  }
1554  ao2_unlock(control->command_queue);
1555 }
1556 
1558  struct ast_channel *chan)
1559 {
1560  struct ao2_container *command_queue;
1561  int count = 0;
1562  struct ao2_iterator iter;
1563  struct stasis_app_command *command;
1564 
1565  ast_channel_lock(chan);
1566  command_queue = command_prestart_get_container(chan);
1567  ast_channel_unlock(chan);
1568  if (!command_queue) {
1569  return 0;
1570  }
1571 
1572  iter = ao2_iterator_init(command_queue, AO2_ITERATOR_UNLINK);
1573 
1574  while ((command = ao2_iterator_next(&iter))) {
1575  command_invoke(command, control, chan);
1576  ao2_cleanup(command);
1577  ++count;
1578  }
1579 
1580  ao2_iterator_destroy(&iter);
1581  ao2_cleanup(command_queue);
1582  return count;
1583 }
1584 
1586 {
1587  return control->app;
1588 }
1589 
1591  unsigned int timeout;
1592  char dialstring[0];
1593 };
1594 
1595 static struct control_dial_args *control_dial_args_alloc(const char *dialstring,
1596  unsigned int timeout)
1597 {
1598  struct control_dial_args *args;
1599 
1600  args = ast_malloc(sizeof(*args) + strlen(dialstring) + 1);
1601  if (!args) {
1602  return NULL;
1603  }
1604 
1605  args->timeout = timeout;
1606  /* Safe */
1607  strcpy(args->dialstring, dialstring);
1608 
1609  return args;
1610 }
1611 
1612 static void control_dial_args_destroy(void *data)
1613 {
1614  struct control_dial_args *args = data;
1615 
1616  ast_free(args);
1617 }
1618 
1619 /*!
1620  * \brief Set dial timeout on a channel to be dialed.
1621  *
1622  * \param chan The channel on which to set the dial timeout
1623  * \param timeout The timeout in seconds
1624  */
1625 static int set_timeout(struct ast_channel *chan, unsigned int timeout)
1626 {
1627  struct ast_datastore *datastore;
1628  struct timeval *hangup_time;
1629 
1630  hangup_time = ast_malloc(sizeof(struct timeval));
1631 
1632  datastore = ast_datastore_alloc(&timeout_datastore, NULL);
1633  if (!datastore) {
1634  return -1;
1635  }
1636  *hangup_time = ast_tvadd(ast_tvnow(), ast_samp2tv(timeout, 1));
1637  datastore->data = hangup_time;
1638 
1639  ast_channel_lock(chan);
1640  ast_channel_datastore_add(chan, datastore);
1641 
1642  if (ast_channel_is_bridged(chan)) {
1643  set_interval_hook(chan);
1644  }
1645  ast_channel_unlock(chan);
1646 
1647  return 0;
1648 }
1649 
1650 static int app_control_dial(struct stasis_app_control *control,
1651  struct ast_channel *chan, void *data)
1652 {
1653  struct control_dial_args *args = data;
1654  int bridged;
1655 
1656  ast_channel_lock(chan);
1657  bridged = ast_channel_is_bridged(chan);
1658  ast_channel_unlock(chan);
1659 
1660  if (!bridged && add_to_dial_bridge(control, chan)) {
1661  return -1;
1662  }
1663 
1664  if (args->timeout && set_timeout(chan, args->timeout)) {
1665  return -1;
1666  }
1667 
1668  if (ast_call(chan, args->dialstring, 0)) {
1669  /* If call fails normally this channel would then just be normally hung up and destroyed.
1670  * In this case though the channel is being handled by the ARI control thread and dial
1671  * bridge which needs to be notified that the channel should be hung up. To do this we
1672  * queue a soft hangup which will cause each to wake up, see that the channel has been
1673  * hung up, and then destroy it.
1674  */
1675  int hangup_flag;
1677  ast_channel_lock(chan);
1678  ast_softhangup_nolock(chan, hangup_flag);
1679  ast_channel_unlock(chan);
1680  return -1;
1681  }
1682 
1683  ast_channel_publish_dial(NULL, chan, args->dialstring, NULL);
1684 
1685  return 0;
1686 }
1687 
1689  const char *dialstring, unsigned int timeout)
1690 {
1691  struct control_dial_args *args;
1692 
1693  args = control_dial_args_alloc(dialstring, timeout);
1694  if (!args) {
1695  return -1;
1696  }
1697 
1698  return stasis_app_send_command_async(control, app_control_dial,
1699  args, control_dial_args_destroy);
1700 }
1701 
1703 {
1704  ast_mutex_lock(&dial_bridge_lock);
1705  shutting_down = 1;
1706  if (dial_bridge) {
1707  ast_bridge_destroy(dial_bridge, 0);
1708  dial_bridge = NULL;
1709  }
1710  ast_mutex_unlock(&dial_bridge_lock);
1711 }
1712 
1713 void control_set_app(struct stasis_app_control *control, struct stasis_app *app)
1714 {
1715  ao2_cleanup(control->app);
1716  control->app = ao2_bump(app);
1717 }
1718 
1719 char *control_next_app(struct stasis_app_control *control)
1720 {
1721  return control->next_app;
1722 }
1723 
1725 {
1726  ast_free(control->next_app);
1727  control->next_app = NULL;
1728 
1730 }
1731 
1733 {
1734  return AST_VECTOR_STEAL_ELEMENTS(&control->next_app_args);
1735 }
1736 
1738 {
1739  return AST_VECTOR_SIZE(&control->next_app_args);
1740 }
const char * type
Definition: datastore.h:32
int ast_dtmf_stream(struct ast_channel *chan, struct ast_channel *peer, const char *digits, int between, unsigned int duration)
Send a string of DTMF digits to a channel.
Definition: main/app.c:1127
int ast_safe_sleep(struct ast_channel *chan, int ms)
Wait for a specified amount of time, looking for hangups.
Definition: channel.c:1574
enum stasis_app_control_channel_result(* check_rule)(const struct stasis_app_control *control)
Checks to see if an operation is allowed on the control.
Definition: stasis_app.h:352
int stasis_app_control_unmute(struct stasis_app_control *control, unsigned int direction, enum ast_frame_type frametype)
Unmute the channel associated with this control.
Definition: control.c:681
char * control_next_app(struct stasis_app_control *control)
Returns the name of the application we are moving to.
Definition: control.c:1719
Main Channel structure associated with a channel.
Music on hold handling.
int control_swap_channel_in_bridge(struct stasis_app_control *control, struct ast_bridge *bridge, struct ast_channel *chan, struct ast_channel *swap)
Command for swapping a channel in a bridge.
Definition: control.c:1306
char * next_app
Definition: control.c:96
char ** control_next_app_args(struct stasis_app_control *control)
Returns the list of arguments to pass to the application we are moving to.
Definition: control.c:1732
unsigned int inhibit_colp
int stasis_app_control_redirect(struct stasis_app_control *control, const char *endpoint)
Redirect a channel in res_stasis to a particular endpoint.
Definition: control.c:522
Asterisk main include file. File version handling, generic pbx functions.
void stasis_app_control_unregister_add_rule(struct stasis_app_control *control, struct stasis_app_control_rule *rule)
UnRegister an add channel to bridge rule.
Definition: control.c:239
const ast_string_field uniqueid
Definition: bridge.h:401
int ao2_container_count(struct ao2_container *c)
Returns the number of elements in a container.
struct ast_bridge_features * features
const char * ast_bridge_after_cb_reason_string(enum ast_bridge_after_cb_reason reason)
Get a string representation of an after bridge callback reason.
Definition: bridge_after.c:288
#define AST_LIST_HEAD(name, type)
Defines a structure to be used to hold a list of specified type.
Definition: linkedlists.h:173
int ast_queue_control(struct ast_channel *chan, enum ast_control_frame_type control)
Queue a control frame without payload.
Definition: channel.c:1231
void stasis_app_control_inhibit_colp_in_bridge(struct stasis_app_control *control, int inhibit_colp)
Set whether COLP frames should be generated when joining the bridge.
Definition: control.c:1498
struct app_control_rules remove_rules
Definition: control.c:82
struct ast_bridge * stasis_app_bridge_create_invisible(const char *type, const char *name, const char *id)
Create an invisible bridge of the specified type.
Definition: res_stasis.c:859
Internal API for the Stasis application commands.
int stasis_app_control_dial(struct stasis_app_control *control, const char *dialstring, unsigned int timeout)
Dial a channel.
Definition: control.c:1688
Structure that contains features information.
int ast_indicate(struct ast_channel *chan, int condition)
Indicates condition of channel.
Definition: channel.c:4277
void ast_channel_publish_dial(struct ast_channel *caller, struct ast_channel *peer, const char *dialstring, const char *dialstatus)
Publish in the ast_channel_topic or ast_channel_topic_all topics a stasis message for the channels in...
static int bridge_timeout(struct ast_bridge_channel *bridge_channel, void *ignore)
Dial timeout.
Definition: control.c:1237
int stasis_app_control_mute(struct stasis_app_control *control, unsigned int direction, enum ast_frame_type frametype)
Mute the channel associated with this control.
Definition: control.c:653
int(* app_command_can_exec_cb)(struct stasis_app_control *control)
Definition: control.c:280
int ast_softhangup(struct ast_channel *chan, int cause)
Softly hangup up a channel.
Definition: channel.c:2471
void __ao2_cleanup(void *obj)
Definition: astobj2.c:677
void control_flush_queue(struct stasis_app_control *control)
Flush the control command queue.
Definition: control.c:1504
#define ao2_container_alloc_list(ao2_options, container_options, sort_fn, cmp_fn)
Allocate and initialize a list container.
Definition: astobj2.h:1327
int ast_call(struct ast_channel *chan, const char *addr, int timeout)
Make a call.
Definition: channel.c:6461
#define AST_VECTOR_APPEND(vec, elem)
Append an element to a vector, growing the vector if needed.
Definition: vector.h:256
Structure representing a snapshot of channel state.
void stasis_app_control_shutdown(void)
Let Stasis app internals shut down.
Definition: control.c:1702
struct ast_bridge * stasis_app_get_bridge(struct stasis_app_control *control)
Gets the bridge currently associated with a control object.
Definition: control.c:953
Assume that the ao2_container is already locked.
Definition: astobj2.h:1063
Structure for a data store type.
Definition: datastore.h:31
ast_channel_state
ast_channel states
Definition: channelstate.h:35
int ast_bridge_destroy(struct ast_bridge *bridge, int cause)
Destroy a bridge.
Definition: bridge.c:944
Dialing API.
void ao2_iterator_destroy(struct ao2_iterator *iter)
Destroy a container iterator.
ast_control_frame_type
Internal control frame subtype field values.
struct timeval ast_tvnow(void)
Returns current timeval. Meant to replace calls to gettimeofday().
Definition: time.h:159
void stasis_app_control_hold(struct stasis_app_control *control)
Place the channel associated with the control on hold.
Definition: control.c:770
struct ao2_container * command_prestart_get_container(struct ast_channel *chan)
Get the Stasis() prestart commands for a channel.
Definition: command.c:160
static int add_to_dial_bridge(struct stasis_app_control *control, struct ast_channel *chan)
Add a channel to the singleton dial bridge.
Definition: control.c:1063
int ast_explicit_goto(struct ast_channel *chan, const char *context, const char *exten, int priority)
Definition: pbx.c:6945
#define ao2_link_flags(container, obj, flags)
Add an object to a container.
Definition: astobj2.h:1554
int64_t ast_tvdiff_ms(struct timeval end, struct timeval start)
Computes the difference (in milliseconds) between two struct timeval instances.
Definition: time.h:107
#define ast_strdup(str)
A wrapper for strdup()
Definition: astmm.h:241
Structure for a data store object.
Definition: datastore.h:64
int stasis_app_control_add_role(struct stasis_app_control *control, const char *role)
Apply a bridge role to a channel controlled by a stasis app control.
Definition: control.c:338
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:2399
int ast_channel_add_bridge_role(struct ast_channel *chan, const char *role_name)
Adds a bridge role to a channel.
Definition: bridge_roles.c:313
int stasis_app_control_continue(struct stasis_app_control *control, const char *context, const char *extension, int priority)
Exit res_stasis and continue execution in the dialplan.
Definition: control.c:411
void ast_moh_stop(struct ast_channel *chan)
Turn off music on hold on a given channel.
Definition: channel.c:7776
int control_command_count(struct stasis_app_control *control)
Returns the count of items in a control's command queue.
Definition: control.c:365
int ast_channel_suppress(struct ast_channel *chan, unsigned int direction, enum ast_frame_type frametype)
Suppress passing of a frame type on a channel.
Definition: channel.c:10777
void ast_free_ptr(void *ptr)
free() wrapper
Definition: main/astmm.c:1739
struct stasis_app * control_app(struct stasis_app_control *control)
Returns the pointer (non-reffed) to the app associated with this control.
Definition: control.c:1585
int ast_bridge_set_after_callback(struct ast_channel *chan, ast_bridge_after_cb callback, ast_bridge_after_cb_failed failed, void *data)
Setup an after bridge callback for when the channel leaves the bridging system.
Definition: bridge_after.c:251
void ast_bridge_features_destroy(struct ast_bridge_features *features)
Destroy an allocated bridge features struct.
Definition: bridge.c:3674
int ast_datastore_free(struct ast_datastore *datastore)
Free a data store object.
Definition: datastore.c:68
int control_add_channel_to_bridge(struct stasis_app_control *control, struct ast_channel *chan, void *data)
Command callback for adding a channel to a bridge.
Definition: control.c:1400
void stasis_app_control_register_add_rule(struct stasis_app_control *control, struct stasis_app_control_rule *rule)
Registers an add channel to bridge rule.
Definition: control.c:232
int control_dispatch_all(struct stasis_app_control *control, struct ast_channel *chan)
Dispatch all commands enqueued to this control.
Definition: control.c:1517
int app_subscribe_bridge(struct stasis_app *app, struct ast_bridge *bridge)
Add a bridge subscription to an existing channel subscription.
struct stasis_app * app
Definition: control.c:92
char * value
Definition: control.c:711
#define AST_LIST_HEAD_DESTROY(head)
Destroys a list head structure.
Definition: linkedlists.h:653
int(* stasis_app_command_cb)(struct stasis_app_control *control, struct ast_channel *chan, void *data)
ast_bridge_after_cb_reason
Definition: bridge_after.h:37
int stasis_app_control_add_channel_to_bridge(struct stasis_app_control *control, struct ast_bridge *bridge)
Add a channel to the bridge.
Definition: control.c:1405
#define ao2_bump(obj)
Bump refcount on an AO2 object by one, returning the object.
Definition: astobj2.h:480
void control_set_thread(struct stasis_app_control *control, pthread_t threadid)
set the control's thread id
Definition: control.c:196
void * ao2_object_get_lockaddr(void *obj)
Return the mutex lock address of an object.
Definition: astobj2.c:476
Definition: pbx.h:214
static void dial_bridge_after_cb(struct ast_channel *chan, void *data)
after bridge callback for the dial bridge
Definition: control.c:1031
int stasis_app_control_move(struct stasis_app_control *control, const char *app_name, const char *app_args)
Exit res_stasis and move to another Stasis application.
Definition: control.c:473
void stasis_app_control_silence_stop(struct stasis_app_control *control)
Stop playing silence to a channel.
Definition: control.c:877
static struct ast_bridge * get_dial_bridge(void)
Retrieve a reference to the dial bridge.
Definition: control.c:996
void control_move_cleanup(struct stasis_app_control *control)
Free any memory that was allocated for switching applications via /channels/{channelId}/move.
Definition: control.c:1724
#define AST_VECTOR_INIT(vec, size)
Initialize a vector.
Definition: vector.h:113
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) attribute_warn_unused_result
Impart a channel to a bridge (non-blocking)
Definition: bridge.c:1878
struct ast_channel_snapshot * stasis_app_control_get_snapshot(const struct stasis_app_control *control)
Returns the most recent snapshot for the associated channel.
Definition: control.c:882
int stasis_app_channel_is_stasis_end_published(struct ast_channel *chan)
Has this channel had a StasisEnd published on it?
Definition: res_stasis.c:1302
stasis_app_control_channel_result
Result codes used when adding/removing channels to/from bridges.
Definition: stasis_app.h:776
struct stasis_app_control::@497 next_app_args
int control_next_app_args_size(struct stasis_app_control *control)
Returns the number of arguments to be passed to the application we are moving to. ...
Definition: control.c:1737
#define ao2_ref(o, delta)
Reference/unreference an object and return the old refcount.
Definition: astobj2.h:459
#define AST_MAX_EXTENSION
Definition: channel.h:134
#define ast_channel_cleanup(c)
Cleanup a channel reference.
Definition: channel.h:2969
structure to hold extensions
Asterisk internal frame definitions.
struct ast_channel * channel
Definition: control.c:62
struct timeval ast_samp2tv(unsigned int _nsamp, unsigned int _rate)
Returns a timeval corresponding to the duration of n samples at rate r. Useful to convert samples to ...
Definition: time.h:282
unsigned int is_done
Definition: control.c:108
void stasis_app_control_mute_in_bridge(struct stasis_app_control *control, int mute)
Set whether audio from the channel is muted instead of passing through to the bridge.
Definition: control.c:1492
static int depart_channel(struct stasis_app_control *control, struct ast_channel *chan)
Depart a channel from a bridge, and potentially add it back to the dial bridge.
Definition: control.c:1091
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:3319
#define ast_malloc(len)
A wrapper for malloc()
Definition: astmm.h:191
#define AST_VECTOR_STEAL_ELEMENTS(vec)
Steal the elements from a vector and reinitialize.
Definition: vector.h:140
#define ast_debug(level,...)
Log a DEBUG message.
#define AST_VECTOR(name, type)
Define a vector structure.
Definition: vector.h:44
Rule to check to see if an operation is allowed.
Definition: stasis_app.h:345
void stasis_app_control_register_remove_rule(struct stasis_app_control *control, struct stasis_app_control_rule *rule)
Registers a remove channel from bridge rule.
Definition: control.c:246
void(* command_data_destructor_fn)(void *data)
Typedef for data destructor for stasis app commands.
Core PBX routines and definitions.
int ast_queue_frame(struct ast_channel *chan, struct ast_frame *f)
Queue one or more frames to a channel's frame queue.
Definition: channel.c:1139
int ast_check_hangup(struct ast_channel *chan)
Check to see if a channel is needing hang up.
Definition: channel.c:445
struct ast_bridge_features * bridge_features
Definition: control.c:70
static int set_timeout(struct ast_channel *chan, unsigned int timeout)
Set dial timeout on a channel to be dialed.
Definition: control.c:1625
struct ao2_container * command_queue
Definition: control.c:56
ast_frame_type
Frame types.
struct ast_silence_generator * ast_channel_start_silence_generator(struct ast_channel *chan)
Starts a silence generator on the given channel.
Definition: channel.c:8164
struct stasis_topic * ast_channel_topic(struct ast_channel *chan)
A topic which publishes the events for a particular channel.
unsigned int dtmf_passthrough
int stasis_app_control_ring(struct stasis_app_control *control)
Indicate ringing to the channel associated with this control.
Definition: control.c:614
Structure that contains information about a bridge.
Definition: bridge.h:349
#define AST_LIST_INSERT_TAIL(head, elm, field)
Appends a list entry to the tail of a list.
Definition: linkedlists.h:731
int stasis_app_control_bridge_features_init(struct stasis_app_control *control)
Initialize bridge features into a channel control.
Definition: control.c:1473
static void set_interval_hook(struct ast_channel *chan)
Set a dial timeout interval hook on the channel.
Definition: control.c:1276
int stasis_app_send_command(struct stasis_app_control *control, stasis_app_command_cb command_fn, void *data, command_data_destructor_fn data_destructor)
Invokes a command on a control's channel.
Definition: control.c:920
int stasis_app_control_dtmf(struct stasis_app_control *control, const char *dtmf, int before, int between, unsigned int duration, int after)
Send DTMF to the channel associated with this control.
Definition: control.c:587
struct timeval ast_tvadd(struct timeval a, struct timeval b)
Returns the sum of two timevals a + b.
Definition: extconf.c:2282
int ast_bridge_depart(struct ast_channel *chan)
Depart a channel from a bridge.
Definition: bridge.c:1906
int ast_moh_start(struct ast_channel *chan, const char *mclass, const char *interpclass)
Turn on music on hold on a given channel.
Definition: channel.c:7766
struct stasis_app_control * control_create(struct ast_channel *channel, struct stasis_app *app)
Create a control object.
Definition: control.c:129
const char * app_name(struct ast_app *app)
Definition: pbx_app.c:463
int stasis_app_control_queue_control(struct stasis_app_control *control, enum ast_control_frame_type frame_type)
Queue a control frame without payload.
Definition: control.c:1467
struct ast_pbx * pbx
Definition: control.c:74
void stasis_app_control_absorb_dtmf_in_bridge(struct stasis_app_control *control, int absorb)
Set whether DTMF from the channel is absorbed instead of passing through to the bridge.
Definition: control.c:1486
int ast_channel_is_bridged(const struct ast_channel *chan)
Determine if a channel is in a bridge.
Definition: channel.c:10545
const char * stasis_app_control_get_channel_id(const struct stasis_app_control *control)
Returns the uniqueid of the channel associated with this control.
Definition: control.c:1452
#define AST_LIST_TRAVERSE(head, var, field)
Loops over (traverses) the entries in a list.
Definition: linkedlists.h:491
pthread_t control_thread
Definition: control.c:100
int stasis_app_control_ring_stop(struct stasis_app_control *control)
Stop locally generated ringing on the channel associated with this control.
Definition: control.c:629
void ast_channel_stop_silence_generator(struct ast_channel *chan, struct ast_silence_generator *state)
Stops a previously-started silence generator on the given channel.
Definition: channel.c:8210
void stasis_publish(struct stasis_topic *topic, struct stasis_message *message)
Publish a message to a topic's subscribers.
Definition: stasis.c:1511
#define AST_MAX_CONTEXT
Definition: channel.h:135
#define AST_LIST_HEAD_INIT(head)
Initializes a list head structure.
Definition: linkedlists.h:626
#define ast_calloc(num, len)
A wrapper for calloc()
Definition: astmm.h:202
void stasis_app_control_publish(struct stasis_app_control *control, struct stasis_message *message)
Publish a message to the control's channel's topic.
Definition: control.c:1458
#define AST_VECTOR_RESET(vec, cleanup)
Reset vector.
Definition: vector.h:625
void stasis_app_control_unregister_remove_rule(struct stasis_app_control *control, struct stasis_app_control_rule *rule)
Unregisters a remove channel from bridge rule.
Definition: control.c:253
void stasis_app_control_moh_stop(struct stasis_app_control *control)
Stop playing music on hold to a channel (does not affect hold status)
Definition: control.c:820
struct ast_bridge * bridge
Definition: control.c:66
void control_set_app(struct stasis_app_control *control, struct stasis_app *app)
Set the application the control object belongs to.
Definition: control.c:1713
struct ast_channel * swap
void stasis_app_control_unhold(struct stasis_app_control *control)
Remove the channel associated with the control from hold.
Definition: control.c:783
Basic bridge subclass API.
struct ast_bridge_channel * ast_channel_get_bridge_channel(struct ast_channel *chan)
Get a reference to the channel's bridge pointer.
Definition: channel.c:10582
int ast_channel_unsuppress(struct ast_channel *chan, unsigned int direction, enum ast_frame_type frametype)
Stop suppressing of a frame type on a channel.
Definition: channel.c:10839
void control_silence_stop_now(struct stasis_app_control *control)
Stop playing silence to a channel right now.
Definition: control.c:859
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...
void ast_channel_clear_bridge_roles(struct ast_channel *chan)
Removes all bridge roles currently on a channel.
Definition: bridge_roles.c:356
int control_is_done(struct stasis_app_control *control)
Returns true if control_continue() has been called on this control.
Definition: control.c:370
struct ast_bridge_features * ast_bridge_features_new(void)
Allocate a new bridge features struct.
Definition: bridge.c:3683
struct ast_frame ast_null_frame
Definition: main/frame.c:79
void stasis_app_control_silence_start(struct stasis_app_control *control)
Start playing silence to a channel.
Definition: control.c:854
void * data
Definition: datastore.h:66
struct ast_channel * chan
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:2947
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:1821
structure for queuing ARI channel variable setting
Definition: control.c:707
int app_unsubscribe_bridge(struct stasis_app *app, struct ast_bridge *bridge)
Cancel the bridge subscription for an application.
Internal API for the Stasis application controller.
char * name
Definition: control.c:709
void ast_copy_string(char *dst, const char *src, size_t size)
Size-limited null-terminating string copy.
Definition: strings.h:425
#define S_OR(a, b)
returns the equivalent of logic or for strings: first one if not empty, otherwise second one...
Definition: strings.h:80
int ast_transfer(struct ast_channel *chan, char *dest)
Transfer a channel (if supported).
Definition: channel.c:6485
int stasis_app_send_command_async(struct stasis_app_control *control, stasis_app_command_cb command_fn, void *data, command_data_destructor_fn data_destructor)
Asynchronous version of stasis_app_send_command().
Definition: control.c:926
int stasis_app_control_set_channel_var(struct stasis_app_control *control, const char *variable, const char *value)
Set a variable on the channel associated with this control to value.
Definition: control.c:733
void stasis_app_control_clear_roles(struct stasis_app_control *control)
Clear bridge roles currently applied to a channel controlled by a stasis app control.
Definition: control.c:360
struct ast_datastore_info timeout_datastore
Dial timeout datastore.
Definition: control.c:1214
Stasis Application API. See Stasis Application API for detailed documentation.
Generic container type.
static int shutting_down
Indicates if the Stasis app internals are being shut down.
Definition: control.c:51
int ast_softhangup_nolock(struct ast_channel *chan, int cause)
Softly hangup up a channel (no channel lock)
Definition: channel.c:2458
Bridging API.
void stasis_app_control_moh_start(struct stasis_app_control *control, const char *moh_class)
Play music on hold to a channel (does not affect hold status)
Definition: control.c:802
#define RAII_VAR(vartype, varname, initval, dtor)
Declare a variable that will call a destructor function when it goes out of scope.
Definition: utils.h:941
int ast_channel_datastore_add(struct ast_channel *chan, struct ast_datastore *datastore)
Add a datastore to a channel.
Definition: channel.c:2385
Application convenience functions, designed to give consistent look and feel to Asterisk apps...
struct ao2_iterator ao2_iterator_init(struct ao2_container *c, int flags) attribute_warn_unused_result
Create an iterator for a container.
int ast_channel_datastore_remove(struct ast_channel *chan, struct ast_datastore *datastore)
Remove a datastore from a channel.
Definition: channel.c:2394
int ast_bridge_setup_after_goto(struct ast_channel *chan)
Setup any after bridge goto location to begin execution.
Definition: bridge_after.c:435
static struct ast_bridge * dial_bridge
Singleton dial bridge.
Definition: control.c:980
int stasis_app_control_remove_channel_from_bridge(struct stasis_app_control *control, struct ast_bridge *bridge)
Remove a channel from the bridge.
Definition: control.c:1442
#define AST_VECTOR_SIZE(vec)
Get the number of elements in a vector.
Definition: vector.h:609
int control_prestart_dispatch_all(struct stasis_app_control *control, struct ast_channel *chan)
Dispatch all queued prestart commands.
Definition: control.c:1557
void ast_dtmf_stream_external(struct ast_channel *chan, const char *digits, int between, unsigned int duration)
Send a string of DTMF digits to a channel from an external thread.
Definition: main/app.c:1142
Channel Bridging API.
struct ast_silence_generator * silgen
Definition: control.c:86
struct app_control_rules add_rules
Definition: control.c:78
void control_wait(struct stasis_app_control *control)
Blocks until control's command queue has a command available.
Definition: control.c:1537
struct stasis_app_control * stasis_app_control_find_by_channel(const struct ast_channel *chan)
Returns the handler for the given channel.
Definition: res_stasis.c:338