Remove const cast from leaf functions.
[asterisk/asterisk.git] / res / stasis / control.c
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 ASTERISK_REGISTER_FILE()
29
30 #include "asterisk/stasis_channels.h"
31
32 #include "command.h"
33 #include "control.h"
34 #include "app.h"
35 #include "asterisk/dial.h"
36 #include "asterisk/bridge.h"
37 #include "asterisk/bridge_after.h"
38 #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 AST_LIST_HEAD(app_control_rules, stasis_app_control_rule);
45
46 struct stasis_app_control {
47         ast_cond_t wait_cond;
48         /*! Queue of commands to dispatch on the channel */
49         struct ao2_container *command_queue;
50         /*!
51          * The associated channel.
52          * Be very careful with the threading associated w/ manipulating
53          * the channel.
54          */
55         struct ast_channel *channel;
56         /*!
57          * When a channel is in a bridge, the bridge that it is in.
58          */
59         struct ast_bridge *bridge;
60         /*!
61          * Holding place for channel's PBX while imparted to a bridge.
62          */
63         struct ast_pbx *pbx;
64         /*!
65          * A list of rules to check before adding a channel to a bridge.
66          */
67         struct app_control_rules add_rules;
68         /*!
69          * A list of rules to check before removing a channel from a bridge.
70          */
71         struct app_control_rules remove_rules;
72         /*!
73          * Silence generator, when silence is being generated.
74          */
75         struct ast_silence_generator *silgen;
76         /*!
77          * The app for which this control was created
78          */
79         struct stasis_app *app;
80         /*!
81          * When set, /c app_stasis should exit and continue in the dialplan.
82          */
83         int is_done:1;
84 };
85
86 static void control_dtor(void *obj)
87 {
88         struct stasis_app_control *control = obj;
89
90         AST_LIST_HEAD_DESTROY(&control->add_rules);
91         AST_LIST_HEAD_DESTROY(&control->remove_rules);
92
93         /* We may have a lingering silence generator; free it */
94         ast_channel_stop_silence_generator(control->channel, control->silgen);
95         control->silgen = NULL;
96
97         ao2_cleanup(control->command_queue);
98         ast_cond_destroy(&control->wait_cond);
99         ao2_cleanup(control->app);
100 }
101
102 struct stasis_app_control *control_create(struct ast_channel *channel, struct stasis_app *app)
103 {
104         RAII_VAR(struct stasis_app_control *, control, NULL, ao2_cleanup);
105         int res;
106
107         control = ao2_alloc(sizeof(*control), control_dtor);
108         if (!control) {
109                 return NULL;
110         }
111
112         control->app = ao2_bump(app);
113
114         res = ast_cond_init(&control->wait_cond, NULL);
115         if (res != 0) {
116                 ast_log(LOG_ERROR, "Error initializing ast_cond_t: %s\n",
117                         strerror(errno));
118                 return NULL;
119         }
120
121         control->command_queue = ao2_container_alloc_list(
122                 AO2_ALLOC_OPT_LOCK_MUTEX, 0, NULL, NULL);
123
124         if (!control->command_queue) {
125                 return NULL;
126         }
127
128         control->channel = channel;
129
130         AST_LIST_HEAD_INIT(&control->add_rules);
131         AST_LIST_HEAD_INIT(&control->remove_rules);
132
133         ao2_ref(control, +1);
134         return control;
135 }
136
137 static void app_control_register_rule(
138         struct stasis_app_control *control,
139         struct app_control_rules *list, struct stasis_app_control_rule *obj)
140 {
141         SCOPED_AO2LOCK(lock, control->command_queue);
142         AST_LIST_INSERT_TAIL(list, obj, next);
143 }
144
145 static void app_control_unregister_rule(
146         struct stasis_app_control *control,
147         struct app_control_rules *list, struct stasis_app_control_rule *obj)
148 {
149         struct stasis_app_control_rule *rule;
150         SCOPED_AO2LOCK(lock, control->command_queue);
151         AST_RWLIST_TRAVERSE_SAFE_BEGIN(list, rule, next) {
152                 if (rule == obj) {
153                         AST_RWLIST_REMOVE_CURRENT(next);
154                         break;
155                 }
156         }
157         AST_RWLIST_TRAVERSE_SAFE_END;
158 }
159
160 /*!
161  * \internal
162  * \brief Checks to make sure each rule in the given list passes.
163  *
164  * \details Loops over a list of rules checking for rejections or failures.
165  *          If one rule fails its resulting error code is returned.
166  *
167  * \note Command queue should be locked before calling this function.
168  *
169  * \param control The stasis application control
170  * \param list The list of rules to check
171  *
172  * \retval 0 if all rules pass
173  * \retval non-zero error code if a rule fails
174  */
175 static enum stasis_app_control_channel_result app_control_check_rules(
176         const struct stasis_app_control *control,
177         struct app_control_rules *list)
178 {
179         int res = 0;
180         struct stasis_app_control_rule *rule;
181         AST_LIST_TRAVERSE(list, rule, next) {
182                 if ((res = rule->check_rule(control))) {
183                         return res;
184                 }
185         }
186         return res;
187 }
188
189 void stasis_app_control_register_add_rule(
190         struct stasis_app_control *control,
191         struct stasis_app_control_rule *rule)
192 {
193         return app_control_register_rule(control, &control->add_rules, rule);
194 }
195
196 void stasis_app_control_unregister_add_rule(
197         struct stasis_app_control *control,
198         struct stasis_app_control_rule *rule)
199 {
200         app_control_unregister_rule(control, &control->add_rules, rule);
201 }
202
203 void stasis_app_control_register_remove_rule(
204         struct stasis_app_control *control,
205         struct stasis_app_control_rule *rule)
206 {
207         return app_control_register_rule(control, &control->remove_rules, rule);
208 }
209
210 void stasis_app_control_unregister_remove_rule(
211         struct stasis_app_control *control,
212         struct stasis_app_control_rule *rule)
213 {
214         app_control_unregister_rule(control, &control->remove_rules, rule);
215 }
216
217 static int app_control_can_add_channel_to_bridge(
218         struct stasis_app_control *control)
219 {
220         return app_control_check_rules(control, &control->add_rules);
221 }
222
223 static int app_control_can_remove_channel_from_bridge(
224         struct stasis_app_control *control)
225 {
226         return app_control_check_rules(control, &control->remove_rules);
227 }
228
229 static int noop_cb(struct stasis_app_control *control,
230         struct ast_channel *chan, void *data)
231 {
232         return 0;
233 }
234
235 /*! Callback type to see if the command can execute
236     note: command_queue is locked during callback */
237 typedef int (*app_command_can_exec_cb)(struct stasis_app_control *control);
238
239 static struct stasis_app_command *exec_command_on_condition(
240         struct stasis_app_control *control, stasis_app_command_cb command_fn,
241         void *data, command_data_destructor_fn data_destructor,
242         app_command_can_exec_cb can_exec_fn)
243 {
244         int retval;
245         struct stasis_app_command *command;
246
247         command_fn = command_fn ? : noop_cb;
248
249         command = command_create(command_fn, data, data_destructor);
250         if (!command) {
251                 return NULL;
252         }
253
254         ao2_lock(control->command_queue);
255         if (can_exec_fn && (retval = can_exec_fn(control))) {
256                 ao2_unlock(control->command_queue);
257                 command_complete(command, retval);
258                 return command;
259         }
260
261         ao2_link_flags(control->command_queue, command, OBJ_NOLOCK);
262         ast_cond_signal(&control->wait_cond);
263         ao2_unlock(control->command_queue);
264
265         return command;
266 }
267
268 static struct stasis_app_command *exec_command(
269         struct stasis_app_control *control, stasis_app_command_cb command_fn,
270         void *data, command_data_destructor_fn data_destructor)
271 {
272         return exec_command_on_condition(control, command_fn, data, data_destructor, NULL);
273 }
274
275 struct stasis_app_control_dial_data {
276         char endpoint[AST_CHANNEL_NAME];
277         int timeout;
278 };
279
280 static int app_control_dial(struct stasis_app_control *control,
281         struct ast_channel *chan, void *data)
282 {
283         RAII_VAR(struct ast_dial *, dial, ast_dial_create(), ast_dial_destroy);
284         struct stasis_app_control_dial_data *dial_data = data;
285         enum ast_dial_result res;
286         char *tech, *resource;
287         struct ast_channel *new_chan;
288         RAII_VAR(struct ast_bridge *, bridge, NULL, ao2_cleanup);
289
290         tech = dial_data->endpoint;
291         if (!(resource = strchr(tech, '/'))) {
292                 return -1;
293         }
294         *resource++ = '\0';
295
296         if (!dial) {
297                 ast_log(LOG_ERROR, "Failed to create dialing structure.\n");
298                 return -1;
299         }
300
301         if (ast_dial_append(dial, tech, resource, NULL) < 0) {
302                 ast_log(LOG_ERROR, "Failed to add %s/%s to dialing structure.\n", tech, resource);
303                 return -1;
304         }
305
306         ast_dial_set_global_timeout(dial, dial_data->timeout);
307
308         res = ast_dial_run(dial, NULL, 0);
309         if (res != AST_DIAL_RESULT_ANSWERED || !(new_chan = ast_dial_answered_steal(dial))) {
310                 return -1;
311         }
312
313         if (!(bridge = ast_bridge_basic_new())) {
314                 ast_log(LOG_ERROR, "Failed to create basic bridge.\n");
315                 return -1;
316         }
317
318         if (ast_bridge_impart(bridge, new_chan, NULL, NULL,
319                 AST_BRIDGE_IMPART_CHAN_INDEPENDENT)) {
320                 ast_hangup(new_chan);
321         } else {
322                 control_add_channel_to_bridge(control, chan, bridge);
323         }
324
325         return 0;
326 }
327
328 int stasis_app_control_dial(struct stasis_app_control *control, const char *endpoint, const char *exten, const char *context,
329                             int timeout)
330 {
331         struct stasis_app_control_dial_data *dial_data;
332
333         if (!(dial_data = ast_calloc(1, sizeof(*dial_data)))) {
334                 return -1;
335         }
336
337         if (!ast_strlen_zero(endpoint)) {
338                 ast_copy_string(dial_data->endpoint, endpoint, sizeof(dial_data->endpoint));
339         } else if (!ast_strlen_zero(exten) && !ast_strlen_zero(context)) {
340                 snprintf(dial_data->endpoint, sizeof(dial_data->endpoint), "Local/%s@%s", exten, context);
341         } else {
342                 return -1;
343         }
344
345         if (timeout > 0) {
346                 dial_data->timeout = timeout * 1000;
347         } else if (timeout == -1) {
348                 dial_data->timeout = -1;
349         } else {
350                 dial_data->timeout = 30000;
351         }
352
353         stasis_app_send_command_async(control, app_control_dial, dial_data, ast_free_ptr);
354
355         return 0;
356 }
357
358 int stasis_app_control_add_role(struct stasis_app_control *control, const char *role)
359 {
360         return ast_channel_add_bridge_role(control->channel, role);
361 }
362
363 void stasis_app_control_clear_roles(struct stasis_app_control *control)
364 {
365         ast_channel_clear_bridge_roles(control->channel);
366 }
367
368 int control_command_count(struct stasis_app_control *control)
369 {
370         return ao2_container_count(control->command_queue);
371 }
372
373 int control_is_done(struct stasis_app_control *control)
374 {
375         /* Called from stasis_app_exec thread; no lock needed */
376         return control->is_done;
377 }
378
379 void control_mark_done(struct stasis_app_control *control)
380 {
381         control->is_done = 1;
382 }
383
384 struct stasis_app_control_continue_data {
385         char context[AST_MAX_CONTEXT];
386         char extension[AST_MAX_EXTENSION];
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->is_done = 1;
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
431 static int app_control_redirect(struct stasis_app_control *control,
432         struct ast_channel *chan, void *data)
433 {
434         char *endpoint = data;
435         int res;
436
437         ast_assert(control->channel != NULL);
438         ast_assert(endpoint != NULL);
439
440         res = ast_transfer(control->channel, endpoint);
441         if (!res) {
442                 ast_log(LOG_NOTICE, "Unsupported transfer requested on channel '%s'\n",
443                         ast_channel_name(control->channel));
444                 return 0;
445         }
446
447         return 0;
448 }
449
450 int stasis_app_control_redirect(struct stasis_app_control *control, const char *endpoint)
451 {
452         char *endpoint_data = ast_strdup(endpoint);
453
454         if (!endpoint_data) {
455                 return -1;
456         }
457
458         stasis_app_send_command_async(control, app_control_redirect, endpoint_data, ast_free_ptr);
459
460         return 0;
461 }
462
463 struct stasis_app_control_dtmf_data {
464         int before;
465         int between;
466         unsigned int duration;
467         int after;
468         char dtmf[];
469 };
470
471 static int app_control_dtmf(struct stasis_app_control *control,
472         struct ast_channel *chan, void *data)
473 {
474         struct stasis_app_control_dtmf_data *dtmf_data = data;
475
476         if (ast_channel_state(chan) != AST_STATE_UP) {
477                 ast_indicate(chan, AST_CONTROL_PROGRESS);
478         }
479
480         if (dtmf_data->before) {
481                 ast_safe_sleep(chan, dtmf_data->before);
482         }
483
484         ast_dtmf_stream(chan, NULL, dtmf_data->dtmf, dtmf_data->between, dtmf_data->duration);
485
486         if (dtmf_data->after) {
487                 ast_safe_sleep(chan, dtmf_data->after);
488         }
489
490         return 0;
491 }
492
493 int stasis_app_control_dtmf(struct stasis_app_control *control, const char *dtmf, int before, int between, unsigned int duration, int after)
494 {
495         struct stasis_app_control_dtmf_data *dtmf_data;
496
497         if (!(dtmf_data = ast_calloc(1, sizeof(*dtmf_data) + strlen(dtmf) + 1))) {
498                 return -1;
499         }
500
501         dtmf_data->before = before;
502         dtmf_data->between = between;
503         dtmf_data->duration = duration;
504         dtmf_data->after = after;
505         strcpy(dtmf_data->dtmf, dtmf);
506
507         stasis_app_send_command_async(control, app_control_dtmf, dtmf_data, ast_free_ptr);
508
509         return 0;
510 }
511
512 static int app_control_ring(struct stasis_app_control *control,
513         struct ast_channel *chan, void *data)
514 {
515         ast_indicate(control->channel, AST_CONTROL_RINGING);
516
517         return 0;
518 }
519
520 int stasis_app_control_ring(struct stasis_app_control *control)
521 {
522         stasis_app_send_command_async(control, app_control_ring, NULL, NULL);
523
524         return 0;
525 }
526
527 static int app_control_ring_stop(struct stasis_app_control *control,
528         struct ast_channel *chan, void *data)
529 {
530         ast_indicate(control->channel, -1);
531
532         return 0;
533 }
534
535 int stasis_app_control_ring_stop(struct stasis_app_control *control)
536 {
537         stasis_app_send_command_async(control, app_control_ring_stop, NULL, NULL);
538
539         return 0;
540 }
541
542 struct stasis_app_control_mute_data {
543         enum ast_frame_type frametype;
544         unsigned int direction;
545 };
546
547 static int app_control_mute(struct stasis_app_control *control,
548         struct ast_channel *chan, void *data)
549 {
550         struct stasis_app_control_mute_data *mute_data = data;
551         SCOPED_CHANNELLOCK(lockvar, chan);
552
553         ast_channel_suppress(control->channel, mute_data->direction, mute_data->frametype);
554
555         return 0;
556 }
557
558 int stasis_app_control_mute(struct stasis_app_control *control, unsigned int direction, enum ast_frame_type frametype)
559 {
560         struct stasis_app_control_mute_data *mute_data;
561
562         if (!(mute_data = ast_calloc(1, sizeof(*mute_data)))) {
563                 return -1;
564         }
565
566         mute_data->direction = direction;
567         mute_data->frametype = frametype;
568
569         stasis_app_send_command_async(control, app_control_mute, mute_data, ast_free_ptr);
570
571         return 0;
572 }
573
574 static int app_control_unmute(struct stasis_app_control *control,
575         struct ast_channel *chan, void *data)
576 {
577         struct stasis_app_control_mute_data *mute_data = data;
578         SCOPED_CHANNELLOCK(lockvar, chan);
579
580         ast_channel_unsuppress(control->channel, mute_data->direction, mute_data->frametype);
581
582         return 0;
583 }
584
585 int stasis_app_control_unmute(struct stasis_app_control *control, unsigned int direction, enum ast_frame_type frametype)
586 {
587         struct stasis_app_control_mute_data *mute_data;
588
589         if (!(mute_data = ast_calloc(1, sizeof(*mute_data)))) {
590                 return -1;
591         }
592
593         mute_data->direction = direction;
594         mute_data->frametype = frametype;
595
596         stasis_app_send_command_async(control, app_control_unmute, mute_data, ast_free_ptr);
597
598         return 0;
599 }
600
601 int stasis_app_control_set_channel_var(struct stasis_app_control *control, const char *variable, const char *value)
602 {
603         return pbx_builtin_setvar_helper(control->channel, variable, value);
604 }
605
606 static int app_control_hold(struct stasis_app_control *control,
607         struct ast_channel *chan, void *data)
608 {
609         ast_indicate(control->channel, AST_CONTROL_HOLD);
610
611         return 0;
612 }
613
614 void stasis_app_control_hold(struct stasis_app_control *control)
615 {
616         stasis_app_send_command_async(control, app_control_hold, NULL, NULL);
617 }
618
619 static int app_control_unhold(struct stasis_app_control *control,
620         struct ast_channel *chan, void *data)
621 {
622         ast_indicate(control->channel, AST_CONTROL_UNHOLD);
623
624         return 0;
625 }
626
627 void stasis_app_control_unhold(struct stasis_app_control *control)
628 {
629         stasis_app_send_command_async(control, app_control_unhold, NULL, NULL);
630 }
631
632 static int app_control_moh_start(struct stasis_app_control *control,
633         struct ast_channel *chan, void *data)
634 {
635         char *moh_class = data;
636
637         if (ast_channel_state(chan) != AST_STATE_UP) {
638                 ast_indicate(chan, AST_CONTROL_PROGRESS);
639         }
640
641         ast_moh_start(chan, moh_class, NULL);
642
643         return 0;
644 }
645
646 void stasis_app_control_moh_start(struct stasis_app_control *control, const char *moh_class)
647 {
648         char *data = NULL;
649
650         if (!ast_strlen_zero(moh_class)) {
651                 data = ast_strdup(moh_class);
652         }
653
654         stasis_app_send_command_async(control, app_control_moh_start, data, ast_free_ptr);
655 }
656
657 static int app_control_moh_stop(struct stasis_app_control *control,
658         struct ast_channel *chan, void *data)
659 {
660         ast_moh_stop(chan);
661         return 0;
662 }
663
664 void stasis_app_control_moh_stop(struct stasis_app_control *control)
665 {
666         stasis_app_send_command_async(control, app_control_moh_stop, NULL, NULL);
667 }
668
669 static int app_control_silence_start(struct stasis_app_control *control,
670         struct ast_channel *chan, void *data)
671 {
672         if (ast_channel_state(chan) != AST_STATE_UP) {
673                 ast_indicate(chan, AST_CONTROL_PROGRESS);
674         }
675
676         if (control->silgen) {
677                 /* We have a silence generator, but it may have been implicitly
678                  * disabled by media actions (music on hold, playing media,
679                  * etc.) Just stop it and restart a new one.
680                  */
681                 ast_channel_stop_silence_generator(
682                         control->channel, control->silgen);
683         }
684
685         ast_debug(3, "%s: Starting silence generator\n",
686                 stasis_app_control_get_channel_id(control));
687         control->silgen = ast_channel_start_silence_generator(control->channel);
688
689         if (!control->silgen) {
690                 ast_log(LOG_WARNING,
691                         "%s: Failed to start silence generator.\n",
692                         stasis_app_control_get_channel_id(control));
693         }
694
695         return 0;
696 }
697
698 void stasis_app_control_silence_start(struct stasis_app_control *control)
699 {
700         stasis_app_send_command_async(control, app_control_silence_start, NULL, NULL);
701 }
702
703 static int app_control_silence_stop(struct stasis_app_control *control,
704         struct ast_channel *chan, void *data)
705 {
706         if (control->silgen) {
707                 ast_debug(3, "%s: Stopping silence generator\n",
708                         stasis_app_control_get_channel_id(control));
709                 ast_channel_stop_silence_generator(
710                         control->channel, control->silgen);
711                 control->silgen = NULL;
712         }
713
714         return 0;
715 }
716
717 void stasis_app_control_silence_stop(struct stasis_app_control *control)
718 {
719         stasis_app_send_command_async(control, app_control_silence_stop, NULL, NULL);
720 }
721
722 struct ast_channel_snapshot *stasis_app_control_get_snapshot(
723         const struct stasis_app_control *control)
724 {
725         RAII_VAR(struct stasis_message *, msg, NULL, ao2_cleanup);
726         struct ast_channel_snapshot *snapshot;
727
728         msg = stasis_cache_get(ast_channel_cache(), ast_channel_snapshot_type(),
729                 stasis_app_control_get_channel_id(control));
730         if (!msg) {
731                 return NULL;
732         }
733
734         snapshot = stasis_message_data(msg);
735         ast_assert(snapshot != NULL);
736
737         ao2_ref(snapshot, +1);
738         return snapshot;
739 }
740
741 static int app_send_command_on_condition(struct stasis_app_control *control,
742                                          stasis_app_command_cb command_fn, void *data,
743                                          command_data_destructor_fn data_destructor,
744                                          app_command_can_exec_cb can_exec_fn)
745 {
746         RAII_VAR(struct stasis_app_command *, command, NULL, ao2_cleanup);
747
748         if (control == NULL) {
749                 return -1;
750         }
751
752         command = exec_command_on_condition(
753                 control, command_fn, data, data_destructor, can_exec_fn);
754         if (!command) {
755                 return -1;
756         }
757
758         return command_join(command);
759 }
760
761 int stasis_app_send_command(struct stasis_app_control *control,
762         stasis_app_command_cb command_fn, void *data, command_data_destructor_fn data_destructor)
763 {
764         return app_send_command_on_condition(control, command_fn, data, data_destructor, NULL);
765 }
766
767 int stasis_app_send_command_async(struct stasis_app_control *control,
768         stasis_app_command_cb command_fn, void *data,
769         command_data_destructor_fn data_destructor)
770 {
771         RAII_VAR(struct stasis_app_command *, command, NULL, ao2_cleanup);
772
773         if (control == NULL) {
774                 return -1;
775         }
776
777         command = exec_command(control, command_fn, data, data_destructor);
778         if (!command) {
779                 return -1;
780         }
781
782         return 0;
783 }
784
785 struct ast_bridge *stasis_app_get_bridge(struct stasis_app_control *control)
786 {
787         if (!control) {
788                 return NULL;
789         } else {
790                 SCOPED_AO2LOCK(lock, control);
791                 return control->bridge;
792         }
793 }
794
795 static int bridge_channel_depart(struct stasis_app_control *control,
796         struct ast_channel *chan, void *data)
797 {
798         struct ast_bridge_channel *bridge_channel = data;
799
800         {
801                 SCOPED_CHANNELLOCK(lock, chan);
802
803                 if (bridge_channel != ast_channel_internal_bridge_channel(chan)) {
804                         ast_debug(3, "%s: Channel is no longer in departable state\n",
805                                 ast_channel_uniqueid(chan));
806                         return -1;
807                 }
808         }
809
810         ast_debug(3, "%s: Channel departing bridge\n",
811                 ast_channel_uniqueid(chan));
812
813         ast_bridge_depart(chan);
814
815         return 0;
816 }
817
818 static void bridge_after_cb(struct ast_channel *chan, void *data)
819 {
820         struct stasis_app_control *control = data;
821         SCOPED_AO2LOCK(lock, control);
822         struct ast_bridge_channel *bridge_channel;
823
824         ast_debug(3, "%s, %s: Channel leaving bridge\n",
825                 ast_channel_uniqueid(chan), control->bridge->uniqueid);
826
827         ast_assert(chan == control->channel);
828
829         /* Restore the channel's PBX */
830         ast_channel_pbx_set(control->channel, control->pbx);
831         control->pbx = NULL;
832
833         app_unsubscribe_bridge(control->app, control->bridge);
834
835         /* No longer in the bridge */
836         control->bridge = NULL;
837
838         /* Get the bridge channel so we don't depart from the wrong bridge */
839         ast_channel_lock(chan);
840         bridge_channel = ast_channel_get_bridge_channel(chan);
841         ast_channel_unlock(chan);
842
843         /* Depart this channel from the bridge using the command queue if possible */
844         stasis_app_send_command_async(control, bridge_channel_depart, bridge_channel, __ao2_cleanup);
845         if (stasis_app_channel_is_stasis_end_published(chan)) {
846                 /* The channel has had a StasisEnd published on it, but until now had remained in
847                  * the bridging system. This means that the channel moved from a Stasis bridge to a
848                  * non-Stasis bridge and is now exiting the bridging system. Because of this, the
849                  * channel needs to exit the Stasis application and go to wherever the non-Stasis
850                  * bridge has directed it to go. If the non-Stasis bridge has not set up an after
851                  * bridge destination, then the channel should be hung up.
852                  */
853                 int hangup_flag;
854
855                 hangup_flag = ast_bridge_setup_after_goto(chan) ? AST_SOFTHANGUP_DEV : AST_SOFTHANGUP_ASYNCGOTO;
856                 ast_channel_lock(chan);
857                 ast_softhangup_nolock(chan, hangup_flag);
858                 ast_channel_unlock(chan);
859         }
860 }
861
862 static void bridge_after_cb_failed(enum ast_bridge_after_cb_reason reason,
863         void *data)
864 {
865         struct stasis_app_control *control = data;
866
867         bridge_after_cb(control->channel, data);
868
869         ast_debug(3, "  reason: %s\n",
870                 ast_bridge_after_cb_reason_string(reason));
871 }
872
873 int control_add_channel_to_bridge(
874         struct stasis_app_control *control,
875         struct ast_channel *chan, void *data)
876 {
877         struct ast_bridge *bridge = data;
878         int res;
879
880         if (!control || !bridge) {
881                 return -1;
882         }
883
884         ast_debug(3, "%s: Adding to bridge %s\n",
885                 stasis_app_control_get_channel_id(control),
886                 bridge->uniqueid);
887
888         ast_assert(chan != NULL);
889
890         /* Depart whatever Stasis bridge we're currently in. */
891         if (stasis_app_get_bridge(control)) {
892                 /* Note that it looks like there's a race condition here, since
893                  * we don't have control locked. But this happens from the
894                  * control callback thread, so there won't be any other
895                  * concurrent attempts to bridge.
896                  */
897                 ast_bridge_depart(chan);
898         }
899
900
901         res = ast_bridge_set_after_callback(chan, bridge_after_cb,
902                 bridge_after_cb_failed, control);
903         if (res != 0) {
904                 ast_log(LOG_ERROR, "Error setting after-bridge callback\n");
905                 return -1;
906         }
907
908         {
909                 /* pbx and bridge are modified by the bridging impart thread.
910                  * It shouldn't happen concurrently, but we still need to lock
911                  * for the memory fence.
912                  */
913                 SCOPED_AO2LOCK(lock, control);
914
915                 /* Ensure the controlling application is subscribed early enough
916                  * to receive the ChannelEnteredBridge message. This works in concert
917                  * with the subscription handled in the Stasis application execution
918                  * loop */
919                 app_subscribe_bridge(control->app, bridge);
920
921                 /* Save off the channel's PBX */
922                 ast_assert(control->pbx == NULL);
923                 if (!control->pbx) {
924                         control->pbx = ast_channel_pbx(chan);
925                         ast_channel_pbx_set(chan, NULL);
926                 }
927
928                 res = ast_bridge_impart(bridge,
929                         chan,
930                         NULL, /* swap channel */
931                         NULL, /* features */
932                         AST_BRIDGE_IMPART_CHAN_DEPARTABLE);
933                 if (res != 0) {
934                         ast_log(LOG_ERROR, "Error adding channel to bridge\n");
935                         ast_channel_pbx_set(chan, control->pbx);
936                         control->pbx = NULL;
937                         return -1;
938                 }
939
940                 ast_assert(stasis_app_get_bridge(control) == NULL);
941                 control->bridge = bridge;
942         }
943         return 0;
944 }
945
946 int stasis_app_control_add_channel_to_bridge(
947         struct stasis_app_control *control, struct ast_bridge *bridge)
948 {
949         ast_debug(3, "%s: Sending channel add_to_bridge command\n",
950                         stasis_app_control_get_channel_id(control));
951
952         return app_send_command_on_condition(
953                 control, control_add_channel_to_bridge, bridge, NULL,
954                 app_control_can_add_channel_to_bridge);
955 }
956
957 static int app_control_remove_channel_from_bridge(
958         struct stasis_app_control *control,
959         struct ast_channel *chan, void *data)
960 {
961         struct ast_bridge *bridge = data;
962
963         if (!control) {
964                 return -1;
965         }
966
967         /* We should only depart from our own bridge */
968         ast_debug(3, "%s: Departing bridge %s\n",
969                 stasis_app_control_get_channel_id(control),
970                 bridge->uniqueid);
971
972         if (bridge != stasis_app_get_bridge(control)) {
973                 ast_log(LOG_WARNING, "%s: Not in bridge %s; not removing\n",
974                         stasis_app_control_get_channel_id(control),
975                         bridge->uniqueid);
976                 return -1;
977         }
978
979         ast_bridge_depart(chan);
980         return 0;
981 }
982
983 int stasis_app_control_remove_channel_from_bridge(
984         struct stasis_app_control *control, struct ast_bridge *bridge)
985 {
986         ast_debug(3, "%s: Sending channel remove_from_bridge command\n",
987                         stasis_app_control_get_channel_id(control));
988         return app_send_command_on_condition(
989                 control, app_control_remove_channel_from_bridge, bridge, NULL,
990                 app_control_can_remove_channel_from_bridge);
991 }
992
993 const char *stasis_app_control_get_channel_id(
994         const struct stasis_app_control *control)
995 {
996         return ast_channel_uniqueid(control->channel);
997 }
998
999 void stasis_app_control_publish(
1000         struct stasis_app_control *control, struct stasis_message *message)
1001 {
1002         if (!control || !control->channel || !message) {
1003                 return;
1004         }
1005         stasis_publish(ast_channel_topic(control->channel), message);
1006 }
1007
1008 int stasis_app_control_queue_control(struct stasis_app_control *control,
1009         enum ast_control_frame_type frame_type)
1010 {
1011         return ast_queue_control(control->channel, frame_type);
1012 }
1013
1014 int control_dispatch_all(struct stasis_app_control *control,
1015         struct ast_channel *chan)
1016 {
1017         int count = 0;
1018         struct ao2_iterator i;
1019         void *obj;
1020
1021         ast_assert(control->channel == chan);
1022
1023         i = ao2_iterator_init(control->command_queue, AO2_ITERATOR_UNLINK);
1024
1025         while ((obj = ao2_iterator_next(&i))) {
1026                 RAII_VAR(struct stasis_app_command *, command, obj, ao2_cleanup);
1027                 command_invoke(command, control, chan);
1028                 ++count;
1029         }
1030
1031         ao2_iterator_destroy(&i);
1032         return count;
1033 }
1034
1035 void control_wait(struct stasis_app_control *control)
1036 {
1037         if (!control) {
1038                 return;
1039         }
1040
1041         ast_assert(control->command_queue != NULL);
1042
1043         ao2_lock(control->command_queue);
1044         while (ao2_container_count(control->command_queue) == 0) {
1045                 int res = ast_cond_wait(&control->wait_cond,
1046                         ao2_object_get_lockaddr(control->command_queue));
1047                 if (res < 0) {
1048                         ast_log(LOG_ERROR, "Error waiting on command queue\n");
1049                         break;
1050                 }
1051         }
1052         ao2_unlock(control->command_queue);
1053 }
1054
1055 int control_prestart_dispatch_all(struct stasis_app_control *control,
1056         struct ast_channel *chan)
1057 {
1058         struct ao2_container *command_queue;
1059         int count = 0;
1060         struct ao2_iterator iter;
1061         struct stasis_app_command *command;
1062
1063         ast_channel_lock(chan);
1064         command_queue = command_prestart_get_container(chan);
1065         ast_channel_unlock(chan);
1066         if (!command_queue) {
1067                 return 0;
1068         }
1069
1070         iter = ao2_iterator_init(command_queue, AO2_ITERATOR_UNLINK);
1071
1072         while ((command = ao2_iterator_next(&iter))) {
1073                 command_invoke(command, control, chan);
1074                 ao2_cleanup(command);
1075                 ++count;
1076         }
1077
1078         ao2_iterator_destroy(&iter);
1079         ao2_cleanup(command_queue);
1080         return count;
1081 }
1082
1083 struct stasis_app *control_app(struct stasis_app_control *control)
1084 {
1085         return control->app;
1086 }