Merge "res_pjsip: New endpoint option "refer_blind_progress""
[asterisk/asterisk.git] / res / res_ari_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 /*
20  * !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
21  * !!!!!                               DO NOT EDIT                        !!!!!
22  * !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
23  * This file is generated by a mustache template. Please see the original
24  * template in rest-api-templates/res_ari_resource.c.mustache
25  */
26
27 /*! \file
28  *
29  * \brief Channel resources
30  *
31  * \author David M. Lee, II <dlee@digium.com>
32  */
33
34 /*** MODULEINFO
35         <depend type="module">res_ari</depend>
36         <depend type="module">res_ari_model</depend>
37         <depend type="module">res_stasis</depend>
38         <support_level>core</support_level>
39  ***/
40
41 #include "asterisk.h"
42
43 #include "asterisk/app.h"
44 #include "asterisk/module.h"
45 #include "asterisk/stasis_app.h"
46 #include "ari/resource_channels.h"
47 #if defined(AST_DEVMODE)
48 #include "ari/ari_model_validators.h"
49 #endif
50
51 #define MAX_VALS 128
52
53 /*!
54  * \brief Parameter parsing callback for /channels.
55  * \param get_params GET parameters in the HTTP request.
56  * \param path_vars Path variables extracted from the request.
57  * \param headers HTTP headers.
58  * \param[out] response Response to the HTTP request.
59  */
60 static void ast_ari_channels_list_cb(
61         struct ast_tcptls_session_instance *ser,
62         struct ast_variable *get_params, struct ast_variable *path_vars,
63         struct ast_variable *headers, struct ast_json *body, struct ast_ari_response *response)
64 {
65         struct ast_ari_channels_list_args args = {};
66 #if defined(AST_DEVMODE)
67         int is_valid;
68         int code;
69 #endif /* AST_DEVMODE */
70
71         ast_ari_channels_list(headers, &args, response);
72 #if defined(AST_DEVMODE)
73         code = response->response_code;
74
75         switch (code) {
76         case 0: /* Implementation is still a stub, or the code wasn't set */
77                 is_valid = response->message == NULL;
78                 break;
79         case 500: /* Internal Server Error */
80         case 501: /* Not Implemented */
81                 is_valid = 1;
82                 break;
83         default:
84                 if (200 <= code && code <= 299) {
85                         is_valid = ast_ari_validate_list(response->message,
86                                 ast_ari_validate_channel_fn());
87                 } else {
88                         ast_log(LOG_ERROR, "Invalid error response %d for /channels\n", code);
89                         is_valid = 0;
90                 }
91         }
92
93         if (!is_valid) {
94                 ast_log(LOG_ERROR, "Response validation failed for /channels\n");
95                 ast_ari_response_error(response, 500,
96                         "Internal Server Error", "Response validation failed");
97         }
98 #endif /* AST_DEVMODE */
99
100 fin: __attribute__((unused))
101         return;
102 }
103 int ast_ari_channels_originate_parse_body(
104         struct ast_json *body,
105         struct ast_ari_channels_originate_args *args)
106 {
107         struct ast_json *field;
108         /* Parse query parameters out of it */
109         field = ast_json_object_get(body, "endpoint");
110         if (field) {
111                 args->endpoint = ast_json_string_get(field);
112         }
113         field = ast_json_object_get(body, "extension");
114         if (field) {
115                 args->extension = ast_json_string_get(field);
116         }
117         field = ast_json_object_get(body, "context");
118         if (field) {
119                 args->context = ast_json_string_get(field);
120         }
121         field = ast_json_object_get(body, "priority");
122         if (field) {
123                 args->priority = ast_json_integer_get(field);
124         }
125         field = ast_json_object_get(body, "label");
126         if (field) {
127                 args->label = ast_json_string_get(field);
128         }
129         field = ast_json_object_get(body, "app");
130         if (field) {
131                 args->app = ast_json_string_get(field);
132         }
133         field = ast_json_object_get(body, "appArgs");
134         if (field) {
135                 args->app_args = ast_json_string_get(field);
136         }
137         field = ast_json_object_get(body, "callerId");
138         if (field) {
139                 args->caller_id = ast_json_string_get(field);
140         }
141         field = ast_json_object_get(body, "timeout");
142         if (field) {
143                 args->timeout = ast_json_integer_get(field);
144         }
145         field = ast_json_object_get(body, "channelId");
146         if (field) {
147                 args->channel_id = ast_json_string_get(field);
148         }
149         field = ast_json_object_get(body, "otherChannelId");
150         if (field) {
151                 args->other_channel_id = ast_json_string_get(field);
152         }
153         field = ast_json_object_get(body, "originator");
154         if (field) {
155                 args->originator = ast_json_string_get(field);
156         }
157         field = ast_json_object_get(body, "formats");
158         if (field) {
159                 args->formats = ast_json_string_get(field);
160         }
161         return 0;
162 }
163
164 /*!
165  * \brief Parameter parsing callback for /channels.
166  * \param get_params GET parameters in the HTTP request.
167  * \param path_vars Path variables extracted from the request.
168  * \param headers HTTP headers.
169  * \param[out] response Response to the HTTP request.
170  */
171 static void ast_ari_channels_originate_cb(
172         struct ast_tcptls_session_instance *ser,
173         struct ast_variable *get_params, struct ast_variable *path_vars,
174         struct ast_variable *headers, struct ast_json *body, struct ast_ari_response *response)
175 {
176         struct ast_ari_channels_originate_args args = {};
177         struct ast_variable *i;
178 #if defined(AST_DEVMODE)
179         int is_valid;
180         int code;
181 #endif /* AST_DEVMODE */
182
183         for (i = get_params; i; i = i->next) {
184                 if (strcmp(i->name, "endpoint") == 0) {
185                         args.endpoint = (i->value);
186                 } else
187                 if (strcmp(i->name, "extension") == 0) {
188                         args.extension = (i->value);
189                 } else
190                 if (strcmp(i->name, "context") == 0) {
191                         args.context = (i->value);
192                 } else
193                 if (strcmp(i->name, "priority") == 0) {
194                         args.priority = atol(i->value);
195                 } else
196                 if (strcmp(i->name, "label") == 0) {
197                         args.label = (i->value);
198                 } else
199                 if (strcmp(i->name, "app") == 0) {
200                         args.app = (i->value);
201                 } else
202                 if (strcmp(i->name, "appArgs") == 0) {
203                         args.app_args = (i->value);
204                 } else
205                 if (strcmp(i->name, "callerId") == 0) {
206                         args.caller_id = (i->value);
207                 } else
208                 if (strcmp(i->name, "timeout") == 0) {
209                         args.timeout = atoi(i->value);
210                 } else
211                 if (strcmp(i->name, "channelId") == 0) {
212                         args.channel_id = (i->value);
213                 } else
214                 if (strcmp(i->name, "otherChannelId") == 0) {
215                         args.other_channel_id = (i->value);
216                 } else
217                 if (strcmp(i->name, "originator") == 0) {
218                         args.originator = (i->value);
219                 } else
220                 if (strcmp(i->name, "formats") == 0) {
221                         args.formats = (i->value);
222                 } else
223                 {}
224         }
225         args.variables = body;
226         ast_ari_channels_originate(headers, &args, response);
227 #if defined(AST_DEVMODE)
228         code = response->response_code;
229
230         switch (code) {
231         case 0: /* Implementation is still a stub, or the code wasn't set */
232                 is_valid = response->message == NULL;
233                 break;
234         case 500: /* Internal Server Error */
235         case 501: /* Not Implemented */
236         case 400: /* Invalid parameters for originating a channel. */
237         case 409: /* Channel with given unique ID already exists. */
238                 is_valid = 1;
239                 break;
240         default:
241                 if (200 <= code && code <= 299) {
242                         is_valid = ast_ari_validate_channel(
243                                 response->message);
244                 } else {
245                         ast_log(LOG_ERROR, "Invalid error response %d for /channels\n", code);
246                         is_valid = 0;
247                 }
248         }
249
250         if (!is_valid) {
251                 ast_log(LOG_ERROR, "Response validation failed for /channels\n");
252                 ast_ari_response_error(response, 500,
253                         "Internal Server Error", "Response validation failed");
254         }
255 #endif /* AST_DEVMODE */
256
257 fin: __attribute__((unused))
258         return;
259 }
260 int ast_ari_channels_create_parse_body(
261         struct ast_json *body,
262         struct ast_ari_channels_create_args *args)
263 {
264         struct ast_json *field;
265         /* Parse query parameters out of it */
266         field = ast_json_object_get(body, "endpoint");
267         if (field) {
268                 args->endpoint = ast_json_string_get(field);
269         }
270         field = ast_json_object_get(body, "app");
271         if (field) {
272                 args->app = ast_json_string_get(field);
273         }
274         field = ast_json_object_get(body, "appArgs");
275         if (field) {
276                 args->app_args = ast_json_string_get(field);
277         }
278         field = ast_json_object_get(body, "channelId");
279         if (field) {
280                 args->channel_id = ast_json_string_get(field);
281         }
282         field = ast_json_object_get(body, "otherChannelId");
283         if (field) {
284                 args->other_channel_id = ast_json_string_get(field);
285         }
286         field = ast_json_object_get(body, "originator");
287         if (field) {
288                 args->originator = ast_json_string_get(field);
289         }
290         field = ast_json_object_get(body, "formats");
291         if (field) {
292                 args->formats = ast_json_string_get(field);
293         }
294         return 0;
295 }
296
297 /*!
298  * \brief Parameter parsing callback for /channels/create.
299  * \param get_params GET parameters in the HTTP request.
300  * \param path_vars Path variables extracted from the request.
301  * \param headers HTTP headers.
302  * \param[out] response Response to the HTTP request.
303  */
304 static void ast_ari_channels_create_cb(
305         struct ast_tcptls_session_instance *ser,
306         struct ast_variable *get_params, struct ast_variable *path_vars,
307         struct ast_variable *headers, struct ast_json *body, struct ast_ari_response *response)
308 {
309         struct ast_ari_channels_create_args args = {};
310         struct ast_variable *i;
311 #if defined(AST_DEVMODE)
312         int is_valid;
313         int code;
314 #endif /* AST_DEVMODE */
315
316         for (i = get_params; i; i = i->next) {
317                 if (strcmp(i->name, "endpoint") == 0) {
318                         args.endpoint = (i->value);
319                 } else
320                 if (strcmp(i->name, "app") == 0) {
321                         args.app = (i->value);
322                 } else
323                 if (strcmp(i->name, "appArgs") == 0) {
324                         args.app_args = (i->value);
325                 } else
326                 if (strcmp(i->name, "channelId") == 0) {
327                         args.channel_id = (i->value);
328                 } else
329                 if (strcmp(i->name, "otherChannelId") == 0) {
330                         args.other_channel_id = (i->value);
331                 } else
332                 if (strcmp(i->name, "originator") == 0) {
333                         args.originator = (i->value);
334                 } else
335                 if (strcmp(i->name, "formats") == 0) {
336                         args.formats = (i->value);
337                 } else
338                 {}
339         }
340         if (ast_ari_channels_create_parse_body(body, &args)) {
341                 ast_ari_response_alloc_failed(response);
342                 goto fin;
343         }
344         ast_ari_channels_create(headers, &args, response);
345 #if defined(AST_DEVMODE)
346         code = response->response_code;
347
348         switch (code) {
349         case 0: /* Implementation is still a stub, or the code wasn't set */
350                 is_valid = response->message == NULL;
351                 break;
352         case 500: /* Internal Server Error */
353         case 501: /* Not Implemented */
354         case 409: /* Channel with given unique ID already exists. */
355                 is_valid = 1;
356                 break;
357         default:
358                 if (200 <= code && code <= 299) {
359                         is_valid = ast_ari_validate_channel(
360                                 response->message);
361                 } else {
362                         ast_log(LOG_ERROR, "Invalid error response %d for /channels/create\n", code);
363                         is_valid = 0;
364                 }
365         }
366
367         if (!is_valid) {
368                 ast_log(LOG_ERROR, "Response validation failed for /channels/create\n");
369                 ast_ari_response_error(response, 500,
370                         "Internal Server Error", "Response validation failed");
371         }
372 #endif /* AST_DEVMODE */
373
374 fin: __attribute__((unused))
375         return;
376 }
377 /*!
378  * \brief Parameter parsing callback for /channels/{channelId}.
379  * \param get_params GET parameters in the HTTP request.
380  * \param path_vars Path variables extracted from the request.
381  * \param headers HTTP headers.
382  * \param[out] response Response to the HTTP request.
383  */
384 static void ast_ari_channels_get_cb(
385         struct ast_tcptls_session_instance *ser,
386         struct ast_variable *get_params, struct ast_variable *path_vars,
387         struct ast_variable *headers, struct ast_json *body, struct ast_ari_response *response)
388 {
389         struct ast_ari_channels_get_args args = {};
390         struct ast_variable *i;
391 #if defined(AST_DEVMODE)
392         int is_valid;
393         int code;
394 #endif /* AST_DEVMODE */
395
396         for (i = path_vars; i; i = i->next) {
397                 if (strcmp(i->name, "channelId") == 0) {
398                         args.channel_id = (i->value);
399                 } else
400                 {}
401         }
402         ast_ari_channels_get(headers, &args, response);
403 #if defined(AST_DEVMODE)
404         code = response->response_code;
405
406         switch (code) {
407         case 0: /* Implementation is still a stub, or the code wasn't set */
408                 is_valid = response->message == NULL;
409                 break;
410         case 500: /* Internal Server Error */
411         case 501: /* Not Implemented */
412         case 404: /* Channel not found */
413                 is_valid = 1;
414                 break;
415         default:
416                 if (200 <= code && code <= 299) {
417                         is_valid = ast_ari_validate_channel(
418                                 response->message);
419                 } else {
420                         ast_log(LOG_ERROR, "Invalid error response %d for /channels/{channelId}\n", code);
421                         is_valid = 0;
422                 }
423         }
424
425         if (!is_valid) {
426                 ast_log(LOG_ERROR, "Response validation failed for /channels/{channelId}\n");
427                 ast_ari_response_error(response, 500,
428                         "Internal Server Error", "Response validation failed");
429         }
430 #endif /* AST_DEVMODE */
431
432 fin: __attribute__((unused))
433         return;
434 }
435 int ast_ari_channels_originate_with_id_parse_body(
436         struct ast_json *body,
437         struct ast_ari_channels_originate_with_id_args *args)
438 {
439         struct ast_json *field;
440         /* Parse query parameters out of it */
441         field = ast_json_object_get(body, "endpoint");
442         if (field) {
443                 args->endpoint = ast_json_string_get(field);
444         }
445         field = ast_json_object_get(body, "extension");
446         if (field) {
447                 args->extension = ast_json_string_get(field);
448         }
449         field = ast_json_object_get(body, "context");
450         if (field) {
451                 args->context = ast_json_string_get(field);
452         }
453         field = ast_json_object_get(body, "priority");
454         if (field) {
455                 args->priority = ast_json_integer_get(field);
456         }
457         field = ast_json_object_get(body, "label");
458         if (field) {
459                 args->label = ast_json_string_get(field);
460         }
461         field = ast_json_object_get(body, "app");
462         if (field) {
463                 args->app = ast_json_string_get(field);
464         }
465         field = ast_json_object_get(body, "appArgs");
466         if (field) {
467                 args->app_args = ast_json_string_get(field);
468         }
469         field = ast_json_object_get(body, "callerId");
470         if (field) {
471                 args->caller_id = ast_json_string_get(field);
472         }
473         field = ast_json_object_get(body, "timeout");
474         if (field) {
475                 args->timeout = ast_json_integer_get(field);
476         }
477         field = ast_json_object_get(body, "otherChannelId");
478         if (field) {
479                 args->other_channel_id = ast_json_string_get(field);
480         }
481         field = ast_json_object_get(body, "originator");
482         if (field) {
483                 args->originator = ast_json_string_get(field);
484         }
485         field = ast_json_object_get(body, "formats");
486         if (field) {
487                 args->formats = ast_json_string_get(field);
488         }
489         return 0;
490 }
491
492 /*!
493  * \brief Parameter parsing callback for /channels/{channelId}.
494  * \param get_params GET parameters in the HTTP request.
495  * \param path_vars Path variables extracted from the request.
496  * \param headers HTTP headers.
497  * \param[out] response Response to the HTTP request.
498  */
499 static void ast_ari_channels_originate_with_id_cb(
500         struct ast_tcptls_session_instance *ser,
501         struct ast_variable *get_params, struct ast_variable *path_vars,
502         struct ast_variable *headers, struct ast_json *body, struct ast_ari_response *response)
503 {
504         struct ast_ari_channels_originate_with_id_args args = {};
505         struct ast_variable *i;
506 #if defined(AST_DEVMODE)
507         int is_valid;
508         int code;
509 #endif /* AST_DEVMODE */
510
511         for (i = get_params; i; i = i->next) {
512                 if (strcmp(i->name, "endpoint") == 0) {
513                         args.endpoint = (i->value);
514                 } else
515                 if (strcmp(i->name, "extension") == 0) {
516                         args.extension = (i->value);
517                 } else
518                 if (strcmp(i->name, "context") == 0) {
519                         args.context = (i->value);
520                 } else
521                 if (strcmp(i->name, "priority") == 0) {
522                         args.priority = atol(i->value);
523                 } else
524                 if (strcmp(i->name, "label") == 0) {
525                         args.label = (i->value);
526                 } else
527                 if (strcmp(i->name, "app") == 0) {
528                         args.app = (i->value);
529                 } else
530                 if (strcmp(i->name, "appArgs") == 0) {
531                         args.app_args = (i->value);
532                 } else
533                 if (strcmp(i->name, "callerId") == 0) {
534                         args.caller_id = (i->value);
535                 } else
536                 if (strcmp(i->name, "timeout") == 0) {
537                         args.timeout = atoi(i->value);
538                 } else
539                 if (strcmp(i->name, "otherChannelId") == 0) {
540                         args.other_channel_id = (i->value);
541                 } else
542                 if (strcmp(i->name, "originator") == 0) {
543                         args.originator = (i->value);
544                 } else
545                 if (strcmp(i->name, "formats") == 0) {
546                         args.formats = (i->value);
547                 } else
548                 {}
549         }
550         for (i = path_vars; i; i = i->next) {
551                 if (strcmp(i->name, "channelId") == 0) {
552                         args.channel_id = (i->value);
553                 } else
554                 {}
555         }
556         args.variables = body;
557         ast_ari_channels_originate_with_id(headers, &args, response);
558 #if defined(AST_DEVMODE)
559         code = response->response_code;
560
561         switch (code) {
562         case 0: /* Implementation is still a stub, or the code wasn't set */
563                 is_valid = response->message == NULL;
564                 break;
565         case 500: /* Internal Server Error */
566         case 501: /* Not Implemented */
567         case 400: /* Invalid parameters for originating a channel. */
568         case 409: /* Channel with given unique ID already exists. */
569                 is_valid = 1;
570                 break;
571         default:
572                 if (200 <= code && code <= 299) {
573                         is_valid = ast_ari_validate_channel(
574                                 response->message);
575                 } else {
576                         ast_log(LOG_ERROR, "Invalid error response %d for /channels/{channelId}\n", code);
577                         is_valid = 0;
578                 }
579         }
580
581         if (!is_valid) {
582                 ast_log(LOG_ERROR, "Response validation failed for /channels/{channelId}\n");
583                 ast_ari_response_error(response, 500,
584                         "Internal Server Error", "Response validation failed");
585         }
586 #endif /* AST_DEVMODE */
587
588 fin: __attribute__((unused))
589         return;
590 }
591 int ast_ari_channels_hangup_parse_body(
592         struct ast_json *body,
593         struct ast_ari_channels_hangup_args *args)
594 {
595         struct ast_json *field;
596         /* Parse query parameters out of it */
597         field = ast_json_object_get(body, "reason");
598         if (field) {
599                 args->reason = ast_json_string_get(field);
600         }
601         return 0;
602 }
603
604 /*!
605  * \brief Parameter parsing callback for /channels/{channelId}.
606  * \param get_params GET parameters in the HTTP request.
607  * \param path_vars Path variables extracted from the request.
608  * \param headers HTTP headers.
609  * \param[out] response Response to the HTTP request.
610  */
611 static void ast_ari_channels_hangup_cb(
612         struct ast_tcptls_session_instance *ser,
613         struct ast_variable *get_params, struct ast_variable *path_vars,
614         struct ast_variable *headers, struct ast_json *body, struct ast_ari_response *response)
615 {
616         struct ast_ari_channels_hangup_args args = {};
617         struct ast_variable *i;
618 #if defined(AST_DEVMODE)
619         int is_valid;
620         int code;
621 #endif /* AST_DEVMODE */
622
623         for (i = get_params; i; i = i->next) {
624                 if (strcmp(i->name, "reason") == 0) {
625                         args.reason = (i->value);
626                 } else
627                 {}
628         }
629         for (i = path_vars; i; i = i->next) {
630                 if (strcmp(i->name, "channelId") == 0) {
631                         args.channel_id = (i->value);
632                 } else
633                 {}
634         }
635         if (ast_ari_channels_hangup_parse_body(body, &args)) {
636                 ast_ari_response_alloc_failed(response);
637                 goto fin;
638         }
639         ast_ari_channels_hangup(headers, &args, response);
640 #if defined(AST_DEVMODE)
641         code = response->response_code;
642
643         switch (code) {
644         case 0: /* Implementation is still a stub, or the code wasn't set */
645                 is_valid = response->message == NULL;
646                 break;
647         case 500: /* Internal Server Error */
648         case 501: /* Not Implemented */
649         case 400: /* Invalid reason for hangup provided */
650         case 404: /* Channel not found */
651                 is_valid = 1;
652                 break;
653         default:
654                 if (200 <= code && code <= 299) {
655                         is_valid = ast_ari_validate_void(
656                                 response->message);
657                 } else {
658                         ast_log(LOG_ERROR, "Invalid error response %d for /channels/{channelId}\n", code);
659                         is_valid = 0;
660                 }
661         }
662
663         if (!is_valid) {
664                 ast_log(LOG_ERROR, "Response validation failed for /channels/{channelId}\n");
665                 ast_ari_response_error(response, 500,
666                         "Internal Server Error", "Response validation failed");
667         }
668 #endif /* AST_DEVMODE */
669
670 fin: __attribute__((unused))
671         return;
672 }
673 int ast_ari_channels_continue_in_dialplan_parse_body(
674         struct ast_json *body,
675         struct ast_ari_channels_continue_in_dialplan_args *args)
676 {
677         struct ast_json *field;
678         /* Parse query parameters out of it */
679         field = ast_json_object_get(body, "context");
680         if (field) {
681                 args->context = ast_json_string_get(field);
682         }
683         field = ast_json_object_get(body, "extension");
684         if (field) {
685                 args->extension = ast_json_string_get(field);
686         }
687         field = ast_json_object_get(body, "priority");
688         if (field) {
689                 args->priority = ast_json_integer_get(field);
690         }
691         field = ast_json_object_get(body, "label");
692         if (field) {
693                 args->label = ast_json_string_get(field);
694         }
695         return 0;
696 }
697
698 /*!
699  * \brief Parameter parsing callback for /channels/{channelId}/continue.
700  * \param get_params GET parameters in the HTTP request.
701  * \param path_vars Path variables extracted from the request.
702  * \param headers HTTP headers.
703  * \param[out] response Response to the HTTP request.
704  */
705 static void ast_ari_channels_continue_in_dialplan_cb(
706         struct ast_tcptls_session_instance *ser,
707         struct ast_variable *get_params, struct ast_variable *path_vars,
708         struct ast_variable *headers, struct ast_json *body, struct ast_ari_response *response)
709 {
710         struct ast_ari_channels_continue_in_dialplan_args args = {};
711         struct ast_variable *i;
712 #if defined(AST_DEVMODE)
713         int is_valid;
714         int code;
715 #endif /* AST_DEVMODE */
716
717         for (i = get_params; i; i = i->next) {
718                 if (strcmp(i->name, "context") == 0) {
719                         args.context = (i->value);
720                 } else
721                 if (strcmp(i->name, "extension") == 0) {
722                         args.extension = (i->value);
723                 } else
724                 if (strcmp(i->name, "priority") == 0) {
725                         args.priority = atoi(i->value);
726                 } else
727                 if (strcmp(i->name, "label") == 0) {
728                         args.label = (i->value);
729                 } else
730                 {}
731         }
732         for (i = path_vars; i; i = i->next) {
733                 if (strcmp(i->name, "channelId") == 0) {
734                         args.channel_id = (i->value);
735                 } else
736                 {}
737         }
738         if (ast_ari_channels_continue_in_dialplan_parse_body(body, &args)) {
739                 ast_ari_response_alloc_failed(response);
740                 goto fin;
741         }
742         ast_ari_channels_continue_in_dialplan(headers, &args, response);
743 #if defined(AST_DEVMODE)
744         code = response->response_code;
745
746         switch (code) {
747         case 0: /* Implementation is still a stub, or the code wasn't set */
748                 is_valid = response->message == NULL;
749                 break;
750         case 500: /* Internal Server Error */
751         case 501: /* Not Implemented */
752         case 404: /* Channel not found */
753         case 409: /* Channel not in a Stasis application */
754         case 412: /* Channel in invalid state */
755                 is_valid = 1;
756                 break;
757         default:
758                 if (200 <= code && code <= 299) {
759                         is_valid = ast_ari_validate_void(
760                                 response->message);
761                 } else {
762                         ast_log(LOG_ERROR, "Invalid error response %d for /channels/{channelId}/continue\n", code);
763                         is_valid = 0;
764                 }
765         }
766
767         if (!is_valid) {
768                 ast_log(LOG_ERROR, "Response validation failed for /channels/{channelId}/continue\n");
769                 ast_ari_response_error(response, 500,
770                         "Internal Server Error", "Response validation failed");
771         }
772 #endif /* AST_DEVMODE */
773
774 fin: __attribute__((unused))
775         return;
776 }
777 int ast_ari_channels_redirect_parse_body(
778         struct ast_json *body,
779         struct ast_ari_channels_redirect_args *args)
780 {
781         struct ast_json *field;
782         /* Parse query parameters out of it */
783         field = ast_json_object_get(body, "endpoint");
784         if (field) {
785                 args->endpoint = ast_json_string_get(field);
786         }
787         return 0;
788 }
789
790 /*!
791  * \brief Parameter parsing callback for /channels/{channelId}/redirect.
792  * \param get_params GET parameters in the HTTP request.
793  * \param path_vars Path variables extracted from the request.
794  * \param headers HTTP headers.
795  * \param[out] response Response to the HTTP request.
796  */
797 static void ast_ari_channels_redirect_cb(
798         struct ast_tcptls_session_instance *ser,
799         struct ast_variable *get_params, struct ast_variable *path_vars,
800         struct ast_variable *headers, struct ast_json *body, struct ast_ari_response *response)
801 {
802         struct ast_ari_channels_redirect_args args = {};
803         struct ast_variable *i;
804 #if defined(AST_DEVMODE)
805         int is_valid;
806         int code;
807 #endif /* AST_DEVMODE */
808
809         for (i = get_params; i; i = i->next) {
810                 if (strcmp(i->name, "endpoint") == 0) {
811                         args.endpoint = (i->value);
812                 } else
813                 {}
814         }
815         for (i = path_vars; i; i = i->next) {
816                 if (strcmp(i->name, "channelId") == 0) {
817                         args.channel_id = (i->value);
818                 } else
819                 {}
820         }
821         if (ast_ari_channels_redirect_parse_body(body, &args)) {
822                 ast_ari_response_alloc_failed(response);
823                 goto fin;
824         }
825         ast_ari_channels_redirect(headers, &args, response);
826 #if defined(AST_DEVMODE)
827         code = response->response_code;
828
829         switch (code) {
830         case 0: /* Implementation is still a stub, or the code wasn't set */
831                 is_valid = response->message == NULL;
832                 break;
833         case 500: /* Internal Server Error */
834         case 501: /* Not Implemented */
835         case 400: /* Endpoint parameter not provided */
836         case 404: /* Channel or endpoint not found */
837         case 409: /* Channel not in a Stasis application */
838         case 422: /* Endpoint is not the same type as the channel */
839         case 412: /* Channel in invalid state */
840                 is_valid = 1;
841                 break;
842         default:
843                 if (200 <= code && code <= 299) {
844                         is_valid = ast_ari_validate_void(
845                                 response->message);
846                 } else {
847                         ast_log(LOG_ERROR, "Invalid error response %d for /channels/{channelId}/redirect\n", code);
848                         is_valid = 0;
849                 }
850         }
851
852         if (!is_valid) {
853                 ast_log(LOG_ERROR, "Response validation failed for /channels/{channelId}/redirect\n");
854                 ast_ari_response_error(response, 500,
855                         "Internal Server Error", "Response validation failed");
856         }
857 #endif /* AST_DEVMODE */
858
859 fin: __attribute__((unused))
860         return;
861 }
862 /*!
863  * \brief Parameter parsing callback for /channels/{channelId}/answer.
864  * \param get_params GET parameters in the HTTP request.
865  * \param path_vars Path variables extracted from the request.
866  * \param headers HTTP headers.
867  * \param[out] response Response to the HTTP request.
868  */
869 static void ast_ari_channels_answer_cb(
870         struct ast_tcptls_session_instance *ser,
871         struct ast_variable *get_params, struct ast_variable *path_vars,
872         struct ast_variable *headers, struct ast_json *body, struct ast_ari_response *response)
873 {
874         struct ast_ari_channels_answer_args args = {};
875         struct ast_variable *i;
876 #if defined(AST_DEVMODE)
877         int is_valid;
878         int code;
879 #endif /* AST_DEVMODE */
880
881         for (i = path_vars; i; i = i->next) {
882                 if (strcmp(i->name, "channelId") == 0) {
883                         args.channel_id = (i->value);
884                 } else
885                 {}
886         }
887         ast_ari_channels_answer(headers, &args, response);
888 #if defined(AST_DEVMODE)
889         code = response->response_code;
890
891         switch (code) {
892         case 0: /* Implementation is still a stub, or the code wasn't set */
893                 is_valid = response->message == NULL;
894                 break;
895         case 500: /* Internal Server Error */
896         case 501: /* Not Implemented */
897         case 404: /* Channel not found */
898         case 409: /* Channel not in a Stasis application */
899         case 412: /* Channel in invalid state */
900                 is_valid = 1;
901                 break;
902         default:
903                 if (200 <= code && code <= 299) {
904                         is_valid = ast_ari_validate_void(
905                                 response->message);
906                 } else {
907                         ast_log(LOG_ERROR, "Invalid error response %d for /channels/{channelId}/answer\n", code);
908                         is_valid = 0;
909                 }
910         }
911
912         if (!is_valid) {
913                 ast_log(LOG_ERROR, "Response validation failed for /channels/{channelId}/answer\n");
914                 ast_ari_response_error(response, 500,
915                         "Internal Server Error", "Response validation failed");
916         }
917 #endif /* AST_DEVMODE */
918
919 fin: __attribute__((unused))
920         return;
921 }
922 /*!
923  * \brief Parameter parsing callback for /channels/{channelId}/ring.
924  * \param get_params GET parameters in the HTTP request.
925  * \param path_vars Path variables extracted from the request.
926  * \param headers HTTP headers.
927  * \param[out] response Response to the HTTP request.
928  */
929 static void ast_ari_channels_ring_cb(
930         struct ast_tcptls_session_instance *ser,
931         struct ast_variable *get_params, struct ast_variable *path_vars,
932         struct ast_variable *headers, struct ast_json *body, struct ast_ari_response *response)
933 {
934         struct ast_ari_channels_ring_args args = {};
935         struct ast_variable *i;
936 #if defined(AST_DEVMODE)
937         int is_valid;
938         int code;
939 #endif /* AST_DEVMODE */
940
941         for (i = path_vars; i; i = i->next) {
942                 if (strcmp(i->name, "channelId") == 0) {
943                         args.channel_id = (i->value);
944                 } else
945                 {}
946         }
947         ast_ari_channels_ring(headers, &args, response);
948 #if defined(AST_DEVMODE)
949         code = response->response_code;
950
951         switch (code) {
952         case 0: /* Implementation is still a stub, or the code wasn't set */
953                 is_valid = response->message == NULL;
954                 break;
955         case 500: /* Internal Server Error */
956         case 501: /* Not Implemented */
957         case 404: /* Channel not found */
958         case 409: /* Channel not in a Stasis application */
959         case 412: /* Channel in invalid state */
960                 is_valid = 1;
961                 break;
962         default:
963                 if (200 <= code && code <= 299) {
964                         is_valid = ast_ari_validate_void(
965                                 response->message);
966                 } else {
967                         ast_log(LOG_ERROR, "Invalid error response %d for /channels/{channelId}/ring\n", code);
968                         is_valid = 0;
969                 }
970         }
971
972         if (!is_valid) {
973                 ast_log(LOG_ERROR, "Response validation failed for /channels/{channelId}/ring\n");
974                 ast_ari_response_error(response, 500,
975                         "Internal Server Error", "Response validation failed");
976         }
977 #endif /* AST_DEVMODE */
978
979 fin: __attribute__((unused))
980         return;
981 }
982 /*!
983  * \brief Parameter parsing callback for /channels/{channelId}/ring.
984  * \param get_params GET parameters in the HTTP request.
985  * \param path_vars Path variables extracted from the request.
986  * \param headers HTTP headers.
987  * \param[out] response Response to the HTTP request.
988  */
989 static void ast_ari_channels_ring_stop_cb(
990         struct ast_tcptls_session_instance *ser,
991         struct ast_variable *get_params, struct ast_variable *path_vars,
992         struct ast_variable *headers, struct ast_json *body, struct ast_ari_response *response)
993 {
994         struct ast_ari_channels_ring_stop_args args = {};
995         struct ast_variable *i;
996 #if defined(AST_DEVMODE)
997         int is_valid;
998         int code;
999 #endif /* AST_DEVMODE */
1000
1001         for (i = path_vars; i; i = i->next) {
1002                 if (strcmp(i->name, "channelId") == 0) {
1003                         args.channel_id = (i->value);
1004                 } else
1005                 {}
1006         }
1007         ast_ari_channels_ring_stop(headers, &args, response);
1008 #if defined(AST_DEVMODE)
1009         code = response->response_code;
1010
1011         switch (code) {
1012         case 0: /* Implementation is still a stub, or the code wasn't set */
1013                 is_valid = response->message == NULL;
1014                 break;
1015         case 500: /* Internal Server Error */
1016         case 501: /* Not Implemented */
1017         case 404: /* Channel not found */
1018         case 409: /* Channel not in a Stasis application */
1019         case 412: /* Channel in invalid state */
1020                 is_valid = 1;
1021                 break;
1022         default:
1023                 if (200 <= code && code <= 299) {
1024                         is_valid = ast_ari_validate_void(
1025                                 response->message);
1026                 } else {
1027                         ast_log(LOG_ERROR, "Invalid error response %d for /channels/{channelId}/ring\n", code);
1028                         is_valid = 0;
1029                 }
1030         }
1031
1032         if (!is_valid) {
1033                 ast_log(LOG_ERROR, "Response validation failed for /channels/{channelId}/ring\n");
1034                 ast_ari_response_error(response, 500,
1035                         "Internal Server Error", "Response validation failed");
1036         }
1037 #endif /* AST_DEVMODE */
1038
1039 fin: __attribute__((unused))
1040         return;
1041 }
1042 int ast_ari_channels_send_dtmf_parse_body(
1043         struct ast_json *body,
1044         struct ast_ari_channels_send_dtmf_args *args)
1045 {
1046         struct ast_json *field;
1047         /* Parse query parameters out of it */
1048         field = ast_json_object_get(body, "dtmf");
1049         if (field) {
1050                 args->dtmf = ast_json_string_get(field);
1051         }
1052         field = ast_json_object_get(body, "before");
1053         if (field) {
1054                 args->before = ast_json_integer_get(field);
1055         }
1056         field = ast_json_object_get(body, "between");
1057         if (field) {
1058                 args->between = ast_json_integer_get(field);
1059         }
1060         field = ast_json_object_get(body, "duration");
1061         if (field) {
1062                 args->duration = ast_json_integer_get(field);
1063         }
1064         field = ast_json_object_get(body, "after");
1065         if (field) {
1066                 args->after = ast_json_integer_get(field);
1067         }
1068         return 0;
1069 }
1070
1071 /*!
1072  * \brief Parameter parsing callback for /channels/{channelId}/dtmf.
1073  * \param get_params GET parameters in the HTTP request.
1074  * \param path_vars Path variables extracted from the request.
1075  * \param headers HTTP headers.
1076  * \param[out] response Response to the HTTP request.
1077  */
1078 static void ast_ari_channels_send_dtmf_cb(
1079         struct ast_tcptls_session_instance *ser,
1080         struct ast_variable *get_params, struct ast_variable *path_vars,
1081         struct ast_variable *headers, struct ast_json *body, struct ast_ari_response *response)
1082 {
1083         struct ast_ari_channels_send_dtmf_args args = {};
1084         struct ast_variable *i;
1085 #if defined(AST_DEVMODE)
1086         int is_valid;
1087         int code;
1088 #endif /* AST_DEVMODE */
1089
1090         for (i = get_params; i; i = i->next) {
1091                 if (strcmp(i->name, "dtmf") == 0) {
1092                         args.dtmf = (i->value);
1093                 } else
1094                 if (strcmp(i->name, "before") == 0) {
1095                         args.before = atoi(i->value);
1096                 } else
1097                 if (strcmp(i->name, "between") == 0) {
1098                         args.between = atoi(i->value);
1099                 } else
1100                 if (strcmp(i->name, "duration") == 0) {
1101                         args.duration = atoi(i->value);
1102                 } else
1103                 if (strcmp(i->name, "after") == 0) {
1104                         args.after = atoi(i->value);
1105                 } else
1106                 {}
1107         }
1108         for (i = path_vars; i; i = i->next) {
1109                 if (strcmp(i->name, "channelId") == 0) {
1110                         args.channel_id = (i->value);
1111                 } else
1112                 {}
1113         }
1114         if (ast_ari_channels_send_dtmf_parse_body(body, &args)) {
1115                 ast_ari_response_alloc_failed(response);
1116                 goto fin;
1117         }
1118         ast_ari_channels_send_dtmf(headers, &args, response);
1119 #if defined(AST_DEVMODE)
1120         code = response->response_code;
1121
1122         switch (code) {
1123         case 0: /* Implementation is still a stub, or the code wasn't set */
1124                 is_valid = response->message == NULL;
1125                 break;
1126         case 500: /* Internal Server Error */
1127         case 501: /* Not Implemented */
1128         case 400: /* DTMF is required */
1129         case 404: /* Channel not found */
1130         case 409: /* Channel not in a Stasis application */
1131         case 412: /* Channel in invalid state */
1132                 is_valid = 1;
1133                 break;
1134         default:
1135                 if (200 <= code && code <= 299) {
1136                         is_valid = ast_ari_validate_void(
1137                                 response->message);
1138                 } else {
1139                         ast_log(LOG_ERROR, "Invalid error response %d for /channels/{channelId}/dtmf\n", code);
1140                         is_valid = 0;
1141                 }
1142         }
1143
1144         if (!is_valid) {
1145                 ast_log(LOG_ERROR, "Response validation failed for /channels/{channelId}/dtmf\n");
1146                 ast_ari_response_error(response, 500,
1147                         "Internal Server Error", "Response validation failed");
1148         }
1149 #endif /* AST_DEVMODE */
1150
1151 fin: __attribute__((unused))
1152         return;
1153 }
1154 int ast_ari_channels_mute_parse_body(
1155         struct ast_json *body,
1156         struct ast_ari_channels_mute_args *args)
1157 {
1158         struct ast_json *field;
1159         /* Parse query parameters out of it */
1160         field = ast_json_object_get(body, "direction");
1161         if (field) {
1162                 args->direction = ast_json_string_get(field);
1163         }
1164         return 0;
1165 }
1166
1167 /*!
1168  * \brief Parameter parsing callback for /channels/{channelId}/mute.
1169  * \param get_params GET parameters in the HTTP request.
1170  * \param path_vars Path variables extracted from the request.
1171  * \param headers HTTP headers.
1172  * \param[out] response Response to the HTTP request.
1173  */
1174 static void ast_ari_channels_mute_cb(
1175         struct ast_tcptls_session_instance *ser,
1176         struct ast_variable *get_params, struct ast_variable *path_vars,
1177         struct ast_variable *headers, struct ast_json *body, struct ast_ari_response *response)
1178 {
1179         struct ast_ari_channels_mute_args args = {};
1180         struct ast_variable *i;
1181 #if defined(AST_DEVMODE)
1182         int is_valid;
1183         int code;
1184 #endif /* AST_DEVMODE */
1185
1186         for (i = get_params; i; i = i->next) {
1187                 if (strcmp(i->name, "direction") == 0) {
1188                         args.direction = (i->value);
1189                 } else
1190                 {}
1191         }
1192         for (i = path_vars; i; i = i->next) {
1193                 if (strcmp(i->name, "channelId") == 0) {
1194                         args.channel_id = (i->value);
1195                 } else
1196                 {}
1197         }
1198         if (ast_ari_channels_mute_parse_body(body, &args)) {
1199                 ast_ari_response_alloc_failed(response);
1200                 goto fin;
1201         }
1202         ast_ari_channels_mute(headers, &args, response);
1203 #if defined(AST_DEVMODE)
1204         code = response->response_code;
1205
1206         switch (code) {
1207         case 0: /* Implementation is still a stub, or the code wasn't set */
1208                 is_valid = response->message == NULL;
1209                 break;
1210         case 500: /* Internal Server Error */
1211         case 501: /* Not Implemented */
1212         case 404: /* Channel not found */
1213         case 409: /* Channel not in a Stasis application */
1214         case 412: /* Channel in invalid state */
1215                 is_valid = 1;
1216                 break;
1217         default:
1218                 if (200 <= code && code <= 299) {
1219                         is_valid = ast_ari_validate_void(
1220                                 response->message);
1221                 } else {
1222                         ast_log(LOG_ERROR, "Invalid error response %d for /channels/{channelId}/mute\n", code);
1223                         is_valid = 0;
1224                 }
1225         }
1226
1227         if (!is_valid) {
1228                 ast_log(LOG_ERROR, "Response validation failed for /channels/{channelId}/mute\n");
1229                 ast_ari_response_error(response, 500,
1230                         "Internal Server Error", "Response validation failed");
1231         }
1232 #endif /* AST_DEVMODE */
1233
1234 fin: __attribute__((unused))
1235         return;
1236 }
1237 int ast_ari_channels_unmute_parse_body(
1238         struct ast_json *body,
1239         struct ast_ari_channels_unmute_args *args)
1240 {
1241         struct ast_json *field;
1242         /* Parse query parameters out of it */
1243         field = ast_json_object_get(body, "direction");
1244         if (field) {
1245                 args->direction = ast_json_string_get(field);
1246         }
1247         return 0;
1248 }
1249
1250 /*!
1251  * \brief Parameter parsing callback for /channels/{channelId}/mute.
1252  * \param get_params GET parameters in the HTTP request.
1253  * \param path_vars Path variables extracted from the request.
1254  * \param headers HTTP headers.
1255  * \param[out] response Response to the HTTP request.
1256  */
1257 static void ast_ari_channels_unmute_cb(
1258         struct ast_tcptls_session_instance *ser,
1259         struct ast_variable *get_params, struct ast_variable *path_vars,
1260         struct ast_variable *headers, struct ast_json *body, struct ast_ari_response *response)
1261 {
1262         struct ast_ari_channels_unmute_args args = {};
1263         struct ast_variable *i;
1264 #if defined(AST_DEVMODE)
1265         int is_valid;
1266         int code;
1267 #endif /* AST_DEVMODE */
1268
1269         for (i = get_params; i; i = i->next) {
1270                 if (strcmp(i->name, "direction") == 0) {
1271                         args.direction = (i->value);
1272                 } else
1273                 {}
1274         }
1275         for (i = path_vars; i; i = i->next) {
1276                 if (strcmp(i->name, "channelId") == 0) {
1277                         args.channel_id = (i->value);
1278                 } else
1279                 {}
1280         }
1281         if (ast_ari_channels_unmute_parse_body(body, &args)) {
1282                 ast_ari_response_alloc_failed(response);
1283                 goto fin;
1284         }
1285         ast_ari_channels_unmute(headers, &args, response);
1286 #if defined(AST_DEVMODE)
1287         code = response->response_code;
1288
1289         switch (code) {
1290         case 0: /* Implementation is still a stub, or the code wasn't set */
1291                 is_valid = response->message == NULL;
1292                 break;
1293         case 500: /* Internal Server Error */
1294         case 501: /* Not Implemented */
1295         case 404: /* Channel not found */
1296         case 409: /* Channel not in a Stasis application */
1297         case 412: /* Channel in invalid state */
1298                 is_valid = 1;
1299                 break;
1300         default:
1301                 if (200 <= code && code <= 299) {
1302                         is_valid = ast_ari_validate_void(
1303                                 response->message);
1304                 } else {
1305                         ast_log(LOG_ERROR, "Invalid error response %d for /channels/{channelId}/mute\n", code);
1306                         is_valid = 0;
1307                 }
1308         }
1309
1310         if (!is_valid) {
1311                 ast_log(LOG_ERROR, "Response validation failed for /channels/{channelId}/mute\n");
1312                 ast_ari_response_error(response, 500,
1313                         "Internal Server Error", "Response validation failed");
1314         }
1315 #endif /* AST_DEVMODE */
1316
1317 fin: __attribute__((unused))
1318         return;
1319 }
1320 /*!
1321  * \brief Parameter parsing callback for /channels/{channelId}/hold.
1322  * \param get_params GET parameters in the HTTP request.
1323  * \param path_vars Path variables extracted from the request.
1324  * \param headers HTTP headers.
1325  * \param[out] response Response to the HTTP request.
1326  */
1327 static void ast_ari_channels_hold_cb(
1328         struct ast_tcptls_session_instance *ser,
1329         struct ast_variable *get_params, struct ast_variable *path_vars,
1330         struct ast_variable *headers, struct ast_json *body, struct ast_ari_response *response)
1331 {
1332         struct ast_ari_channels_hold_args args = {};
1333         struct ast_variable *i;
1334 #if defined(AST_DEVMODE)
1335         int is_valid;
1336         int code;
1337 #endif /* AST_DEVMODE */
1338
1339         for (i = path_vars; i; i = i->next) {
1340                 if (strcmp(i->name, "channelId") == 0) {
1341                         args.channel_id = (i->value);
1342                 } else
1343                 {}
1344         }
1345         ast_ari_channels_hold(headers, &args, response);
1346 #if defined(AST_DEVMODE)
1347         code = response->response_code;
1348
1349         switch (code) {
1350         case 0: /* Implementation is still a stub, or the code wasn't set */
1351                 is_valid = response->message == NULL;
1352                 break;
1353         case 500: /* Internal Server Error */
1354         case 501: /* Not Implemented */
1355         case 404: /* Channel not found */
1356         case 409: /* Channel not in a Stasis application */
1357         case 412: /* Channel in invalid state */
1358                 is_valid = 1;
1359                 break;
1360         default:
1361                 if (200 <= code && code <= 299) {
1362                         is_valid = ast_ari_validate_void(
1363                                 response->message);
1364                 } else {
1365                         ast_log(LOG_ERROR, "Invalid error response %d for /channels/{channelId}/hold\n", code);
1366                         is_valid = 0;
1367                 }
1368         }
1369
1370         if (!is_valid) {
1371                 ast_log(LOG_ERROR, "Response validation failed for /channels/{channelId}/hold\n");
1372                 ast_ari_response_error(response, 500,
1373                         "Internal Server Error", "Response validation failed");
1374         }
1375 #endif /* AST_DEVMODE */
1376
1377 fin: __attribute__((unused))
1378         return;
1379 }
1380 /*!
1381  * \brief Parameter parsing callback for /channels/{channelId}/hold.
1382  * \param get_params GET parameters in the HTTP request.
1383  * \param path_vars Path variables extracted from the request.
1384  * \param headers HTTP headers.
1385  * \param[out] response Response to the HTTP request.
1386  */
1387 static void ast_ari_channels_unhold_cb(
1388         struct ast_tcptls_session_instance *ser,
1389         struct ast_variable *get_params, struct ast_variable *path_vars,
1390         struct ast_variable *headers, struct ast_json *body, struct ast_ari_response *response)
1391 {
1392         struct ast_ari_channels_unhold_args args = {};
1393         struct ast_variable *i;
1394 #if defined(AST_DEVMODE)
1395         int is_valid;
1396         int code;
1397 #endif /* AST_DEVMODE */
1398
1399         for (i = path_vars; i; i = i->next) {
1400                 if (strcmp(i->name, "channelId") == 0) {
1401                         args.channel_id = (i->value);
1402                 } else
1403                 {}
1404         }
1405         ast_ari_channels_unhold(headers, &args, response);
1406 #if defined(AST_DEVMODE)
1407         code = response->response_code;
1408
1409         switch (code) {
1410         case 0: /* Implementation is still a stub, or the code wasn't set */
1411                 is_valid = response->message == NULL;
1412                 break;
1413         case 500: /* Internal Server Error */
1414         case 501: /* Not Implemented */
1415         case 404: /* Channel not found */
1416         case 409: /* Channel not in a Stasis application */
1417         case 412: /* Channel in invalid state */
1418                 is_valid = 1;
1419                 break;
1420         default:
1421                 if (200 <= code && code <= 299) {
1422                         is_valid = ast_ari_validate_void(
1423                                 response->message);
1424                 } else {
1425                         ast_log(LOG_ERROR, "Invalid error response %d for /channels/{channelId}/hold\n", code);
1426                         is_valid = 0;
1427                 }
1428         }
1429
1430         if (!is_valid) {
1431                 ast_log(LOG_ERROR, "Response validation failed for /channels/{channelId}/hold\n");
1432                 ast_ari_response_error(response, 500,
1433                         "Internal Server Error", "Response validation failed");
1434         }
1435 #endif /* AST_DEVMODE */
1436
1437 fin: __attribute__((unused))
1438         return;
1439 }
1440 int ast_ari_channels_start_moh_parse_body(
1441         struct ast_json *body,
1442         struct ast_ari_channels_start_moh_args *args)
1443 {
1444         struct ast_json *field;
1445         /* Parse query parameters out of it */
1446         field = ast_json_object_get(body, "mohClass");
1447         if (field) {
1448                 args->moh_class = ast_json_string_get(field);
1449         }
1450         return 0;
1451 }
1452
1453 /*!
1454  * \brief Parameter parsing callback for /channels/{channelId}/moh.
1455  * \param get_params GET parameters in the HTTP request.
1456  * \param path_vars Path variables extracted from the request.
1457  * \param headers HTTP headers.
1458  * \param[out] response Response to the HTTP request.
1459  */
1460 static void ast_ari_channels_start_moh_cb(
1461         struct ast_tcptls_session_instance *ser,
1462         struct ast_variable *get_params, struct ast_variable *path_vars,
1463         struct ast_variable *headers, struct ast_json *body, struct ast_ari_response *response)
1464 {
1465         struct ast_ari_channels_start_moh_args args = {};
1466         struct ast_variable *i;
1467 #if defined(AST_DEVMODE)
1468         int is_valid;
1469         int code;
1470 #endif /* AST_DEVMODE */
1471
1472         for (i = get_params; i; i = i->next) {
1473                 if (strcmp(i->name, "mohClass") == 0) {
1474                         args.moh_class = (i->value);
1475                 } else
1476                 {}
1477         }
1478         for (i = path_vars; i; i = i->next) {
1479                 if (strcmp(i->name, "channelId") == 0) {
1480                         args.channel_id = (i->value);
1481                 } else
1482                 {}
1483         }
1484         if (ast_ari_channels_start_moh_parse_body(body, &args)) {
1485                 ast_ari_response_alloc_failed(response);
1486                 goto fin;
1487         }
1488         ast_ari_channels_start_moh(headers, &args, response);
1489 #if defined(AST_DEVMODE)
1490         code = response->response_code;
1491
1492         switch (code) {
1493         case 0: /* Implementation is still a stub, or the code wasn't set */
1494                 is_valid = response->message == NULL;
1495                 break;
1496         case 500: /* Internal Server Error */
1497         case 501: /* Not Implemented */
1498         case 404: /* Channel not found */
1499         case 409: /* Channel not in a Stasis application */
1500         case 412: /* Channel in invalid state */
1501                 is_valid = 1;
1502                 break;
1503         default:
1504                 if (200 <= code && code <= 299) {
1505                         is_valid = ast_ari_validate_void(
1506                                 response->message);
1507                 } else {
1508                         ast_log(LOG_ERROR, "Invalid error response %d for /channels/{channelId}/moh\n", code);
1509                         is_valid = 0;
1510                 }
1511         }
1512
1513         if (!is_valid) {
1514                 ast_log(LOG_ERROR, "Response validation failed for /channels/{channelId}/moh\n");
1515                 ast_ari_response_error(response, 500,
1516                         "Internal Server Error", "Response validation failed");
1517         }
1518 #endif /* AST_DEVMODE */
1519
1520 fin: __attribute__((unused))
1521         return;
1522 }
1523 /*!
1524  * \brief Parameter parsing callback for /channels/{channelId}/moh.
1525  * \param get_params GET parameters in the HTTP request.
1526  * \param path_vars Path variables extracted from the request.
1527  * \param headers HTTP headers.
1528  * \param[out] response Response to the HTTP request.
1529  */
1530 static void ast_ari_channels_stop_moh_cb(
1531         struct ast_tcptls_session_instance *ser,
1532         struct ast_variable *get_params, struct ast_variable *path_vars,
1533         struct ast_variable *headers, struct ast_json *body, struct ast_ari_response *response)
1534 {
1535         struct ast_ari_channels_stop_moh_args args = {};
1536         struct ast_variable *i;
1537 #if defined(AST_DEVMODE)
1538         int is_valid;
1539         int code;
1540 #endif /* AST_DEVMODE */
1541
1542         for (i = path_vars; i; i = i->next) {
1543                 if (strcmp(i->name, "channelId") == 0) {
1544                         args.channel_id = (i->value);
1545                 } else
1546                 {}
1547         }
1548         ast_ari_channels_stop_moh(headers, &args, response);
1549 #if defined(AST_DEVMODE)
1550         code = response->response_code;
1551
1552         switch (code) {
1553         case 0: /* Implementation is still a stub, or the code wasn't set */
1554                 is_valid = response->message == NULL;
1555                 break;
1556         case 500: /* Internal Server Error */
1557         case 501: /* Not Implemented */
1558         case 404: /* Channel not found */
1559         case 409: /* Channel not in a Stasis application */
1560         case 412: /* Channel in invalid state */
1561                 is_valid = 1;
1562                 break;
1563         default:
1564                 if (200 <= code && code <= 299) {
1565                         is_valid = ast_ari_validate_void(
1566                                 response->message);
1567                 } else {
1568                         ast_log(LOG_ERROR, "Invalid error response %d for /channels/{channelId}/moh\n", code);
1569                         is_valid = 0;
1570                 }
1571         }
1572
1573         if (!is_valid) {
1574                 ast_log(LOG_ERROR, "Response validation failed for /channels/{channelId}/moh\n");
1575                 ast_ari_response_error(response, 500,
1576                         "Internal Server Error", "Response validation failed");
1577         }
1578 #endif /* AST_DEVMODE */
1579
1580 fin: __attribute__((unused))
1581         return;
1582 }
1583 /*!
1584  * \brief Parameter parsing callback for /channels/{channelId}/silence.
1585  * \param get_params GET parameters in the HTTP request.
1586  * \param path_vars Path variables extracted from the request.
1587  * \param headers HTTP headers.
1588  * \param[out] response Response to the HTTP request.
1589  */
1590 static void ast_ari_channels_start_silence_cb(
1591         struct ast_tcptls_session_instance *ser,
1592         struct ast_variable *get_params, struct ast_variable *path_vars,
1593         struct ast_variable *headers, struct ast_json *body, struct ast_ari_response *response)
1594 {
1595         struct ast_ari_channels_start_silence_args args = {};
1596         struct ast_variable *i;
1597 #if defined(AST_DEVMODE)
1598         int is_valid;
1599         int code;
1600 #endif /* AST_DEVMODE */
1601
1602         for (i = path_vars; i; i = i->next) {
1603                 if (strcmp(i->name, "channelId") == 0) {
1604                         args.channel_id = (i->value);
1605                 } else
1606                 {}
1607         }
1608         ast_ari_channels_start_silence(headers, &args, response);
1609 #if defined(AST_DEVMODE)
1610         code = response->response_code;
1611
1612         switch (code) {
1613         case 0: /* Implementation is still a stub, or the code wasn't set */
1614                 is_valid = response->message == NULL;
1615                 break;
1616         case 500: /* Internal Server Error */
1617         case 501: /* Not Implemented */
1618         case 404: /* Channel not found */
1619         case 409: /* Channel not in a Stasis application */
1620         case 412: /* Channel in invalid state */
1621                 is_valid = 1;
1622                 break;
1623         default:
1624                 if (200 <= code && code <= 299) {
1625                         is_valid = ast_ari_validate_void(
1626                                 response->message);
1627                 } else {
1628                         ast_log(LOG_ERROR, "Invalid error response %d for /channels/{channelId}/silence\n", code);
1629                         is_valid = 0;
1630                 }
1631         }
1632
1633         if (!is_valid) {
1634                 ast_log(LOG_ERROR, "Response validation failed for /channels/{channelId}/silence\n");
1635                 ast_ari_response_error(response, 500,
1636                         "Internal Server Error", "Response validation failed");
1637         }
1638 #endif /* AST_DEVMODE */
1639
1640 fin: __attribute__((unused))
1641         return;
1642 }
1643 /*!
1644  * \brief Parameter parsing callback for /channels/{channelId}/silence.
1645  * \param get_params GET parameters in the HTTP request.
1646  * \param path_vars Path variables extracted from the request.
1647  * \param headers HTTP headers.
1648  * \param[out] response Response to the HTTP request.
1649  */
1650 static void ast_ari_channels_stop_silence_cb(
1651         struct ast_tcptls_session_instance *ser,
1652         struct ast_variable *get_params, struct ast_variable *path_vars,
1653         struct ast_variable *headers, struct ast_json *body, struct ast_ari_response *response)
1654 {
1655         struct ast_ari_channels_stop_silence_args args = {};
1656         struct ast_variable *i;
1657 #if defined(AST_DEVMODE)
1658         int is_valid;
1659         int code;
1660 #endif /* AST_DEVMODE */
1661
1662         for (i = path_vars; i; i = i->next) {
1663                 if (strcmp(i->name, "channelId") == 0) {
1664                         args.channel_id = (i->value);
1665                 } else
1666                 {}
1667         }
1668         ast_ari_channels_stop_silence(headers, &args, response);
1669 #if defined(AST_DEVMODE)
1670         code = response->response_code;
1671
1672         switch (code) {
1673         case 0: /* Implementation is still a stub, or the code wasn't set */
1674                 is_valid = response->message == NULL;
1675                 break;
1676         case 500: /* Internal Server Error */
1677         case 501: /* Not Implemented */
1678         case 404: /* Channel not found */
1679         case 409: /* Channel not in a Stasis application */
1680         case 412: /* Channel in invalid state */
1681                 is_valid = 1;
1682                 break;
1683         default:
1684                 if (200 <= code && code <= 299) {
1685                         is_valid = ast_ari_validate_void(
1686                                 response->message);
1687                 } else {
1688                         ast_log(LOG_ERROR, "Invalid error response %d for /channels/{channelId}/silence\n", code);
1689                         is_valid = 0;
1690                 }
1691         }
1692
1693         if (!is_valid) {
1694                 ast_log(LOG_ERROR, "Response validation failed for /channels/{channelId}/silence\n");
1695                 ast_ari_response_error(response, 500,
1696                         "Internal Server Error", "Response validation failed");
1697         }
1698 #endif /* AST_DEVMODE */
1699
1700 fin: __attribute__((unused))
1701         return;
1702 }
1703 int ast_ari_channels_play_parse_body(
1704         struct ast_json *body,
1705         struct ast_ari_channels_play_args *args)
1706 {
1707         struct ast_json *field;
1708         /* Parse query parameters out of it */
1709         field = ast_json_object_get(body, "media");
1710         if (field) {
1711                 /* If they were silly enough to both pass in a query param and a
1712                  * JSON body, free up the query value.
1713                  */
1714                 ast_free(args->media);
1715                 if (ast_json_typeof(field) == AST_JSON_ARRAY) {
1716                         /* Multiple param passed as array */
1717                         size_t i;
1718                         args->media_count = ast_json_array_size(field);
1719                         args->media = ast_malloc(sizeof(*args->media) * args->media_count);
1720
1721                         if (!args->media) {
1722                                 return -1;
1723                         }
1724
1725                         for (i = 0; i < args->media_count; ++i) {
1726                                 args->media[i] = ast_json_string_get(ast_json_array_get(field, i));
1727                         }
1728                 } else {
1729                         /* Multiple param passed as single value */
1730                         args->media_count = 1;
1731                         args->media = ast_malloc(sizeof(*args->media) * args->media_count);
1732                         if (!args->media) {
1733                                 return -1;
1734                         }
1735                         args->media[0] = ast_json_string_get(field);
1736                 }
1737         }
1738         field = ast_json_object_get(body, "lang");
1739         if (field) {
1740                 args->lang = ast_json_string_get(field);
1741         }
1742         field = ast_json_object_get(body, "offsetms");
1743         if (field) {
1744                 args->offsetms = ast_json_integer_get(field);
1745         }
1746         field = ast_json_object_get(body, "skipms");
1747         if (field) {
1748                 args->skipms = ast_json_integer_get(field);
1749         }
1750         field = ast_json_object_get(body, "playbackId");
1751         if (field) {
1752                 args->playback_id = ast_json_string_get(field);
1753         }
1754         return 0;
1755 }
1756
1757 /*!
1758  * \brief Parameter parsing callback for /channels/{channelId}/play.
1759  * \param get_params GET parameters in the HTTP request.
1760  * \param path_vars Path variables extracted from the request.
1761  * \param headers HTTP headers.
1762  * \param[out] response Response to the HTTP request.
1763  */
1764 static void ast_ari_channels_play_cb(
1765         struct ast_tcptls_session_instance *ser,
1766         struct ast_variable *get_params, struct ast_variable *path_vars,
1767         struct ast_variable *headers, struct ast_json *body, struct ast_ari_response *response)
1768 {
1769         struct ast_ari_channels_play_args args = {};
1770         struct ast_variable *i;
1771 #if defined(AST_DEVMODE)
1772         int is_valid;
1773         int code;
1774 #endif /* AST_DEVMODE */
1775
1776         for (i = get_params; i; i = i->next) {
1777                 if (strcmp(i->name, "media") == 0) {
1778                         /* Parse comma separated list */
1779                         char *vals[MAX_VALS];
1780                         size_t j;
1781
1782                         args.media_parse = ast_strdup(i->value);
1783                         if (!args.media_parse) {
1784                                 ast_ari_response_alloc_failed(response);
1785                                 goto fin;
1786                         }
1787
1788                         if (strlen(args.media_parse) == 0) {
1789                                 /* ast_app_separate_args can't handle "" */
1790                                 args.media_count = 1;
1791                                 vals[0] = args.media_parse;
1792                         } else {
1793                                 args.media_count = ast_app_separate_args(
1794                                         args.media_parse, ',', vals,
1795                                         ARRAY_LEN(vals));
1796                         }
1797
1798                         if (args.media_count == 0) {
1799                                 ast_ari_response_alloc_failed(response);
1800                                 goto fin;
1801                         }
1802
1803                         if (args.media_count >= MAX_VALS) {
1804                                 ast_ari_response_error(response, 400,
1805                                         "Bad Request",
1806                                         "Too many values for media");
1807                                 goto fin;
1808                         }
1809
1810                         args.media = ast_malloc(sizeof(*args.media) * args.media_count);
1811                         if (!args.media) {
1812                                 ast_ari_response_alloc_failed(response);
1813                                 goto fin;
1814                         }
1815
1816                         for (j = 0; j < args.media_count; ++j) {
1817                                 args.media[j] = (vals[j]);
1818                         }
1819                 } else
1820                 if (strcmp(i->name, "lang") == 0) {
1821                         args.lang = (i->value);
1822                 } else
1823                 if (strcmp(i->name, "offsetms") == 0) {
1824                         args.offsetms = atoi(i->value);
1825                 } else
1826                 if (strcmp(i->name, "skipms") == 0) {
1827                         args.skipms = atoi(i->value);
1828                 } else
1829                 if (strcmp(i->name, "playbackId") == 0) {
1830                         args.playback_id = (i->value);
1831                 } else
1832                 {}
1833         }
1834         for (i = path_vars; i; i = i->next) {
1835                 if (strcmp(i->name, "channelId") == 0) {
1836                         args.channel_id = (i->value);
1837                 } else
1838                 {}
1839         }
1840         if (ast_ari_channels_play_parse_body(body, &args)) {
1841                 ast_ari_response_alloc_failed(response);
1842                 goto fin;
1843         }
1844         ast_ari_channels_play(headers, &args, response);
1845 #if defined(AST_DEVMODE)
1846         code = response->response_code;
1847
1848         switch (code) {
1849         case 0: /* Implementation is still a stub, or the code wasn't set */
1850                 is_valid = response->message == NULL;
1851                 break;
1852         case 500: /* Internal Server Error */
1853         case 501: /* Not Implemented */
1854         case 404: /* Channel not found */
1855         case 409: /* Channel not in a Stasis application */
1856         case 412: /* Channel in invalid state */
1857                 is_valid = 1;
1858                 break;
1859         default:
1860                 if (200 <= code && code <= 299) {
1861                         is_valid = ast_ari_validate_playback(
1862                                 response->message);
1863                 } else {
1864                         ast_log(LOG_ERROR, "Invalid error response %d for /channels/{channelId}/play\n", code);
1865                         is_valid = 0;
1866                 }
1867         }
1868
1869         if (!is_valid) {
1870                 ast_log(LOG_ERROR, "Response validation failed for /channels/{channelId}/play\n");
1871                 ast_ari_response_error(response, 500,
1872                         "Internal Server Error", "Response validation failed");
1873         }
1874 #endif /* AST_DEVMODE */
1875
1876 fin: __attribute__((unused))
1877         ast_free(args.media_parse);
1878         ast_free(args.media);
1879         return;
1880 }
1881 int ast_ari_channels_play_with_id_parse_body(
1882         struct ast_json *body,
1883         struct ast_ari_channels_play_with_id_args *args)
1884 {
1885         struct ast_json *field;
1886         /* Parse query parameters out of it */
1887         field = ast_json_object_get(body, "media");
1888         if (field) {
1889                 /* If they were silly enough to both pass in a query param and a
1890                  * JSON body, free up the query value.
1891                  */
1892                 ast_free(args->media);
1893                 if (ast_json_typeof(field) == AST_JSON_ARRAY) {
1894                         /* Multiple param passed as array */
1895                         size_t i;
1896                         args->media_count = ast_json_array_size(field);
1897                         args->media = ast_malloc(sizeof(*args->media) * args->media_count);
1898
1899                         if (!args->media) {
1900                                 return -1;
1901                         }
1902
1903                         for (i = 0; i < args->media_count; ++i) {
1904                                 args->media[i] = ast_json_string_get(ast_json_array_get(field, i));
1905                         }
1906                 } else {
1907                         /* Multiple param passed as single value */
1908                         args->media_count = 1;
1909                         args->media = ast_malloc(sizeof(*args->media) * args->media_count);
1910                         if (!args->media) {
1911                                 return -1;
1912                         }
1913                         args->media[0] = ast_json_string_get(field);
1914                 }
1915         }
1916         field = ast_json_object_get(body, "lang");
1917         if (field) {
1918                 args->lang = ast_json_string_get(field);
1919         }
1920         field = ast_json_object_get(body, "offsetms");
1921         if (field) {
1922                 args->offsetms = ast_json_integer_get(field);
1923         }
1924         field = ast_json_object_get(body, "skipms");
1925         if (field) {
1926                 args->skipms = ast_json_integer_get(field);
1927         }
1928         return 0;
1929 }
1930
1931 /*!
1932  * \brief Parameter parsing callback for /channels/{channelId}/play/{playbackId}.
1933  * \param get_params GET parameters in the HTTP request.
1934  * \param path_vars Path variables extracted from the request.
1935  * \param headers HTTP headers.
1936  * \param[out] response Response to the HTTP request.
1937  */
1938 static void ast_ari_channels_play_with_id_cb(
1939         struct ast_tcptls_session_instance *ser,
1940         struct ast_variable *get_params, struct ast_variable *path_vars,
1941         struct ast_variable *headers, struct ast_json *body, struct ast_ari_response *response)
1942 {
1943         struct ast_ari_channels_play_with_id_args args = {};
1944         struct ast_variable *i;
1945 #if defined(AST_DEVMODE)
1946         int is_valid;
1947         int code;
1948 #endif /* AST_DEVMODE */
1949
1950         for (i = get_params; i; i = i->next) {
1951                 if (strcmp(i->name, "media") == 0) {
1952                         /* Parse comma separated list */
1953                         char *vals[MAX_VALS];
1954                         size_t j;
1955
1956                         args.media_parse = ast_strdup(i->value);
1957                         if (!args.media_parse) {
1958                                 ast_ari_response_alloc_failed(response);
1959                                 goto fin;
1960                         }
1961
1962                         if (strlen(args.media_parse) == 0) {
1963                                 /* ast_app_separate_args can't handle "" */
1964                                 args.media_count = 1;
1965                                 vals[0] = args.media_parse;
1966                         } else {
1967                                 args.media_count = ast_app_separate_args(
1968                                         args.media_parse, ',', vals,
1969                                         ARRAY_LEN(vals));
1970                         }
1971
1972                         if (args.media_count == 0) {
1973                                 ast_ari_response_alloc_failed(response);
1974                                 goto fin;
1975                         }
1976
1977                         if (args.media_count >= MAX_VALS) {
1978                                 ast_ari_response_error(response, 400,
1979                                         "Bad Request",
1980                                         "Too many values for media");
1981                                 goto fin;
1982                         }
1983
1984                         args.media = ast_malloc(sizeof(*args.media) * args.media_count);
1985                         if (!args.media) {
1986                                 ast_ari_response_alloc_failed(response);
1987                                 goto fin;
1988                         }
1989
1990                         for (j = 0; j < args.media_count; ++j) {
1991                                 args.media[j] = (vals[j]);
1992                         }
1993                 } else
1994                 if (strcmp(i->name, "lang") == 0) {
1995                         args.lang = (i->value);
1996                 } else
1997                 if (strcmp(i->name, "offsetms") == 0) {
1998                         args.offsetms = atoi(i->value);
1999                 } else
2000                 if (strcmp(i->name, "skipms") == 0) {
2001                         args.skipms = atoi(i->value);
2002                 } else
2003                 {}
2004         }
2005         for (i = path_vars; i; i = i->next) {
2006                 if (strcmp(i->name, "channelId") == 0) {
2007                         args.channel_id = (i->value);
2008                 } else
2009                 if (strcmp(i->name, "playbackId") == 0) {
2010                         args.playback_id = (i->value);
2011                 } else
2012                 {}
2013         }
2014         if (ast_ari_channels_play_with_id_parse_body(body, &args)) {
2015                 ast_ari_response_alloc_failed(response);
2016                 goto fin;
2017         }
2018         ast_ari_channels_play_with_id(headers, &args, response);
2019 #if defined(AST_DEVMODE)
2020         code = response->response_code;
2021
2022         switch (code) {
2023         case 0: /* Implementation is still a stub, or the code wasn't set */
2024                 is_valid = response->message == NULL;
2025                 break;
2026         case 500: /* Internal Server Error */
2027         case 501: /* Not Implemented */
2028         case 404: /* Channel not found */
2029         case 409: /* Channel not in a Stasis application */
2030         case 412: /* Channel in invalid state */
2031                 is_valid = 1;
2032                 break;
2033         default:
2034                 if (200 <= code && code <= 299) {
2035                         is_valid = ast_ari_validate_playback(
2036                                 response->message);
2037                 } else {
2038                         ast_log(LOG_ERROR, "Invalid error response %d for /channels/{channelId}/play/{playbackId}\n", code);
2039                         is_valid = 0;
2040                 }
2041         }
2042
2043         if (!is_valid) {
2044                 ast_log(LOG_ERROR, "Response validation failed for /channels/{channelId}/play/{playbackId}\n");
2045                 ast_ari_response_error(response, 500,
2046                         "Internal Server Error", "Response validation failed");
2047         }
2048 #endif /* AST_DEVMODE */
2049
2050 fin: __attribute__((unused))
2051         ast_free(args.media_parse);
2052         ast_free(args.media);
2053         return;
2054 }
2055 int ast_ari_channels_record_parse_body(
2056         struct ast_json *body,
2057         struct ast_ari_channels_record_args *args)
2058 {
2059         struct ast_json *field;
2060         /* Parse query parameters out of it */
2061         field = ast_json_object_get(body, "name");
2062         if (field) {
2063                 args->name = ast_json_string_get(field);
2064         }
2065         field = ast_json_object_get(body, "format");
2066         if (field) {
2067                 args->format = ast_json_string_get(field);
2068         }
2069         field = ast_json_object_get(body, "maxDurationSeconds");
2070         if (field) {
2071                 args->max_duration_seconds = ast_json_integer_get(field);
2072         }
2073         field = ast_json_object_get(body, "maxSilenceSeconds");
2074         if (field) {
2075                 args->max_silence_seconds = ast_json_integer_get(field);
2076         }
2077         field = ast_json_object_get(body, "ifExists");
2078         if (field) {
2079                 args->if_exists = ast_json_string_get(field);
2080         }
2081         field = ast_json_object_get(body, "beep");
2082         if (field) {
2083                 args->beep = ast_json_is_true(field);
2084         }
2085         field = ast_json_object_get(body, "terminateOn");
2086         if (field) {
2087                 args->terminate_on = ast_json_string_get(field);
2088         }
2089         return 0;
2090 }
2091
2092 /*!
2093  * \brief Parameter parsing callback for /channels/{channelId}/record.
2094  * \param get_params GET parameters in the HTTP request.
2095  * \param path_vars Path variables extracted from the request.
2096  * \param headers HTTP headers.
2097  * \param[out] response Response to the HTTP request.
2098  */
2099 static void ast_ari_channels_record_cb(
2100         struct ast_tcptls_session_instance *ser,
2101         struct ast_variable *get_params, struct ast_variable *path_vars,
2102         struct ast_variable *headers, struct ast_json *body, struct ast_ari_response *response)
2103 {
2104         struct ast_ari_channels_record_args args = {};
2105         struct ast_variable *i;
2106 #if defined(AST_DEVMODE)
2107         int is_valid;
2108         int code;
2109 #endif /* AST_DEVMODE */
2110
2111         for (i = get_params; i; i = i->next) {
2112                 if (strcmp(i->name, "name") == 0) {
2113                         args.name = (i->value);
2114                 } else
2115                 if (strcmp(i->name, "format") == 0) {
2116                         args.format = (i->value);
2117                 } else
2118                 if (strcmp(i->name, "maxDurationSeconds") == 0) {
2119                         args.max_duration_seconds = atoi(i->value);
2120                 } else
2121                 if (strcmp(i->name, "maxSilenceSeconds") == 0) {
2122                         args.max_silence_seconds = atoi(i->value);
2123                 } else
2124                 if (strcmp(i->name, "ifExists") == 0) {
2125                         args.if_exists = (i->value);
2126                 } else
2127                 if (strcmp(i->name, "beep") == 0) {
2128                         args.beep = ast_true(i->value);
2129                 } else
2130                 if (strcmp(i->name, "terminateOn") == 0) {
2131                         args.terminate_on = (i->value);
2132                 } else
2133                 {}
2134         }
2135         for (i = path_vars; i; i = i->next) {
2136                 if (strcmp(i->name, "channelId") == 0) {
2137                         args.channel_id = (i->value);
2138                 } else
2139                 {}
2140         }
2141         if (ast_ari_channels_record_parse_body(body, &args)) {
2142                 ast_ari_response_alloc_failed(response);
2143                 goto fin;
2144         }
2145         ast_ari_channels_record(headers, &args, response);
2146 #if defined(AST_DEVMODE)
2147         code = response->response_code;
2148
2149         switch (code) {
2150         case 0: /* Implementation is still a stub, or the code wasn't set */
2151                 is_valid = response->message == NULL;
2152                 break;
2153         case 500: /* Internal Server Error */
2154         case 501: /* Not Implemented */
2155         case 400: /* Invalid parameters */
2156         case 404: /* Channel not found */
2157         case 409: /* Channel is not in a Stasis application; the channel is currently bridged with other hcannels; A recording with the same name already exists on the system and can not be overwritten because it is in progress or ifExists=fail */
2158         case 422: /* The format specified is unknown on this system */
2159                 is_valid = 1;
2160                 break;
2161         default:
2162                 if (200 <= code && code <= 299) {
2163                         is_valid = ast_ari_validate_live_recording(
2164                                 response->message);
2165                 } else {
2166                         ast_log(LOG_ERROR, "Invalid error response %d for /channels/{channelId}/record\n", code);
2167                         is_valid = 0;
2168                 }
2169         }
2170
2171         if (!is_valid) {
2172                 ast_log(LOG_ERROR, "Response validation failed for /channels/{channelId}/record\n");
2173                 ast_ari_response_error(response, 500,
2174                         "Internal Server Error", "Response validation failed");
2175         }
2176 #endif /* AST_DEVMODE */
2177
2178 fin: __attribute__((unused))
2179         return;
2180 }
2181 int ast_ari_channels_get_channel_var_parse_body(
2182         struct ast_json *body,
2183         struct ast_ari_channels_get_channel_var_args *args)
2184 {
2185         struct ast_json *field;
2186         /* Parse query parameters out of it */
2187         field = ast_json_object_get(body, "variable");
2188         if (field) {
2189                 args->variable = ast_json_string_get(field);
2190         }
2191         return 0;
2192 }
2193
2194 /*!
2195  * \brief Parameter parsing callback for /channels/{channelId}/variable.
2196  * \param get_params GET parameters in the HTTP request.
2197  * \param path_vars Path variables extracted from the request.
2198  * \param headers HTTP headers.
2199  * \param[out] response Response to the HTTP request.
2200  */
2201 static void ast_ari_channels_get_channel_var_cb(
2202         struct ast_tcptls_session_instance *ser,
2203         struct ast_variable *get_params, struct ast_variable *path_vars,
2204         struct ast_variable *headers, struct ast_json *body, struct ast_ari_response *response)
2205 {
2206         struct ast_ari_channels_get_channel_var_args args = {};
2207         struct ast_variable *i;
2208 #if defined(AST_DEVMODE)
2209         int is_valid;
2210         int code;
2211 #endif /* AST_DEVMODE */
2212
2213         for (i = get_params; i; i = i->next) {
2214                 if (strcmp(i->name, "variable") == 0) {
2215                         args.variable = (i->value);
2216                 } else
2217                 {}
2218         }
2219         for (i = path_vars; i; i = i->next) {
2220                 if (strcmp(i->name, "channelId") == 0) {
2221                         args.channel_id = (i->value);
2222                 } else
2223                 {}
2224         }
2225         if (ast_ari_channels_get_channel_var_parse_body(body, &args)) {
2226                 ast_ari_response_alloc_failed(response);
2227                 goto fin;
2228         }
2229         ast_ari_channels_get_channel_var(headers, &args, response);
2230 #if defined(AST_DEVMODE)
2231         code = response->response_code;
2232
2233         switch (code) {
2234         case 0: /* Implementation is still a stub, or the code wasn't set */
2235                 is_valid = response->message == NULL;
2236                 break;
2237         case 500: /* Internal Server Error */
2238         case 501: /* Not Implemented */
2239         case 400: /* Missing variable parameter. */
2240         case 404: /* Channel or variable not found */
2241         case 409: /* Channel not in a Stasis application */
2242                 is_valid = 1;
2243                 break;
2244         default:
2245                 if (200 <= code && code <= 299) {
2246                         is_valid = ast_ari_validate_variable(
2247                                 response->message);
2248                 } else {
2249                         ast_log(LOG_ERROR, "Invalid error response %d for /channels/{channelId}/variable\n", code);
2250                         is_valid = 0;
2251                 }
2252         }
2253
2254         if (!is_valid) {
2255                 ast_log(LOG_ERROR, "Response validation failed for /channels/{channelId}/variable\n");
2256                 ast_ari_response_error(response, 500,
2257                         "Internal Server Error", "Response validation failed");
2258         }
2259 #endif /* AST_DEVMODE */
2260
2261 fin: __attribute__((unused))
2262         return;
2263 }
2264 int ast_ari_channels_set_channel_var_parse_body(
2265         struct ast_json *body,
2266         struct ast_ari_channels_set_channel_var_args *args)
2267 {
2268         struct ast_json *field;
2269         /* Parse query parameters out of it */
2270         field = ast_json_object_get(body, "variable");
2271         if (field) {
2272                 args->variable = ast_json_string_get(field);
2273         }
2274         field = ast_json_object_get(body, "value");
2275         if (field) {
2276                 args->value = ast_json_string_get(field);
2277         }
2278         return 0;
2279 }
2280
2281 /*!
2282  * \brief Parameter parsing callback for /channels/{channelId}/variable.
2283  * \param get_params GET parameters in the HTTP request.
2284  * \param path_vars Path variables extracted from the request.
2285  * \param headers HTTP headers.
2286  * \param[out] response Response to the HTTP request.
2287  */
2288 static void ast_ari_channels_set_channel_var_cb(
2289         struct ast_tcptls_session_instance *ser,
2290         struct ast_variable *get_params, struct ast_variable *path_vars,
2291         struct ast_variable *headers, struct ast_json *body, struct ast_ari_response *response)
2292 {
2293         struct ast_ari_channels_set_channel_var_args args = {};
2294         struct ast_variable *i;
2295 #if defined(AST_DEVMODE)
2296         int is_valid;
2297         int code;
2298 #endif /* AST_DEVMODE */
2299
2300         for (i = get_params; i; i = i->next) {
2301                 if (strcmp(i->name, "variable") == 0) {
2302                         args.variable = (i->value);
2303                 } else
2304                 if (strcmp(i->name, "value") == 0) {
2305                         args.value = (i->value);
2306                 } else
2307                 {}
2308         }
2309         for (i = path_vars; i; i = i->next) {
2310                 if (strcmp(i->name, "channelId") == 0) {
2311                         args.channel_id = (i->value);
2312                 } else
2313                 {}
2314         }
2315         if (ast_ari_channels_set_channel_var_parse_body(body, &args)) {
2316                 ast_ari_response_alloc_failed(response);
2317                 goto fin;
2318         }
2319         ast_ari_channels_set_channel_var(headers, &args, response);
2320 #if defined(AST_DEVMODE)
2321         code = response->response_code;
2322
2323         switch (code) {
2324         case 0: /* Implementation is still a stub, or the code wasn't set */
2325                 is_valid = response->message == NULL;
2326                 break;
2327         case 500: /* Internal Server Error */
2328         case 501: /* Not Implemented */
2329         case 400: /* Missing variable parameter. */
2330         case 404: /* Channel not found */
2331         case 409: /* Channel not in a Stasis application */
2332                 is_valid = 1;
2333                 break;
2334         default:
2335                 if (200 <= code && code <= 299) {
2336                         is_valid = ast_ari_validate_void(
2337                                 response->message);
2338                 } else {
2339                         ast_log(LOG_ERROR, "Invalid error response %d for /channels/{channelId}/variable\n", code);
2340                         is_valid = 0;
2341                 }
2342         }
2343
2344         if (!is_valid) {
2345                 ast_log(LOG_ERROR, "Response validation failed for /channels/{channelId}/variable\n");
2346                 ast_ari_response_error(response, 500,
2347                         "Internal Server Error", "Response validation failed");
2348         }
2349 #endif /* AST_DEVMODE */
2350
2351 fin: __attribute__((unused))
2352         return;
2353 }
2354 int ast_ari_channels_snoop_channel_parse_body(
2355         struct ast_json *body,
2356         struct ast_ari_channels_snoop_channel_args *args)
2357 {
2358         struct ast_json *field;
2359         /* Parse query parameters out of it */
2360         field = ast_json_object_get(body, "spy");
2361         if (field) {
2362                 args->spy = ast_json_string_get(field);
2363         }
2364         field = ast_json_object_get(body, "whisper");
2365         if (field) {
2366                 args->whisper = ast_json_string_get(field);
2367         }
2368         field = ast_json_object_get(body, "app");
2369         if (field) {
2370                 args->app = ast_json_string_get(field);
2371         }
2372         field = ast_json_object_get(body, "appArgs");
2373         if (field) {
2374                 args->app_args = ast_json_string_get(field);
2375         }
2376         field = ast_json_object_get(body, "snoopId");
2377         if (field) {
2378                 args->snoop_id = ast_json_string_get(field);
2379         }
2380         return 0;
2381 }
2382
2383 /*!
2384  * \brief Parameter parsing callback for /channels/{channelId}/snoop.
2385  * \param get_params GET parameters in the HTTP request.
2386  * \param path_vars Path variables extracted from the request.
2387  * \param headers HTTP headers.
2388  * \param[out] response Response to the HTTP request.
2389  */
2390 static void ast_ari_channels_snoop_channel_cb(
2391         struct ast_tcptls_session_instance *ser,
2392         struct ast_variable *get_params, struct ast_variable *path_vars,
2393         struct ast_variable *headers, struct ast_json *body, struct ast_ari_response *response)
2394 {
2395         struct ast_ari_channels_snoop_channel_args args = {};
2396         struct ast_variable *i;
2397 #if defined(AST_DEVMODE)
2398         int is_valid;
2399         int code;
2400 #endif /* AST_DEVMODE */
2401
2402         for (i = get_params; i; i = i->next) {
2403                 if (strcmp(i->name, "spy") == 0) {
2404                         args.spy = (i->value);
2405                 } else
2406                 if (strcmp(i->name, "whisper") == 0) {
2407                         args.whisper = (i->value);
2408                 } else
2409                 if (strcmp(i->name, "app") == 0) {
2410                         args.app = (i->value);
2411                 } else
2412                 if (strcmp(i->name, "appArgs") == 0) {
2413                         args.app_args = (i->value);
2414                 } else
2415                 if (strcmp(i->name, "snoopId") == 0) {
2416                         args.snoop_id = (i->value);
2417                 } else
2418                 {}
2419         }
2420         for (i = path_vars; i; i = i->next) {
2421                 if (strcmp(i->name, "channelId") == 0) {
2422                         args.channel_id = (i->value);
2423                 } else
2424                 {}
2425         }
2426         if (ast_ari_channels_snoop_channel_parse_body(body, &args)) {
2427                 ast_ari_response_alloc_failed(response);
2428                 goto fin;
2429         }
2430         ast_ari_channels_snoop_channel(headers, &args, response);
2431 #if defined(AST_DEVMODE)
2432         code = response->response_code;
2433
2434         switch (code) {
2435         case 0: /* Implementation is still a stub, or the code wasn't set */
2436                 is_valid = response->message == NULL;
2437                 break;
2438         case 500: /* Internal Server Error */
2439         case 501: /* Not Implemented */
2440         case 400: /* Invalid parameters */
2441         case 404: /* Channel not found */
2442                 is_valid = 1;
2443                 break;
2444         default:
2445                 if (200 <= code && code <= 299) {
2446                         is_valid = ast_ari_validate_channel(
2447                                 response->message);
2448                 } else {
2449                         ast_log(LOG_ERROR, "Invalid error response %d for /channels/{channelId}/snoop\n", code);
2450                         is_valid = 0;
2451                 }
2452         }
2453
2454         if (!is_valid) {
2455                 ast_log(LOG_ERROR, "Response validation failed for /channels/{channelId}/snoop\n");
2456                 ast_ari_response_error(response, 500,
2457                         "Internal Server Error", "Response validation failed");
2458         }
2459 #endif /* AST_DEVMODE */
2460
2461 fin: __attribute__((unused))
2462         return;
2463 }
2464 int ast_ari_channels_snoop_channel_with_id_parse_body(
2465         struct ast_json *body,
2466         struct ast_ari_channels_snoop_channel_with_id_args *args)
2467 {
2468         struct ast_json *field;
2469         /* Parse query parameters out of it */
2470         field = ast_json_object_get(body, "spy");
2471         if (field) {
2472                 args->spy = ast_json_string_get(field);
2473         }
2474         field = ast_json_object_get(body, "whisper");
2475         if (field) {
2476                 args->whisper = ast_json_string_get(field);
2477         }
2478         field = ast_json_object_get(body, "app");
2479         if (field) {
2480                 args->app = ast_json_string_get(field);
2481         }
2482         field = ast_json_object_get(body, "appArgs");
2483         if (field) {
2484                 args->app_args = ast_json_string_get(field);
2485         }
2486         return 0;
2487 }
2488
2489 /*!
2490  * \brief Parameter parsing callback for /channels/{channelId}/snoop/{snoopId}.
2491  * \param get_params GET parameters in the HTTP request.
2492  * \param path_vars Path variables extracted from the request.
2493  * \param headers HTTP headers.
2494  * \param[out] response Response to the HTTP request.
2495  */
2496 static void ast_ari_channels_snoop_channel_with_id_cb(
2497         struct ast_tcptls_session_instance *ser,
2498         struct ast_variable *get_params, struct ast_variable *path_vars,
2499         struct ast_variable *headers, struct ast_json *body, struct ast_ari_response *response)
2500 {
2501         struct ast_ari_channels_snoop_channel_with_id_args args = {};
2502         struct ast_variable *i;
2503 #if defined(AST_DEVMODE)
2504         int is_valid;
2505         int code;
2506 #endif /* AST_DEVMODE */
2507
2508         for (i = get_params; i; i = i->next) {
2509                 if (strcmp(i->name, "spy") == 0) {
2510                         args.spy = (i->value);
2511                 } else
2512                 if (strcmp(i->name, "whisper") == 0) {
2513                         args.whisper = (i->value);
2514                 } else
2515                 if (strcmp(i->name, "app") == 0) {
2516                         args.app = (i->value);
2517                 } else
2518                 if (strcmp(i->name, "appArgs") == 0) {
2519                         args.app_args = (i->value);
2520                 } else
2521                 {}
2522         }
2523         for (i = path_vars; i; i = i->next) {
2524                 if (strcmp(i->name, "channelId") == 0) {
2525                         args.channel_id = (i->value);
2526                 } else
2527                 if (strcmp(i->name, "snoopId") == 0) {
2528                         args.snoop_id = (i->value);
2529                 } else
2530                 {}
2531         }
2532         if (ast_ari_channels_snoop_channel_with_id_parse_body(body, &args)) {
2533                 ast_ari_response_alloc_failed(response);
2534                 goto fin;
2535         }
2536         ast_ari_channels_snoop_channel_with_id(headers, &args, response);
2537 #if defined(AST_DEVMODE)
2538         code = response->response_code;
2539
2540         switch (code) {
2541         case 0: /* Implementation is still a stub, or the code wasn't set */
2542                 is_valid = response->message == NULL;
2543                 break;
2544         case 500: /* Internal Server Error */
2545         case 501: /* Not Implemented */
2546         case 400: /* Invalid parameters */
2547         case 404: /* Channel not found */
2548                 is_valid = 1;
2549                 break;
2550         default:
2551                 if (200 <= code && code <= 299) {
2552                         is_valid = ast_ari_validate_channel(
2553                                 response->message);
2554                 } else {
2555                         ast_log(LOG_ERROR, "Invalid error response %d for /channels/{channelId}/snoop/{snoopId}\n", code);
2556                         is_valid = 0;
2557                 }
2558         }
2559
2560         if (!is_valid) {
2561                 ast_log(LOG_ERROR, "Response validation failed for /channels/{channelId}/snoop/{snoopId}\n");
2562                 ast_ari_response_error(response, 500,
2563                         "Internal Server Error", "Response validation failed");
2564         }
2565 #endif /* AST_DEVMODE */
2566
2567 fin: __attribute__((unused))
2568         return;
2569 }
2570 int ast_ari_channels_dial_parse_body(
2571         struct ast_json *body,
2572         struct ast_ari_channels_dial_args *args)
2573 {
2574         struct ast_json *field;
2575         /* Parse query parameters out of it */
2576         field = ast_json_object_get(body, "caller");
2577         if (field) {
2578                 args->caller = ast_json_string_get(field);
2579         }
2580         field = ast_json_object_get(body, "timeout");
2581         if (field) {
2582                 args->timeout = ast_json_integer_get(field);
2583         }
2584         return 0;
2585 }
2586
2587 /*!
2588  * \brief Parameter parsing callback for /channels/{channelId}/dial.
2589  * \param get_params GET parameters in the HTTP request.
2590  * \param path_vars Path variables extracted from the request.
2591  * \param headers HTTP headers.
2592  * \param[out] response Response to the HTTP request.
2593  */
2594 static void ast_ari_channels_dial_cb(
2595         struct ast_tcptls_session_instance *ser,
2596         struct ast_variable *get_params, struct ast_variable *path_vars,
2597         struct ast_variable *headers, struct ast_json *body, struct ast_ari_response *response)
2598 {
2599         struct ast_ari_channels_dial_args args = {};
2600         struct ast_variable *i;
2601 #if defined(AST_DEVMODE)
2602         int is_valid;
2603         int code;
2604 #endif /* AST_DEVMODE */
2605
2606         for (i = get_params; i; i = i->next) {
2607                 if (strcmp(i->name, "caller") == 0) {
2608                         args.caller = (i->value);
2609                 } else
2610                 if (strcmp(i->name, "timeout") == 0) {
2611                         args.timeout = atoi(i->value);
2612                 } else
2613                 {}
2614         }
2615         for (i = path_vars; i; i = i->next) {
2616                 if (strcmp(i->name, "channelId") == 0) {
2617                         args.channel_id = (i->value);
2618                 } else
2619                 {}
2620         }
2621         if (ast_ari_channels_dial_parse_body(body, &args)) {
2622                 ast_ari_response_alloc_failed(response);
2623                 goto fin;
2624         }
2625         ast_ari_channels_dial(headers, &args, response);
2626 #if defined(AST_DEVMODE)
2627         code = response->response_code;
2628
2629         switch (code) {
2630         case 0: /* Implementation is still a stub, or the code wasn't set */
2631                 is_valid = response->message == NULL;
2632                 break;
2633         case 500: /* Internal Server Error */
2634         case 501: /* Not Implemented */
2635         case 404: /* Channel cannot be found. */
2636         case 409: /* Channel cannot be dialed. */
2637                 is_valid = 1;
2638                 break;
2639         default:
2640                 if (200 <= code && code <= 299) {
2641                         is_valid = ast_ari_validate_void(
2642                                 response->message);
2643                 } else {
2644                         ast_log(LOG_ERROR, "Invalid error response %d for /channels/{channelId}/dial\n", code);
2645                         is_valid = 0;
2646                 }
2647         }
2648
2649         if (!is_valid) {
2650                 ast_log(LOG_ERROR, "Response validation failed for /channels/{channelId}/dial\n");
2651                 ast_ari_response_error(response, 500,
2652                         "Internal Server Error", "Response validation failed");
2653         }
2654 #endif /* AST_DEVMODE */
2655
2656 fin: __attribute__((unused))
2657         return;
2658 }
2659
2660 /*! \brief REST handler for /api-docs/channels.json */
2661 static struct stasis_rest_handlers channels_create = {
2662         .path_segment = "create",
2663         .callbacks = {
2664                 [AST_HTTP_POST] = ast_ari_channels_create_cb,
2665         },
2666         .num_children = 0,
2667         .children = {  }
2668 };
2669 /*! \brief REST handler for /api-docs/channels.json */
2670 static struct stasis_rest_handlers channels_channelId_continue = {
2671         .path_segment = "continue",
2672         .callbacks = {
2673                 [AST_HTTP_POST] = ast_ari_channels_continue_in_dialplan_cb,
2674         },
2675         .num_children = 0,
2676         .children = {  }
2677 };
2678 /*! \brief REST handler for /api-docs/channels.json */
2679 static struct stasis_rest_handlers channels_channelId_redirect = {
2680         .path_segment = "redirect",
2681         .callbacks = {
2682                 [AST_HTTP_POST] = ast_ari_channels_redirect_cb,
2683         },
2684         .num_children = 0,
2685         .children = {  }
2686 };
2687 /*! \brief REST handler for /api-docs/channels.json */
2688 static struct stasis_rest_handlers channels_channelId_answer = {
2689         .path_segment = "answer",
2690         .callbacks = {
2691                 [AST_HTTP_POST] = ast_ari_channels_answer_cb,
2692         },
2693         .num_children = 0,
2694         .children = {  }
2695 };
2696 /*! \brief REST handler for /api-docs/channels.json */
2697 static struct stasis_rest_handlers channels_channelId_ring = {
2698         .path_segment = "ring",
2699         .callbacks = {
2700                 [AST_HTTP_POST] = ast_ari_channels_ring_cb,
2701                 [AST_HTTP_DELETE] = ast_ari_channels_ring_stop_cb,
2702         },
2703         .num_children = 0,
2704         .children = {  }
2705 };
2706 /*! \brief REST handler for /api-docs/channels.json */
2707 static struct stasis_rest_handlers channels_channelId_dtmf = {
2708         .path_segment = "dtmf",
2709         .callbacks = {
2710                 [AST_HTTP_POST] = ast_ari_channels_send_dtmf_cb,
2711         },
2712         .num_children = 0,
2713         .children = {  }
2714 };
2715 /*! \brief REST handler for /api-docs/channels.json */
2716 static struct stasis_rest_handlers channels_channelId_mute = {
2717         .path_segment = "mute",
2718         .callbacks = {
2719                 [AST_HTTP_POST] = ast_ari_channels_mute_cb,
2720                 [AST_HTTP_DELETE] = ast_ari_channels_unmute_cb,
2721         },
2722         .num_children = 0,
2723         .children = {  }
2724 };
2725 /*! \brief REST handler for /api-docs/channels.json */
2726 static struct stasis_rest_handlers channels_channelId_hold = {
2727         .path_segment = "hold",
2728         .callbacks = {
2729                 [AST_HTTP_POST] = ast_ari_channels_hold_cb,
2730                 [AST_HTTP_DELETE] = ast_ari_channels_unhold_cb,
2731         },
2732         .num_children = 0,
2733         .children = {  }
2734 };
2735 /*! \brief REST handler for /api-docs/channels.json */
2736 static struct stasis_rest_handlers channels_channelId_moh = {
2737         .path_segment = "moh",
2738         .callbacks = {
2739                 [AST_HTTP_POST] = ast_ari_channels_start_moh_cb,
2740                 [AST_HTTP_DELETE] = ast_ari_channels_stop_moh_cb,
2741         },
2742         .num_children = 0,
2743         .children = {  }
2744 };
2745 /*! \brief REST handler for /api-docs/channels.json */
2746 static struct stasis_rest_handlers channels_channelId_silence = {
2747         .path_segment = "silence",
2748         .callbacks = {
2749                 [AST_HTTP_POST] = ast_ari_channels_start_silence_cb,
2750                 [AST_HTTP_DELETE] = ast_ari_channels_stop_silence_cb,
2751         },
2752         .num_children = 0,
2753         .children = {  }
2754 };
2755 /*! \brief REST handler for /api-docs/channels.json */
2756 static struct stasis_rest_handlers channels_channelId_play_playbackId = {
2757         .path_segment = "playbackId",
2758         .is_wildcard = 1,
2759         .callbacks = {
2760                 [AST_HTTP_POST] = ast_ari_channels_play_with_id_cb,
2761         },
2762         .num_children = 0,
2763         .children = {  }
2764 };
2765 /*! \brief REST handler for /api-docs/channels.json */
2766 static struct stasis_rest_handlers channels_channelId_play = {
2767         .path_segment = "play",
2768         .callbacks = {
2769                 [AST_HTTP_POST] = ast_ari_channels_play_cb,
2770         },
2771         .num_children = 1,
2772         .children = { &channels_channelId_play_playbackId, }
2773 };
2774 /*! \brief REST handler for /api-docs/channels.json */
2775 static struct stasis_rest_handlers channels_channelId_record = {
2776         .path_segment = "record",
2777         .callbacks = {
2778                 [AST_HTTP_POST] = ast_ari_channels_record_cb,
2779         },
2780         .num_children = 0,
2781         .children = {  }
2782 };
2783 /*! \brief REST handler for /api-docs/channels.json */
2784 static struct stasis_rest_handlers channels_channelId_variable = {
2785         .path_segment = "variable",
2786         .callbacks = {
2787                 [AST_HTTP_GET] = ast_ari_channels_get_channel_var_cb,
2788                 [AST_HTTP_POST] = ast_ari_channels_set_channel_var_cb,
2789         },
2790         .num_children = 0,
2791         .children = {  }
2792 };
2793 /*! \brief REST handler for /api-docs/channels.json */
2794 static struct stasis_rest_handlers channels_channelId_snoop_snoopId = {
2795         .path_segment = "snoopId",
2796         .is_wildcard = 1,
2797         .callbacks = {
2798                 [AST_HTTP_POST] = ast_ari_channels_snoop_channel_with_id_cb,
2799         },
2800         .num_children = 0,
2801         .children = {  }
2802 };
2803 /*! \brief REST handler for /api-docs/channels.json */
2804 static struct stasis_rest_handlers channels_channelId_snoop = {
2805         .path_segment = "snoop",
2806         .callbacks = {
2807                 [AST_HTTP_POST] = ast_ari_channels_snoop_channel_cb,
2808         },
2809         .num_children = 1,
2810         .children = { &channels_channelId_snoop_snoopId, }
2811 };
2812 /*! \brief REST handler for /api-docs/channels.json */
2813 static struct stasis_rest_handlers channels_channelId_dial = {
2814         .path_segment = "dial",
2815         .callbacks = {
2816                 [AST_HTTP_POST] = ast_ari_channels_dial_cb,
2817         },
2818         .num_children = 0,
2819         .children = {  }
2820 };
2821 /*! \brief REST handler for /api-docs/channels.json */
2822 static struct stasis_rest_handlers channels_channelId = {
2823         .path_segment = "channelId",
2824         .is_wildcard = 1,
2825         .callbacks = {
2826                 [AST_HTTP_GET] = ast_ari_channels_get_cb,
2827                 [AST_HTTP_POST] = ast_ari_channels_originate_with_id_cb,
2828                 [AST_HTTP_DELETE] = ast_ari_channels_hangup_cb,
2829         },
2830         .num_children = 14,
2831         .children = { &channels_channelId_continue,&channels_channelId_redirect,&channels_channelId_answer,&channels_channelId_ring,&channels_channelId_dtmf,&channels_channelId_mute,&channels_channelId_hold,&channels_channelId_moh,&channels_channelId_silence,&channels_channelId_play,&channels_channelId_record,&channels_channelId_variable,&channels_channelId_snoop,&channels_channelId_dial, }
2832 };
2833 /*! \brief REST handler for /api-docs/channels.json */
2834 static struct stasis_rest_handlers channels = {
2835         .path_segment = "channels",
2836         .callbacks = {
2837                 [AST_HTTP_GET] = ast_ari_channels_list_cb,
2838                 [AST_HTTP_POST] = ast_ari_channels_originate_cb,
2839         },
2840         .num_children = 2,
2841         .children = { &channels_create,&channels_channelId, }
2842 };
2843
2844 static int unload_module(void)
2845 {
2846         ast_ari_remove_handler(&channels);
2847         stasis_app_unref();
2848         return 0;
2849 }
2850
2851 static int load_module(void)
2852 {
2853         int res = 0;
2854         stasis_app_ref();
2855         res |= ast_ari_add_handler(&channels);
2856         if (res) {
2857                 unload_module();
2858                 return AST_MODULE_LOAD_DECLINE;
2859         }
2860
2861         return AST_MODULE_LOAD_SUCCESS;
2862 }
2863
2864 AST_MODULE_INFO(ASTERISK_GPL_KEY, AST_MODFLAG_DEFAULT, "RESTful API module - Channel resources",
2865         .support_level = AST_MODULE_SUPPORT_CORE,
2866         .load = load_module,
2867         .unload = unload_module,
2868         .nonoptreq = "res_ari,res_stasis",
2869 );