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