Merge "func_jitterbuffer: Add audio/video sync support."
[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         <support_level>core</support_level>
28  ***/
29
30 #include "asterisk.h"
31
32 #include "asterisk/file.h"
33 #include "asterisk/pbx.h"
34 #include "asterisk/bridge.h"
35 #include "asterisk/callerid.h"
36 #include "asterisk/stasis_app.h"
37 #include "asterisk/stasis_app_playback.h"
38 #include "asterisk/stasis_app_recording.h"
39 #include "asterisk/stasis_app_snoop.h"
40 #include "asterisk/stasis_channels.h"
41 #include "asterisk/causes.h"
42 #include "asterisk/format_cache.h"
43 #include "asterisk/core_local.h"
44 #include "asterisk/dial.h"
45 #include "asterisk/max_forwards.h"
46 #include "asterisk/rtp_engine.h"
47 #include "resource_channels.h"
48
49 #include <limits.h>
50
51
52 /*! \brief Return the corresponded hangup code of the given reason */
53 static int convert_reason_to_hangup_code(const char* reason)
54 {
55         if (!strcmp(reason, "normal")) {
56                 return AST_CAUSE_NORMAL;
57         } else if (!strcmp(reason, "busy")) {
58                 return AST_CAUSE_BUSY;
59         } else if (!strcmp(reason, "congestion")) {
60                 return AST_CAUSE_CONGESTION;
61         } else if (!strcmp(reason, "no_answer")) {
62                 return AST_CAUSE_NOANSWER;
63         } else if (!strcmp(reason, "timeout")) {
64                 return AST_CAUSE_NO_USER_RESPONSE;
65         } else if (!strcmp(reason, "rejected")) {
66                 return AST_CAUSE_CALL_REJECTED;
67         } else if (!strcmp(reason, "unallocated")) {
68                 return AST_CAUSE_UNALLOCATED;
69         } else if (!strcmp(reason, "normal_unspecified")) {
70                 return AST_CAUSE_NORMAL_UNSPECIFIED;
71         } else if (!strcmp(reason, "number_incomplete")) {
72                 return AST_CAUSE_INVALID_NUMBER_FORMAT;
73         } else if (!strcmp(reason, "codec_mismatch")) {
74                 return AST_CAUSE_BEARERCAPABILITY_NOTAVAIL;
75         } else if (!strcmp(reason, "interworking")) {
76                 return AST_CAUSE_INTERWORKING;
77         } else if (!strcmp(reason, "failure")) {
78                 return AST_CAUSE_FAILURE;
79         } else if(!strcmp(reason, "answered_elsewhere")) {
80                 return AST_CAUSE_ANSWERED_ELSEWHERE;
81         }
82
83         return -1;
84 }
85
86 /*!
87  * \brief Ensure channel is in a state that allows operation to be performed.
88  *
89  * Since Asterisk 14, it has been possible for down channels, as well as unanswered
90  * outbound channels to enter Stasis. While some operations are fine to perform on
91  * such channels, operations that
92  *
93  * - Attempt to manipulate channel state
94  * - Attempt to play media
95  * - Attempt to control the channel's location in the dialplan
96  *
97  * are invalid. This function can be used to determine if the channel is in an
98  * appropriate state.
99  *
100  * \note When this function returns an error, the HTTP response is taken care of.
101  *
102  * \param control The app control
103  * \param response Response to fill in if there is an error
104  *
105  * \retval 0 Channel is in a valid state. Continue on!
106  * \retval non-zero Channel is in an invalid state. Bail!
107  */
108 static int channel_state_invalid(struct stasis_app_control *control,
109         struct ast_ari_response *response)
110 {
111         struct ast_channel_snapshot *snapshot;
112
113         snapshot = stasis_app_control_get_snapshot(control);
114         if (!snapshot) {
115                 ast_ari_response_error(response, 404, "Not Found", "Channel not found");
116                 return -1;
117         }
118
119         /* These channel states apply only to outbound channels:
120          * - Down: Channel has been created, and nothing else has been done
121          * - Reserved: For a PRI, an underlying B-channel is reserved,
122          *   but the channel is not yet dialed
123          * - Ringing: The channel has been dialed.
124          *
125          * This does not affect inbound channels. Inbound channels, when they
126          * enter the dialplan, are in the "Ring" state. If they have already
127          * been answered, then they are in the "Up" state.
128          */
129         if (snapshot->state == AST_STATE_DOWN
130                 || snapshot->state == AST_STATE_RESERVED
131                 || snapshot->state == AST_STATE_RINGING) {
132                 ast_ari_response_error(response, 412, "Precondition Failed",
133                         "Channel in invalid state");
134                 ao2_ref(snapshot, -1);
135
136                 return -1;
137         }
138
139         ao2_ref(snapshot, -1);
140
141         return 0;
142 }
143
144 /*!
145  * \brief Finds the control object for a channel, filling the response with an
146  * error, if appropriate.
147  * \param[out] response Response to fill with an error if control is not found.
148  * \param channel_id ID of the channel to lookup.
149  * \return Channel control object.
150  * \return \c NULL if control object does not exist.
151  */
152 static struct stasis_app_control *find_control(
153         struct ast_ari_response *response,
154         const char *channel_id)
155 {
156         RAII_VAR(struct stasis_app_control *, control, NULL, ao2_cleanup);
157
158         ast_assert(response != NULL);
159
160         control = stasis_app_control_find_by_channel_id(channel_id);
161         if (control == NULL) {
162                 /* Distinguish between 404 and 409 errors */
163                 RAII_VAR(struct ast_channel *, chan, NULL, ao2_cleanup);
164                 chan = ast_channel_get_by_name(channel_id);
165                 if (chan == NULL) {
166                         ast_ari_response_error(response, 404, "Not Found",
167                                    "Channel not found");
168                         return NULL;
169                 }
170
171                 ast_ari_response_error(response, 409, "Conflict",
172                            "Channel not in Stasis application");
173                 return NULL;
174         }
175
176         ao2_ref(control, +1);
177         return control;
178 }
179
180 void ast_ari_channels_continue_in_dialplan(
181         struct ast_variable *headers,
182         struct ast_ari_channels_continue_in_dialplan_args *args,
183         struct ast_ari_response *response)
184 {
185         RAII_VAR(struct stasis_app_control *, control, NULL, ao2_cleanup);
186         RAII_VAR(struct ast_channel_snapshot *, snapshot, NULL, ao2_cleanup);
187         int ipri;
188         const char *context;
189         const char *exten;
190
191         ast_assert(response != NULL);
192
193         control = find_control(response, args->channel_id);
194         if (control == NULL) {
195                 return;
196         }
197
198         if (channel_state_invalid(control, response)) {
199                 return;
200         }
201
202         snapshot = stasis_app_control_get_snapshot(control);
203         if (!snapshot) {
204                 ast_ari_response_error(response, 404, "Not Found", "Channel not found");
205                 return;
206         }
207
208         if (ast_strlen_zero(args->context)) {
209                 context = snapshot->dialplan->context;
210                 exten = S_OR(args->extension, snapshot->dialplan->exten);
211         } else {
212                 context = args->context;
213                 exten = S_OR(args->extension, "s");
214         }
215
216         if (!ast_strlen_zero(args->label)) {
217                 /* A label was provided in the request, use that */
218
219                 if (sscanf(args->label, "%30d", &ipri) != 1) {
220                         ipri = ast_findlabel_extension(NULL, context, exten, args->label, NULL);
221                         if (ipri == -1) {
222                                 ast_log(AST_LOG_ERROR, "Requested label: %s can not be found in context: %s\n", args->label, context);
223                                 ast_ari_response_error(response, 404, "Not Found", "Requested label can not be found");
224                                 return;
225                         }
226                 } else {
227                         ast_debug(3, "Numeric value provided for label, jumping to that priority\n");
228                 }
229
230                 if (ipri == 0) {
231                         ast_log(AST_LOG_ERROR, "Invalid priority label '%s' specified for extension %s in context: %s\n",
232                                         args->label, exten, context);
233                         ast_ari_response_error(response, 400, "Bad Request", "Requested priority is illegal");
234                         return;
235                 }
236
237         } else if (args->priority) {
238                 /* No label provided, use provided priority */
239                 ipri = args->priority;
240         } else if (ast_strlen_zero(args->context) && ast_strlen_zero(args->extension)) {
241                 /* Special case. No exten, context, or priority provided, then move on to the next priority */
242                 ipri = snapshot->dialplan->priority + 1;
243         } else {
244                 ipri = 1;
245         }
246
247
248         if (stasis_app_control_continue(control, context, exten, ipri)) {
249                 ast_ari_response_alloc_failed(response);
250                 return;
251         }
252
253         ast_ari_response_no_content(response);
254 }
255
256 void ast_ari_channels_move(struct ast_variable *headers,
257         struct ast_ari_channels_move_args *args,
258         struct ast_ari_response *response)
259 {
260         RAII_VAR(struct stasis_app_control *, control, NULL, ao2_cleanup);
261
262         control = find_control(response, args->channel_id);
263         if (!control) {
264                 return;
265         }
266
267         if (stasis_app_control_move(control, args->app, args->app_args)) {
268                 ast_ari_response_error(response, 500, "Internal Server Error",
269                         "Failed to switch Stasis applications");
270                 return;
271         }
272
273         ast_ari_response_no_content(response);
274 }
275
276 void ast_ari_channels_redirect(struct ast_variable *headers,
277         struct ast_ari_channels_redirect_args *args,
278         struct ast_ari_response *response)
279 {
280         RAII_VAR(struct stasis_app_control *, control, NULL, ao2_cleanup);
281         RAII_VAR(struct ast_channel_snapshot *, chan_snapshot, NULL, ao2_cleanup);
282         char *tech;
283         char *resource;
284         int tech_len;
285
286         control = find_control(response, args->channel_id);
287         if (!control) {
288                 return;
289         }
290
291         if (channel_state_invalid(control, response)) {
292                 return;
293         }
294
295         if (ast_strlen_zero(args->endpoint)) {
296                 ast_ari_response_error(response, 400, "Not Found",
297                         "Required parameter 'endpoint' not provided.");
298                 return;
299         }
300
301         tech = ast_strdupa(args->endpoint);
302         if (!(resource = strchr(tech, '/')) || !(tech_len = resource - tech)) {
303                 ast_ari_response_error(response, 422, "Unprocessable Entity",
304                         "Endpoint parameter '%s' does not contain tech/resource", args->endpoint);
305                 return;
306         }
307
308         *resource++ = '\0';
309         if (ast_strlen_zero(resource)) {
310                 ast_ari_response_error(response, 422, "Unprocessable Entity",
311                         "No resource provided in endpoint parameter '%s'", args->endpoint);
312                 return;
313         }
314
315         chan_snapshot = ast_channel_snapshot_get_latest(args->channel_id);
316         if (!chan_snapshot) {
317                 ast_ari_response_error(response, 500, "Internal Server Error",
318                         "Unable to find channel snapshot for '%s'", args->channel_id);
319                 return;
320         }
321
322         if (strncasecmp(chan_snapshot->base->type, tech, tech_len)) {
323                 ast_ari_response_error(response, 422, "Unprocessable Entity",
324                         "Endpoint technology '%s' does not match channel technology '%s'",
325                         tech, chan_snapshot->base->type);
326                 return;
327         }
328
329         if (stasis_app_control_redirect(control, resource)) {
330                 ast_ari_response_error(response, 500, "Internal Server Error",
331                         "Failed to redirect channel");
332                 return;
333         }
334
335         ast_ari_response_no_content(response);
336 }
337
338 void ast_ari_channels_answer(struct ast_variable *headers,
339         struct ast_ari_channels_answer_args *args,
340         struct ast_ari_response *response)
341 {
342         RAII_VAR(struct stasis_app_control *, control, NULL, ao2_cleanup);
343
344         control = find_control(response, args->channel_id);
345         if (control == NULL) {
346                 return;
347         }
348
349         if (channel_state_invalid(control, response)) {
350                 return;
351         }
352
353         if (stasis_app_control_answer(control) != 0) {
354                 ast_ari_response_error(
355                         response, 500, "Internal Server Error",
356                         "Failed to answer channel");
357                 return;
358         }
359
360         ast_ari_response_no_content(response);
361 }
362
363 void ast_ari_channels_ring(struct ast_variable *headers,
364         struct ast_ari_channels_ring_args *args,
365         struct ast_ari_response *response)
366 {
367         RAII_VAR(struct stasis_app_control *, control, NULL, ao2_cleanup);
368
369         control = find_control(response, args->channel_id);
370         if (control == NULL) {
371                 return;
372         }
373
374         if (channel_state_invalid(control, response)) {
375                 return;
376         }
377
378         stasis_app_control_ring(control);
379
380         ast_ari_response_no_content(response);
381 }
382
383 void ast_ari_channels_ring_stop(struct ast_variable *headers,
384         struct ast_ari_channels_ring_stop_args *args,
385         struct ast_ari_response *response)
386 {
387         RAII_VAR(struct stasis_app_control *, control, NULL, ao2_cleanup);
388
389         control = find_control(response, args->channel_id);
390         if (control == NULL) {
391                 return;
392         }
393
394         if (channel_state_invalid(control, response)) {
395                 return;
396         }
397
398         stasis_app_control_ring_stop(control);
399
400         ast_ari_response_no_content(response);
401 }
402
403 void ast_ari_channels_mute(struct ast_variable *headers,
404         struct ast_ari_channels_mute_args *args,
405         struct ast_ari_response *response)
406 {
407         RAII_VAR(struct stasis_app_control *, control, NULL, ao2_cleanup);
408         unsigned int direction = 0;
409         enum ast_frame_type frametype = AST_FRAME_VOICE;
410
411         control = find_control(response, args->channel_id);
412         if (control == NULL) {
413                 return;
414         }
415
416         if (channel_state_invalid(control, response)) {
417                 return;
418         }
419
420         if (ast_strlen_zero(args->direction)) {
421                 ast_ari_response_error(
422                         response, 400, "Bad Request",
423                         "Direction is required");
424                 return;
425         }
426
427         if (!strcmp(args->direction, "in")) {
428                 direction = AST_MUTE_DIRECTION_READ;
429         } else if (!strcmp(args->direction, "out")) {
430                 direction = AST_MUTE_DIRECTION_WRITE;
431         } else if (!strcmp(args->direction, "both")) {
432                 direction = AST_MUTE_DIRECTION_READ | AST_MUTE_DIRECTION_WRITE;
433         } else {
434                 ast_ari_response_error(
435                         response, 400, "Bad Request",
436                         "Invalid direction specified");
437                 return;
438         }
439
440         stasis_app_control_mute(control, direction, frametype);
441
442         ast_ari_response_no_content(response);
443 }
444
445 void ast_ari_channels_unmute(struct ast_variable *headers,
446         struct ast_ari_channels_unmute_args *args,
447         struct ast_ari_response *response)
448 {
449         RAII_VAR(struct stasis_app_control *, control, NULL, ao2_cleanup);
450         unsigned int direction = 0;
451         enum ast_frame_type frametype = AST_FRAME_VOICE;
452
453         control = find_control(response, args->channel_id);
454         if (control == NULL) {
455                 return;
456         }
457
458         if (channel_state_invalid(control, response)) {
459                 return;
460         }
461
462         if (ast_strlen_zero(args->direction)) {
463                 ast_ari_response_error(
464                         response, 400, "Bad Request",
465                         "Direction is required");
466                 return;
467         }
468
469         if (!strcmp(args->direction, "in")) {
470                 direction = AST_MUTE_DIRECTION_READ;
471         } else if (!strcmp(args->direction, "out")) {
472                 direction = AST_MUTE_DIRECTION_WRITE;
473         } else if (!strcmp(args->direction, "both")) {
474                 direction = AST_MUTE_DIRECTION_READ | AST_MUTE_DIRECTION_WRITE;
475         } else {
476                 ast_ari_response_error(
477                         response, 400, "Bad Request",
478                         "Invalid direction specified");
479                 return;
480         }
481
482         stasis_app_control_unmute(control, direction, frametype);
483
484         ast_ari_response_no_content(response);
485 }
486
487 void ast_ari_channels_send_dtmf(struct ast_variable *headers,
488         struct ast_ari_channels_send_dtmf_args *args,
489         struct ast_ari_response *response)
490 {
491         RAII_VAR(struct stasis_app_control *, control, NULL, ao2_cleanup);
492
493         control = find_control(response, args->channel_id);
494         if (control == NULL) {
495                 return;
496         }
497
498         if (channel_state_invalid(control, response)) {
499                 return;
500         }
501
502         if (ast_strlen_zero(args->dtmf)) {
503                 ast_ari_response_error(
504                         response, 400, "Bad Request",
505                         "DTMF is required");
506                 return;
507         }
508
509         stasis_app_control_dtmf(control, args->dtmf, args->before, args->between, args->duration, args->after);
510
511         ast_ari_response_no_content(response);
512 }
513
514 void ast_ari_channels_hold(struct ast_variable *headers,
515         struct ast_ari_channels_hold_args *args,
516         struct ast_ari_response *response)
517 {
518         RAII_VAR(struct stasis_app_control *, control, NULL, ao2_cleanup);
519
520         control = find_control(response, args->channel_id);
521         if (control == NULL) {
522                 /* Response filled in by find_control */
523                 return;
524         }
525
526         if (channel_state_invalid(control, response)) {
527                 return;
528         }
529
530         stasis_app_control_hold(control);
531
532         ast_ari_response_no_content(response);
533 }
534
535 void ast_ari_channels_unhold(struct ast_variable *headers,
536         struct ast_ari_channels_unhold_args *args,
537         struct ast_ari_response *response)
538 {
539         RAII_VAR(struct stasis_app_control *, control, NULL, ao2_cleanup);
540
541         control = find_control(response, args->channel_id);
542         if (control == NULL) {
543                 /* Response filled in by find_control */
544                 return;
545         }
546
547         if (channel_state_invalid(control, response)) {
548                 return;
549         }
550
551         stasis_app_control_unhold(control);
552
553         ast_ari_response_no_content(response);
554 }
555
556 void ast_ari_channels_start_moh(struct ast_variable *headers,
557         struct ast_ari_channels_start_moh_args *args,
558         struct ast_ari_response *response)
559 {
560         RAII_VAR(struct stasis_app_control *, control, NULL, ao2_cleanup);
561
562         control = find_control(response, args->channel_id);
563         if (control == NULL) {
564                 /* Response filled in by find_control */
565                 return;
566         }
567
568         if (channel_state_invalid(control, response)) {
569                 return;
570         }
571
572         stasis_app_control_moh_start(control, args->moh_class);
573         ast_ari_response_no_content(response);
574 }
575
576 void ast_ari_channels_stop_moh(struct ast_variable *headers,
577         struct ast_ari_channels_stop_moh_args *args,
578         struct ast_ari_response *response)
579 {
580         RAII_VAR(struct stasis_app_control *, control, NULL, ao2_cleanup);
581
582         control = find_control(response, args->channel_id);
583         if (control == NULL) {
584                 /* Response filled in by find_control */
585                 return;
586         }
587
588         if (channel_state_invalid(control, response)) {
589                 return;
590         }
591
592         stasis_app_control_moh_stop(control);
593         ast_ari_response_no_content(response);
594 }
595
596 void ast_ari_channels_start_silence(struct ast_variable *headers,
597         struct ast_ari_channels_start_silence_args *args,
598         struct ast_ari_response *response)
599 {
600         RAII_VAR(struct stasis_app_control *, control, NULL, ao2_cleanup);
601
602         control = find_control(response, args->channel_id);
603         if (control == NULL) {
604                 /* Response filled in by find_control */
605                 return;
606         }
607
608         if (channel_state_invalid(control, response)) {
609                 return;
610         }
611
612         stasis_app_control_silence_start(control);
613         ast_ari_response_no_content(response);
614 }
615
616 void ast_ari_channels_stop_silence(struct ast_variable *headers,
617         struct ast_ari_channels_stop_silence_args *args,
618         struct ast_ari_response *response)
619 {
620         RAII_VAR(struct stasis_app_control *, control, NULL, ao2_cleanup);
621
622         control = find_control(response, args->channel_id);
623         if (control == NULL) {
624                 /* Response filled in by find_control */
625                 return;
626         }
627
628         if (channel_state_invalid(control, response)) {
629                 return;
630         }
631
632         stasis_app_control_silence_stop(control);
633         ast_ari_response_no_content(response);
634 }
635
636 static void ari_channels_handle_play(
637         const char *args_channel_id,
638         const char **args_media,
639         size_t args_media_count,
640         const char *args_lang,
641         int args_offsetms,
642         int args_skipms,
643         const char *args_playback_id,
644         struct ast_ari_response *response)
645 {
646         RAII_VAR(struct stasis_app_control *, control, NULL, ao2_cleanup);
647         RAII_VAR(struct ast_channel_snapshot *, snapshot, NULL, ao2_cleanup);
648         RAII_VAR(struct stasis_app_playback *, playback, NULL, ao2_cleanup);
649         RAII_VAR(char *, playback_url, NULL, ast_free);
650         struct ast_json *json;
651         const char *language;
652
653         ast_assert(response != NULL);
654
655         control = find_control(response, args_channel_id);
656         if (control == NULL) {
657                 /* Response filled in by find_control */
658                 return;
659         }
660
661         if (channel_state_invalid(control, response)) {
662                 return;
663         }
664
665         snapshot = stasis_app_control_get_snapshot(control);
666         if (!snapshot) {
667                 ast_ari_response_error(
668                         response, 404, "Not Found",
669                         "Channel not found");
670                 return;
671         }
672
673         if (args_skipms < 0) {
674                 ast_ari_response_error(
675                         response, 400, "Bad Request",
676                         "skipms cannot be negative");
677                 return;
678         }
679
680         if (args_offsetms < 0) {
681                 ast_ari_response_error(
682                         response, 400, "Bad Request",
683                         "offsetms cannot be negative");
684                 return;
685         }
686
687         language = S_OR(args_lang, snapshot->base->language);
688
689         playback = stasis_app_control_play_uri(control, args_media, args_media_count, language,
690                 args_channel_id, STASIS_PLAYBACK_TARGET_CHANNEL, args_skipms, args_offsetms, args_playback_id);
691         if (!playback) {
692                 ast_ari_response_error(
693                         response, 500, "Internal Server Error",
694                         "Failed to queue media for playback");
695                 return;
696         }
697
698         if (ast_asprintf(&playback_url, "/playbacks/%s",
699                         stasis_app_playback_get_id(playback)) == -1) {
700                 playback_url = NULL;
701                 ast_ari_response_error(
702                         response, 500, "Internal Server Error",
703                         "Out of memory");
704                 return;
705         }
706
707         json = stasis_app_playback_to_json(playback);
708         if (!json) {
709                 ast_ari_response_error(
710                         response, 500, "Internal Server Error",
711                         "Out of memory");
712                 return;
713         }
714
715         ast_ari_response_created(response, playback_url, json);
716 }
717
718 void ast_ari_channels_play(struct ast_variable *headers,
719         struct ast_ari_channels_play_args *args,
720         struct ast_ari_response *response)
721 {
722         ari_channels_handle_play(
723                 args->channel_id,
724                 args->media,
725                 args->media_count,
726                 args->lang,
727                 args->offsetms,
728                 args->skipms,
729                 args->playback_id,
730                 response);
731 }
732
733 void ast_ari_channels_play_with_id(struct ast_variable *headers,
734         struct ast_ari_channels_play_with_id_args *args,
735         struct ast_ari_response *response)
736 {
737         ari_channels_handle_play(
738                 args->channel_id,
739                 args->media,
740                 args->media_count,
741                 args->lang,
742                 args->offsetms,
743                 args->skipms,
744                 args->playback_id,
745                 response);
746 }
747
748 void ast_ari_channels_record(struct ast_variable *headers,
749         struct ast_ari_channels_record_args *args,
750         struct ast_ari_response *response)
751 {
752         RAII_VAR(struct stasis_app_control *, control, NULL, ao2_cleanup);
753         RAII_VAR(struct stasis_app_recording *, recording, NULL, ao2_cleanup);
754         RAII_VAR(char *, recording_url, NULL, ast_free);
755         struct ast_json *json;
756         RAII_VAR(struct stasis_app_recording_options *, options, NULL,
757                 ao2_cleanup);
758         RAII_VAR(char *, uri_encoded_name, NULL, ast_free);
759         size_t uri_name_maxlen;
760
761         ast_assert(response != NULL);
762
763         if (args->max_duration_seconds < 0) {
764                 ast_ari_response_error(
765                         response, 400, "Bad Request",
766                         "max_duration_seconds cannot be negative");
767                 return;
768         }
769
770         if (args->max_silence_seconds < 0) {
771                 ast_ari_response_error(
772                         response, 400, "Bad Request",
773                         "max_silence_seconds cannot be negative");
774                 return;
775         }
776
777         control = find_control(response, args->channel_id);
778         if (control == NULL) {
779                 /* Response filled in by find_control */
780                 return;
781         }
782
783         options = stasis_app_recording_options_create(args->name, args->format);
784         if (options == NULL) {
785                 ast_ari_response_error(
786                         response, 500, "Internal Server Error",
787                         "Out of memory");
788         }
789         ast_string_field_build(options, target, "channel:%s", args->channel_id);
790         options->max_silence_seconds = args->max_silence_seconds;
791         options->max_duration_seconds = args->max_duration_seconds;
792         options->terminate_on =
793                 stasis_app_recording_termination_parse(args->terminate_on);
794         options->if_exists =
795                 stasis_app_recording_if_exists_parse(args->if_exists);
796         options->beep = args->beep;
797
798         if (options->terminate_on == STASIS_APP_RECORDING_TERMINATE_INVALID) {
799                 ast_ari_response_error(
800                         response, 400, "Bad Request",
801                         "terminateOn invalid");
802                 return;
803         }
804
805         if (options->if_exists == AST_RECORD_IF_EXISTS_ERROR) {
806                 ast_ari_response_error(
807                         response, 400, "Bad Request",
808                         "ifExists invalid");
809                 return;
810         }
811
812         if (!ast_get_format_for_file_ext(options->format)) {
813                 ast_ari_response_error(
814                         response, 422, "Unprocessable Entity",
815                         "specified format is unknown on this system");
816                 return;
817         }
818
819         recording = stasis_app_control_record(control, options);
820         if (recording == NULL) {
821                 switch(errno) {
822                 case EINVAL:
823                         /* While the arguments are invalid, we should have
824                          * caught them prior to calling record.
825                          */
826                         ast_ari_response_error(
827                                 response, 500, "Internal Server Error",
828                                 "Error parsing request");
829                         break;
830                 case EEXIST:
831                         ast_ari_response_error(response, 409, "Conflict",
832                                 "Recording '%s' already exists and can not be overwritten",
833                                 args->name);
834                         break;
835                 case ENOMEM:
836                         ast_ari_response_error(
837                                 response, 500, "Internal Server Error",
838                                 "Out of memory");
839                         break;
840                 case EPERM:
841                         ast_ari_response_error(
842                                 response, 400, "Bad Request",
843                                 "Recording name invalid");
844                         break;
845                 default:
846                         ast_log(LOG_WARNING,
847                                 "Unrecognized recording error: %s\n",
848                                 strerror(errno));
849                         ast_ari_response_error(
850                                 response, 500, "Internal Server Error",
851                                 "Internal Server Error");
852                         break;
853                 }
854                 return;
855         }
856
857         uri_name_maxlen = strlen(args->name) * 3;
858         uri_encoded_name = ast_malloc(uri_name_maxlen);
859         if (!uri_encoded_name) {
860                 ast_ari_response_error(
861                         response, 500, "Internal Server Error",
862                         "Out of memory");
863                 return;
864         }
865         ast_uri_encode(args->name, uri_encoded_name, uri_name_maxlen,
866                 ast_uri_http);
867
868         if (ast_asprintf(&recording_url, "/recordings/live/%s",
869                         uri_encoded_name) == -1) {
870                 recording_url = NULL;
871                 ast_ari_response_error(
872                         response, 500, "Internal Server Error",
873                         "Out of memory");
874                 return;
875         }
876
877         json = stasis_app_recording_to_json(recording);
878         if (!json) {
879                 ast_ari_response_error(
880                         response, 500, "Internal Server Error",
881                         "Out of memory");
882                 return;
883         }
884
885         ast_ari_response_created(response, recording_url, json);
886 }
887
888 void ast_ari_channels_get(struct ast_variable *headers,
889         struct ast_ari_channels_get_args *args,
890         struct ast_ari_response *response)
891 {
892         struct ast_channel_snapshot *snapshot;
893
894         snapshot = ast_channel_snapshot_get_latest(args->channel_id);
895         if (!snapshot) {
896                 ast_ari_response_error(
897                         response, 404, "Not Found",
898                         "Channel not found");
899                 return;
900         }
901
902         ast_ari_response_ok(response,
903                                 ast_channel_snapshot_to_json(snapshot, NULL));
904         ao2_ref(snapshot, -1);
905 }
906
907 void ast_ari_channels_hangup(struct ast_variable *headers,
908         struct ast_ari_channels_hangup_args *args,
909         struct ast_ari_response *response)
910 {
911         RAII_VAR(struct ast_channel *, chan, NULL, ao2_cleanup);
912         int cause;
913
914         chan = ast_channel_get_by_name(args->channel_id);
915         if (chan == NULL) {
916                 ast_ari_response_error(
917                         response, 404, "Not Found",
918                         "Channel not found");
919                 return;
920         }
921
922         if (!ast_strlen_zero(args->reason) && !ast_strlen_zero(args->reason_code)) {
923                 ast_ari_response_error(response, 400, "Bad Request",
924                         "The reason and reason_code can't both be specified");
925                 return;
926         }
927
928         if (!ast_strlen_zero(args->reason_code)) {
929                 /* reason_code allows any hangup code */
930                 if (sscanf(args->reason_code, "%30d", &cause) != 1) {
931                         ast_ari_response_error(
932                                 response, 400, "Invalid Reason Code",
933                                 "Invalid reason for hangup reason code provided");
934                         return;
935                 }
936         } else if (!ast_strlen_zero(args->reason)) {
937                 /* reason allows only listed hangup reason */
938                 cause = convert_reason_to_hangup_code(args->reason);
939                 if (cause == -1) {
940                         ast_ari_response_error(
941                                 response, 400, "Invalid Reason",
942                                 "Invalid reason for hangup reason provided");
943                         return;
944                 }
945         } else {
946                 /* not specified. set default hangup */
947                 cause = AST_CAUSE_NORMAL;
948         }
949
950         ast_channel_hangupcause_set(chan, cause);
951         ast_softhangup(chan, AST_SOFTHANGUP_EXPLICIT);
952
953         ast_ari_response_no_content(response);
954 }
955
956 void ast_ari_channels_list(struct ast_variable *headers,
957         struct ast_ari_channels_list_args *args,
958         struct ast_ari_response *response)
959 {
960         RAII_VAR(struct ao2_container *, snapshots, NULL, ao2_cleanup);
961         RAII_VAR(struct ast_json *, json, NULL, ast_json_unref);
962         struct ao2_iterator i;
963         void *obj;
964         struct stasis_message_sanitizer *sanitize = stasis_app_get_sanitizer();
965
966         snapshots = ast_channel_cache_all();
967
968         json = ast_json_array_create();
969         if (!json) {
970                 ast_ari_response_alloc_failed(response);
971                 return;
972         }
973
974         i = ao2_iterator_init(snapshots, 0);
975         while ((obj = ao2_iterator_next(&i))) {
976                 struct ast_channel_snapshot *snapshot = obj;
977                 int r;
978
979                 if (sanitize && sanitize->channel_snapshot
980                         && sanitize->channel_snapshot(snapshot)) {
981                         ao2_ref(snapshot, -1);
982                         continue;
983                 }
984
985                 r = ast_json_array_append(
986                         json, ast_channel_snapshot_to_json(snapshot, NULL));
987                 if (r != 0) {
988                         ast_ari_response_alloc_failed(response);
989                         ao2_iterator_destroy(&i);
990                         ao2_ref(snapshot, -1);
991                         return;
992                 }
993                 ao2_ref(snapshot, -1);
994         }
995         ao2_iterator_destroy(&i);
996
997         ast_ari_response_ok(response, ast_json_ref(json));
998 }
999
1000 /*! \brief Structure used for origination */
1001 struct ari_origination {
1002         /*! \brief Dialplan context */
1003         char context[AST_MAX_CONTEXT];
1004         /*! \brief Dialplan extension */
1005         char exten[AST_MAX_EXTENSION];
1006         /*! \brief Dialplan priority */
1007         int priority;
1008         /*! \brief Application data to pass to Stasis application */
1009         char appdata[0];
1010 };
1011
1012 /*! \brief Thread which dials and executes upon answer */
1013 static void *ari_originate_dial(void *data)
1014 {
1015         struct ast_dial *dial = data;
1016         struct ari_origination *origination = ast_dial_get_user_data(dial);
1017         enum ast_dial_result res;
1018
1019         res = ast_dial_run(dial, NULL, 0);
1020         if (res != AST_DIAL_RESULT_ANSWERED) {
1021                 goto end;
1022         }
1023
1024         if (!ast_strlen_zero(origination->appdata)) {
1025                 struct ast_app *app = pbx_findapp("Stasis");
1026
1027                 if (app) {
1028                         ast_verb(4, "Launching Stasis(%s) on %s\n", origination->appdata,
1029                                 ast_channel_name(ast_dial_answered(dial)));
1030                         pbx_exec(ast_dial_answered(dial), app, origination->appdata);
1031                 } else {
1032                         ast_log(LOG_WARNING, "No such application 'Stasis'\n");
1033                 }
1034         } else {
1035                 struct ast_channel *answered = ast_dial_answered(dial);
1036
1037                 if (!ast_strlen_zero(origination->context)) {
1038                         ast_channel_context_set(answered, origination->context);
1039                 }
1040
1041                 if (!ast_strlen_zero(origination->exten)) {
1042                         ast_channel_exten_set(answered, origination->exten);
1043                 }
1044
1045                 if (origination->priority > 0) {
1046                         ast_channel_priority_set(answered, origination->priority);
1047                 }
1048
1049                 if (ast_pbx_run(answered)) {
1050                         ast_log(LOG_ERROR, "Failed to start PBX on %s\n", ast_channel_name(answered));
1051                 } else {
1052                         /* PBX will have taken care of hanging up, so we steal the answered channel so dial doesn't do it */
1053                         ast_dial_answered_steal(dial);
1054                 }
1055         }
1056
1057 end:
1058         ast_dial_destroy(dial);
1059         ast_free(origination);
1060         return NULL;
1061 }
1062
1063 static void ari_channels_handle_originate_with_id(const char *args_endpoint,
1064         const char *args_extension,
1065         const char *args_context,
1066         long args_priority,
1067         const char *args_label,
1068         const char *args_app,
1069         const char *args_app_args,
1070         const char *args_caller_id,
1071         int args_timeout,
1072         struct ast_variable *variables,
1073         const char *args_channel_id,
1074         const char *args_other_channel_id,
1075         const char *args_originator,
1076         const char *args_formats,
1077         struct ast_ari_response *response)
1078 {
1079         char *dialtech;
1080         char dialdevice[AST_CHANNEL_NAME];
1081         struct ast_dial *dial;
1082         char *caller_id = NULL;
1083         char *cid_num = NULL;
1084         char *cid_name = NULL;
1085         char *stuff;
1086         struct ast_channel *other = NULL;
1087         struct ast_channel *chan = NULL;
1088         RAII_VAR(struct ast_channel_snapshot *, snapshot, NULL, ao2_cleanup);
1089         struct ast_assigned_ids assignedids = {
1090                 .uniqueid = args_channel_id,
1091                 .uniqueid2 = args_other_channel_id,
1092         };
1093         struct ari_origination *origination;
1094         pthread_t thread;
1095         struct ast_format_cap *format_cap = NULL;
1096
1097         if ((assignedids.uniqueid && AST_MAX_PUBLIC_UNIQUEID < strlen(assignedids.uniqueid))
1098                 || (assignedids.uniqueid2 && AST_MAX_PUBLIC_UNIQUEID < strlen(assignedids.uniqueid2))) {
1099                 ast_ari_response_error(response, 400, "Bad Request",
1100                         "Uniqueid length exceeds maximum of %d", AST_MAX_PUBLIC_UNIQUEID);
1101                 return;
1102         }
1103
1104         if (ast_strlen_zero(args_endpoint)) {
1105                 ast_ari_response_error(response, 400, "Bad Request",
1106                         "Endpoint must be specified");
1107                 return;
1108         }
1109
1110         if (!ast_strlen_zero(args_originator) && !ast_strlen_zero(args_formats)) {
1111                 ast_ari_response_error(response, 400, "Bad Request",
1112                         "Originator and formats can't both be specified");
1113                 return;
1114         }
1115
1116         dialtech = ast_strdupa(args_endpoint);
1117         if ((stuff = strchr(dialtech, '/'))) {
1118                 *stuff++ = '\0';
1119                 ast_copy_string(dialdevice, stuff, sizeof(dialdevice));
1120         }
1121
1122         if (ast_strlen_zero(dialtech) || ast_strlen_zero(dialdevice)) {
1123                 ast_ari_response_error(response, 400, "Bad Request",
1124                         "Invalid endpoint specified");
1125                 return;
1126         }
1127
1128         if (!ast_strlen_zero(args_app)) {
1129                 RAII_VAR(struct ast_str *, appdata, ast_str_create(64), ast_free);
1130
1131                 if (!appdata) {
1132                         ast_ari_response_alloc_failed(response);
1133                         return;
1134                 }
1135
1136                 ast_str_set(&appdata, 0, "%s", args_app);
1137                 if (!ast_strlen_zero(args_app_args)) {
1138                         ast_str_append(&appdata, 0, ",%s", args_app_args);
1139                 }
1140
1141                 origination = ast_calloc(1, sizeof(*origination) + ast_str_size(appdata) + 1);
1142                 if (!origination) {
1143                         ast_ari_response_alloc_failed(response);
1144                         return;
1145                 }
1146
1147                 strcpy(origination->appdata, ast_str_buffer(appdata));
1148         } else if (!ast_strlen_zero(args_extension)) {
1149                 origination = ast_calloc(1, sizeof(*origination) + 1);
1150                 if (!origination) {
1151                         ast_ari_response_alloc_failed(response);
1152                         return;
1153                 }
1154
1155                 ast_copy_string(origination->context, S_OR(args_context, "default"), sizeof(origination->context));
1156                 ast_copy_string(origination->exten, args_extension, sizeof(origination->exten));
1157
1158                 if (!ast_strlen_zero(args_label)) {
1159                         /* A label was provided in the request, use that */
1160                         int ipri = 1;
1161                         if (sscanf(args_label, "%30d", &ipri) != 1) {
1162                                 ipri = ast_findlabel_extension(chan, origination->context, origination->exten, args_label, args_caller_id);
1163
1164                                 if (ipri == -1) {
1165                                         ast_log(AST_LOG_ERROR, "Requested label: %s can not be found in context: %s\n", args_label, args_context);
1166                                         ast_ari_response_error(response, 404, "Not Found", "Requested label can not be found");
1167                                         return;
1168                                 }
1169                         } else {
1170                                 ast_debug(3, "Numeric value provided for label, jumping to that priority\n");
1171                         }
1172
1173                         if (ipri == 0) {
1174                                 ast_log(AST_LOG_ERROR, "Invalid priority label '%s' specified for extension %s in context: %s\n",
1175                                                 args_label, args_extension, args_context);
1176                                 ast_ari_response_error(response, 400, "Bad Request", "Requested priority is illegal");
1177                                 return;
1178                         }
1179
1180                         /* Our priority was provided by a label */
1181                         origination->priority =  ipri;
1182                 } else {
1183                         /* No label provided, use provided priority */
1184                         origination->priority = args_priority ? args_priority : 1;
1185                 }
1186
1187                 origination->appdata[0] = '\0';
1188         } else {
1189                 ast_ari_response_error(response, 400, "Bad Request",
1190                         "Application or extension must be specified");
1191                 return;
1192         }
1193
1194         dial = ast_dial_create();
1195         if (!dial) {
1196                 ast_ari_response_alloc_failed(response);
1197                 ast_free(origination);
1198                 return;
1199         }
1200         ast_dial_set_user_data(dial, origination);
1201
1202         if (ast_dial_append(dial, dialtech, dialdevice, &assignedids)) {
1203                 ast_ari_response_alloc_failed(response);
1204                 ast_dial_destroy(dial);
1205                 ast_free(origination);
1206                 return;
1207         }
1208
1209         if (args_timeout > 0) {
1210                 ast_dial_set_global_timeout(dial, args_timeout * 1000);
1211         } else if (args_timeout == -1) {
1212                 ast_dial_set_global_timeout(dial, -1);
1213         } else {
1214                 ast_dial_set_global_timeout(dial, 30000);
1215         }
1216
1217         if (!ast_strlen_zero(args_caller_id)) {
1218                 caller_id = ast_strdupa(args_caller_id);
1219                 ast_callerid_parse(caller_id, &cid_name, &cid_num);
1220
1221                 if (ast_is_shrinkable_phonenumber(cid_num)) {
1222                         ast_shrink_phone_number(cid_num);
1223                 }
1224         }
1225
1226         if (!ast_strlen_zero(args_originator)) {
1227                 other = ast_channel_get_by_name(args_originator);
1228                 if (!other) {
1229                         ast_ari_response_error(
1230                                 response, 400, "Bad Request",
1231                                 "Provided originator channel was not found");
1232                         ast_dial_destroy(dial);
1233                         ast_free(origination);
1234                         return;
1235                 }
1236         }
1237
1238         if (!ast_strlen_zero(args_formats)) {
1239                 char *format_name;
1240                 char *formats_copy = ast_strdupa(args_formats);
1241
1242                 if (!(format_cap = ast_format_cap_alloc(AST_FORMAT_CAP_FLAG_DEFAULT))) {
1243                         ast_ari_response_alloc_failed(response);
1244                         ast_dial_destroy(dial);
1245                         ast_free(origination);
1246                         ast_channel_cleanup(other);
1247                         return;
1248                 }
1249
1250                 while ((format_name = ast_strip(strsep(&formats_copy, ",")))) {
1251                         struct ast_format *fmt = ast_format_cache_get(format_name);
1252
1253                         if (!fmt || ast_format_cap_append(format_cap, fmt, 0)) {
1254                                 if (!fmt) {
1255                                         ast_ari_response_error(
1256                                                 response, 400, "Bad Request",
1257                                                 "Provided format (%s) was not found", format_name);
1258                                 } else {
1259                                         ast_ari_response_alloc_failed(response);
1260                                 }
1261                                 ast_dial_destroy(dial);
1262                                 ast_free(origination);
1263                                 ast_channel_cleanup(other);
1264                                 ao2_ref(format_cap, -1);
1265                                 ao2_cleanup(fmt);
1266                                 return;
1267                         }
1268                         ao2_ref(fmt, -1);
1269                 }
1270         }
1271
1272         if (ast_dial_prerun(dial, other, format_cap)) {
1273                 if (ast_channel_errno() == AST_CHANNEL_ERROR_ID_EXISTS) {
1274                         ast_ari_response_error(response, 409, "Conflict",
1275                                 "Channel with given unique ID already exists");
1276                 } else {
1277                         ast_ari_response_alloc_failed(response);
1278                 }
1279                 ast_dial_destroy(dial);
1280                 ast_free(origination);
1281                 ast_channel_cleanup(other);
1282                 return;
1283         }
1284
1285         ast_channel_cleanup(other);
1286         ao2_cleanup(format_cap);
1287
1288         chan = ast_dial_get_channel(dial, 0);
1289         if (!chan) {
1290                 ast_ari_response_alloc_failed(response);
1291                 ast_dial_destroy(dial);
1292                 ast_free(origination);
1293                 return;
1294         }
1295
1296         if (!ast_strlen_zero(cid_num) || !ast_strlen_zero(cid_name)) {
1297                 struct ast_party_connected_line connected;
1298
1299                 /*
1300                  * It seems strange to set the CallerID on an outgoing call leg
1301                  * to whom we are calling, but this function's callers are doing
1302                  * various Originate methods.  This call leg goes to the local
1303                  * user.  Once the called party answers, the dialplan needs to
1304                  * be able to access the CallerID from the CALLERID function as
1305                  * if the called party had placed this call.
1306                  */
1307                 ast_set_callerid(chan, cid_num, cid_name, cid_num);
1308
1309                 ast_party_connected_line_set_init(&connected, ast_channel_connected(chan));
1310                 if (!ast_strlen_zero(cid_num)) {
1311                         connected.id.number.valid = 1;
1312                         connected.id.number.str = (char *) cid_num;
1313                         connected.id.number.presentation = AST_PRES_ALLOWED_USER_NUMBER_NOT_SCREENED;
1314                 }
1315                 if (!ast_strlen_zero(cid_name)) {
1316                         connected.id.name.valid = 1;
1317                         connected.id.name.str = (char *) cid_name;
1318                         connected.id.name.presentation = AST_PRES_ALLOWED_USER_NUMBER_NOT_SCREENED;
1319                 }
1320                 ast_channel_set_connected_line(chan, &connected, NULL);
1321         }
1322
1323         ast_channel_lock(chan);
1324         if (variables) {
1325                 ast_set_variables(chan, variables);
1326         }
1327         ast_set_flag(ast_channel_flags(chan), AST_FLAG_ORIGINATED);
1328
1329         if (!ast_strlen_zero(args_app)) {
1330                 struct ast_channel *local_peer;
1331
1332                 stasis_app_subscribe_channel(args_app, chan);
1333
1334                 /* Subscribe to the Local channel peer also. */
1335                 local_peer = ast_local_get_peer(chan);
1336                 if (local_peer) {
1337                         stasis_app_subscribe_channel(args_app, local_peer);
1338                         ast_channel_unref(local_peer);
1339                 }
1340         }
1341
1342         snapshot = ast_channel_snapshot_get_latest(ast_channel_uniqueid(chan));
1343         ast_channel_unlock(chan);
1344
1345         /* Before starting the async dial bump the ref in case the dial quickly goes away and takes
1346          * the reference with it
1347          */
1348         ast_channel_ref(chan);
1349
1350         if (ast_pthread_create_detached(&thread, NULL, ari_originate_dial, dial)) {
1351                 ast_ari_response_alloc_failed(response);
1352                 ast_dial_destroy(dial);
1353                 ast_free(origination);
1354         } else {
1355                 ast_ari_response_ok(response, ast_channel_snapshot_to_json(snapshot, NULL));
1356         }
1357
1358         ast_channel_unref(chan);
1359         return;
1360 }
1361
1362 /*!
1363  * \internal
1364  * \brief Convert a \c ast_json list of key/value pair tuples into a \c ast_variable list
1365  * \since 13.3.0
1366  *
1367  * \param[out] response HTTP response if error
1368  * \param json_variables The JSON blob containing the variable
1369  * \param[out] variables An out reference to the variables to populate.
1370  *
1371  * \retval 0 on success.
1372  * \retval -1 on error.
1373  */
1374 static int json_to_ast_variables(struct ast_ari_response *response, struct ast_json *json_variables, struct ast_variable **variables)
1375 {
1376         enum ast_json_to_ast_vars_code res;
1377
1378         res = ast_json_to_ast_variables(json_variables, variables);
1379         switch (res) {
1380         case AST_JSON_TO_AST_VARS_CODE_SUCCESS:
1381                 return 0;
1382         case AST_JSON_TO_AST_VARS_CODE_INVALID_TYPE:
1383                 ast_ari_response_error(response, 400, "Bad Request",
1384                         "Only string values in the 'variables' object allowed");
1385                 break;
1386         case AST_JSON_TO_AST_VARS_CODE_OOM:
1387                 ast_ari_response_alloc_failed(response);
1388                 break;
1389         }
1390         ast_log(AST_LOG_ERROR, "Unable to convert 'variables' in JSON body to channel variables\n");
1391
1392         return -1;
1393 }
1394
1395 void ast_ari_channels_originate_with_id(struct ast_variable *headers,
1396         struct ast_ari_channels_originate_with_id_args *args,
1397         struct ast_ari_response *response)
1398 {
1399         struct ast_variable *variables = NULL;
1400
1401         /* Parse any query parameters out of the body parameter */
1402         if (args->variables) {
1403                 struct ast_json *json_variables;
1404
1405                 ast_ari_channels_originate_with_id_parse_body(args->variables, args);
1406                 json_variables = ast_json_object_get(args->variables, "variables");
1407                 if (json_variables
1408                         && json_to_ast_variables(response, json_variables, &variables)) {
1409                         return;
1410                 }
1411         }
1412
1413         ari_channels_handle_originate_with_id(
1414                 args->endpoint,
1415                 args->extension,
1416                 args->context,
1417                 args->priority,
1418                 args->label,
1419                 args->app,
1420                 args->app_args,
1421                 args->caller_id,
1422                 args->timeout,
1423                 variables,
1424                 args->channel_id,
1425                 args->other_channel_id,
1426                 args->originator,
1427                 args->formats,
1428                 response);
1429         ast_variables_destroy(variables);
1430 }
1431
1432 void ast_ari_channels_originate(struct ast_variable *headers,
1433         struct ast_ari_channels_originate_args *args,
1434         struct ast_ari_response *response)
1435 {
1436         struct ast_variable *variables = NULL;
1437
1438         /* Parse any query parameters out of the body parameter */
1439         if (args->variables) {
1440                 struct ast_json *json_variables;
1441
1442                 ast_ari_channels_originate_parse_body(args->variables, args);
1443                 json_variables = ast_json_object_get(args->variables, "variables");
1444                 if (json_variables
1445                         && json_to_ast_variables(response, json_variables, &variables)) {
1446                         return;
1447                 }
1448         }
1449
1450         ari_channels_handle_originate_with_id(
1451                 args->endpoint,
1452                 args->extension,
1453                 args->context,
1454                 args->priority,
1455                 args->label,
1456                 args->app,
1457                 args->app_args,
1458                 args->caller_id,
1459                 args->timeout,
1460                 variables,
1461                 args->channel_id,
1462                 args->other_channel_id,
1463                 args->originator,
1464                 args->formats,
1465                 response);
1466         ast_variables_destroy(variables);
1467 }
1468
1469 void ast_ari_channels_get_channel_var(struct ast_variable *headers,
1470         struct ast_ari_channels_get_channel_var_args *args,
1471         struct ast_ari_response *response)
1472 {
1473         RAII_VAR(struct ast_json *, json, NULL, ast_json_unref);
1474         RAII_VAR(struct stasis_app_control *, control, NULL, ao2_cleanup);
1475         RAII_VAR(struct ast_str *, value, ast_str_create(32), ast_free);
1476         RAII_VAR(struct ast_channel *, channel, NULL, ast_channel_cleanup);
1477
1478         ast_assert(response != NULL);
1479
1480         if (!value) {
1481                 ast_ari_response_alloc_failed(response);
1482                 return;
1483         }
1484
1485         if (ast_strlen_zero(args->variable)) {
1486                 ast_ari_response_error(
1487                         response, 400, "Bad Request",
1488                         "Variable name is required");
1489                 return;
1490         }
1491
1492         if (ast_strlen_zero(args->channel_id)) {
1493                 ast_ari_response_error(
1494                         response, 400, "Bad Request",
1495                         "Channel ID is required");
1496                 return;
1497         }
1498
1499         channel = ast_channel_get_by_name(args->channel_id);
1500         if (!channel) {
1501                 ast_ari_response_error(
1502                         response, 404, "Channel Not Found",
1503                         "Provided channel was not found");
1504                 return;
1505         }
1506
1507         /* You may be tempted to lock the channel you're about to read from. You
1508          * would be wrong. Some dialplan functions put the channel into
1509          * autoservice, which deadlocks if the channel is already locked.
1510          * ast_str_retrieve_variable() does its own locking, and the dialplan
1511          * functions need to as well. We should be fine without the lock.
1512          */
1513
1514         if (args->variable[strlen(args->variable) - 1] == ')') {
1515                 if (ast_func_read2(channel, args->variable, &value, 0)) {
1516                         ast_ari_response_error(
1517                                 response, 500, "Error With Function",
1518                                 "Unable to read provided function");
1519                         return;
1520                 }
1521         } else {
1522                 if (!ast_str_retrieve_variable(&value, 0, channel, NULL, args->variable)) {
1523                         ast_ari_response_error(
1524                                 response, 404, "Variable Not Found",
1525                                 "Provided variable was not found");
1526                         return;
1527                 }
1528         }
1529
1530         if (!(json = ast_json_pack("{s: s}", "value", S_OR(ast_str_buffer(value), "")))) {
1531                 ast_ari_response_alloc_failed(response);
1532                 return;
1533         }
1534
1535         ast_ari_response_ok(response, ast_json_ref(json));
1536 }
1537
1538 void ast_ari_channels_set_channel_var(struct ast_variable *headers,
1539         struct ast_ari_channels_set_channel_var_args *args,
1540         struct ast_ari_response *response)
1541 {
1542         RAII_VAR(struct stasis_app_control *, control, NULL, ao2_cleanup);
1543
1544         ast_assert(response != NULL);
1545
1546         if (ast_strlen_zero(args->variable)) {
1547                 ast_ari_response_error(
1548                         response, 400, "Bad Request",
1549                         "Variable name is required");
1550                 return;
1551         }
1552
1553         control = find_control(response, args->channel_id);
1554         if (control == NULL) {
1555                 /* response filled in by find_control */
1556                 return;
1557         }
1558
1559         if (stasis_app_control_set_channel_var(control, args->variable, args->value)) {
1560                 ast_ari_response_error(
1561                         response, 400, "Bad Request",
1562                         "Failed to execute function");
1563                 return;
1564         }
1565
1566         ast_ari_response_no_content(response);
1567 }
1568
1569 static void ari_channels_handle_snoop_channel(
1570         const char *args_channel_id,
1571         const char *args_spy,
1572         const char *args_whisper,
1573         const char *args_app,
1574         const char *args_app_args,
1575         const char *args_snoop_id,
1576         struct ast_ari_response *response)
1577 {
1578         enum stasis_app_snoop_direction spy, whisper;
1579         RAII_VAR(struct ast_channel *, chan, NULL, ast_channel_cleanup);
1580         RAII_VAR(struct ast_channel *, snoop, NULL, ast_channel_cleanup);
1581         RAII_VAR(struct ast_channel_snapshot *, snapshot, NULL, ao2_cleanup);
1582
1583         ast_assert(response != NULL);
1584
1585         if (ast_strlen_zero(args_spy) || !strcmp(args_spy, "none")) {
1586                 spy = STASIS_SNOOP_DIRECTION_NONE;
1587         } else if (!strcmp(args_spy, "both")) {
1588                 spy = STASIS_SNOOP_DIRECTION_BOTH;
1589         } else if (!strcmp(args_spy, "out")) {
1590                 spy = STASIS_SNOOP_DIRECTION_OUT;
1591         } else if (!strcmp(args_spy, "in")) {
1592                 spy = STASIS_SNOOP_DIRECTION_IN;
1593         } else {
1594                 ast_ari_response_error(
1595                         response, 400, "Bad Request",
1596                         "Invalid direction specified for spy");
1597                 return;
1598         }
1599
1600         if (ast_strlen_zero(args_whisper) || !strcmp(args_whisper, "none")) {
1601                 whisper = STASIS_SNOOP_DIRECTION_NONE;
1602         } else if (!strcmp(args_whisper, "both")) {
1603                 whisper = STASIS_SNOOP_DIRECTION_BOTH;
1604         } else if (!strcmp(args_whisper, "out")) {
1605                 whisper = STASIS_SNOOP_DIRECTION_OUT;
1606         } else if (!strcmp(args_whisper, "in")) {
1607                 whisper = STASIS_SNOOP_DIRECTION_IN;
1608         } else {
1609                 ast_ari_response_error(
1610                         response, 400, "Bad Request",
1611                         "Invalid direction specified for whisper");
1612                 return;
1613         }
1614
1615         if (spy == STASIS_SNOOP_DIRECTION_NONE && whisper == STASIS_SNOOP_DIRECTION_NONE) {
1616                 ast_ari_response_error(
1617                         response, 400, "Bad Request",
1618                         "Direction must be specified for at least spy or whisper");
1619                 return;
1620         } else if (ast_strlen_zero(args_app)) {
1621                 ast_ari_response_error(
1622                         response, 400, "Bad Request",
1623                         "Application name is required");
1624                 return;
1625         }
1626
1627         chan = ast_channel_get_by_name(args_channel_id);
1628         if (chan == NULL) {
1629                 ast_ari_response_error(
1630                         response, 404, "Channel Not Found",
1631                         "Provided channel was not found");
1632                 return;
1633         }
1634
1635         snoop = stasis_app_control_snoop(chan, spy, whisper, args_app, args_app_args,
1636                 args_snoop_id);
1637         if (snoop == NULL) {
1638                 ast_ari_response_error(
1639                         response, 500, "Internal error",
1640                         "Snoop channel could not be created");
1641                 return;
1642         }
1643
1644         snapshot = ast_channel_snapshot_get_latest(ast_channel_uniqueid(snoop));
1645         ast_ari_response_ok(response, ast_channel_snapshot_to_json(snapshot, NULL));
1646 }
1647
1648 void ast_ari_channels_snoop_channel(struct ast_variable *headers,
1649         struct ast_ari_channels_snoop_channel_args *args,
1650         struct ast_ari_response *response)
1651 {
1652         ari_channels_handle_snoop_channel(
1653                 args->channel_id,
1654                 args->spy,
1655                 args->whisper,
1656                 args->app,
1657                 args->app_args,
1658                 args->snoop_id,
1659                 response);
1660 }
1661
1662 void ast_ari_channels_snoop_channel_with_id(struct ast_variable *headers,
1663         struct ast_ari_channels_snoop_channel_with_id_args *args,
1664         struct ast_ari_response *response)
1665 {
1666         ari_channels_handle_snoop_channel(
1667                 args->channel_id,
1668                 args->spy,
1669                 args->whisper,
1670                 args->app,
1671                 args->app_args,
1672                 args->snoop_id,
1673                 response);
1674 }
1675
1676 struct ari_channel_thread_data {
1677         struct ast_channel *chan;
1678         struct ast_str *stasis_stuff;
1679 };
1680
1681 static void chan_data_destroy(struct ari_channel_thread_data *chan_data)
1682 {
1683         ast_free(chan_data->stasis_stuff);
1684         ast_hangup(chan_data->chan);
1685         ast_free(chan_data);
1686 }
1687
1688 /*!
1689  * \brief Thread that owns stasis-created channel.
1690  *
1691  * The channel enters into a Stasis application immediately upon creation. In this
1692  * way, the channel can be manipulated by the Stasis application. Once the channel
1693  * exits the Stasis application, it is hung up.
1694  */
1695 static void *ari_channel_thread(void *data)
1696 {
1697         struct ari_channel_thread_data *chan_data = data;
1698         struct ast_app *stasis_app;
1699
1700         stasis_app = pbx_findapp("Stasis");
1701         if (!stasis_app) {
1702                 ast_log(LOG_ERROR, "Stasis dialplan application is not registered");
1703                 chan_data_destroy(chan_data);
1704                 return NULL;
1705         }
1706
1707         pbx_exec(chan_data->chan, stasis_app, ast_str_buffer(chan_data->stasis_stuff));
1708
1709         chan_data_destroy(chan_data);
1710
1711         return NULL;
1712 }
1713
1714 struct ast_datastore_info dialstring_info = {
1715         .type = "ARI Dialstring",
1716         .destroy = ast_free_ptr,
1717 };
1718
1719 /*!
1720  * \brief Save dialstring onto a channel datastore
1721  *
1722  * This will later be retrieved when it comes time to actually dial the channel
1723  *
1724  * \param chan The channel on which to save the dialstring
1725  * \param dialstring The dialstring to save
1726  * \retval 0 SUCCESS!
1727  * \reval -1 Failure :(
1728  */
1729 static int save_dialstring(struct ast_channel *chan, const char *dialstring)
1730 {
1731         struct ast_datastore *datastore;
1732
1733         datastore = ast_datastore_alloc(&dialstring_info, NULL);
1734         if (!datastore) {
1735                 return -1;
1736         }
1737
1738         datastore->data = ast_strdup(dialstring);
1739         if (!datastore->data) {
1740                 ast_datastore_free(datastore);
1741                 return -1;
1742         }
1743
1744         ast_channel_lock(chan);
1745         if (ast_channel_datastore_add(chan, datastore)) {
1746                 ast_channel_unlock(chan);
1747                 ast_datastore_free(datastore);
1748                 return -1;
1749         }
1750         ast_channel_unlock(chan);
1751
1752         return 0;
1753 }
1754
1755 /*!
1756  * \brief Retrieve the dialstring from the channel datastore
1757  *
1758  * \pre chan is locked
1759  * \param chan Channel that was previously created in ARI
1760  * \retval NULL Failed to find datastore
1761  * \retval non-NULL The dialstring
1762  */
1763 static char *restore_dialstring(struct ast_channel *chan)
1764 {
1765         struct ast_datastore *datastore;
1766
1767         datastore = ast_channel_datastore_find(chan, &dialstring_info, NULL);
1768         if (!datastore) {
1769                 return NULL;
1770         }
1771
1772         return datastore->data;
1773 }
1774
1775 void ast_ari_channels_create(struct ast_variable *headers,
1776         struct ast_ari_channels_create_args *args,
1777         struct ast_ari_response *response)
1778 {
1779         struct ast_assigned_ids assignedids = {
1780                 .uniqueid = args->channel_id,
1781                 .uniqueid2 = args->other_channel_id,
1782         };
1783         struct ari_channel_thread_data *chan_data;
1784         struct ast_channel_snapshot *snapshot;
1785         pthread_t thread;
1786         char *dialtech;
1787         char dialdevice[AST_CHANNEL_NAME];
1788         char *stuff;
1789         int cause;
1790         struct ast_format_cap *request_cap;
1791         struct ast_channel *originator;
1792
1793         if (!ast_strlen_zero(args->originator) && !ast_strlen_zero(args->formats)) {
1794                 ast_ari_response_error(response, 400, "Bad Request",
1795                         "Originator and formats can't both be specified");
1796                 return;
1797         }
1798
1799         if (ast_strlen_zero(args->endpoint)) {
1800                 ast_ari_response_error(response, 400, "Bad Request",
1801                         "Endpoint must be specified");
1802                 return;
1803         }
1804
1805         chan_data = ast_calloc(1, sizeof(*chan_data));
1806         if (!chan_data) {
1807                 ast_ari_response_alloc_failed(response);
1808                 return;
1809         }
1810
1811         chan_data->stasis_stuff = ast_str_create(32);
1812         if (!chan_data->stasis_stuff) {
1813                 ast_ari_response_alloc_failed(response);
1814                 chan_data_destroy(chan_data);
1815                 return;
1816         }
1817
1818         ast_str_append(&chan_data->stasis_stuff, 0, "%s", args->app);
1819         if (!ast_strlen_zero(args->app_args)) {
1820                 ast_str_append(&chan_data->stasis_stuff, 0, ",%s", args->app_args);
1821         }
1822
1823         dialtech = ast_strdupa(args->endpoint);
1824         if ((stuff = strchr(dialtech, '/'))) {
1825                 *stuff++ = '\0';
1826                 ast_copy_string(dialdevice, stuff, sizeof(dialdevice));
1827         }
1828
1829         originator = ast_channel_get_by_name(args->originator);
1830         if (originator) {
1831                 request_cap = ao2_bump(ast_channel_nativeformats(originator));
1832                 if (!ast_strlen_zero(args->app)) {
1833                         stasis_app_subscribe_channel(args->app, originator);
1834                 }
1835         } else if (!ast_strlen_zero(args->formats)) {
1836                 char *format_name;
1837                 char *formats_copy = ast_strdupa(args->formats);
1838
1839                 if (!(request_cap = ast_format_cap_alloc(AST_FORMAT_CAP_FLAG_DEFAULT))) {
1840                         ast_ari_response_alloc_failed(response);
1841                         chan_data_destroy(chan_data);
1842                         return;
1843                 }
1844
1845                 while ((format_name = ast_strip(strsep(&formats_copy, ",")))) {
1846                         struct ast_format *fmt = ast_format_cache_get(format_name);
1847
1848                         if (!fmt || ast_format_cap_append(request_cap, fmt, 0)) {
1849                                 if (!fmt) {
1850                                         ast_ari_response_error(
1851                                                 response, 400, "Bad Request",
1852                                                 "Provided format (%s) was not found", format_name);
1853                                 } else {
1854                                         ast_ari_response_alloc_failed(response);
1855                                 }
1856                                 ao2_ref(request_cap, -1);
1857                                 ao2_cleanup(fmt);
1858                                 chan_data_destroy(chan_data);
1859                                 return;
1860                         }
1861                         ao2_ref(fmt, -1);
1862                 }
1863         } else {
1864                 if (!(request_cap = ast_format_cap_alloc(AST_FORMAT_CAP_FLAG_DEFAULT))) {
1865                         ast_ari_response_alloc_failed(response);
1866                         chan_data_destroy(chan_data);
1867                         return;
1868                 }
1869
1870                 ast_format_cap_append_by_type(request_cap, AST_MEDIA_TYPE_AUDIO);
1871         }
1872
1873         chan_data->chan = ast_request(dialtech, request_cap, &assignedids, originator, dialdevice, &cause);
1874         ao2_cleanup(request_cap);
1875
1876         if (!chan_data->chan) {
1877                 if (ast_channel_errno() == AST_CHANNEL_ERROR_ID_EXISTS) {
1878                         ast_ari_response_error(response, 409, "Conflict",
1879                                 "Channel with given unique ID already exists");
1880                 } else {
1881                         ast_ari_response_alloc_failed(response);
1882                 }
1883                 ast_channel_cleanup(originator);
1884                 chan_data_destroy(chan_data);
1885                 return;
1886         }
1887
1888         if (!ast_strlen_zero(args->app)) {
1889                 stasis_app_subscribe_channel(args->app, chan_data->chan);
1890         }
1891
1892         ast_channel_cleanup(originator);
1893
1894         if (save_dialstring(chan_data->chan, stuff)) {
1895                 ast_ari_response_alloc_failed(response);
1896                 chan_data_destroy(chan_data);
1897                 return;
1898         }
1899
1900         snapshot = ast_channel_snapshot_get_latest(ast_channel_uniqueid(chan_data->chan));
1901
1902         if (ast_pthread_create_detached(&thread, NULL, ari_channel_thread, chan_data)) {
1903                 ast_ari_response_alloc_failed(response);
1904                 chan_data_destroy(chan_data);
1905         } else {
1906                 ast_ari_response_ok(response, ast_channel_snapshot_to_json(snapshot, NULL));
1907         }
1908
1909         ao2_ref(snapshot, -1);
1910 }
1911
1912 void ast_ari_channels_dial(struct ast_variable *headers,
1913         struct ast_ari_channels_dial_args *args,
1914         struct ast_ari_response *response)
1915 {
1916         RAII_VAR(struct stasis_app_control *, control, NULL, ao2_cleanup);
1917         RAII_VAR(struct ast_channel *, caller, NULL, ast_channel_cleanup);
1918         RAII_VAR(struct ast_channel *, callee, NULL, ast_channel_cleanup);
1919         char *dialstring;
1920
1921         control = find_control(response, args->channel_id);
1922         if (control == NULL) {
1923                 /* Response filled in by find_control */
1924                 return;
1925         }
1926
1927         caller = ast_channel_get_by_name(args->caller);
1928
1929         callee = ast_channel_get_by_name(args->channel_id);
1930         if (!callee) {
1931                 ast_ari_response_error(response, 404, "Not Found",
1932                         "Callee not found");
1933                 return;
1934         }
1935
1936         if (ast_channel_state(callee) != AST_STATE_DOWN
1937                 && ast_channel_state(callee) != AST_STATE_RESERVED) {
1938                 ast_ari_response_error(response, 409, "Conflict",
1939                         "Channel is not in the 'Down' state");
1940                 return;
1941         }
1942
1943         /* XXX This is straight up copied from main/dial.c. It's probably good
1944          * to separate this to some common method.
1945          */
1946         if (caller) {
1947                 ast_channel_lock_both(caller, callee);
1948         } else {
1949                 ast_channel_lock(callee);
1950         }
1951
1952         dialstring = restore_dialstring(callee);
1953         if (!dialstring) {
1954                 ast_channel_unlock(callee);
1955                 if (caller) {
1956                         ast_channel_unlock(caller);
1957                 }
1958                 ast_ari_response_error(response, 409, "Conflict",
1959                         "Dialing a channel not created by ARI");
1960                 return;
1961         }
1962         /* Make a copy of the dialstring just in case some jerk tries to hang up the
1963          * channel before we can actually dial
1964          */
1965         dialstring = ast_strdupa(dialstring);
1966
1967         ast_channel_stage_snapshot(callee);
1968         if (caller) {
1969                 ast_channel_inherit_variables(caller, callee);
1970                 ast_channel_datastore_inherit(caller, callee);
1971                 ast_max_forwards_decrement(callee);
1972
1973                 /* Copy over callerid information */
1974                 ast_party_redirecting_copy(ast_channel_redirecting(callee), ast_channel_redirecting(caller));
1975
1976                 ast_channel_dialed(callee)->transit_network_select = ast_channel_dialed(caller)->transit_network_select;
1977
1978                 ast_connected_line_copy_from_caller(ast_channel_connected(callee), ast_channel_caller(caller));
1979
1980                 ast_channel_language_set(callee, ast_channel_language(caller));
1981                 ast_channel_req_accountcodes(callee, caller, AST_CHANNEL_REQUESTOR_BRIDGE_PEER);
1982                 if (ast_strlen_zero(ast_channel_musicclass(callee)))
1983                         ast_channel_musicclass_set(callee, ast_channel_musicclass(caller));
1984
1985                 ast_channel_adsicpe_set(callee, ast_channel_adsicpe(caller));
1986                 ast_channel_transfercapability_set(callee, ast_channel_transfercapability(caller));
1987                 ast_channel_unlock(caller);
1988         }
1989
1990         ast_channel_stage_snapshot_done(callee);
1991         ast_channel_unlock(callee);
1992
1993         if (stasis_app_control_dial(control, dialstring, args->timeout)) {
1994                 ast_ari_response_alloc_failed(response);
1995                 return;
1996         }
1997
1998         ast_ari_response_no_content(response);
1999 }
2000
2001 void ast_ari_channels_rtpstatistics(struct ast_variable *headers,
2002                 struct ast_ari_channels_rtpstatistics_args *args,
2003                 struct ast_ari_response *response)
2004 {
2005         RAII_VAR(struct ast_channel *, chan, NULL, ast_channel_cleanup);
2006         RAII_VAR(struct ast_rtp_instance *, rtp, NULL, ao2_cleanup);
2007         struct ast_json *j_res;
2008         const struct ast_channel_tech *tech;
2009         struct ast_rtp_glue *glue;
2010
2011         chan = ast_channel_get_by_name(args->channel_id);
2012         if (!chan) {
2013                 ast_ari_response_error(response, 404, "Not Found",
2014                         "Channel not found");
2015                 return;
2016         }
2017
2018         ast_channel_lock(chan);
2019         tech = ast_channel_tech(chan);
2020         if (!tech) {
2021                 ast_channel_unlock(chan);
2022                 ast_ari_response_error(response, 404, "Not Found",
2023                         "Channel's tech not found");
2024                 return;
2025         }
2026
2027         glue = ast_rtp_instance_get_glue(tech->type);
2028         if (!glue) {
2029                 ast_channel_unlock(chan);
2030                 ast_ari_response_error(response, 403, "Forbidden",
2031                         "Unsupported channel type");
2032                 return;
2033         }
2034
2035         glue->get_rtp_info(chan, &rtp);
2036         if (!rtp) {
2037                 ast_channel_unlock(chan);
2038                 ast_ari_response_error(response, 404, "Not Found",
2039                         "RTP info not found");
2040                 return;
2041         }
2042
2043         j_res = ast_rtp_instance_get_stats_all_json(rtp);
2044         if (!j_res) {
2045                 ast_channel_unlock(chan);
2046                 ast_ari_response_error(response, 404, "Not Found",
2047                         "Statistics not found");
2048                 return;
2049         }
2050
2051         ast_channel_unlock(chan);
2052         ast_ari_response_ok(response, j_res);
2053
2054         return;
2055 }