res/ari/resource_channels: Add missing 'no_answer' reason to DELETE /channels
[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 if (!strcmp(args->reason, "no_answer")) {
708                 cause = AST_CAUSE_NOANSWER;
709         } else {
710                 ast_ari_response_error(
711                         response, 400, "Invalid Reason",
712                         "Invalid reason for hangup provided");
713                 return;
714         }
715
716         ast_channel_hangupcause_set(chan, cause);
717         ast_softhangup(chan, AST_SOFTHANGUP_EXPLICIT);
718
719         ast_ari_response_no_content(response);
720 }
721
722 void ast_ari_channels_list(struct ast_variable *headers,
723         struct ast_ari_channels_list_args *args,
724         struct ast_ari_response *response)
725 {
726         RAII_VAR(struct stasis_cache *, cache, NULL, ao2_cleanup);
727         RAII_VAR(struct ao2_container *, snapshots, NULL, ao2_cleanup);
728         RAII_VAR(struct ast_json *, json, NULL, ast_json_unref);
729         struct ao2_iterator i;
730         void *obj;
731         struct stasis_message_sanitizer *sanitize = stasis_app_get_sanitizer();
732
733         cache = ast_channel_cache();
734         if (!cache) {
735                 ast_ari_response_error(
736                         response, 500, "Internal Server Error",
737                         "Message bus not initialized");
738                 return;
739         }
740         ao2_ref(cache, +1);
741
742         snapshots = stasis_cache_dump(cache, ast_channel_snapshot_type());
743         if (!snapshots) {
744                 ast_ari_response_alloc_failed(response);
745                 return;
746         }
747
748         json = ast_json_array_create();
749         if (!json) {
750                 ast_ari_response_alloc_failed(response);
751                 return;
752         }
753
754         i = ao2_iterator_init(snapshots, 0);
755         while ((obj = ao2_iterator_next(&i))) {
756                 RAII_VAR(struct stasis_message *, msg, obj, ao2_cleanup);
757                 struct ast_channel_snapshot *snapshot = stasis_message_data(msg);
758                 int r;
759
760                 if (sanitize && sanitize->channel_snapshot
761                         && sanitize->channel_snapshot(snapshot)) {
762                         continue;
763                 }
764
765                 r = ast_json_array_append(
766                         json, ast_channel_snapshot_to_json(snapshot, NULL));
767                 if (r != 0) {
768                         ast_ari_response_alloc_failed(response);
769                         ao2_iterator_destroy(&i);
770                         return;
771                 }
772         }
773         ao2_iterator_destroy(&i);
774
775         ast_ari_response_ok(response, ast_json_ref(json));
776 }
777
778 /*! \brief Structure used for origination */
779 struct ari_origination {
780         /*! \brief Dialplan context */
781         char context[AST_MAX_CONTEXT];
782         /*! \brief Dialplan extension */
783         char exten[AST_MAX_EXTENSION];
784         /*! \brief Dialplan priority */
785         int priority;
786         /*! \brief Application data to pass to Stasis application */
787         char appdata[0];
788 };
789
790 /*! \brief Thread which dials and executes upon answer */
791 static void *ari_originate_dial(void *data)
792 {
793         struct ast_dial *dial = data;
794         struct ari_origination *origination = ast_dial_get_user_data(dial);
795         enum ast_dial_result res;
796
797         res = ast_dial_run(dial, NULL, 0);
798         if (res != AST_DIAL_RESULT_ANSWERED) {
799                 goto end;
800         }
801
802         if (!ast_strlen_zero(origination->appdata)) {
803                 struct ast_app *app = pbx_findapp("Stasis");
804
805                 if (app) {
806                         ast_verb(4, "Launching Stasis(%s) on %s\n", origination->appdata,
807                                 ast_channel_name(ast_dial_answered(dial)));
808                         pbx_exec(ast_dial_answered(dial), app, origination->appdata);
809                 } else {
810                         ast_log(LOG_WARNING, "No such application 'Stasis'\n");
811                 }
812         } else {
813                 struct ast_channel *answered = ast_dial_answered(dial);
814
815                 if (!ast_strlen_zero(origination->context)) {
816                         ast_channel_context_set(answered, origination->context);
817                 }
818
819                 if (!ast_strlen_zero(origination->exten)) {
820                         ast_channel_exten_set(answered, origination->exten);
821                 }
822
823                 if (origination->priority > 0) {
824                         ast_channel_priority_set(answered, origination->priority);
825                 }
826
827                 if (ast_pbx_run(answered)) {
828                         ast_log(LOG_ERROR, "Failed to start PBX on %s\n", ast_channel_name(answered));
829                 } else {
830                         /* PBX will have taken care of hanging up, so we steal the answered channel so dial doesn't do it */
831                         ast_dial_answered_steal(dial);
832                 }
833         }
834
835 end:
836         ast_dial_destroy(dial);
837         ast_free(origination);
838         return NULL;
839 }
840
841 static void ari_channels_handle_originate_with_id(const char *args_endpoint,
842         const char *args_extension,
843         const char *args_context,
844         long args_priority,
845         const char *args_label,
846         const char *args_app,
847         const char *args_app_args,
848         const char *args_caller_id,
849         int args_timeout,
850         struct ast_variable *variables,
851         const char *args_channel_id,
852         const char *args_other_channel_id,
853         const char *args_originator,
854         struct ast_ari_response *response)
855 {
856         char *dialtech;
857         char dialdevice[AST_CHANNEL_NAME];
858         struct ast_dial *dial;
859         char *caller_id = NULL;
860         char *cid_num = NULL;
861         char *cid_name = NULL;
862         RAII_VAR(struct ast_format_cap *, cap,
863                 ast_format_cap_alloc(AST_FORMAT_CAP_FLAG_DEFAULT), ao2_cleanup);
864         char *stuff;
865         struct ast_channel *other = NULL;
866         struct ast_channel *chan = NULL;
867         RAII_VAR(struct ast_channel_snapshot *, snapshot, NULL, ao2_cleanup);
868         struct ast_assigned_ids assignedids = {
869                 .uniqueid = args_channel_id,
870                 .uniqueid2 = args_other_channel_id,
871         };
872         struct ari_origination *origination;
873         pthread_t thread;
874
875         if (!cap) {
876                 ast_ari_response_alloc_failed(response);
877                 return;
878         }
879         ast_format_cap_append(cap, ast_format_slin, 0);
880
881         if ((assignedids.uniqueid && AST_MAX_PUBLIC_UNIQUEID < strlen(assignedids.uniqueid))
882                 || (assignedids.uniqueid2 && AST_MAX_PUBLIC_UNIQUEID < strlen(assignedids.uniqueid2))) {
883                 ast_ari_response_error(response, 400, "Bad Request",
884                         "Uniqueid length exceeds maximum of %d", AST_MAX_PUBLIC_UNIQUEID);
885                 return;
886         }
887
888         if (ast_strlen_zero(args_endpoint)) {
889                 ast_ari_response_error(response, 400, "Bad Request",
890                         "Endpoint must be specified");
891                 return;
892         }
893
894         dialtech = ast_strdupa(args_endpoint);
895         if ((stuff = strchr(dialtech, '/'))) {
896                 *stuff++ = '\0';
897                 ast_copy_string(dialdevice, stuff, sizeof(dialdevice));
898         }
899
900         if (ast_strlen_zero(dialtech) || ast_strlen_zero(dialdevice)) {
901                 ast_ari_response_error(response, 400, "Bad Request",
902                         "Invalid endpoint specified");
903                 return;
904         }
905
906         if (!ast_strlen_zero(args_app)) {
907                 RAII_VAR(struct ast_str *, appdata, ast_str_create(64), ast_free);
908
909                 if (!appdata) {
910                         ast_ari_response_alloc_failed(response);
911                         return;
912                 }
913
914                 ast_str_set(&appdata, 0, "%s", args_app);
915                 if (!ast_strlen_zero(args_app_args)) {
916                         ast_str_append(&appdata, 0, ",%s", args_app_args);
917                 }
918
919                 origination = ast_calloc(1, sizeof(*origination) + ast_str_size(appdata) + 1);
920                 if (!origination) {
921                         ast_ari_response_alloc_failed(response);
922                         return;
923                 }
924
925                 strcpy(origination->appdata, ast_str_buffer(appdata));
926         } else if (!ast_strlen_zero(args_extension)) {
927                 origination = ast_calloc(1, sizeof(*origination) + 1);
928                 if (!origination) {
929                         ast_ari_response_alloc_failed(response);
930                         return;
931                 }
932
933                 ast_copy_string(origination->context, S_OR(args_context, "default"), sizeof(origination->context));
934                 ast_copy_string(origination->exten, args_extension, sizeof(origination->exten));
935
936                 if (!ast_strlen_zero(args_label)) {
937                         /* A label was provided in the request, use that */
938                         int ipri = 1;
939                         if (sscanf(args_label, "%30d", &ipri) != 1) {
940                                 ipri = ast_findlabel_extension(chan, origination->context, origination->exten, args_label, args_caller_id);
941
942                                 if (ipri == -1) {
943                                         ast_log(AST_LOG_ERROR, "Requested label: %s can not be found in context: %s\n", args_label, args_context);
944                                         ast_ari_response_error(response, 404, "Not Found", "Requested label can not be found");
945                                         return;
946                                 }
947                         } else {
948                                 ast_debug(3, "Numeric value provided for label, jumping to that priority\n");
949                         }
950
951                         if (ipri == 0) {
952                                 ast_log(AST_LOG_ERROR, "Invalid priority label '%s' specified for extension %s in context: %s\n",
953                                                 args_label, args_extension, args_context);
954                                 ast_ari_response_error(response, 400, "Bad Request", "Requested priority is illegal");
955                                 return;
956                         }
957
958                         /* Our priority was provided by a label */
959                         origination->priority =  ipri;
960                 } else {
961                         /* No label provided, use provided priority */
962                         origination->priority = args_priority ? args_priority : 1;
963                 }
964
965                 origination->appdata[0] = '\0';
966         } else {
967                 ast_ari_response_error(response, 400, "Bad Request",
968                         "Application or extension must be specified");
969                 return;
970         }
971
972         dial = ast_dial_create();
973         if (!dial) {
974                 ast_ari_response_alloc_failed(response);
975                 ast_free(origination);
976                 return;
977         }
978         ast_dial_set_user_data(dial, origination);
979
980         if (ast_dial_append(dial, dialtech, dialdevice, &assignedids)) {
981                 ast_ari_response_alloc_failed(response);
982                 ast_dial_destroy(dial);
983                 ast_free(origination);
984                 return;
985         }
986
987         if (args_timeout > 0) {
988                 ast_dial_set_global_timeout(dial, args_timeout * 1000);
989         } else if (args_timeout == -1) {
990                 ast_dial_set_global_timeout(dial, -1);
991         } else {
992                 ast_dial_set_global_timeout(dial, 30000);
993         }
994
995         if (!ast_strlen_zero(args_caller_id)) {
996                 caller_id = ast_strdupa(args_caller_id);
997                 ast_callerid_parse(caller_id, &cid_name, &cid_num);
998
999                 if (ast_is_shrinkable_phonenumber(cid_num)) {
1000                         ast_shrink_phone_number(cid_num);
1001                 }
1002         }
1003
1004         if (!ast_strlen_zero(args_originator)) {
1005                 other = ast_channel_get_by_name(args_originator);
1006                 if (!other) {
1007                         ast_ari_response_error(
1008                                 response, 400, "Bad Request",
1009                                 "Provided originator channel was not found");
1010                         ast_dial_destroy(dial);
1011                         ast_free(origination);
1012                         return;
1013                 }
1014         }
1015
1016         if (ast_dial_prerun(dial, other, cap)) {
1017                 ast_ari_response_alloc_failed(response);
1018                 ast_dial_destroy(dial);
1019                 ast_free(origination);
1020                 ast_channel_cleanup(other);
1021                 return;
1022         }
1023
1024         ast_channel_cleanup(other);
1025
1026         chan = ast_dial_get_channel(dial, 0);
1027         if (!chan) {
1028                 ast_ari_response_alloc_failed(response);
1029                 ast_dial_destroy(dial);
1030                 ast_free(origination);
1031                 return;
1032         }
1033
1034         if (!ast_strlen_zero(cid_num) || !ast_strlen_zero(cid_name)) {
1035                 struct ast_party_connected_line connected;
1036
1037                 /*
1038                  * It seems strange to set the CallerID on an outgoing call leg
1039                  * to whom we are calling, but this function's callers are doing
1040                  * various Originate methods.  This call leg goes to the local
1041                  * user.  Once the called party answers, the dialplan needs to
1042                  * be able to access the CallerID from the CALLERID function as
1043                  * if the called party had placed this call.
1044                  */
1045                 ast_set_callerid(chan, cid_num, cid_name, cid_num);
1046
1047                 ast_party_connected_line_set_init(&connected, ast_channel_connected(chan));
1048                 if (!ast_strlen_zero(cid_num)) {
1049                         connected.id.number.valid = 1;
1050                         connected.id.number.str = (char *) cid_num;
1051                         connected.id.number.presentation = AST_PRES_ALLOWED_USER_NUMBER_NOT_SCREENED;
1052                 }
1053                 if (!ast_strlen_zero(cid_name)) {
1054                         connected.id.name.valid = 1;
1055                         connected.id.name.str = (char *) cid_name;
1056                         connected.id.name.presentation = AST_PRES_ALLOWED_USER_NUMBER_NOT_SCREENED;
1057                 }
1058                 ast_channel_set_connected_line(chan, &connected, NULL);
1059         }
1060
1061         ast_channel_lock(chan);
1062         if (variables) {
1063                 ast_set_variables(chan, variables);
1064         }
1065         ast_set_flag(ast_channel_flags(chan), AST_FLAG_ORIGINATED);
1066
1067         if (!ast_strlen_zero(args_app)) {
1068                 struct ast_channel *local_peer;
1069
1070                 stasis_app_subscribe_channel(args_app, chan);
1071
1072                 /* Subscribe to the Local channel peer also. */
1073                 local_peer = ast_local_get_peer(chan);
1074                 if (local_peer) {
1075                         stasis_app_subscribe_channel(args_app, local_peer);
1076                         ast_channel_unref(local_peer);
1077                 }
1078         }
1079
1080         snapshot = ast_channel_snapshot_get_latest(ast_channel_uniqueid(chan));
1081         ast_channel_unlock(chan);
1082
1083         /* Before starting the async dial bump the ref in case the dial quickly goes away and takes
1084          * the reference with it
1085          */
1086         ast_channel_ref(chan);
1087
1088         if (ast_pthread_create_detached(&thread, NULL, ari_originate_dial, dial)) {
1089                 ast_ari_response_alloc_failed(response);
1090                 ast_dial_destroy(dial);
1091                 ast_free(origination);
1092         } else {
1093                 ast_ari_response_ok(response, ast_channel_snapshot_to_json(snapshot, NULL));
1094         }
1095
1096         ast_channel_unref(chan);
1097         return;
1098 }
1099
1100 void ast_ari_channels_originate_with_id(struct ast_variable *headers,
1101         struct ast_ari_channels_originate_with_id_args *args,
1102         struct ast_ari_response *response)
1103 {
1104         RAII_VAR(struct ast_variable *, variables, NULL, ast_variables_destroy);
1105
1106         /* Parse any query parameters out of the body parameter */
1107         if (args->variables) {
1108                 struct ast_json *json_variables;
1109
1110                 ast_ari_channels_originate_with_id_parse_body(args->variables, args);
1111                 json_variables = ast_json_object_get(args->variables, "variables");
1112                 if (json_variables) {
1113                         if (ast_json_to_ast_variables(json_variables, &variables)) {
1114                                 ast_log(AST_LOG_ERROR, "Unable to convert 'variables' in JSON body to channel variables\n");
1115                                 ast_ari_response_alloc_failed(response);
1116                                 return;
1117                         }
1118                 }
1119         }
1120
1121         ari_channels_handle_originate_with_id(
1122                 args->endpoint,
1123                 args->extension,
1124                 args->context,
1125                 args->priority,
1126                 args->label,
1127                 args->app,
1128                 args->app_args,
1129                 args->caller_id,
1130                 args->timeout,
1131                 variables,
1132                 args->channel_id,
1133                 args->other_channel_id,
1134                 args->originator,
1135                 response);
1136 }
1137
1138 void ast_ari_channels_originate(struct ast_variable *headers,
1139         struct ast_ari_channels_originate_args *args,
1140         struct ast_ari_response *response)
1141 {
1142         RAII_VAR(struct ast_variable *, variables, NULL, ast_variables_destroy);
1143
1144         /* Parse any query parameters out of the body parameter */
1145         if (args->variables) {
1146                 struct ast_json *json_variables;
1147
1148                 ast_ari_channels_originate_parse_body(args->variables, args);
1149                 json_variables = ast_json_object_get(args->variables, "variables");
1150                 if (json_variables) {
1151                         if (ast_json_to_ast_variables(json_variables, &variables)) {
1152                                 ast_log(AST_LOG_ERROR, "Unable to convert 'variables' in JSON body to channel variables\n");
1153                                 ast_ari_response_alloc_failed(response);
1154                                 return;
1155                         }
1156                 }
1157         }
1158
1159         ari_channels_handle_originate_with_id(
1160                 args->endpoint,
1161                 args->extension,
1162                 args->context,
1163                 args->priority,
1164                 args->label,
1165                 args->app,
1166                 args->app_args,
1167                 args->caller_id,
1168                 args->timeout,
1169                 variables,
1170                 args->channel_id,
1171                 args->other_channel_id,
1172                 args->originator,
1173                 response);
1174 }
1175
1176 void ast_ari_channels_get_channel_var(struct ast_variable *headers,
1177         struct ast_ari_channels_get_channel_var_args *args,
1178         struct ast_ari_response *response)
1179 {
1180         RAII_VAR(struct ast_json *, json, NULL, ast_json_unref);
1181         RAII_VAR(struct stasis_app_control *, control, NULL, ao2_cleanup);
1182         RAII_VAR(struct ast_str *, value, ast_str_create(32), ast_free);
1183         RAII_VAR(struct ast_channel *, channel, NULL, ast_channel_cleanup);
1184
1185         ast_assert(response != NULL);
1186
1187         if (ast_strlen_zero(args->variable)) {
1188                 ast_ari_response_error(
1189                         response, 400, "Bad Request",
1190                         "Variable name is required");
1191                 return;
1192         }
1193
1194         if (ast_strlen_zero(args->channel_id)) {
1195                 ast_ari_response_error(
1196                         response, 400, "Bad Request",
1197                         "Channel ID is required");
1198                 return;
1199         }
1200
1201         channel = ast_channel_get_by_name(args->channel_id);
1202         if (!channel) {
1203                 ast_ari_response_error(
1204                         response, 404, "Channel Not Found",
1205                         "Provided channel was not found");
1206                 return;
1207         }
1208
1209         /* You may be tempted to lock the channel you're about to read from. You
1210          * would be wrong. Some dialplan functions put the channel into
1211          * autoservice, which deadlocks if the channel is already locked.
1212          * ast_str_retrieve_variable() does its own locking, and the dialplan
1213          * functions need to as well. We should be fine without the lock.
1214          */
1215
1216         if (args->variable[strlen(args->variable) - 1] == ')') {
1217                 if (ast_func_read2(channel, args->variable, &value, 0)) {
1218                         ast_ari_response_error(
1219                                 response, 500, "Error With Function",
1220                                 "Unable to read provided function");
1221                         return;
1222                 }
1223         } else {
1224                 if (!ast_str_retrieve_variable(&value, 0, channel, NULL, args->variable)) {
1225                         ast_ari_response_alloc_failed(response);
1226                         return;
1227                 }
1228         }
1229
1230         if (!(json = ast_json_pack("{s: s}", "value", S_OR(ast_str_buffer(value), "")))) {
1231                 ast_ari_response_alloc_failed(response);
1232                 return;
1233         }
1234
1235         ast_ari_response_ok(response, ast_json_ref(json));
1236 }
1237
1238 void ast_ari_channels_set_channel_var(struct ast_variable *headers,
1239         struct ast_ari_channels_set_channel_var_args *args,
1240         struct ast_ari_response *response)
1241 {
1242         RAII_VAR(struct stasis_app_control *, control, NULL, ao2_cleanup);
1243
1244         ast_assert(response != NULL);
1245
1246         if (ast_strlen_zero(args->variable)) {
1247                 ast_ari_response_error(
1248                         response, 400, "Bad Request",
1249                         "Variable name is required");
1250                 return;
1251         }
1252
1253         control = find_control(response, args->channel_id);
1254         if (control == NULL) {
1255                 /* response filled in by find_control */
1256                 return;
1257         }
1258
1259         if (stasis_app_control_set_channel_var(control, args->variable, args->value)) {
1260                 ast_ari_response_error(
1261                         response, 400, "Bad Request",
1262                         "Failed to execute function");
1263                 return;
1264         }
1265
1266         ast_ari_response_no_content(response);
1267 }
1268
1269 static void ari_channels_handle_snoop_channel(
1270         const char *args_channel_id,
1271         const char *args_spy,
1272         const char *args_whisper,
1273         const char *args_app,
1274         const char *args_app_args,
1275         const char *args_snoop_id,
1276         struct ast_ari_response *response)
1277 {
1278         enum stasis_app_snoop_direction spy, whisper;
1279         RAII_VAR(struct ast_channel *, chan, NULL, ast_channel_cleanup);
1280         RAII_VAR(struct ast_channel *, snoop, NULL, ast_channel_cleanup);
1281         RAII_VAR(struct ast_channel_snapshot *, snapshot, NULL, ao2_cleanup);
1282
1283         ast_assert(response != NULL);
1284
1285         if (ast_strlen_zero(args_spy) || !strcmp(args_spy, "none")) {
1286                 spy = STASIS_SNOOP_DIRECTION_NONE;
1287         } else if (!strcmp(args_spy, "both")) {
1288                 spy = STASIS_SNOOP_DIRECTION_BOTH;
1289         } else if (!strcmp(args_spy, "out")) {
1290                 spy = STASIS_SNOOP_DIRECTION_OUT;
1291         } else if (!strcmp(args_spy, "in")) {
1292                 spy = STASIS_SNOOP_DIRECTION_IN;
1293         } else {
1294                 ast_ari_response_error(
1295                         response, 400, "Bad Request",
1296                         "Invalid direction specified for spy");
1297                 return;
1298         }
1299
1300         if (ast_strlen_zero(args_whisper) || !strcmp(args_whisper, "none")) {
1301                 whisper = STASIS_SNOOP_DIRECTION_NONE;
1302         } else if (!strcmp(args_whisper, "both")) {
1303                 whisper = STASIS_SNOOP_DIRECTION_BOTH;
1304         } else if (!strcmp(args_whisper, "out")) {
1305                 whisper = STASIS_SNOOP_DIRECTION_OUT;
1306         } else if (!strcmp(args_whisper, "in")) {
1307                 whisper = STASIS_SNOOP_DIRECTION_IN;
1308         } else {
1309                 ast_ari_response_error(
1310                         response, 400, "Bad Request",
1311                         "Invalid direction specified for whisper");
1312                 return;
1313         }
1314
1315         if (spy == STASIS_SNOOP_DIRECTION_NONE && whisper == STASIS_SNOOP_DIRECTION_NONE) {
1316                 ast_ari_response_error(
1317                         response, 400, "Bad Request",
1318                         "Direction must be specified for at least spy or whisper");
1319                 return;
1320         } else if (ast_strlen_zero(args_app)) {
1321                 ast_ari_response_error(
1322                         response, 400, "Bad Request",
1323                         "Application name is required");
1324                 return;
1325         }
1326
1327         chan = ast_channel_get_by_name(args_channel_id);
1328         if (chan == NULL) {
1329                 ast_ari_response_error(
1330                         response, 404, "Channel Not Found",
1331                         "Provided channel was not found");
1332                 return;
1333         }
1334
1335         snoop = stasis_app_control_snoop(chan, spy, whisper, args_app, args_app_args,
1336                 args_snoop_id);
1337         if (snoop == NULL) {
1338                 ast_ari_response_error(
1339                         response, 500, "Internal error",
1340                         "Snoop channel could not be created");
1341                 return;
1342         }
1343
1344         snapshot = ast_channel_snapshot_get_latest(ast_channel_uniqueid(snoop));
1345         ast_ari_response_ok(response, ast_channel_snapshot_to_json(snapshot, NULL));
1346 }
1347
1348 void ast_ari_channels_snoop_channel(struct ast_variable *headers,
1349         struct ast_ari_channels_snoop_channel_args *args,
1350         struct ast_ari_response *response)
1351 {
1352         ari_channels_handle_snoop_channel(
1353                 args->channel_id,
1354                 args->spy,
1355                 args->whisper,
1356                 args->app,
1357                 args->app_args,
1358                 args->snoop_id,
1359                 response);
1360 }
1361
1362 void ast_ari_channels_snoop_channel_with_id(struct ast_variable *headers,
1363         struct ast_ari_channels_snoop_channel_with_id_args *args,
1364         struct ast_ari_response *response)
1365 {
1366         ari_channels_handle_snoop_channel(
1367                 args->channel_id,
1368                 args->spy,
1369                 args->whisper,
1370                 args->app,
1371                 args->app_args,
1372                 args->snoop_id,
1373                 response);
1374 }