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