d1d54a2f042f9ffc6648a4746d380fea33654ba8
[asterisk/asterisk.git] / res / ari / resource_channels.c
1 /*
2  * Asterisk -- An open source telephony toolkit.
3  *
4  * Copyright (C) 2012 - 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 Implementation for ARI stubs.
22  *
23  * \author David M. Lee, II <dlee@digium.com>
24  */
25
26 /*** MODULEINFO
27         <depend type="module">res_stasis_app_playback</depend>
28         <support_level>core</support_level>
29  ***/
30
31 #include "asterisk.h"
32
33 ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
34
35 #include "asterisk/file.h"
36 #include "asterisk/pbx.h"
37 #include "asterisk/bridge.h"
38 #include "asterisk/callerid.h"
39 #include "asterisk/stasis_app.h"
40 #include "asterisk/stasis_app_playback.h"
41 #include "asterisk/stasis_app_recording.h"
42 #include "asterisk/stasis_app_snoop.h"
43 #include "asterisk/stasis_channels.h"
44 #include "asterisk/causes.h"
45 #include "asterisk/format_cache.h"
46 #include "asterisk/core_local.h"
47 #include "asterisk/dial.h"
48 #include "resource_channels.h"
49
50 #include <limits.h>
51
52 /*!
53  * \brief Finds the control object for a channel, filling the response with an
54  * error, if appropriate.
55  * \param[out] response Response to fill with an error if control is not found.
56  * \param channel_id ID of the channel to lookup.
57  * \return Channel control object.
58  * \return \c NULL if control object does not exist.
59  */
60 static struct stasis_app_control *find_control(
61         struct ast_ari_response *response,
62         const char *channel_id)
63 {
64         RAII_VAR(struct stasis_app_control *, control, NULL, ao2_cleanup);
65
66         ast_assert(response != NULL);
67
68         control = stasis_app_control_find_by_channel_id(channel_id);
69         if (control == NULL) {
70                 /* Distinguish between 404 and 409 errors */
71                 RAII_VAR(struct ast_channel *, chan, NULL, ao2_cleanup);
72                 chan = ast_channel_get_by_name(channel_id);
73                 if (chan == NULL) {
74                         ast_ari_response_error(response, 404, "Not Found",
75                                    "Channel not found");
76                         return NULL;
77                 }
78
79                 ast_ari_response_error(response, 409, "Conflict",
80                            "Channel not in Stasis application");
81                 return NULL;
82         }
83
84         ao2_ref(control, +1);
85         return control;
86 }
87
88 void ast_ari_channels_continue_in_dialplan(
89         struct ast_variable *headers,
90         struct ast_ari_channels_continue_in_dialplan_args *args,
91         struct ast_ari_response *response)
92 {
93         RAII_VAR(struct stasis_app_control *, control, NULL, ao2_cleanup);
94         RAII_VAR(struct ast_channel_snapshot *, snapshot, NULL, ao2_cleanup);
95         int ipri;
96         const char *context;
97         const char *exten;
98
99         ast_assert(response != NULL);
100
101         control = find_control(response, args->channel_id);
102         if (control == NULL) {
103                 return;
104         }
105
106         snapshot = stasis_app_control_get_snapshot(control);
107         if (!snapshot) {
108                 return;
109         }
110
111         if (ast_strlen_zero(args->context)) {
112                 context = snapshot->context;
113                 exten = S_OR(args->extension, snapshot->exten);
114         } else {
115                 context = args->context;
116                 exten = S_OR(args->extension, "s");
117         }
118
119         if (!ast_strlen_zero(args->label)) {
120                 /* A label was provided in the request, use that */
121
122                 if (sscanf(args->label, "%30d", &ipri) != 1) {
123                         ipri = ast_findlabel_extension(NULL, context, exten, args->label, NULL);
124                         if (ipri == -1) {
125                                 ast_log(AST_LOG_ERROR, "Requested label: %s can not be found in context: %s\n", args->label, context);
126                                 ast_ari_response_error(response, 404, "Not Found", "Requested label can not be found");
127                                 return;
128                         }
129                 } else {
130                         ast_debug(3, "Numeric value provided for label, jumping to that priority\n");
131                 }
132
133                 if (ipri == 0) {
134                         ast_log(AST_LOG_ERROR, "Invalid priority label '%s' specified for extension %s in context: %s\n",
135                                         args->label, exten, context);
136                         ast_ari_response_error(response, 400, "Bad Request", "Requested priority is illegal");
137                         return;
138                 }
139
140         } else if (args->priority) {
141                 /* No label provided, use provided priority */
142                 ipri = args->priority;
143         } else if (ast_strlen_zero(args->context) && ast_strlen_zero(args->extension)) {
144                 /* Special case. No exten, context, or priority provided, then move on to the next priority */
145                 ipri = snapshot->priority + 1;
146         } else {
147                 ipri = 1;
148         }
149
150
151         if (stasis_app_control_continue(control, context, exten, ipri)) {
152                 ast_ari_response_alloc_failed(response);
153                 return;
154         }
155
156         ast_ari_response_no_content(response);
157 }
158
159 void ast_ari_channels_answer(struct ast_variable *headers,
160         struct ast_ari_channels_answer_args *args,
161         struct ast_ari_response *response)
162 {
163         RAII_VAR(struct stasis_app_control *, control, NULL, ao2_cleanup);
164
165         control = find_control(response, args->channel_id);
166         if (control == NULL) {
167                 return;
168         }
169
170         if (stasis_app_control_answer(control) != 0) {
171                 ast_ari_response_error(
172                         response, 500, "Internal Server Error",
173                         "Failed to answer channel");
174                 return;
175         }
176
177         ast_ari_response_no_content(response);
178 }
179
180 void ast_ari_channels_ring(struct ast_variable *headers,
181         struct ast_ari_channels_ring_args *args,
182         struct ast_ari_response *response)
183 {
184         RAII_VAR(struct stasis_app_control *, control, NULL, ao2_cleanup);
185
186         control = find_control(response, args->channel_id);
187         if (control == NULL) {
188                 return;
189         }
190
191         stasis_app_control_ring(control);
192
193         ast_ari_response_no_content(response);
194 }
195
196 void ast_ari_channels_ring_stop(struct ast_variable *headers,
197         struct ast_ari_channels_ring_stop_args *args,
198         struct ast_ari_response *response)
199 {
200         RAII_VAR(struct stasis_app_control *, control, NULL, ao2_cleanup);
201
202         control = find_control(response, args->channel_id);
203         if (control == NULL) {
204                 return;
205         }
206
207         stasis_app_control_ring_stop(control);
208
209         ast_ari_response_no_content(response);
210 }
211
212 void ast_ari_channels_mute(struct ast_variable *headers,
213         struct ast_ari_channels_mute_args *args,
214         struct ast_ari_response *response)
215 {
216         RAII_VAR(struct stasis_app_control *, control, NULL, ao2_cleanup);
217         unsigned int direction = 0;
218         enum ast_frame_type frametype = AST_FRAME_VOICE;
219
220         control = find_control(response, args->channel_id);
221         if (control == NULL) {
222                 return;
223         }
224
225         if (ast_strlen_zero(args->direction)) {
226                 ast_ari_response_error(
227                         response, 400, "Bad Request",
228                         "Direction is required");
229                 return;
230         }
231
232         if (!strcmp(args->direction, "in")) {
233                 direction = AST_MUTE_DIRECTION_READ;
234         } else if (!strcmp(args->direction, "out")) {
235                 direction = AST_MUTE_DIRECTION_WRITE;
236         } else if (!strcmp(args->direction, "both")) {
237                 direction = AST_MUTE_DIRECTION_READ | AST_MUTE_DIRECTION_WRITE;
238         } else {
239                 ast_ari_response_error(
240                         response, 400, "Bad Request",
241                         "Invalid direction specified");
242                 return;
243         }
244
245         stasis_app_control_mute(control, direction, frametype);
246
247         ast_ari_response_no_content(response);
248 }
249
250 void ast_ari_channels_unmute(struct ast_variable *headers,
251         struct ast_ari_channels_unmute_args *args,
252         struct ast_ari_response *response)
253 {
254         RAII_VAR(struct stasis_app_control *, control, NULL, ao2_cleanup);
255         unsigned int direction = 0;
256         enum ast_frame_type frametype = AST_FRAME_VOICE;
257
258         control = find_control(response, args->channel_id);
259         if (control == NULL) {
260                 return;
261         }
262
263         if (ast_strlen_zero(args->direction)) {
264                 ast_ari_response_error(
265                         response, 400, "Bad Request",
266                         "Direction is required");
267                 return;
268         }
269
270         if (!strcmp(args->direction, "in")) {
271                 direction = AST_MUTE_DIRECTION_READ;
272         } else if (!strcmp(args->direction, "out")) {
273                 direction = AST_MUTE_DIRECTION_WRITE;
274         } else if (!strcmp(args->direction, "both")) {
275                 direction = AST_MUTE_DIRECTION_READ | AST_MUTE_DIRECTION_WRITE;
276         } else {
277                 ast_ari_response_error(
278                         response, 400, "Bad Request",
279                         "Invalid direction specified");
280                 return;
281         }
282
283         stasis_app_control_unmute(control, direction, frametype);
284
285         ast_ari_response_no_content(response);
286 }
287
288 void ast_ari_channels_send_dtmf(struct ast_variable *headers,
289         struct ast_ari_channels_send_dtmf_args *args,
290         struct ast_ari_response *response)
291 {
292         RAII_VAR(struct stasis_app_control *, control, NULL, ao2_cleanup);
293
294         control = find_control(response, args->channel_id);
295         if (control == NULL) {
296                 return;
297         }
298
299         if (ast_strlen_zero(args->dtmf)) {
300                 ast_ari_response_error(
301                         response, 400, "Bad Request",
302                         "DTMF is required");
303                 return;
304         }
305
306         stasis_app_control_dtmf(control, args->dtmf, args->before, args->between, args->duration, args->after);
307
308         ast_ari_response_no_content(response);
309 }
310
311 void ast_ari_channels_hold(struct ast_variable *headers,
312         struct ast_ari_channels_hold_args *args,
313         struct ast_ari_response *response)
314 {
315         RAII_VAR(struct stasis_app_control *, control, NULL, ao2_cleanup);
316
317         control = find_control(response, args->channel_id);
318         if (control == NULL) {
319                 /* Response filled in by find_control */
320                 return;
321         }
322
323         stasis_app_control_hold(control);
324
325         ast_ari_response_no_content(response);
326 }
327
328 void ast_ari_channels_unhold(struct ast_variable *headers,
329         struct ast_ari_channels_unhold_args *args,
330         struct ast_ari_response *response)
331 {
332         RAII_VAR(struct stasis_app_control *, control, NULL, ao2_cleanup);
333
334         control = find_control(response, args->channel_id);
335         if (control == NULL) {
336                 /* Response filled in by find_control */
337                 return;
338         }
339
340         stasis_app_control_unhold(control);
341
342         ast_ari_response_no_content(response);
343 }
344
345 void ast_ari_channels_start_moh(struct ast_variable *headers,
346         struct ast_ari_channels_start_moh_args *args,
347         struct ast_ari_response *response)
348 {
349         RAII_VAR(struct stasis_app_control *, control, NULL, ao2_cleanup);
350
351         control = find_control(response, args->channel_id);
352         if (control == NULL) {
353                 /* Response filled in by find_control */
354                 return;
355         }
356
357         stasis_app_control_moh_start(control, args->moh_class);
358         ast_ari_response_no_content(response);
359 }
360
361 void ast_ari_channels_stop_moh(struct ast_variable *headers,
362         struct ast_ari_channels_stop_moh_args *args,
363         struct ast_ari_response *response)
364 {
365         RAII_VAR(struct stasis_app_control *, control, NULL, ao2_cleanup);
366
367         control = find_control(response, args->channel_id);
368         if (control == NULL) {
369                 /* Response filled in by find_control */
370                 return;
371         }
372
373         stasis_app_control_moh_stop(control);
374         ast_ari_response_no_content(response);
375 }
376
377 void ast_ari_channels_start_silence(struct ast_variable *headers,
378         struct ast_ari_channels_start_silence_args *args,
379         struct ast_ari_response *response)
380 {
381         RAII_VAR(struct stasis_app_control *, control, NULL, ao2_cleanup);
382
383         control = find_control(response, args->channel_id);
384         if (control == NULL) {
385                 /* Response filled in by find_control */
386                 return;
387         }
388
389         stasis_app_control_silence_start(control);
390         ast_ari_response_no_content(response);
391 }
392
393 void ast_ari_channels_stop_silence(struct ast_variable *headers,
394         struct ast_ari_channels_stop_silence_args *args,
395         struct ast_ari_response *response)
396 {
397         RAII_VAR(struct stasis_app_control *, control, NULL, ao2_cleanup);
398
399         control = find_control(response, args->channel_id);
400         if (control == NULL) {
401                 /* Response filled in by find_control */
402                 return;
403         }
404
405         stasis_app_control_silence_stop(control);
406         ast_ari_response_no_content(response);
407 }
408
409 static void ari_channels_handle_play(
410         const char *args_channel_id,
411         const char *args_media,
412         const char *args_lang,
413         int args_offsetms,
414         int args_skipms,
415         const char *args_playback_id,
416         struct ast_ari_response *response)
417 {
418         RAII_VAR(struct stasis_app_control *, control, NULL, ao2_cleanup);
419         RAII_VAR(struct ast_channel_snapshot *, snapshot, NULL, ao2_cleanup);
420         RAII_VAR(struct stasis_app_playback *, playback, NULL, ao2_cleanup);
421         RAII_VAR(char *, playback_url, NULL, ast_free);
422         struct ast_json *json;
423         const char *language;
424
425         ast_assert(response != NULL);
426
427         control = find_control(response, args_channel_id);
428         if (control == NULL) {
429                 /* Response filled in by find_control */
430                 return;
431         }
432
433         snapshot = stasis_app_control_get_snapshot(control);
434         if (!snapshot) {
435                 ast_ari_response_error(
436                         response, 404, "Not Found",
437                         "Channel not found");
438                 return;
439         }
440
441         if (args_skipms < 0) {
442                 ast_ari_response_error(
443                         response, 400, "Bad Request",
444                         "skipms cannot be negative");
445                 return;
446         }
447
448         if (args_offsetms < 0) {
449                 ast_ari_response_error(
450                         response, 400, "Bad Request",
451                         "offsetms cannot be negative");
452                 return;
453         }
454
455         language = S_OR(args_lang, snapshot->language);
456
457         playback = stasis_app_control_play_uri(control, args_media, language,
458                 args_channel_id, STASIS_PLAYBACK_TARGET_CHANNEL, args_skipms, args_offsetms, args_playback_id);
459         if (!playback) {
460                 ast_ari_response_error(
461                         response, 500, "Internal Server Error",
462                         "Failed to queue media for playback");
463                 return;
464         }
465
466         if (ast_asprintf(&playback_url, "/playback/%s",
467                         stasis_app_playback_get_id(playback)) == -1) {
468                 playback_url = NULL;
469                 ast_ari_response_error(
470                         response, 500, "Internal Server Error",
471                         "Out of memory");
472                 return;
473         }
474
475         json = stasis_app_playback_to_json(playback);
476         if (!json) {
477                 ast_ari_response_error(
478                         response, 500, "Internal Server Error",
479                         "Out of memory");
480                 return;
481         }
482
483         ast_ari_response_created(response, playback_url, json);
484 }
485
486 void ast_ari_channels_play(struct ast_variable *headers,
487         struct ast_ari_channels_play_args *args,
488         struct ast_ari_response *response)
489 {
490         ari_channels_handle_play(
491                 args->channel_id,
492                 args->media,
493                 args->lang,
494                 args->offsetms,
495                 args->skipms,
496                 args->playback_id,
497                 response);
498 }
499
500 void ast_ari_channels_play_with_id(struct ast_variable *headers,
501         struct ast_ari_channels_play_with_id_args *args,
502         struct ast_ari_response *response)
503 {
504         ari_channels_handle_play(
505                 args->channel_id,
506                 args->media,
507                 args->lang,
508                 args->offsetms,
509                 args->skipms,
510                 args->playback_id,
511                 response);
512 }
513
514 void ast_ari_channels_record(struct ast_variable *headers,
515         struct ast_ari_channels_record_args *args,
516         struct ast_ari_response *response)
517 {
518         RAII_VAR(struct stasis_app_control *, control, NULL, ao2_cleanup);
519         RAII_VAR(struct stasis_app_recording *, recording, NULL, ao2_cleanup);
520         RAII_VAR(char *, recording_url, NULL, ast_free);
521         struct ast_json *json;
522         RAII_VAR(struct stasis_app_recording_options *, options, NULL,
523                 ao2_cleanup);
524         RAII_VAR(char *, uri_encoded_name, NULL, ast_free);
525         size_t uri_name_maxlen;
526
527         ast_assert(response != NULL);
528
529         if (args->max_duration_seconds < 0) {
530                 ast_ari_response_error(
531                         response, 400, "Bad Request",
532                         "max_duration_seconds cannot be negative");
533                 return;
534         }
535
536         if (args->max_silence_seconds < 0) {
537                 ast_ari_response_error(
538                         response, 400, "Bad Request",
539                         "max_silence_seconds cannot be negative");
540                 return;
541         }
542
543         control = find_control(response, args->channel_id);
544         if (control == NULL) {
545                 /* Response filled in by find_control */
546                 return;
547         }
548
549         options = stasis_app_recording_options_create(args->name, args->format);
550         if (options == NULL) {
551                 ast_ari_response_error(
552                         response, 500, "Internal Server Error",
553                         "Out of memory");
554         }
555         ast_string_field_build(options, target, "channel:%s", args->channel_id);
556         options->max_silence_seconds = args->max_silence_seconds;
557         options->max_duration_seconds = args->max_duration_seconds;
558         options->terminate_on =
559                 stasis_app_recording_termination_parse(args->terminate_on);
560         options->if_exists =
561                 stasis_app_recording_if_exists_parse(args->if_exists);
562         options->beep = args->beep;
563
564         if (options->terminate_on == STASIS_APP_RECORDING_TERMINATE_INVALID) {
565                 ast_ari_response_error(
566                         response, 400, "Bad Request",
567                         "terminateOn invalid");
568                 return;
569         }
570
571         if (options->if_exists == -1) {
572                 ast_ari_response_error(
573                         response, 400, "Bad Request",
574                         "ifExists invalid");
575                 return;
576         }
577
578         if (!ast_get_format_for_file_ext(options->format)) {
579                 ast_ari_response_error(
580                         response, 422, "Unprocessable Entity",
581                         "specified format is unknown on this system");
582                 return;
583         }
584
585         recording = stasis_app_control_record(control, options);
586         if (recording == NULL) {
587                 switch(errno) {
588                 case EINVAL:
589                         /* While the arguments are invalid, we should have
590                          * caught them prior to calling record.
591                          */
592                         ast_ari_response_error(
593                                 response, 500, "Internal Server Error",
594                                 "Error parsing request");
595                         break;
596                 case EEXIST:
597                         ast_ari_response_error(response, 409, "Conflict",
598                                 "Recording '%s' already exists and can not be overwritten",
599                                 args->name);
600                         break;
601                 case ENOMEM:
602                         ast_ari_response_error(
603                                 response, 500, "Internal Server Error",
604                                 "Out of memory");
605                         break;
606                 case EPERM:
607                         ast_ari_response_error(
608                                 response, 400, "Bad Request",
609                                 "Recording name invalid");
610                         break;
611                 default:
612                         ast_log(LOG_WARNING,
613                                 "Unrecognized recording error: %s\n",
614                                 strerror(errno));
615                         ast_ari_response_error(
616                                 response, 500, "Internal Server Error",
617                                 "Internal Server Error");
618                         break;
619                 }
620                 return;
621         }
622
623         uri_name_maxlen = strlen(args->name) * 3;
624         uri_encoded_name = ast_malloc(uri_name_maxlen);
625         if (!uri_encoded_name) {
626                 ast_ari_response_error(
627                         response, 500, "Internal Server Error",
628                         "Out of memory");
629                 return;
630         }
631         ast_uri_encode(args->name, uri_encoded_name, uri_name_maxlen,
632                 ast_uri_http);
633
634         if (ast_asprintf(&recording_url, "/recordings/live/%s",
635                         uri_encoded_name) == -1) {
636                 recording_url = NULL;
637                 ast_ari_response_error(
638                         response, 500, "Internal Server Error",
639                         "Out of memory");
640                 return;
641         }
642
643         json = stasis_app_recording_to_json(recording);
644         if (!json) {
645                 ast_ari_response_error(
646                         response, 500, "Internal Server Error",
647                         "Out of memory");
648                 return;
649         }
650
651         ast_ari_response_created(response, recording_url, json);
652 }
653
654 void ast_ari_channels_get(struct ast_variable *headers,
655         struct ast_ari_channels_get_args *args,
656         struct ast_ari_response *response)
657 {
658         RAII_VAR(struct stasis_message *, msg, NULL, ao2_cleanup);
659         struct stasis_cache *cache;
660         struct ast_channel_snapshot *snapshot;
661
662         cache = ast_channel_cache();
663         if (!cache) {
664                 ast_ari_response_error(
665                         response, 500, "Internal Server Error",
666                         "Message bus not initialized");
667                 return;
668         }
669
670         msg = stasis_cache_get(cache, ast_channel_snapshot_type(),
671                                    args->channel_id);
672         if (!msg) {
673                 ast_ari_response_error(
674                         response, 404, "Not Found",
675                         "Channel not found");
676                 return;
677         }
678
679         snapshot = stasis_message_data(msg);
680         ast_assert(snapshot != NULL);
681
682         ast_ari_response_ok(response,
683                                 ast_channel_snapshot_to_json(snapshot, NULL));
684 }
685
686 void ast_ari_channels_hangup(struct ast_variable *headers,
687         struct ast_ari_channels_hangup_args *args,
688         struct ast_ari_response *response)
689 {
690         RAII_VAR(struct ast_channel *, chan, NULL, ao2_cleanup);
691         int cause;
692
693         chan = ast_channel_get_by_name(args->channel_id);
694         if (chan == NULL) {
695                 ast_ari_response_error(
696                         response, 404, "Not Found",
697                         "Channel not found");
698                 return;
699         }
700
701         if (ast_strlen_zero(args->reason) || !strcmp(args->reason, "normal")) {
702                 cause = AST_CAUSE_NORMAL;
703         } else if (!strcmp(args->reason, "busy")) {
704                 cause = AST_CAUSE_BUSY;
705         } else if (!strcmp(args->reason, "congestion")) {
706                 cause = AST_CAUSE_CONGESTION;
707         } else {
708                 ast_ari_response_error(
709                         response, 400, "Invalid Reason",
710                         "Invalid reason for hangup provided");
711                 return;
712         }
713
714         ast_channel_hangupcause_set(chan, cause);
715         ast_softhangup(chan, AST_SOFTHANGUP_EXPLICIT);
716
717         ast_ari_response_no_content(response);
718 }
719
720 void ast_ari_channels_list(struct ast_variable *headers,
721         struct ast_ari_channels_list_args *args,
722         struct ast_ari_response *response)
723 {
724         RAII_VAR(struct stasis_cache *, cache, NULL, ao2_cleanup);
725         RAII_VAR(struct ao2_container *, snapshots, NULL, ao2_cleanup);
726         RAII_VAR(struct ast_json *, json, NULL, ast_json_unref);
727         struct ao2_iterator i;
728         void *obj;
729         struct stasis_message_sanitizer *sanitize = stasis_app_get_sanitizer();
730
731         cache = ast_channel_cache();
732         if (!cache) {
733                 ast_ari_response_error(
734                         response, 500, "Internal Server Error",
735                         "Message bus not initialized");
736                 return;
737         }
738         ao2_ref(cache, +1);
739
740         snapshots = stasis_cache_dump(cache, ast_channel_snapshot_type());
741         if (!snapshots) {
742                 ast_ari_response_alloc_failed(response);
743                 return;
744         }
745
746         json = ast_json_array_create();
747         if (!json) {
748                 ast_ari_response_alloc_failed(response);
749                 return;
750         }
751
752         i = ao2_iterator_init(snapshots, 0);
753         while ((obj = ao2_iterator_next(&i))) {
754                 RAII_VAR(struct stasis_message *, msg, obj, ao2_cleanup);
755                 struct ast_channel_snapshot *snapshot = stasis_message_data(msg);
756                 int r;
757
758                 if (sanitize && sanitize->channel_snapshot
759                         && sanitize->channel_snapshot(snapshot)) {
760                         continue;
761                 }
762
763                 r = ast_json_array_append(
764                         json, ast_channel_snapshot_to_json(snapshot, NULL));
765                 if (r != 0) {
766                         ast_ari_response_alloc_failed(response);
767                         ao2_iterator_destroy(&i);
768                         return;
769                 }
770         }
771         ao2_iterator_destroy(&i);
772
773         ast_ari_response_ok(response, ast_json_ref(json));
774 }
775
776 /*! \brief Structure used for origination */
777 struct ari_origination {
778         /*! \brief Dialplan context */
779         char context[AST_MAX_CONTEXT];
780         /*! \brief Dialplan extension */
781         char exten[AST_MAX_EXTENSION];
782         /*! \brief Dialplan priority */
783         int priority;
784         /*! \brief Application data to pass to Stasis application */
785         char appdata[0];
786 };
787
788 /*! \brief Thread which dials and executes upon answer */
789 static void *ari_originate_dial(void *data)
790 {
791         struct ast_dial *dial = data;
792         struct ari_origination *origination = ast_dial_get_user_data(dial);
793         enum ast_dial_result res;
794
795         res = ast_dial_run(dial, NULL, 0);
796         if (res != AST_DIAL_RESULT_ANSWERED) {
797                 goto end;
798         }
799
800         if (!ast_strlen_zero(origination->appdata)) {
801                 struct ast_app *app = pbx_findapp("Stasis");
802
803                 if (app) {
804                         ast_verb(4, "Launching Stasis(%s) on %s\n", origination->appdata,
805                                 ast_channel_name(ast_dial_answered(dial)));
806                         pbx_exec(ast_dial_answered(dial), app, origination->appdata);
807                 } else {
808                         ast_log(LOG_WARNING, "No such application 'Stasis'\n");
809                 }
810         } else {
811                 struct ast_channel *answered = ast_dial_answered(dial);
812
813                 if (!ast_strlen_zero(origination->context)) {
814                         ast_channel_context_set(answered, origination->context);
815                 }
816
817                 if (!ast_strlen_zero(origination->exten)) {
818                         ast_channel_exten_set(answered, origination->exten);
819                 }
820
821                 if (origination->priority > 0) {
822                         ast_channel_priority_set(answered, origination->priority);
823                 }
824
825                 if (ast_pbx_run(answered)) {
826                         ast_log(LOG_ERROR, "Failed to start PBX on %s\n", ast_channel_name(answered));
827                 } else {
828                         /* PBX will have taken care of hanging up, so we steal the answered channel so dial doesn't do it */
829                         ast_dial_answered_steal(dial);
830                 }
831         }
832
833 end:
834         ast_dial_destroy(dial);
835         ast_free(origination);
836         return NULL;
837 }
838
839 static void ari_channels_handle_originate_with_id(const char *args_endpoint,
840         const char *args_extension,
841         const char *args_context,
842         long args_priority,
843         const char *args_label,
844         const char *args_app,
845         const char *args_app_args,
846         const char *args_caller_id,
847         int args_timeout,
848         struct ast_variable *variables,
849         const char *args_channel_id,
850         const char *args_other_channel_id,
851         const char *args_originator,
852         struct ast_ari_response *response)
853 {
854         char *dialtech;
855         char dialdevice[AST_CHANNEL_NAME];
856         struct ast_dial *dial;
857         char *caller_id = NULL;
858         char *cid_num = NULL;
859         char *cid_name = NULL;
860         RAII_VAR(struct ast_format_cap *, cap,
861                 ast_format_cap_alloc(AST_FORMAT_CAP_FLAG_DEFAULT), ao2_cleanup);
862         char *stuff;
863         struct ast_channel *other = NULL;
864         struct ast_channel *chan = NULL;
865         RAII_VAR(struct ast_channel_snapshot *, snapshot, NULL, ao2_cleanup);
866         struct ast_assigned_ids assignedids = {
867                 .uniqueid = args_channel_id,
868                 .uniqueid2 = args_other_channel_id,
869         };
870         struct ari_origination *origination;
871         pthread_t thread;
872
873         if (!cap) {
874                 ast_ari_response_alloc_failed(response);
875                 return;
876         }
877         ast_format_cap_append(cap, ast_format_slin, 0);
878
879         if ((assignedids.uniqueid && AST_MAX_PUBLIC_UNIQUEID < strlen(assignedids.uniqueid))
880                 || (assignedids.uniqueid2 && AST_MAX_PUBLIC_UNIQUEID < strlen(assignedids.uniqueid2))) {
881                 ast_ari_response_error(response, 400, "Bad Request",
882                         "Uniqueid length exceeds maximum of %d", AST_MAX_PUBLIC_UNIQUEID);
883                 return;
884         }
885
886         if (ast_strlen_zero(args_endpoint)) {
887                 ast_ari_response_error(response, 400, "Bad Request",
888                         "Endpoint must be specified");
889                 return;
890         }
891
892         dialtech = ast_strdupa(args_endpoint);
893         if ((stuff = strchr(dialtech, '/'))) {
894                 *stuff++ = '\0';
895                 ast_copy_string(dialdevice, stuff, sizeof(dialdevice));
896         }
897
898         if (ast_strlen_zero(dialtech) || ast_strlen_zero(dialdevice)) {
899                 ast_ari_response_error(response, 400, "Bad Request",
900                         "Invalid endpoint specified");
901                 return;
902         }
903
904         if (!ast_strlen_zero(args_app)) {
905                 RAII_VAR(struct ast_str *, appdata, ast_str_create(64), ast_free);
906
907                 if (!appdata) {
908                         ast_ari_response_alloc_failed(response);
909                         return;
910                 }
911
912                 ast_str_set(&appdata, 0, "%s", args_app);
913                 if (!ast_strlen_zero(args_app_args)) {
914                         ast_str_append(&appdata, 0, ",%s", args_app_args);
915                 }
916
917                 origination = ast_calloc(1, sizeof(*origination) + ast_str_size(appdata) + 1);
918                 if (!origination) {
919                         ast_ari_response_alloc_failed(response);
920                         return;
921                 }
922
923                 strcpy(origination->appdata, ast_str_buffer(appdata));
924         } else if (!ast_strlen_zero(args_extension)) {
925                 origination = ast_calloc(1, sizeof(*origination) + 1);
926                 if (!origination) {
927                         ast_ari_response_alloc_failed(response);
928                         return;
929                 }
930
931                 ast_copy_string(origination->context, S_OR(args_context, "default"), sizeof(origination->context));
932                 ast_copy_string(origination->exten, args_extension, sizeof(origination->exten));
933
934                 if (!ast_strlen_zero(args_label)) {
935                         /* A label was provided in the request, use that */
936                         int ipri = 1;
937                         if (sscanf(args_label, "%30d", &ipri) != 1) {
938                                 ipri = ast_findlabel_extension(chan, origination->context, origination->exten, args_label, args_caller_id);
939
940                                 if (ipri == -1) {
941                                         ast_log(AST_LOG_ERROR, "Requested label: %s can not be found in context: %s\n", args_label, args_context);
942                                         ast_ari_response_error(response, 404, "Not Found", "Requested label can not be found");
943                                         return;
944                                 }
945                         } else {
946                                 ast_debug(3, "Numeric value provided for label, jumping to that priority\n");
947                         }
948
949                         if (ipri == 0) {
950                                 ast_log(AST_LOG_ERROR, "Invalid priority label '%s' specified for extension %s in context: %s\n",
951                                                 args_label, args_extension, args_context);
952                                 ast_ari_response_error(response, 400, "Bad Request", "Requested priority is illegal");
953                                 return;
954                         }
955
956                         /* Our priority was provided by a label */
957                         origination->priority =  ipri;
958                 } else {
959                         /* No label provided, use provided priority */
960                         origination->priority = args_priority ? args_priority : 1;
961                 }
962
963                 origination->appdata[0] = '\0';
964         } else {
965                 ast_ari_response_error(response, 400, "Bad Request",
966                         "Application or extension must be specified");
967                 return;
968         }
969
970         dial = ast_dial_create();
971         if (!dial) {
972                 ast_ari_response_alloc_failed(response);
973                 ast_free(origination);
974                 return;
975         }
976         ast_dial_set_user_data(dial, origination);
977
978         if (ast_dial_append(dial, dialtech, dialdevice, &assignedids)) {
979                 ast_ari_response_alloc_failed(response);
980                 ast_dial_destroy(dial);
981                 ast_free(origination);
982                 return;
983         }
984
985         if (args_timeout > 0) {
986                 ast_dial_set_global_timeout(dial, args_timeout * 1000);
987         } else if (args_timeout == -1) {
988                 ast_dial_set_global_timeout(dial, -1);
989         } else {
990                 ast_dial_set_global_timeout(dial, 30000);
991         }
992
993         if (!ast_strlen_zero(args_caller_id)) {
994                 caller_id = ast_strdupa(args_caller_id);
995                 ast_callerid_parse(caller_id, &cid_name, &cid_num);
996
997                 if (ast_is_shrinkable_phonenumber(cid_num)) {
998                         ast_shrink_phone_number(cid_num);
999                 }
1000         }
1001
1002         if (!ast_strlen_zero(args_originator)) {
1003                 other = ast_channel_get_by_name(args_originator);
1004                 if (!other) {
1005                         ast_ari_response_error(
1006                                 response, 400, "Bad Request",
1007                                 "Provided originator channel was not found");
1008                         ast_dial_destroy(dial);
1009                         ast_free(origination);
1010                         return;
1011                 }
1012         }
1013
1014         if (ast_dial_prerun(dial, other, cap)) {
1015                 ast_ari_response_alloc_failed(response);
1016                 ast_dial_destroy(dial);
1017                 ast_free(origination);
1018                 ast_channel_cleanup(other);
1019                 return;
1020         }
1021
1022         ast_channel_cleanup(other);
1023
1024         chan = ast_dial_get_channel(dial, 0);
1025         if (!chan) {
1026                 ast_ari_response_alloc_failed(response);
1027                 ast_dial_destroy(dial);
1028                 ast_free(origination);
1029                 return;
1030         }
1031
1032         if (!ast_strlen_zero(cid_num) || !ast_strlen_zero(cid_name)) {
1033                 struct ast_party_connected_line connected;
1034
1035                 /*
1036                  * It seems strange to set the CallerID on an outgoing call leg
1037                  * to whom we are calling, but this function's callers are doing
1038                  * various Originate methods.  This call leg goes to the local
1039                  * user.  Once the called party answers, the dialplan needs to
1040                  * be able to access the CallerID from the CALLERID function as
1041                  * if the called party had placed this call.
1042                  */
1043                 ast_set_callerid(chan, cid_num, cid_name, cid_num);
1044
1045                 ast_party_connected_line_set_init(&connected, ast_channel_connected(chan));
1046                 if (!ast_strlen_zero(cid_num)) {
1047                         connected.id.number.valid = 1;
1048                         connected.id.number.str = (char *) cid_num;
1049                         connected.id.number.presentation = AST_PRES_ALLOWED_USER_NUMBER_NOT_SCREENED;
1050                 }
1051                 if (!ast_strlen_zero(cid_name)) {
1052                         connected.id.name.valid = 1;
1053                         connected.id.name.str = (char *) cid_name;
1054                         connected.id.name.presentation = AST_PRES_ALLOWED_USER_NUMBER_NOT_SCREENED;
1055                 }
1056                 ast_channel_set_connected_line(chan, &connected, NULL);
1057         }
1058
1059         ast_channel_lock(chan);
1060         if (variables) {
1061                 ast_set_variables(chan, variables);
1062         }
1063         ast_set_flag(ast_channel_flags(chan), AST_FLAG_ORIGINATED);
1064
1065         if (!ast_strlen_zero(args_app)) {
1066                 struct ast_channel *local_peer;
1067
1068                 stasis_app_subscribe_channel(args_app, chan);
1069
1070                 /* Subscribe to the Local channel peer also. */
1071                 local_peer = ast_local_get_peer(chan);
1072                 if (local_peer) {
1073                         stasis_app_subscribe_channel(args_app, local_peer);
1074                         ast_channel_unref(local_peer);
1075                 }
1076         }
1077
1078         snapshot = ast_channel_snapshot_get_latest(ast_channel_uniqueid(chan));
1079         ast_channel_unlock(chan);
1080
1081         /* Before starting the async dial bump the ref in case the dial quickly goes away and takes
1082          * the reference with it
1083          */
1084         ast_channel_ref(chan);
1085
1086         if (ast_pthread_create_detached(&thread, NULL, ari_originate_dial, dial)) {
1087                 ast_ari_response_alloc_failed(response);
1088                 ast_dial_destroy(dial);
1089                 ast_free(origination);
1090         } else {
1091                 ast_ari_response_ok(response, ast_channel_snapshot_to_json(snapshot, NULL));
1092         }
1093
1094         ast_channel_unref(chan);
1095         return;
1096 }
1097
1098 void ast_ari_channels_originate_with_id(struct ast_variable *headers,
1099         struct ast_ari_channels_originate_with_id_args *args,
1100         struct ast_ari_response *response)
1101 {
1102         RAII_VAR(struct ast_variable *, variables, NULL, ast_variables_destroy);
1103
1104         /* Parse any query parameters out of the body parameter */
1105         if (args->variables) {
1106                 struct ast_json *json_variables;
1107
1108                 ast_ari_channels_originate_with_id_parse_body(args->variables, args);
1109                 json_variables = ast_json_object_get(args->variables, "variables");
1110                 if (json_variables) {
1111                         if (ast_json_to_ast_variables(json_variables, &variables)) {
1112                                 ast_log(AST_LOG_ERROR, "Unable to convert 'variables' in JSON body to channel variables\n");
1113                                 ast_ari_response_alloc_failed(response);
1114                                 return;
1115                         }
1116                 }
1117         }
1118
1119         ari_channels_handle_originate_with_id(
1120                 args->endpoint,
1121                 args->extension,
1122                 args->context,
1123                 args->priority,
1124                 args->label,
1125                 args->app,
1126                 args->app_args,
1127                 args->caller_id,
1128                 args->timeout,
1129                 variables,
1130                 args->channel_id,
1131                 args->other_channel_id,
1132                 args->originator,
1133                 response);
1134 }
1135
1136 void ast_ari_channels_originate(struct ast_variable *headers,
1137         struct ast_ari_channels_originate_args *args,
1138         struct ast_ari_response *response)
1139 {
1140         RAII_VAR(struct ast_variable *, variables, NULL, ast_variables_destroy);
1141
1142         /* Parse any query parameters out of the body parameter */
1143         if (args->variables) {
1144                 struct ast_json *json_variables;
1145
1146                 ast_ari_channels_originate_parse_body(args->variables, args);
1147                 json_variables = ast_json_object_get(args->variables, "variables");
1148                 if (json_variables) {
1149                         if (ast_json_to_ast_variables(json_variables, &variables)) {
1150                                 ast_log(AST_LOG_ERROR, "Unable to convert 'variables' in JSON body to channel variables\n");
1151                                 ast_ari_response_alloc_failed(response);
1152                                 return;
1153                         }
1154                 }
1155         }
1156
1157         ari_channels_handle_originate_with_id(
1158                 args->endpoint,
1159                 args->extension,
1160                 args->context,
1161                 args->priority,
1162                 args->label,
1163                 args->app,
1164                 args->app_args,
1165                 args->caller_id,
1166                 args->timeout,
1167                 variables,
1168                 args->channel_id,
1169                 args->other_channel_id,
1170                 args->originator,
1171                 response);
1172 }
1173
1174 void ast_ari_channels_get_channel_var(struct ast_variable *headers,
1175         struct ast_ari_channels_get_channel_var_args *args,
1176         struct ast_ari_response *response)
1177 {
1178         RAII_VAR(struct ast_json *, json, NULL, ast_json_unref);
1179         RAII_VAR(struct stasis_app_control *, control, NULL, ao2_cleanup);
1180         RAII_VAR(struct ast_str *, value, ast_str_create(32), ast_free);
1181         RAII_VAR(struct ast_channel *, channel, NULL, ast_channel_cleanup);
1182
1183         ast_assert(response != NULL);
1184
1185         if (ast_strlen_zero(args->variable)) {
1186                 ast_ari_response_error(
1187                         response, 400, "Bad Request",
1188                         "Variable name is required");
1189                 return;
1190         }
1191
1192         if (ast_strlen_zero(args->channel_id)) {
1193                 ast_ari_response_error(
1194                         response, 400, "Bad Request",
1195                         "Channel ID is required");
1196                 return;
1197         }
1198
1199         channel = ast_channel_get_by_name(args->channel_id);
1200         if (!channel) {
1201                 ast_ari_response_error(
1202                         response, 404, "Channel Not Found",
1203                         "Provided channel was not found");
1204                 return;
1205         }
1206
1207         /* You may be tempted to lock the channel you're about to read from. You
1208          * would be wrong. Some dialplan functions put the channel into
1209          * autoservice, which deadlocks if the channel is already locked.
1210          * ast_str_retrieve_variable() does its own locking, and the dialplan
1211          * functions need to as well. We should be fine without the lock.
1212          */
1213
1214         if (args->variable[strlen(args->variable) - 1] == ')') {
1215                 if (ast_func_read2(channel, args->variable, &value, 0)) {
1216                         ast_ari_response_error(
1217                                 response, 500, "Error With Function",
1218                                 "Unable to read provided function");
1219                         return;
1220                 }
1221         } else {
1222                 if (!ast_str_retrieve_variable(&value, 0, channel, NULL, args->variable)) {
1223                         ast_ari_response_alloc_failed(response);
1224                         return;
1225                 }
1226         }
1227
1228         if (!(json = ast_json_pack("{s: s}", "value", S_OR(ast_str_buffer(value), "")))) {
1229                 ast_ari_response_alloc_failed(response);
1230                 return;
1231         }
1232
1233         ast_ari_response_ok(response, ast_json_ref(json));
1234 }
1235
1236 void ast_ari_channels_set_channel_var(struct ast_variable *headers,
1237         struct ast_ari_channels_set_channel_var_args *args,
1238         struct ast_ari_response *response)
1239 {
1240         RAII_VAR(struct stasis_app_control *, control, NULL, ao2_cleanup);
1241
1242         ast_assert(response != NULL);
1243
1244         if (ast_strlen_zero(args->variable)) {
1245                 ast_ari_response_error(
1246                         response, 400, "Bad Request",
1247                         "Variable name is required");
1248                 return;
1249         }
1250
1251         control = find_control(response, args->channel_id);
1252         if (control == NULL) {
1253                 /* response filled in by find_control */
1254                 return;
1255         }
1256
1257         if (stasis_app_control_set_channel_var(control, args->variable, args->value)) {
1258                 ast_ari_response_error(
1259                         response, 400, "Bad Request",
1260                         "Failed to execute function");
1261                 return;
1262         }
1263
1264         ast_ari_response_no_content(response);
1265 }
1266
1267 static void ari_channels_handle_snoop_channel(
1268         const char *args_channel_id,
1269         const char *args_spy,
1270         const char *args_whisper,
1271         const char *args_app,
1272         const char *args_app_args,
1273         const char *args_snoop_id,
1274         struct ast_ari_response *response)
1275 {
1276         enum stasis_app_snoop_direction spy, whisper;
1277         RAII_VAR(struct ast_channel *, chan, NULL, ast_channel_cleanup);
1278         RAII_VAR(struct ast_channel *, snoop, NULL, ast_channel_cleanup);
1279         RAII_VAR(struct ast_channel_snapshot *, snapshot, NULL, ao2_cleanup);
1280
1281         ast_assert(response != NULL);
1282
1283         if (ast_strlen_zero(args_spy) || !strcmp(args_spy, "none")) {
1284                 spy = STASIS_SNOOP_DIRECTION_NONE;
1285         } else if (!strcmp(args_spy, "both")) {
1286                 spy = STASIS_SNOOP_DIRECTION_BOTH;
1287         } else if (!strcmp(args_spy, "out")) {
1288                 spy = STASIS_SNOOP_DIRECTION_OUT;
1289         } else if (!strcmp(args_spy, "in")) {
1290                 spy = STASIS_SNOOP_DIRECTION_IN;
1291         } else {
1292                 ast_ari_response_error(
1293                         response, 400, "Bad Request",
1294                         "Invalid direction specified for spy");
1295                 return;
1296         }
1297
1298         if (ast_strlen_zero(args_whisper) || !strcmp(args_whisper, "none")) {
1299                 whisper = STASIS_SNOOP_DIRECTION_NONE;
1300         } else if (!strcmp(args_whisper, "both")) {
1301                 whisper = STASIS_SNOOP_DIRECTION_BOTH;
1302         } else if (!strcmp(args_whisper, "out")) {
1303                 whisper = STASIS_SNOOP_DIRECTION_OUT;
1304         } else if (!strcmp(args_whisper, "in")) {
1305                 whisper = STASIS_SNOOP_DIRECTION_IN;
1306         } else {
1307                 ast_ari_response_error(
1308                         response, 400, "Bad Request",
1309                         "Invalid direction specified for whisper");
1310                 return;
1311         }
1312
1313         if (spy == STASIS_SNOOP_DIRECTION_NONE && whisper == STASIS_SNOOP_DIRECTION_NONE) {
1314                 ast_ari_response_error(
1315                         response, 400, "Bad Request",
1316                         "Direction must be specified for at least spy or whisper");
1317                 return;
1318         } else if (ast_strlen_zero(args_app)) {
1319                 ast_ari_response_error(
1320                         response, 400, "Bad Request",
1321                         "Application name is required");
1322                 return;
1323         }
1324
1325         chan = ast_channel_get_by_name(args_channel_id);
1326         if (chan == NULL) {
1327                 ast_ari_response_error(
1328                         response, 404, "Channel Not Found",
1329                         "Provided channel was not found");
1330                 return;
1331         }
1332
1333         snoop = stasis_app_control_snoop(chan, spy, whisper, args_app, args_app_args,
1334                 args_snoop_id);
1335         if (snoop == NULL) {
1336                 ast_ari_response_error(
1337                         response, 500, "Internal error",
1338                         "Snoop channel could not be created");
1339                 return;
1340         }
1341
1342         snapshot = ast_channel_snapshot_get_latest(ast_channel_uniqueid(snoop));
1343         ast_ari_response_ok(response, ast_channel_snapshot_to_json(snapshot, NULL));
1344 }
1345
1346 void ast_ari_channels_snoop_channel(struct ast_variable *headers,
1347         struct ast_ari_channels_snoop_channel_args *args,
1348         struct ast_ari_response *response)
1349 {
1350         ari_channels_handle_snoop_channel(
1351                 args->channel_id,
1352                 args->spy,
1353                 args->whisper,
1354                 args->app,
1355                 args->app_args,
1356                 args->snoop_id,
1357                 response);
1358 }
1359
1360 void ast_ari_channels_snoop_channel_with_id(struct ast_variable *headers,
1361         struct ast_ari_channels_snoop_channel_with_id_args *args,
1362         struct ast_ari_response *response)
1363 {
1364         ari_channels_handle_snoop_channel(
1365                 args->channel_id,
1366                 args->spy,
1367                 args->whisper,
1368                 args->app,
1369                 args->app_args,
1370                 args->snoop_id,
1371                 response);
1372 }